commit 6550dcd9e879806d359d0549a2f045c70430ac74 Author: disclearing <46827438+disclearing@users.noreply.github.com> Date: Mon Sep 12 23:34:05 2022 +0100 All src diff --git a/bungee-master@696956eaecd/.gitignore b/bungee-master@696956eaecd/.gitignore new file mode 100644 index 0000000..ad7f541 --- /dev/null +++ b/bungee-master@696956eaecd/.gitignore @@ -0,0 +1,8 @@ + +\.idea/ + +target/classes/ + +target/ + +*.iml \ No newline at end of file diff --git a/bungee-master@696956eaecd/README.md b/bungee-master@696956eaecd/README.md new file mode 100644 index 0000000..63f8f25 --- /dev/null +++ b/bungee-master@696956eaecd/README.md @@ -0,0 +1,2 @@ +First commit. +test \ No newline at end of file diff --git a/bungee-master@696956eaecd/pom.xml b/bungee-master@696956eaecd/pom.xml new file mode 100644 index 0000000..f45535f --- /dev/null +++ b/bungee-master@696956eaecd/pom.xml @@ -0,0 +1,146 @@ + + 4.0.0 + + net.grandtheftmc + bungee + 1.0.6 + Bungee + + + + bungee-repo + https://oss.sonatype.org/content/groups/public/ + + + md_5-snapshots + http://repo.md-5.net/content/repositories/snapshots/ + + + nexus-release + http://nexus.grandtheftmc.net/content/repositories/releases + + + + + + nexus-release + Internal Releases + http://nexus.grandtheftmc.net/content/repositories/releases + + + nexus-snapshot + Internal Snapshots + http://nexus.grandtheftmc.net/content/repositories/snapshots + + + + + + net.md-5 + bungeecord-api + LATEST + provided + + + com.imaginarycode.minecraft + RedisBungee + 0.3.6-SNAPSHOT + provided + + + org.json + json + 20131018 + compile + + + com.authy + authy-java + LATEST + + + net.grandtheftmc + common + 1.1.1 + compile + + + redis.clients + jedis + 2.8.0 + jar + compile + + + com.google.code.gson + gson + 2.8.0 + compile + + + com.google.guava + guava + 21.0 + compile + + + org.apache.commons + commons-pool2 + LATEST + + + com.zaxxer + HikariCP + 2.6.0 + + + + + UTF-8 + 1.8 + 1.8 + + + + + + org.apache.maven.plugins + maven-shade-plugin + + Bungee + + + + package + + shade + + + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.8 + true + + + default-deploy + deploy + + deploy + + + + + nexus + http://nexus.grandtheftmc.net/ + true + + + + + \ No newline at end of file diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/Bungee.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/Bungee.java new file mode 100644 index 0000000..b7a431e --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/Bungee.java @@ -0,0 +1,305 @@ +package net.grandtheftmc.Bungee; + +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; + +import com.imaginarycode.minecraft.redisbungee.RedisBungee; + +import net.grandtheftmc.ServerType; +import net.grandtheftmc.ServerTypeId; +import net.grandtheftmc.Bungee.authy.AuthyManager; +import net.grandtheftmc.Bungee.commands.AuthyCommand; +import net.grandtheftmc.Bungee.commands.FindCommand; +import net.grandtheftmc.Bungee.commands.GlobalMessageCommand; +import net.grandtheftmc.Bungee.commands.HelpCommand; +import net.grandtheftmc.Bungee.commands.HubCommand; +import net.grandtheftmc.Bungee.commands.MotdCommand; +import net.grandtheftmc.Bungee.commands.PermsCommand; +import net.grandtheftmc.Bungee.commands.PlaytimeCommand; +import net.grandtheftmc.Bungee.commands.ServerCommand; +import net.grandtheftmc.Bungee.commands.StaffChatCommand; +import net.grandtheftmc.Bungee.database.BaseDatabase; +import net.grandtheftmc.Bungee.help.HelpCore; +import net.grandtheftmc.Bungee.listeners.Chat; +import net.grandtheftmc.Bungee.listeners.Connect; +import net.grandtheftmc.Bungee.listeners.Disconnect; +import net.grandtheftmc.Bungee.listeners.Kick; +import net.grandtheftmc.Bungee.listeners.Login; +import net.grandtheftmc.Bungee.listeners.Ping; +import net.grandtheftmc.Bungee.redisbungee.RedisListener; +import net.grandtheftmc.Bungee.redisbungee.RedisManager; +import net.grandtheftmc.Bungee.tasks.AnnouncerTask; +import net.grandtheftmc.Bungee.tasks.AuthyTask; +import net.grandtheftmc.Bungee.tasks.PlaytimePurgeTask; +import net.grandtheftmc.Bungee.tasks.ServerStatusTask; +import net.grandtheftmc.Bungee.users.UserManager; +import net.grandtheftmc.jedis.JMessageListener; +import net.grandtheftmc.jedis.JedisChannel; +import net.grandtheftmc.jedis.JedisManager; +import net.grandtheftmc.jedis.message.ServerJoinRequestMessage; +import net.grandtheftmc.slack.Slack; +import net.grandtheftmc.slack.SlackChannel; +import net.grandtheftmc.slack.SlackField; +import net.grandtheftmc.slack.SlackHook; +import net.grandtheftmc.slack.attachment.SlackAttachment; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.plugin.Listener; +import net.md_5.bungee.api.plugin.Plugin; +import net.md_5.bungee.api.plugin.PluginManager; +import net.md_5.bungee.api.scheduler.ScheduledTask; +import net.md_5.bungee.config.Configuration; + +public class Bungee extends Plugin implements Listener { + + // TODO remove + // test commit + + private static Bungee instance; + private RedisManager redisManager; + private AuthyManager authyManager; + private Settings settings; + private UserManager um; + private JedisManager jedisManager; + + public boolean enabled = false; + + public static final boolean GTM = true; + + private HelpCore helpCore; + + private Long startTime; + private ScheduledTask task69; + + public static Bungee getInstance() { + return instance; + } + + public static Settings getSettings() { + return instance.settings; + } + + public static UserManager getUserManager() { + return instance.um; + } + + public static RedisManager getRedisManager() { + return instance.redisManager; + } + + public static AuthyManager getAuthyManager() { + return instance.authyManager; + } + + public static void log(String msg) { + Bungee.getInstance().getLogger().log(Level.INFO, msg); + } + + public static void error(String msg) { + Bungee.getInstance().getLogger().log(Level.SEVERE, msg); + } + + public static void consoleLog(String log) { + } + + public HelpCore getHelpCore() { + return helpCore; + } + + public Long getStartTime() { + return this.startTime; + } + + @Override + public void onEnable() { + instance = this; + + getProxy().getScheduler().runAsync(this, () -> { + this.jedisManager = new JedisManager(); + this.jedisManager.initModule(new ServerTypeId(ServerType.PROXY, -1), JedisChannel.SERVER_QUEUE, GTM ? "172.16.0.1" : "databasesql", 5555, GTM ? "gtmredispass" : "redispass"); + this.jedisManager.getModule(JedisChannel.SERVER_QUEUE).registerListener(ServerJoinRequestMessage.class, new QueueListener()); + }); + + this.settings = new Settings(); + this.load(); + this.um = new UserManager(); + this.registerCommands(); + this.registerListeners(); + new AnnouncerTask(); + new ServerStatusTask(); + new PlaytimePurgeTask(); + new AuthyTask(); + this.startTime = System.currentTimeMillis(); + + enabled = true; + } + + @Override + public void onDisable() { + if(this.task69 != null && this.task69.getTask() != null) + this.task69.cancel(); + + for(JedisChannel channel : this.jedisManager.getJedisModules().keySet()) { + this.jedisManager.getModule(channel).disconnect(); + } + } + + public void registerCommands() { + PluginManager pm = ProxyServer.getInstance().getPluginManager(); + for (String st : this.settings.getServers().keySet()) + pm.registerCommand(this, new ServerCommand(st, this.jedisManager)); +// pm.registerCommand(this, new AltCommand()); + pm.registerCommand(this, new GlobalMessageCommand()); + pm.registerCommand(this, new HelpCommand()); + pm.registerCommand(this, new HubCommand(this.jedisManager, "hub")); + pm.registerCommand(this, new HubCommand(this.jedisManager, "lobby")); + pm.registerCommand(this, new HubCommand(this.jedisManager, "gtm")); + pm.registerCommand(this, new HubCommand(this.jedisManager, "vice")); + pm.registerCommand(this, new MotdCommand()); + pm.registerCommand(this, new PermsCommand()); +// pm.registerCommand(this, new SeenCommand()); + pm.registerCommand(this, new StaffChatCommand()); + pm.registerCommand(this, new PlaytimeCommand()); + pm.registerCommand(this, new AuthyCommand()); + pm.registerCommand(this, new FindCommand()); + } + + private void registerListeners() { + PluginManager pm = ProxyServer.getInstance().getPluginManager(); + pm.registerListener(this, new Chat()); + pm.registerListener(this, new Disconnect()); + pm.registerListener(this, new Login()); + pm.registerListener(this, new Connect()); + pm.registerListener(this, new Kick()); + pm.registerListener(this, new Ping()); + pm.registerListener(this, new RedisListener()); + + getRedisManager().getRedisAPI().registerPubSubChannels(getRedisManager().getMessageChannel()); + } + + private void load() { + this.settings.setMySQLConfig(Utils.loadConfigFromMaster("mysql")); +// this.settings.setBATConfig(BAT.getInstance().getConfiguration()); + this.settings.setPermsConfig(Utils.loadConfig("perms")); + this.settings.setMotdConfig(Utils.loadConfig("motd")); + this.settings.setGtmConfig(Utils.loadConfig("gtmconfig")); + + this.settings.setHelpConfig(Utils.loadConfig("help")); + //Init help core. + this.helpCore = new HelpCore(this.settings.getHelpConfiguration()); + + this.settings.setMotd(this.settings.getMotdConfig().getString("motd")); + this.loadMySQL(); + if (this.getProxy().getPluginManager().getPlugin("RedisBungee") != null) { + this.redisManager = new RedisManager(RedisBungee.getApi()); + } else { + error("RedisBungee not found!"); + } + + this.authyManager = new AuthyManager(); + } + + private void loadMySQL() { + Configuration c = this.settings.getMySQLConfig(); + this.settings.setHost(c.getString("mysql.host")); + this.settings.setPort(c.getString("mysql.port")); + this.settings.setDatabase(c.getString("mysql.database")); + this.settings.setUser(c.getString("mysql.user")); + this.settings.setPassword(c.getString("mysql.password")); + + BaseDatabase.getInstance().init( + this.settings.getHost(), + Integer.parseInt(this.settings.getPort()), + this.settings.getDatabase(), + this.settings.getUser(), + this.settings.getPassword() + ); + } + + private void initHubPinger() { + for (String str : getProxy().getServers().keySet()) { + Utils.SERVERS.putIfAbsent(getProxy().getServerInfo(str), true); + } + + task69 = getProxy().getScheduler().schedule(this, () -> { + for(ServerInfo server : Utils.SERVERS.keySet()) { + if(!Utils.SERVERS.get(server)) continue; + getProxy().getScheduler().runAsync(this, () -> server.ping((serverPing, throwable) -> { + if(throwable != null) { + Utils.SERVERS.put(server, false); + + String[] serv = getServerType(server.getName()); + Slack.send(SlackChannel.PRODUCTION_ALERTS, SlackHook.SERVER_HEARTBEAT, + new SlackAttachment("Server down! " + server.getName()) + .setColor("#e01563") + .setAuthorName("BungeeCord") + .addFields( + new SlackField().setTitle("Server Type").setValue(serv[0]).setShorten(true) + ) + .addFields( + new SlackField().setTitle("Identifier").setValue(serv[1]).setShorten(true) + ) + .addFields( + new SlackField().setTitle("Triggered By").setValue(throwable.getLocalizedMessage()).setShorten(false) + ) + .setFooter("Timestamp") + ); + } + else { + Utils.SERVERS.put(server, true); + } + })); + } + }, 10, 30, TimeUnit.SECONDS); + } + + public String[] getServerType(String server) { + String id = "-1"; + ServerType type = ServerType.OPERATOR; + if(server.toLowerCase().startsWith("hub")) { + id = server.toLowerCase().split("hub")[1]; + type = ServerType.HUB; + } + + if(server.toLowerCase().startsWith("gtm")) { + id = server.toLowerCase().split("gtm")[1]; + type = ServerType.GTM; + } + + if(server.toLowerCase().startsWith("vice")) { + id = server.toLowerCase().split("vice")[1]; + type = ServerType.VICE; + } + + if(server.toLowerCase().startsWith("creative")) { + id = server.toLowerCase().split("creative")[1]; + type = ServerType.CREATIVE; + } + + return new String[]{ type == ServerType.OPERATOR ? server.toUpperCase() : type.name(), id }; + } + + public class QueueListener implements JMessageListener { + + @Override + public void onReceive(ServerTypeId serverTypeId, ServerJoinRequestMessage message) { + if(!enabled) return; + + ProxiedPlayer player = instance.getProxy().getPlayer(message.getUniqueId()); + if(player == null) return; + ServerInfo info = instance.getProxy().getServerInfo(message.getTargetServer().getServerType().getServerName() + message.getTargetServer().getId()); + if(info != null) { + info.ping((serverPing, throwable) -> { + if(serverPing != null) { + player.connect(info); + player.sendMessage(Utils.f("&aSending you to server!")); + } + }); + } + else { + player.sendMessage(Utils.f("&cThis server cannot be recognised!")); + } + } + } +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/Lang.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/Lang.java new file mode 100644 index 0000000..ae48f34 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/Lang.java @@ -0,0 +1,80 @@ +package net.grandtheftmc.Bungee; + +import net.md_5.bungee.api.chat.TextComponent; + +public enum Lang { + + GMSG(" &a&lGMSG&8&l> "), + MSG(" &a&lMSG&8&l> "), + BUCKS(" &a&lBUCKS&8&l> "), + BUCKS_ADD(" &a&lBUCKS&8&l> &a&l+&a $&l"), + BUCKS_TAKE(" &a&lBUCKS&8&l> &c&l-&c $&l"), + TOKENS(" &e&lTOKENS&8&l> "), + TOKENS_ADD(" &e&lTOKENS&8&l> &e&l+&e&l"), + TOKENS_TAKE(" &e&lTOKENS&8&l> &c&l-&c&l"), + MONEY(" &3&lMONEY&8&l> "), + MONEY_ADD(" &3&lMONEY&8&l> &a&l+&a $&l"), + MONEY_TAKE(" &3&lMONEY&8&l> &c&l-&c $&l"), + ATM(" &3&lATM&8&l> "), + BANK(" &3&lBANK&8&l> "), + BANK_ADD("&3&lBANK&8&l> &a&l+&a $&l"), + BANK_TAKE("&3&lBANK&8&l> &c&l-&c $&l"), + GTM(" &7&l" + (Bungee.GTM ? "GTM" : "GTA") + "&8&l> "), + PREFS(" &5&lPREFS&8&l> "), + AMMUNATION(" &9&lAMMU&4&lNATION&8&l> "), + WANTED(" &c&lWANTED&8&l> "), + TAXI(" &e&lTAXI&8&l> "), + SHOP(" &a&lSHOP&8&l> "), + TRASH_CAN(" &7&lTRASH CAN&8&l> "), + HEY(" &c&lHEY&8&l> "), + COMBATTAG(" &7&lCOMBATTAG&8&l> "), + GUARDPETS("&c&l GUARD PETS&8&l> "), + BOUNTIES(" &5&lBOUNTIES&8&l> "), + VOTE(" &e&lVOTE&8&l> "), + TOKEN_SHOP(" &e&lTOKEN SHOP&8&l> "), + KITS(" &b&lKITS&8&l> "), + RANKUP(" &a&lRANKUP&8&l> "), + RANKS(" &a&lRANKS&8&l> "), + JOBS(" &3&lJOBS&8&l> "), + COP_MODE(" &3&lCOP MODE&8&l> "), + HITMAN_MODE(" &8&lHITMAN MODE> "), + GPS(" &7&lGPS&8&l> "), + HOUSES(" &3&lHOUSES&8&l> "), + TUTORIALS(" &2&lTUTORIALS&8&l> "), + GANGS(" &a&lGANGS&8&l> "), + NOPERM("&cYou want me to clap yo ass? You ain't got permission for this shit!"), + NOTPLAYER("&cDawg you ain't a player!"), + STAFF(" &c&lSTAFF&8&l> "), + HELP(" &d&lHELP&8&l> "), + GSPY(" &a&lGSPY&8&l> "), + PERMS(" &c&lGPERMS&8&l> "), + VERIFICATION(" &c&lVERIFICATION&8&l> "); + + private final String s; + + Lang(String s) { + this.s = s; + } + + public String s() { + return Utils.f(this.s); + } + + @Override + public String toString() { + return Utils.f(this.s); + } + + public String f(String s) { + return Utils.f(this.s + s); + } + + public TextComponent ft(String s) { + return Utils.ft(this.s + s); + } + + public TextComponent st() { + return Utils.ft(this.s); + } + +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/Settings.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/Settings.java new file mode 100644 index 0000000..d489b57 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/Settings.java @@ -0,0 +1,132 @@ +package net.grandtheftmc.Bungee; + +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.config.Configuration; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +public class Settings { + private final Map servers = new HashMap<>(); + private Configuration config; + private Configuration mysqlConfig; + private Configuration permsConfig; + private Configuration motdConfig; + private Configuration helpConfig; + private Configuration gtmConfig; + private String motd; + private String host = "error"; + private String port = "error"; + private String database = "error"; + private String user = "error"; + private String password = "error"; + + Settings() { + this.servers.clear(); + Set s = ProxyServer.getInstance().getServers().keySet(); + for (String c : s) + this.servers.put(c, c); + this.servers.put("creative", "creative1"); + this.servers.put("crea", "creative1"); + this.servers.put("gtm", "gtm1"); + this.servers.put("legacy", "legacygtm"); + this.servers.put("gtmlegacy", "legacygtm"); + this.servers.put("oldgtm", "legacy"); + this.servers.put("gliders", "gliders1"); + this.servers.put("dev", "gtm0"); + this.servers.put("vice","vice1"); + } + + public Configuration getMySQLConfig() { + return this.mysqlConfig; + } + + public void setMySQLConfig(Configuration mysqlConfig) { + this.mysqlConfig = mysqlConfig; + } + + public Configuration getHelpConfiguration(){ + return this.helpConfig; + } + + public void setHelpConfig(Configuration config) { + this.helpConfig = config; + } + + public Map getServers() { + return this.servers; + } + + public Configuration getPermsConfig() { + return this.permsConfig; + } + + public void setPermsConfig(Configuration permsConfig) { + this.permsConfig = permsConfig; + } + + public String getMotd() { + return Utils.f(this.motd); + } + + public void setMotd(String motd) { + this.motd = motd; + } + + public Configuration getMotdConfig() { + return this.motdConfig; + } + + public void setMotdConfig(Configuration motdConfig) { + this.motdConfig = motdConfig; + } + + public Configuration getGtmConfig() { + return this.gtmConfig; + } + + public void setGtmConfig(Configuration gtmConfig) { + this.gtmConfig = gtmConfig; + } + + public String getHost() { + return this.host; + } + + public void setHost(String host) { + this.host = host; + } + + public String getPort() { + return this.port; + } + + public void setPort(String port) { + this.port = port; + } + + public String getDatabase() { + return this.database; + } + + public void setDatabase(String database) { + this.database = database; + } + + public String getUser() { + return this.user; + } + + public void setUser(String user) { + this.user = user; + } + + public String getPassword() { + return this.password; + } + + public void setPassword(String password) { + this.password = password; + } +} \ No newline at end of file diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/Utils.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/Utils.java new file mode 100644 index 0000000..99b90fb --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/Utils.java @@ -0,0 +1,386 @@ +package net.grandtheftmc.Bungee; + +import net.grandtheftmc.Bungee.redisbungee.data.DataType; +import net.grandtheftmc.Bungee.users.User; +import net.grandtheftmc.Bungee.users.UserRank; +import net.grandtheftmc.Bungee.utils.DefaultFontInfo; +import net.grandtheftmc.Bungee.utils.ServerStatus; +import net.grandtheftmc.Bungee.utils.TimeFormatter; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.chat.*; +import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.config.Configuration; +import net.md_5.bungee.config.ConfigurationProvider; +import net.md_5.bungee.config.YamlConfiguration; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +public final class Utils { + public static final ConcurrentHashMap SERVERS = new ConcurrentHashMap<>(); + private static final Random RANDOM = new Random(); + public static Collection recentHelps = new ArrayList<>(); + + private Utils() { + } + + public static TextComponent ft(String s) { + return new TextComponent(ChatColor.translateAlternateColorCodes('&', s)); + } + + public static String fc(String s) { + s = Utils.f(s); + int messagePxSize = 0; + boolean previousCode = false; + boolean isBold = false; + + for (char c : s.toCharArray()) { + if (c == '§') { + previousCode = true; + } else if (previousCode) { + previousCode = false; + isBold = c == 'l' || c == 'L'; + } else { + DefaultFontInfo dFI = DefaultFontInfo.getDefaultFontInfo(c); + messagePxSize += isBold ? dFI.getBoldLength() : dFI.getLength(); + messagePxSize++; + } + } + + int halvedMessageSize = messagePxSize / 2; + int toCompensate = 154 - halvedMessageSize; + int spaceLength = DefaultFontInfo.SPACE.getLength() + 1; + int compensated = 0; + StringBuilder sb = new StringBuilder(); + while (compensated < toCompensate) { + sb.append(' '); + compensated += spaceLength; + } + return sb + s; + } + + public static String[] fc(String[] array) { + if (array == null) + return null; + String[] a = new String[array.length]; + for (int i = 0; i < array.length; i++) + a[i] = Utils.fc(array[i]); + return a; + } + + public static void loop(int amount, Runnable runnable) { + for (int i = 0; i < amount; i++) runnable.run(); + } + + public static String f(String s) { + return ChatColor.translateAlternateColorCodes('&', s); + } + + public static void redisChatLog(String sender, String msg) { + Map chatLogSerializd = new HashMap<>(); + chatLogSerializd.put("type", "staff"); + chatLogSerializd.put("sender", sender); + chatLogSerializd.put("message", msg); + Bungee.getRedisManager().sendMessage(Bungee.getRedisManager().serialize(DataType.LOG, chatLogSerializd)); + } + + public static void chatLog(String sender, String msg) { + String fileName = new SimpleDateFormat("MM-dd-yy").format(new Date()); + File file = new File("gtmlogs/gtmlog_staff_" + fileName + ".txt"); + try { + if (!file.isFile() || !file.exists()) { + file.createNewFile(); + } + String date = new SimpleDateFormat("MM/dd/yy - h:mm a").format(new Date()); + String message = date + " - " + sender + ": " + msg + "\n"; + FileWriter fileWriter = new FileWriter(file, true); + BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); + bufferedWriter.write(message); + bufferedWriter.close(); + } catch (IOException exception) { + exception.printStackTrace(); + } + } + + public static void log(String msg, String logName) { + String fileName = new SimpleDateFormat("MM-dd-yy").format(new Date()); + File file = new File("gtmlogs/gtmlog_" + logName + "_" + fileName + ".txt"); + try { + if (!file.isFile() || !file.exists()) { + file.createNewFile(); + } + String date = new SimpleDateFormat("MM/dd/yy - h:mm a").format(new Date()); + String message = date + " - " + msg + "\n"; + FileWriter fileWriter = new FileWriter(file, true); + BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); + bufferedWriter.write(message); + bufferedWriter.close(); + } catch (IOException exception) { + exception.printStackTrace(); + } + } + + public static void redisStaffChat(String sender, String msg) { + Map staffChatSerialized = new HashMap<>(); + staffChatSerialized.put("sender", sender); + staffChatSerialized.put("message", msg); + + Bungee.getRedisManager().sendMessage(Bungee.getRedisManager().serialize(DataType.STAFFCHAT, staffChatSerialized)); + } + + public static void staffChat(String name, String msg) { + String prefix = "&7[&a&l" + name + "&7] "; + ComponentBuilder a = new ComponentBuilder(Lang.STAFF.f(prefix)) + .append(msg) + .color(ChatColor.GREEN); + for (String string : msg.split(" ")) { + if (string.matches("^((https?|ftp)://|(www|ftp)\\.)?[a-z0-9-]+(\\.[a-z0-9-]+)+([/?].*)?$")) { + a.event(new ClickEvent(ClickEvent.Action.OPEN_URL, string)); + break; + } + } + ProxyServer.getInstance().getPlayers().stream().filter(player -> player.hasPermission("staffchat.use")).forEach(player -> player.sendMessage(a.create())); + Bungee.log(Lang.STAFF.f("[" + name + "] " + msg)); + } + + /** + * Called when a help request has been invoked on the Redis listener. This forwards the request to all staff. + * + * @param playerName Player who requested help. + * @param msg What did they ask for help with? + * @param server What server is the player on. + */ + public static void redisHelp(String playerName, String msg, String server) { + //can't pass proxy player here as staff and help requester may be on different instances + BaseComponent[] a = new ComponentBuilder(Lang.HELP.f("&7[&8" + playerName + "&7] ")) + .append(msg) + .color(ChatColor.GREEN) + .event(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/gmsg " + playerName + " ")) + .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(Utils.f("&7User is on server &a" + server)).create())) + .create(); + + ProxyServer.getInstance().getPlayers().stream().filter(p -> p.hasPermission("staffchat.use") || p.getName().equalsIgnoreCase(playerName)).forEach(p -> p.sendMessage(a)); + Bungee.log(Lang.HELP.f("&7[&8" + playerName + "&7] &r" + msg)); + } + + @Deprecated + public static void help(ProxiedPlayer player, String msg) { + if (msg.split(" ").length <= 1) { + player.sendMessage(Lang.HELP.f("&7Only one word? Try to describe your problem more accurately.")); + return; + } + + String name = getColoredName(player); + BaseComponent[] a = new ComponentBuilder(Lang.HELP.f("&7[&a&l" + name + "&7] ")) + .append(msg).color(ChatColor.GREEN) + .event(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/gmsg " + player.getName() + " ")) + .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(Utils.f("&7User is on server &a" + player.getServer().getInfo().getName())).create())) + .create(); + + ProxyServer.getInstance().getPlayers().stream().filter(p -> p.hasPermission("staffchat.use") || p.equals(player)).forEach(p -> p.sendMessage(a)); + Bungee.log(Lang.HELP.f("&7[&a&l" + name + "&7] &r" + msg)); + player.sendMessage(Lang.HELP.f("&7Your message has been sent to all online staff. Use &a&l\"/gmsg \"&7 to talk to them individually.")); + addRecentHelp(player.getName()); + } + + public static void msg(ProxiedPlayer player, String msg) { + player.sendMessage(ft(msg)); + } + + public static void msg(CommandSender player, String msg) { + player.sendMessage(ft(msg)); + } + + public static void redisGlobalMessage(ProxiedPlayer sender, String target, String msg) { + if (!Bungee.getRedisManager().isPlayerOnline(target)) { + msg(sender, "&7That player is not on the server!"); + return; + } + + String to = Lang.GMSG.f("&7[" + getColoredName(sender) + "&7 -> me] &r" + msg); + String from = Lang.GMSG.f("&7[me -> " + getColoredName(target) + "&7] &r" + msg); + String ss = Lang.GSPY.f("&7[" + getColoredName(sender) + "&7 -> " + getColoredName(target) + "&7] &r" + msg); + msg(sender, from); + + Map toSerialized = new HashMap<>(); + toSerialized.put("sender", sender.getName()); + toSerialized.put("target", target); + toSerialized.put("message", to); + Bungee.getRedisManager().sendMessage(Bungee.getRedisManager().serialize(DataType.GMSG, toSerialized)); + + + Map socialSpySerialized = new HashMap<>(); + socialSpySerialized.put("message", ss); + Bungee.getRedisManager().sendMessage(Bungee.getRedisManager().serialize(DataType.SOCIALSPY, socialSpySerialized)); + } + + @Deprecated + public static void globalMessage(ProxiedPlayer sender, ProxiedPlayer target, String msg) { + if (target == null) { + msg(sender, "&7That player is not on the server!"); + return; + } + + String to = Lang.GMSG.f("&7[" + getColoredName(sender) + "&7 -> me] &r" + msg); + String from = Lang.GMSG.f("&7[me -> " + getColoredName(target) + "&7] &r" + msg); + String ss = Lang.GSPY.f("&7[" + getColoredName(sender) + "&7 -> " + getColoredName(target) + "&7] &r" + msg); + String url = ""; + for (String string : msg.split(" ")) { + if (string.matches("^((https?|ftp)://|(www|ftp)\\.)?[a-z0-9-]+(\\.[a-z0-9-]+)+([/?].*)?$")) { + url = string; + break; + } + } + + BaseComponent[] a = new ComponentBuilder(to) + .event(url.isEmpty() ? new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/gmsg " + sender.getName() + " ") + : new ClickEvent(ClickEvent.Action.OPEN_URL, url)) + .create(); + target.sendMessage(a); + msg(sender, from); + Bungee.log(Lang.GMSG.f("&7[" + sender.getName() + " -> " + target.getName() + "&7] &r" + msg)); + log("[" + sender.getName() + " -> " + target.getName() + "] " + msg, "gmsglog"); + socialSpy(ss, sender, target); + } + + public static void socialSpy(String msg, ProxiedPlayer sender, ProxiedPlayer target) { + Bungee.getUserManager().getLoadedUsers().forEach(user -> { + if (Bungee.getInstance().getProxy().getPlayer(user.getUUID()) == null) return; + if (!user.isRank(UserRank.ADMIN)) return; + ProxiedPlayer staff = Bungee.getInstance().getProxy().getPlayer(user.getUUID()); + if (user.getSocialSpy()) { + if (!staff.getName().equals(sender.getName()) || !staff.getName().equals(target.getName())) { + staff.sendMessage(Utils.f(msg)); + } + } + }); + } + + public static Configuration loadConfigFile(File file) { + Configuration c = null; + try { + if (!file.exists()) + file.createNewFile(); + c = ConfigurationProvider.getProvider(YamlConfiguration.class).load(file); + } catch (IOException e) { + e.printStackTrace(); + } + return c; + } + + public static Configuration loadConfig(String src) { + return loadConfigFile(new File(src + ".yml")); + } + + public static Configuration loadConfigFromMaps(String src) { + return loadConfigFile(new File("/home/mcservers/development/master/maps/" + src + ".yml")); + } + + public static Configuration loadConfigFromMaster(String src) { + return loadConfigFile(new File("/home/mcservers/development/master/" + src + ".yml")); + } + + public static void saveConfigFile(Configuration c, File file) { + try { + if (!file.exists()) + file.createNewFile(); + ConfigurationProvider.getProvider(YamlConfiguration.class).save(c, file); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static void saveConfig(Configuration c, String src) { + saveConfigFile(c, new File(src + ".yml")); + } + + public static Random getRandom() { + return RANDOM; + } + + public static List getPlayerNames() { + return ProxyServer.getInstance().getPlayers().stream().map(CommandSender::getName).collect(Collectors.toList()); + } + + public static void addRecentHelp(String player) { + recentHelps.add(player); + Bungee.getInstance().getProxy().getScheduler().schedule(Bungee.getInstance(), new Runnable() { + @Override + public void run() { + recentHelps.remove(player); + } + }, 30, TimeUnit.SECONDS); + } + + public static ServerInfo getRandomHub() { + List hubs = Bungee.getInstance().getProxy().getServers().entrySet().stream().filter(map -> map.getKey().startsWith("hub")).map(Map.Entry::getValue).collect(Collectors.toList()); + return getLeastPlayers(hubs).orElse(hubs.get(Utils.getRandom().nextInt(hubs.size()))); + } + + public static ServerInfo getRandomServer(String type) { + List servs = Bungee.getInstance().getProxy().getServers().entrySet().stream().filter(map -> map.getKey().startsWith(type)).map(Map.Entry::getValue).collect(Collectors.toList()); + return getLeastPlayers(servs).orElse(servs.get(Utils.getRandom().nextInt(servs.size()))); + } + + public static Optional getLeastPlayers(Collection servers) { + Optional leastPlayers = Optional.empty(); + for (ServerInfo server : servers) { + if (!isOnline(server)) { + Bungee.error(server.getName() + " is offline"); + continue; + } + + if (server.getPlayers().isEmpty()) { + leastPlayers = Optional.of(server); + break; + } + + if (!leastPlayers.isPresent()) { + leastPlayers = Optional.of(server); + continue; + } + + if (server.getPlayers().size() < leastPlayers.get().getPlayers().size()) { + leastPlayers = Optional.of(server); + } + } + return leastPlayers; + } + + public static boolean isOnline(ServerInfo serverInfo) { + ServerStatus serverStatus = ServerStatus.getServerStatus(serverInfo); + return serverStatus.isOnline(); + } + + public static String getColoredName(ProxiedPlayer player) { + Optional userOptional = Bungee.getUserManager().getLoadedUser(player.getUniqueId()); + return Utils.f(userOptional.map(user -> Utils.f(user.getUserRank().getColor() + player.getName())).orElseGet(() -> "&8" + player.getName())); + } + + public static String getColoredName(String player) { + return Utils.f("&8" + player); + } + + public static String formatPlaytime(Long playtime) { + TimeFormatter tf = new TimeFormatter(TimeUnit.MILLISECONDS, playtime); + return tf.getHours() + "h " + tf.getMinutes() + "m"; + } + + public static boolean isStaff(String name) { + for (User user : Bungee.getUserManager().getLoadedUsers()) { + if (user.getUsername().equalsIgnoreCase(name)) return true; + } + return false; + } +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/authy/AuthyManager.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/authy/AuthyManager.java new file mode 100644 index 0000000..317666e --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/authy/AuthyManager.java @@ -0,0 +1,42 @@ +package net.grandtheftmc.Bungee.authy; + +import com.authy.AuthyApiClient; +import com.authy.api.Hash; +import com.authy.api.Token; +import com.authy.api.User; +import net.grandtheftmc.Bungee.Bungee; + +public class AuthyManager { + private final String apiKey = Bungee.getSettings().getGtmConfig().getString("authy-api-key"); + private AuthyApiClient authyApiClient; + + public AuthyManager() { + init(); + } + + public void init() { + this.authyApiClient = new AuthyApiClient(apiKey); + } + + public User createUser(String email, String phoneNumber, String countryCode) { + return this.authyApiClient.getUsers().createUser(email, phoneNumber, countryCode); + } + + public String verifyToken(int authy_id, String userToken) { + Token verification = this.authyApiClient.getTokens().verify(authy_id, userToken); + if (verification.isOk()) { + return "400"; + } else { + return verification.getError().toString(); + } + } + + public String sendSMSToken(int authy_id) { + Hash sms = this.authyApiClient.getUsers().requestSms(authy_id); + if (sms.isOk()) { + return "400"; + } else { + return sms.getError().toString(); + } + } +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/AltCommand.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/AltCommand.java new file mode 100644 index 0000000..21b7fe7 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/AltCommand.java @@ -0,0 +1,72 @@ +package net.grandtheftmc.Bungee.commands; + +//import fr.Alphart.BAT.Modules.Core.LookupFormatter; +import net.grandtheftmc.Bungee.Bungee; +import net.grandtheftmc.Bungee.Utils; +import net.grandtheftmc.Bungee.utils.RequestRateLimiter; +import net.grandtheftmc.Bungee.utils.TabComplete; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.plugin.Command; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.UUID; + +public class AltCommand extends Command { + + public AltCommand() { + super("alt", "bat.lookup.ip", "alts"); + } + + @Override + public void execute(CommandSender s, String[] args) { + /*if (args.length != 1) { + s.sendMessage(Utils.ft("&c/alt ")); + return; + } + if (!(s instanceof ProxiedPlayer)) { + s.sendMessage(Utils.ft("&cYou are not a player!")); + return; + } + ProxiedPlayer p = (ProxiedPlayer) s; + UUID sender = p.getUniqueId(); + + if (!RequestRateLimiter.requestCmd(sender)) { + s.sendMessage(Utils.ft("&cYou have issued this command recently, please wait a second.")); + return; + } + + String player = args[0]; + s.sendMessage(Utils.ft("&7Looking up player &a" + player + "&7 in the database.")); + ProxyServer.getInstance().getScheduler().runAsync(Bungee.getInstance(), () -> { + ResultSet rs = Bungee.getBATSQL() + .query("select BAT_player,lastip from BAT_players where BAT_player='" + player + "';"); + String name1 = null; + String lastip = null; + try { + if (rs.next()) { + name1 = rs.getString("BAT_player"); + lastip = rs.getString("lastip"); + } + rs.close(); + } catch (SQLException ignored) { + + } + ProxiedPlayer p1 = ProxyServer.getInstance().getPlayer(sender); + if (p1 == null) + return; +// if (lastip == null || name1 == null || !fr.Alphart.BAT.Utils.Utils.validIP(lastip)) { +// p1.sendMessage(Utils.ft("&7That player is not in the database!")); +// return; +// } +// new LookupFormatter().getSummaryLookupIP(lastip).forEach(p1::sendMessage); + });*/ + } + + public Iterable onTabComplete(CommandSender sender, String[] args) { + return TabComplete.onTabComplete(sender, args); + } + +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/AuthyCommand.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/AuthyCommand.java new file mode 100644 index 0000000..8e495bb --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/AuthyCommand.java @@ -0,0 +1,132 @@ +package net.grandtheftmc.Bungee.commands; + +import net.grandtheftmc.Bungee.Bungee; +import net.grandtheftmc.Bungee.Lang; +import net.grandtheftmc.Bungee.Utils; +import net.grandtheftmc.Bungee.users.User; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.plugin.Command; + +import java.util.Optional; + +public class AuthyCommand extends Command { + + public AuthyCommand() { + super("authy", "authy.admin"); + } + + @Override + public void execute(CommandSender s, String[] args) { + if (!(s instanceof ProxiedPlayer)) return; + ProxiedPlayer player = (ProxiedPlayer) s; + Optional userOptional = Bungee.getUserManager().getLoadedUser(player.getUniqueId()); + if (!userOptional.isPresent()) return; + User user = userOptional.get(); + if (args.length == 0) { + sendHelp(player); + return; + } + + if (args.length == 1) { + if (args[0].equalsIgnoreCase("help")) + sendHelp(player); + + else if (args[0].equalsIgnoreCase("countrycodes")) + sendCountryCodes(player); + + return; + } + + else { + if (user.isAuthyVerified()) { + player.sendMessage(Lang.VERIFICATION.ft("&7You are already verified!")); + return; + } + + if (args[0].equalsIgnoreCase("verify")) { + if (args.length != 2) { + sendHelp(player); + } else { + String token = args[1]; + if (user.getAuthyId() == 0) { + player.sendMessage(Lang.VERIFICATION.ft("&cYou must register first!")); + } else { + String result = Bungee.getAuthyManager().verifyToken(user.getAuthyId(), token); + if (result.equals("400")) { + user.setAuthyVerified(true); + player.sendMessage(Lang.VERIFICATION.ft("&aVerification Successful")); + user.setLastIPAddress(player.getAddress().getAddress().getHostAddress()); + } else { + player.sendMessage(Lang.VERIFICATION.ft("&cError! Verification Failed: " + result)); + } + return; + } + } + } + + else if (args[0].equalsIgnoreCase("sendsms")) { + if (user.getAuthyId() == 0) { + player.sendMessage(Lang.VERIFICATION.ft("&cYou must register first!")); + } else { + String result = Bungee.getAuthyManager().sendSMSToken(user.getAuthyId()); + if (result.equals("400")) { + player.sendMessage(Lang.VERIFICATION.ft("&aToken sent via SMS")); + } else { + player.sendMessage(Lang.VERIFICATION.ft("&cError: " + result)); + } + return; + } + } + + else if (args[0].equalsIgnoreCase("register")) { + if (args.length != 4) { + sendHelp(player); + } else { + String email = args[1]; + String phoneNumber = args[2]; + String countryCode = args[3]; + com.authy.api.User authyUser = Bungee.getAuthyManager().createUser(email, phoneNumber, countryCode); + if (authyUser.isOk()) { + user.setAuthyId(authyUser.getId()); + player.sendMessage(Lang.VERIFICATION.ft("&aRegistration Successful")); + } + + else { + player.sendMessage(Lang.VERIFICATION.ft("&cError! Registration Failed: " + authyUser.getError().toString())); + } + return; + } + } + } + } + + public void sendHelp(ProxiedPlayer player) { + player.sendMessage(Lang.VERIFICATION.ft("&7Help")); + player.sendMessage(Utils.ft("&a/authy help &7- Display this information")); + player.sendMessage(Utils.ft("&a/authy verify &7- Verify yourself using your Authy &7 (you must be registered)")); + player.sendMessage(Utils.ft("&a/authy sendsms &7- If not using Authy app request your verification token to be sent via SMS")); + player.sendMessage(Utils.ft("&a/authy register &7- &7Register for verification. " + + "Example command: &a/authy register &bme@grandtheftmc.net 5276449341 1")); + player.sendMessage(Utils.ft("&a/authy countrycodes &7- List all valid country codes")); + } + + public void sendCountryCodes(ProxiedPlayer player) { + player.sendMessage(Lang.VERIFICATION.ft("&7Country Codes")); + player.sendMessages( + "United States of America: 1" , + "Canada: 1" , + "Russia: 7" , + "Netherlands: 31" , + "Belgium: 32" , + "Spain: 34" , + "Italy: 39" , + "United Kingdom: 44" , + "Mexico: 52" , + "Australia: 61" , + "Korea (+South): 82" , + "Korea (+North): gtfo crue" + ); + } + +} \ No newline at end of file diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/FindCommand.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/FindCommand.java new file mode 100644 index 0000000..08540aa --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/FindCommand.java @@ -0,0 +1,37 @@ +package net.grandtheftmc.Bungee.commands; + +import net.grandtheftmc.Bungee.Bungee; +import net.grandtheftmc.Bungee.Lang; +import net.grandtheftmc.Bungee.Utils; +import net.grandtheftmc.Bungee.utils.TabComplete; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.api.plugin.Command; + +public class FindCommand extends Command { + + public FindCommand() { + super("find"); + } + + @Override + public void execute(CommandSender s, String[] args) { + if (args.length != 1) { + s.sendMessage(Utils.ft("&c/find ")); + return; + } + + String target = args[0]; + if (Bungee.getRedisManager().isPlayerOnline(target) && !Utils.isStaff(target)) { + ServerInfo serverInfo = Bungee.getRedisManager().getRedisAPI().getServerFor(Bungee.getRedisManager().getUUIDFromName(target)); + s.sendMessage(Lang.GTM.ft("&a" + target + " &7was found on server &a" + serverInfo.getName().toUpperCase())); + } + else { + s.sendMessage(Lang.GTM.ft("&a" + target + " &7is not online!")); + } + } + + public Iterable onTabComplete(CommandSender sender, String[] args) { + return TabComplete.onTabComplete(sender, args); + } +} \ No newline at end of file diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/GlobalMessageCommand.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/GlobalMessageCommand.java new file mode 100644 index 0000000..6b651a0 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/GlobalMessageCommand.java @@ -0,0 +1,294 @@ +package net.grandtheftmc.Bungee.commands; + +import net.grandtheftmc.Bungee.Bungee; +import net.grandtheftmc.Bungee.Lang; +import net.grandtheftmc.Bungee.Utils; +import net.grandtheftmc.Bungee.redisbungee.RedisManager; +import net.grandtheftmc.Bungee.redisbungee.data.DataType; +import net.grandtheftmc.Bungee.users.User; +import net.grandtheftmc.Bungee.utils.HelpLog; +import net.grandtheftmc.Bungee.utils.TabComplete; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.plugin.Command; +import net.md_5.bungee.api.plugin.TabExecutor; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +public class GlobalMessageCommand extends Command implements TabExecutor { + + public GlobalMessageCommand() { + super( + "globalmessage", + null, + "gmsg", "gmessage", "globalmsg", "gtell", "globaltell", "gwhisper", "globalwhisper", "globalw", "gw", "globalchat", "globalc" + ); + } + + /* + Redis procedure: + ---------------- + - Players may reside on different servers across bungee instances. + 1) Check if name matches, or part matches a player on the current bungee instance. + Yes: Send msg directly. + No: Go to step 2. + 2) Check if name matches, or part matches a player across all redis instances. + Yes: Send GMSG packet on PubSub redis channel. + No: Notify player not found. + */ + + @Override + public void execute(CommandSender s, String[] args) { + if (args.length < 2) { + s.sendMessage(Utils.ft("&c/gmsg ")); + return; + } + + if (!(s instanceof ProxiedPlayer)) { + s.sendMessage(Utils.ft("&cYou are not a player!")); + return; + } + + String sender = s.getName(); + String targetName = null; + ProxiedPlayer senderPlayer = (ProxiedPlayer) s; + + if (args[0].equalsIgnoreCase(senderPlayer.getName())) { + s.sendMessage(Utils.ft("&cYou cannot message yourself!")); + return; + } + + try { + ProxiedPlayer target = null; + + //Try to direct match player name with all players on this proxy instance. + if ((target = ProxyServer.getInstance().getPlayer(args[0])) == null) { + + //Prefix tab matching, if they haven't typed the full name we may still find a match + String search = args[0].toLowerCase(); + for (ProxiedPlayer player : ProxyServer.getInstance().getPlayers()) { + if (player.getName().toLowerCase().startsWith(search)) { + target = player; + targetName = player.getName(); + break; + } + } + + if (target == null) { + //The player we are searching for is not on this bungee instance, try search on redis + + RedisManager mngr = Bungee.getRedisManager(); + + //We fail to find a direct match on redis + if (!mngr.isPlayerOnline(args[0])) { + + //Try a partial match search + for (String redisName : mngr.getRedisAPI().getHumanPlayersOnline()) { + if (redisName.startsWith(search)) { + targetName = redisName; + break; + } + } + } else { + //the player is online, but on another server so send a pub sub msg. + targetName = args[0]; + } + } + } + + //If the player couldn't be found locally, or via redis let the player know. + if (target == null && targetName == null) { + Utils.msg(s, "&7That player is not on the server!"); + return; + } + + else if (targetName != null && targetName.equalsIgnoreCase(senderPlayer.getName())) { + s.sendMessage(Utils.ft("&cYou cannot message yourself!")); + return; + } + + else if (target != null && target.getName().equalsIgnoreCase(senderPlayer.getName())) { + s.sendMessage(Utils.ft("&cYou cannot message yourself!")); + return; + } + + //Build the message + String msg = ""; + for (int i = 1; i < args.length; i++) { + msg += (i > 1 ? " " : "") + args[i]; + } + + + if (target != null) { + //player is on same server so we can message them directly + //This method is deprecated, but still has use in local instances so this should be reviewed. TODO. + String url = ""; + for (String string : msg.split(" ")) { + if (string.matches("^((https?|ftp)://|(www|ftp)\\.)?[a-z0-9-]+(\\.[a-z0-9-]+)+([/?].*)?$")) { + url = string; + break; + } + } + + //Send GMSG to recipient + BaseComponent[] a = new ComponentBuilder(Lang.GMSG.f("&7[" + Utils.getColoredName(senderPlayer) + "&7 -> me] &r" + msg)) + .event(url.isEmpty() ? new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/gmsg " + sender + " ") + : new ClickEvent(ClickEvent.Action.OPEN_URL, url)) + .create(); + target.sendMessage(a); + + //Send GMSG to sender + a = new ComponentBuilder(Lang.GMSG.f("&7[me&7 -> " + Utils.getColoredName(target) + "&7] &r" + msg)) + .event(url.isEmpty() ? new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/gmsg " + target.getName() + " ") + : new ClickEvent(ClickEvent.Action.OPEN_URL, url)) + .create(); + senderPlayer.sendMessage(a); + + //show the player what they said + Optional userOptional; + if (target == null) { + userOptional = Optional.empty(); + } + else { + userOptional = Bungee.getUserManager().getLoadedUser(target.getUniqueId()); + } + + //Color the target name + String coloredName; + if (userOptional.isPresent()) { + coloredName = Utils.f(userOptional.get().getUserRank().getColor() + target.getName()); + } + else { + coloredName = "&8" + target.getName(); + } + + Optional senderOptional = Bungee.getUserManager().getLoadedUser(senderPlayer.getUniqueId()); + + //COlor the senders name + String coloredSenderName; + if (senderOptional.isPresent()) { + coloredSenderName = Utils.f(senderOptional.get().getUserRank().getColor() + senderPlayer.getName()); + } + else { + coloredSenderName = "&8" + senderPlayer.getName(); + } + + //send on social spy + sendSocialSpy(senderPlayer, coloredSenderName, coloredName, targetName, msg); + + //Check if sender is staff, if so sent help_close if needed, this should now let staff get tokens for local reqs. + closeHelp(senderPlayer, target.getName()); + + return; + } + + else { + //player on another redis bungee instance + Map map = new HashMap<>(); + map.put("target", targetName); + map.put("sender", senderPlayer.getName()); + Optional userOptional = Bungee.getUserManager().getLoadedUser(senderPlayer.getUniqueId()); + String coloredName; + if (userOptional.isPresent()) { + coloredName = userOptional.get().getUserRank().getColor() + senderPlayer.getName(); + } else { + coloredName = "&8" + sender; + } + map.put("senderCol", coloredName); + map.put("message", msg); + String ser = Bungee.getRedisManager().serialize(DataType.GMSG, map); + //Send this serialised object to other redis servers for handling... + Bungee.getRedisManager().sendMessage(ser); + } + + //show the player what they said + Optional userOptional; + if (targetName == null) { + userOptional = Optional.empty(); + } + else { + userOptional = Bungee.getUserManager().getLoadedUser(Bungee.getRedisManager().getRedisAPI().getUuidFromName(targetName)); + } + + String coloredName; + if (userOptional.isPresent()) { + coloredName = Utils.f(userOptional.get().getUserRank().getColor() + targetName); + } + else { + coloredName = "&8" + targetName; + } + + Optional senderOptional = Bungee.getUserManager().getLoadedUser(senderPlayer.getUniqueId()); + + String coloredSenderName; + if (senderOptional.isPresent()) { + coloredSenderName = Utils.f(senderOptional.get().getUserRank().getColor() + senderPlayer.getName()); + } + else { + coloredSenderName = "&8" + senderPlayer.getName(); + } + + String from = Lang.GMSG.f("&7[me -> " + Utils.f(coloredName) + "&7] &r" + msg); + + String url = ""; + for (String string : msg.split(" ")) { + if (string.matches("^((https?|ftp)://|(www|ftp)\\.)?[a-z0-9-]+(\\.[a-z0-9-]+)+([/?].*)?$")) { + url = string; + break; + } + } + + //Send GMSG to recipient + BaseComponent[] a = new ComponentBuilder(Lang.GMSG.f("&7[me &7-> " + Utils.f(coloredName) + "&r&7] &r" + msg)) + .event(url.isEmpty() ? new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/gmsg " + targetName + " ") + : new ClickEvent(ClickEvent.Action.OPEN_URL, url)) + .create(); + + senderPlayer.sendMessage(a); + + sendSocialSpy(senderPlayer, coloredSenderName, coloredName, targetName, msg); + + //Check if sender is staff, if so sent help_close if needed + closeHelp(senderPlayer, targetName); + + } catch (Exception exception) { + exception.printStackTrace(); + } + } + + private void sendSocialSpy(ProxiedPlayer senderPlayer, String coloredSenderName, String coloredName, String targetName, String msg){ + //regardless of where the recipient is we should socialspy this on the staff chat channel + String ss = Lang.GSPY.f("&7[" + coloredSenderName + "&7 -> " + coloredName + "&7] &r" + msg); + + Map socialSpySerialized = new HashMap<>(); + socialSpySerialized.put("message", ss); + socialSpySerialized.put("exclude", ChatColor.stripColor(targetName) + "," + senderPlayer.getName()); + Bungee.getRedisManager().sendMessage(Bungee.getRedisManager().serialize(DataType.SOCIALSPY, socialSpySerialized)); + } + + private void closeHelp(ProxiedPlayer player, String targetName) { + //Check if sender is staff, if so sent help_close if needed + if (player.hasPermission("staffchat.use") && HelpLog.helpTicketExists(targetName)) { + Optional helperUserOptional = Bungee.getUserManager().getLoadedUser(player.getUniqueId()); + String helperName = helperUserOptional.isPresent() ? helperUserOptional.get().getColoredName(player) : player.getName(); + Map map = new HashMap<>(); + map.put("helper", helperName); + map.put("helperUUID", player.getUniqueId().toString()); + map.put("sender", targetName); + String ser = Bungee.getRedisManager().serialize(DataType.HELP_CLOSE, map); + Bungee.getRedisManager().sendMessage(ser); + } + } + + @Override + public Iterable onTabComplete(CommandSender sender, String[] args) { + return TabComplete.onTabComplete(sender, args); + } +} \ No newline at end of file diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/HelpCommand.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/HelpCommand.java new file mode 100644 index 0000000..aa1a0a5 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/HelpCommand.java @@ -0,0 +1,199 @@ +package net.grandtheftmc.Bungee.commands; + +import net.grandtheftmc.Bungee.Bungee; +import net.grandtheftmc.Bungee.Lang; +import net.grandtheftmc.Bungee.Utils; +import net.grandtheftmc.Bungee.help.data.HelpCategory; +import net.grandtheftmc.Bungee.redisbungee.data.DataType; +import net.grandtheftmc.Bungee.utils.RequestRateLimiter; +import net.grandtheftmc.Bungee.utils.TabComplete; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.plugin.Command; + +import java.util.*; +import java.util.regex.Pattern; + +public class HelpCommand extends Command { + + private static final Pattern PATTERN = Pattern.compile(".*(?:h.?ck).*", Pattern.CASE_INSENSITIVE); + + //Allow players to still bypass help if the topic for help isn't listed. + private HashMap bypassHelp = new HashMap<>(); + + /* + Redis procedure: + ---------------- + 1) Forward the help request to the staff chat of all staff members across all bungee instances using redis. + 2) Clicking on the message should allow the staff member to reply by prompting /gmsg ... + */ + + public HelpCommand() { + super("help", null, "helpop", "ask", "question", "howto", "admin", "mod"); + } + + @Override + public void execute(CommandSender s, String[] args) { + if (!(s instanceof ProxiedPlayer)) { + //It doesn't make sense for the console to ask for help. + return; + } + + ProxiedPlayer player = (ProxiedPlayer) s; + + if (args.length == 0) { + player.sendMessage(Lang.HELP.f("&7Try something like this: &a/help how do I use my car?")); + //Bungee.getInstance().getHelpCore().getMainHelpMenu().stream().forEach(bc -> player.sendMessage(bc)); + return; + } + + String msg = String.join(" ", args); + + if (args.length == 1) { + + if (args[0].equalsIgnoreCase("reload")) { + //reload the configuration + if (player.hasPermission("gtm.generic.admin")) { + //reload, for this perm only + Bungee.getInstance().getHelpCore().reload(); + player.sendMessage(Utils.f("&aHelp configuration file has been reloaded.")); + } + + return; + } + + if (args[0].equalsIgnoreCase("view-null")) { + //Workaround to prevent clicking on the last list items + return; + } + + HelpCategory cat = Bungee.getInstance().getHelpCore().getAssociatedCategory(args[0].toLowerCase()); + + if (args[0].equalsIgnoreCase("help")) { + //link to main help menu + Bungee.getInstance().getHelpCore().getMainHelpMenu().forEach(player::sendMessage); + return; + } + + if (cat != null) { + cat.getDisplay().forEach(player::sendMessage); + } else { + + if (msg.split(" ").length <= 1) { + player.sendMessage(Lang.HELP.f("&7Only one word? Try to describe your problem more accurately.")); + return; + } + + } + + } + + if(PATTERN.matcher(msg).find()) { + player.sendMessage(new ComponentBuilder(Utils.f(" &c&lWATCHDAWG&8&l> &7Please use &f/report &7<&fplayer&7> <&freason&7>")).create()); + return; + } + + + boolean skipCheck = true; + + /*if(bypassHelp.containsKey(player.getUniqueId())){ + long last = bypassHelp.get(player.getUniqueId()); + long ms = System.currentTimeMillis() - last; + if (ms <= (1000 * 60)) { + //if less than a minute ago allow it + skipCheck = true; + } + }*/ + + if (skipCheck) { + bypassHelp.remove(player.getUniqueId()); + } + + if (!skipCheck) { + + List cats = new ArrayList<>(); + Set existingCats = new HashSet<>(); + + //check for matches + for (String a : args) { + HelpCategory hc = Bungee.getInstance().getHelpCore().getAssociatedCategory(a.toLowerCase()); + + if (hc != null && !existingCats.contains(hc.getSectionName())) { + cats.add(hc); + //prevent duplicates + existingCats.add(hc.getSectionName()); + } + } + + if (!cats.isEmpty()) { + //Prompt them to review help before pushing to staff. + //Your query matches n help topics. + // Click on any of these for further information or do /help. + //If this still hasnt answered your question click HERE to ask a staff member. + ComponentBuilder b = new ComponentBuilder(Bungee.getInstance().getHelpCore().getHelpMatch()); + + for (int i = 0; i < cats.size(); i++) { + HelpCategory hc = cats.get(i); + b.append(hc.getDisplayName()).event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/help " + hc.getSectionName())); + + + if ((i + 1) != cats.size()) { + //comma delimiters + b.append(", ").color(ChatColor.WHITE); + } + } + + + //add headers + Bungee.getInstance().getHelpCore().getHeader().forEach(h -> player.sendMessage(new ComponentBuilder(Utils.f(h)).create())); + + //matching categories + player.sendMessage(b.create()); + + //generic msg + player.sendMessage(new ComponentBuilder(" " + Bungee.getInstance().getHelpCore().getSendHelp()).event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/help " + msg)).create()); + + //add footers + Bungee.getInstance().getHelpCore().getFooter().forEach(h -> player.sendMessage(new ComponentBuilder(Utils.f(h)).create())); + + bypassHelp.put(player.getUniqueId(), System.currentTimeMillis()); + + return; + } + } + + if (!RequestRateLimiter.requestCmd(player.getUniqueId())) { + s.sendMessage(Utils.ft("&cYou have issued this command recently, please wait a second.")); + return; + } + + //broadcast to redis + Map map = new HashMap<>(); + map.put("sender", player.getName()); + map.put("server", player.getServer().getInfo().getName()); + map.put("message", msg); + + String ser = Bungee.getRedisManager().serialize(DataType.HELP, map); + //Send this serialised object to other redis servers for handling... + Bungee.getRedisManager().sendMessage(ser); + + player.sendMessage(Lang.HELP.f("&7Your message has been sent to all online staff. Use &a&l\"/gmsg \"&7 to talk to them individually.")); + + // log + String logMessage = "[HELP] " + player.getName() + ": " + msg; + + Map chatLogSerializd = new HashMap<>(); + chatLogSerializd.put("type", "help"); + chatLogSerializd.put("message", logMessage); + chatLogSerializd.put("logname", "help"); + Bungee.getRedisManager().sendMessage(Bungee.getRedisManager().serialize(DataType.LOG, chatLogSerializd)); + } + + public Iterable onTabComplete(CommandSender sender, String[] args) { + return TabComplete.onTabComplete(sender, args); + } +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/HubCommand.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/HubCommand.java new file mode 100644 index 0000000..b8476c6 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/HubCommand.java @@ -0,0 +1,69 @@ +package net.grandtheftmc.Bungee.commands; + +import net.grandtheftmc.Bungee.Bungee; +import net.grandtheftmc.Bungee.Utils; +import net.grandtheftmc.Bungee.users.User; +import net.grandtheftmc.Bungee.users.UserRank; +import net.grandtheftmc.ServerType; +import net.grandtheftmc.ServerTypeId; +import net.grandtheftmc.jedis.JedisChannel; +import net.grandtheftmc.jedis.JedisManager; +import net.grandtheftmc.jedis.message.ServerQueueMessage; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.plugin.Command; + +import java.util.Optional; + +public class HubCommand extends Command { + + private final JedisManager jedisManager; + private final String command; + + public HubCommand(JedisManager jedisManager, String command) { + super(command, null); + this.jedisManager = jedisManager; + this.command = command; + } + + @Override + public void execute(CommandSender s, String[] args) { + if (!(s instanceof ProxiedPlayer)) return; + ProxiedPlayer player = (ProxiedPlayer) s; +// player.connect(Utils.getRandomHub()); + ServerInfo info = null; + ServerType type = ServerType.GLOBAL; + + int id = -1; + if(command.toLowerCase().startsWith("hub")) { + type = ServerType.HUB; + info = Utils.getRandomHub(); + id = Integer.parseInt(info.getName().toLowerCase().split("hub")[1]); + } + + if(command.toLowerCase().startsWith("vice")) { + type = ServerType.VICE; + info = Utils.getRandomServer(command); + id = Integer.parseInt(info.getName().toLowerCase().split("vice")[1]); + } + if(command.toLowerCase().startsWith("gtm") || command.toLowerCase().startsWith("gta")) { + type = ServerType.GTM; + info = Utils.getRandomServer(command); + id = Integer.parseInt(info.getName().toLowerCase().split("gtm")[1]); + } + + if(id == -1 || info == null || type == ServerType.GLOBAL) { + s.sendMessage(Utils.ft("&cServer couldn't be found.")); + return; + } + + Optional user = Bungee.getUserManager().getLoadedUser(player.getUniqueId()); + UserRank rank = user.map(User::getUserRank).orElse(UserRank.DEFAULT); + this.jedisManager.getModule(JedisChannel.SERVER_QUEUE).sendMessage( + new ServerQueueMessage(player.getUniqueId(), rank.name(), new ServerTypeId(type, id)), + new ServerTypeId(ServerType.OPERATOR, -1) + ); + } + +} \ No newline at end of file diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/MotdCommand.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/MotdCommand.java new file mode 100644 index 0000000..ed16dd8 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/MotdCommand.java @@ -0,0 +1,76 @@ +package net.grandtheftmc.Bungee.commands; + +import net.grandtheftmc.Bungee.Bungee; +import net.grandtheftmc.Bungee.Utils; +import net.grandtheftmc.Bungee.redisbungee.data.DataType; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.plugin.Command; + +import java.util.HashMap; +import java.util.Map; + +public class MotdCommand extends Command { + + public MotdCommand() { + super("motd", "motd", "gmotd", "bungeemotd"); + } + + /* + Redis procedure: + ---------------- + + Reload: + ------- + 1) Send a pub sub message to all instances to force a reload of the MOTD configurations. + + Set: + ---- + 1) Send a pub sub message to all instances to set a new MOTD message. + */ + + @Override + public void execute(CommandSender s, String[] args) { + + if (args.length == 0) { + s.sendMessage(Utils.ft("&7/motd reload")); + s.sendMessage(Utils.ft("&7/motd set ")); + return; + } + + switch (args[0]) { + + case "reload": + Map map = new HashMap<>(); + map.put("reload", true); + map.put("sender", (s instanceof ProxiedPlayer) ? ((ProxiedPlayer) s).getName() : "CONSOLE"); + + String ser = Bungee.getRedisManager().serialize(DataType.MOTD, map); + //Send this serialised object to other redis servers for handling... + //The player/console is notified on the listener end.. + Bungee.getRedisManager().sendMessage(ser); + return; + + case "set": + String msg = ""; + for (int i = 1; i < args.length; i++) + msg += args[i] + ' '; + if (msg.endsWith(" ")) + msg = msg.substring(0, msg.length() - 1); + + map = new HashMap<>(); + map.put("motd", msg); + map.put("sender", (s instanceof ProxiedPlayer) ? ((ProxiedPlayer) s).getName() : "CONSOLE"); + + ser = Bungee.getRedisManager().serialize(DataType.MOTD, map); + //Send this serialised object to other redis servers for handling... + //The player/console is notified on the listener end.. + Bungee.getRedisManager().sendMessage(ser); + return; + + default: + break; + } + + } +} \ No newline at end of file diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/PermsCommand.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/PermsCommand.java new file mode 100644 index 0000000..ca7642b --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/PermsCommand.java @@ -0,0 +1,113 @@ +package net.grandtheftmc.Bungee.commands; + +import net.grandtheftmc.Bungee.Bungee; +import net.grandtheftmc.Bungee.Utils; +import net.grandtheftmc.Bungee.database.BaseDatabase; +import net.grandtheftmc.Bungee.redisbungee.data.DataType; +import net.grandtheftmc.Bungee.users.UserRank; +import net.grandtheftmc.Bungee.utils.TabComplete; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.plugin.Command; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public class PermsCommand extends Command { + + public PermsCommand() { + super("gperms", "gperms", "gpermissions", "globalperms", "globalpermissions"); + } + + /* + Redis procedure: + ---------------- + - Send out a request to reload all configurations + - Checking userank, direct database lookup + - Perms update + */ + + @Override + public void execute(CommandSender s, String[] args) { + if (args.length == 0) { + s.sendMessage(Utils.ft("&7/gperms reload")); + s.sendMessage(Utils.ft("&7/gperms check ")); + s.sendMessage(Utils.ft("&7/gperms update ")); + return; + } + + String sender = s instanceof ProxiedPlayer ? s.getName() : "CONSOLE"; + + switch (args[0].toLowerCase()) { + case "reload": + Map map = new HashMap<>(); + map.put("reload", true); + map.put("sender", sender); + String ser = Bungee.getRedisManager().serialize(DataType.PERMS, map); + Bungee.getRedisManager().sendMessage(ser); + return; + + case "check": + if (args.length != 2) { + s.sendMessage(Utils.ft("&7/gperms check ")); + return; + } + Bungee.getInstance().getProxy().getScheduler().runAsync(Bungee.getInstance(), () -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT lastname,userrank FROM users WHERE lastname=?;")) { + statement.setString(1, args[1]); + try (ResultSet result = statement.executeQuery()) { + if (result.isBeforeFirst()) { + if (result.isBeforeFirst()) { + result.next(); + UserRank ur = UserRank.getUserRank(result.getString("userrank")); + s.sendMessage(Utils.ft("&7User " + args[1] + " rank: " + ur.getColoredName())); + } else { + s.sendMessage(Utils.ft("&7The user " + args[1] + " does not exist.")); + } + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + }); + return; + + case "update": + if (args.length != 2) { + s.sendMessage(Utils.ft("&7/gperms update ")); + return; + } + + UUID u = Bungee.getRedisManager().getRedisAPI().getUuidFromName(args[1]); + if (u == null || !Bungee.getRedisManager().getRedisAPI().isPlayerOnline(u)) { + Utils.msg(s, "&7That player is not online!"); + return; + } + + map = new HashMap<>(); + map.put("sender", sender); + map.put("target", args[1]); + ser = Bungee.getRedisManager().serialize(DataType.PERMS, map); + Bungee.getRedisManager().sendMessage(ser); + return; + + default: + s.sendMessage(Utils.ft("&7/gperms reload")); + s.sendMessage(Utils.ft("&7/gperms check ")); + s.sendMessage(Utils.ft("&7/gperms update ")); + return; + } + } + + public Iterable onTabComplete(CommandSender sender, String[] args) { + return TabComplete.onTabComplete(sender, args); + } + +} \ No newline at end of file diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/PlaytimeCommand.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/PlaytimeCommand.java new file mode 100644 index 0000000..2b332d3 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/PlaytimeCommand.java @@ -0,0 +1,48 @@ +package net.grandtheftmc.Bungee.commands; + +import net.grandtheftmc.Bungee.Bungee; +import net.grandtheftmc.Bungee.Lang; +import net.grandtheftmc.Bungee.users.User; +import net.grandtheftmc.Bungee.users.UserRank; +import net.grandtheftmc.Bungee.utils.PlaytimeManager; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.plugin.Command; + +import java.util.Optional; + +public class PlaytimeCommand extends Command { + + public PlaytimeCommand() { + super("playtime", "playtime.admin", "playtime"); + } + + /* + MySQL DB: + --------- + Typical Row: + + UUID - UUID of player. + Username - Username of player. + Session Time - Time, in MS that the player was connected to this proxy. + Date Time - System time in MS upon disconnect, used to purge old playtime records. + */ + + @Override + public void execute(CommandSender s, String[] args) { + if (!(s instanceof ProxiedPlayer)) return; + + ProxiedPlayer player = (ProxiedPlayer) s; + + //Don't allow non-admins to use this command. + Optional userOptional = Bungee.getUserManager().getLoadedUser(player.getUniqueId()); + if (!userOptional.isPresent() || !userOptional.get().isRank(UserRank.ADMIN)) { + player.sendMessage(Lang.NOPERM.st()); + return; + } + + Bungee.getUserManager().getSortedUsers().forEach(user -> { + PlaytimeManager.lookupPlaytime(player, user.getUsername()); + }); + } +} \ No newline at end of file diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/SeenCommand.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/SeenCommand.java new file mode 100644 index 0000000..225e8ed --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/SeenCommand.java @@ -0,0 +1,95 @@ +package net.grandtheftmc.Bungee.commands; + +//import fr.Alphart.BAT.Utils.EnhancedDateFormat; +import net.grandtheftmc.Bungee.Bungee; +import net.grandtheftmc.Bungee.Utils; +import net.grandtheftmc.Bungee.utils.RequestRateLimiter; +import net.grandtheftmc.Bungee.utils.TabComplete; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.plugin.Command; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; + +public class SeenCommand extends Command { + +// private final EnhancedDateFormat dateFormat = new EnhancedDateFormat(true); + + public SeenCommand() { + super("seen", null, "lastonline", "lastlogin"); + } + + /* + Redis procedure: + ---------------- + 1) Checks if player is on the local instance, if not checks redis distributed. + 2) If player is not found online we check the database. Again TODO: limitations on frequency of access calls. + */ + + @Override + public void execute(CommandSender s, String[] args) { + /*if (args.length != 1) { + s.sendMessage(Utils.ft("&c/seen ")); + return; + } + if (!(s instanceof ProxiedPlayer)) { + s.sendMessage(Utils.ft("&cYou are not a player!")); + return; + } + + UUID sender = ((ProxiedPlayer) s).getUniqueId(); + String player = args[0]; + ProxiedPlayer p = ProxyServer.getInstance().getPlayer(player); + + boolean online = p != null || Bungee.getRedisManager().isPlayerOnline(player); + + if (online) { + s.sendMessage(Utils.ft("&7The player &a" + (p != null ? p.getName() : args[0]) + "&7 is &aonline&7!")); + return; + } + + if (!RequestRateLimiter.requestCmd(sender)) { + s.sendMessage(Utils.ft("&cYou have issued this command recently, please wait a second.")); + return; + } + + s.sendMessage(Utils.ft("&7Looking up player &a" + player + "&7 in the database.")); + ProxyServer.getInstance().getScheduler().runAsync(Bungee.getInstance(), () -> { + ResultSet rs = Bungee.getBATSQL().query("select BAT_player,lastlogin from BAT_players where BAT_player='" + player + "';"); + String name1 = null; + Timestamp lastlogin = null; + ProxiedPlayer p1 = ProxyServer.getInstance().getPlayer(sender); + try { + if (rs.isBeforeFirst()) { + rs.next(); + name1 = rs.getString("BAT_player"); + lastlogin = rs.getTimestamp("lastlogin"); + } + rs.close(); + } catch (SQLException ignored) { + p1.sendMessage(Utils.ft("&7Oops, something went wrong! Please try again.")); + return; + } + + if (p1 == null) + return; + if (lastlogin == null || name1 == null) { + p1.sendMessage(Utils.ft("&7That player is not in the database!")); + return; + } +// p1.sendMessage(Utils.ft("&7The player &a" + name1 + "&7 last logged in &a" + this.dateFormat.format(lastlogin) + "&7!")); + + });*/ + + } + public Iterable onTabComplete(CommandSender sender, String[] args) { + return TabComplete.onTabComplete(sender, args); + } +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/ServerCommand.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/ServerCommand.java new file mode 100644 index 0000000..292d4f8 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/ServerCommand.java @@ -0,0 +1,88 @@ +package net.grandtheftmc.Bungee.commands; + +import net.grandtheftmc.Bungee.Bungee; +import net.grandtheftmc.Bungee.Utils; +import net.grandtheftmc.Bungee.users.User; +import net.grandtheftmc.Bungee.users.UserRank; +import net.grandtheftmc.ServerType; +import net.grandtheftmc.ServerTypeId; +import net.grandtheftmc.jedis.JedisChannel; +import net.grandtheftmc.jedis.JedisManager; +import net.grandtheftmc.jedis.message.ServerQueueMessage; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.plugin.Command; + +import java.util.Optional; + +public class ServerCommand extends Command { + + private final JedisManager jedisManager; + private final String command; + + public ServerCommand(String command, JedisManager jedisManager) { + super(command); + this.command = command; + this.jedisManager = jedisManager; + } + + /** + * Connects the player to the specific Bungee server. + * @param s Who executes the command. + * @param args The desired server ID to connect to. + */ + @Override + public void execute(CommandSender s, String[] args) { + if (!(s instanceof ProxiedPlayer)) return; + ProxiedPlayer player = (ProxiedPlayer) s; + ServerInfo info = ProxyServer.getInstance().getServerInfo(Bungee.getSettings().getServers().get(this.command)); + if (info == null) { + player.sendMessage(Utils.ft("&cThat server does not exist!")); + return; + } + + if(player.getServer().getInfo().getName().equals(info.getName())) { + player.sendMessage(Utils.ft("&cYou're already connected to this server!")); + return; + } + + int id = -1; + ServerType type = ServerType.OPERATOR; + if(this.command.toLowerCase().startsWith("hub")) { + id = Integer.parseInt(this.command.toLowerCase().split("hub")[1]); + type = ServerType.HUB; + } + + if(this.command.toLowerCase().startsWith("gtm")) { + id = Integer.parseInt(this.command.toLowerCase().split("gtm")[1]); + type = ServerType.GTM; + } + + if(this.command.toLowerCase().startsWith("vice")) { + id = Integer.parseInt(this.command.toLowerCase().split("vice")[1]); + type = ServerType.VICE; + } + + if(this.command.toLowerCase().startsWith("creative")) { + id = Integer.parseInt(this.command.toLowerCase().split("creative")[1]); + type = ServerType.CREATIVE; + } + + if(type == ServerType.OPERATOR || id == -1) return; + +// player.connect(info); + Optional user = Bungee.getUserManager().getLoadedUser(player.getUniqueId()); + UserRank rank = user.map(User::getUserRank).orElse(UserRank.DEFAULT); + this.jedisManager.getModule(JedisChannel.SERVER_QUEUE).sendMessage( + new ServerQueueMessage(player.getUniqueId(), rank.name(), new ServerTypeId(type, id)), + new ServerTypeId(ServerType.OPERATOR, -1) + ); + } + + public Iterable onTabComplete(CommandSender sender, String[] args) { + return ProxyServer.getInstance().getServers().keySet(); + } + +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/StaffChatCommand.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/StaffChatCommand.java new file mode 100644 index 0000000..1ed89fa --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/commands/StaffChatCommand.java @@ -0,0 +1,90 @@ +package net.grandtheftmc.Bungee.commands; + +import net.grandtheftmc.Bungee.Bungee; +import net.grandtheftmc.Bungee.Lang; +import net.grandtheftmc.Bungee.Utils; +import net.grandtheftmc.Bungee.redisbungee.data.DataType; +import net.grandtheftmc.Bungee.users.User; +import net.grandtheftmc.Bungee.utils.TabComplete; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.plugin.Command; + +import java.util.*; +import java.util.stream.Collectors; + +public class StaffChatCommand extends Command { + + public StaffChatCommand() { + super("staffchat", "staffchat.use", "sc", "staffc", "schat", "adminchat", "adminc", "ac", "achat"); + } + + /* + Redis procedure: + ---------------- + 1) Staff chat messages should simply be forwarded to all redis instances. + */ + + @Override + public void execute(CommandSender s, String[] args) { + //Allow to chat in staff chat via console + if (!(s instanceof ProxiedPlayer)) { + StringBuilder msg = new StringBuilder(); + for (int i = 0; i < args.length; i++) + msg.append(i > 0 ? " " : "").append(args[i]); + //broadcast to redis + Map map = new HashMap<>(); + map.put("sender", "CONSOLE"); + map.put("message", msg.toString()); + + String ser = Bungee.getRedisManager().serialize(DataType.STAFFCHAT, map); + //Send this serialised object to other redis servers for handling... + Bungee.getRedisManager().sendMessage(ser); + return; + } + + + ProxiedPlayer player = (ProxiedPlayer) s; + //This list only contains staff anyway. + Optional userOptional = Bungee.getUserManager().getLoadedUser(player.getUniqueId()); + userOptional.ifPresent(user -> { + if (args.length == 0) { + user.toggleStaffChat(); + s.sendMessage(Lang.STAFF.ft("&7You turned " + (user.getStaffChat() ? "&a&lon" : "&c&loff") + "&7 staff chat!")); + return; + } + + if ("on".equalsIgnoreCase(args[0])) { + user.setStaffChat(true); + s.sendMessage(Lang.STAFF.ft("&7You turned &a&lon&7 staff chat!")); + return; + } + + if ("off".equalsIgnoreCase(args[0])) { + user.setStaffChat(false); + s.sendMessage(Lang.STAFF.ft("&7You turned &c&loff&7 staff chat!")); + return; + } + + String msg = ""; + for (int i = 0; i < args.length; i++) + msg = (i > 0 ? " " : "") + args[i]; + + //broadcast to redis + Map map = new HashMap<>(); + map.put("sender", player.getName()); + map.put("message", msg); + + String ser = Bungee.getRedisManager().serialize(DataType.STAFFCHAT, map); + //Send this serialised object to other redis servers for handling... + Bungee.getRedisManager().sendMessage(ser); + }); + } + + + //Autocompleting playing names accross the redis network. + public Iterable onTabComplete(CommandSender sender, String[] args) { + return TabComplete.onTabComplete(sender, args); + } +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/database/BaseDatabase.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/database/BaseDatabase.java new file mode 100644 index 0000000..947c73c --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/database/BaseDatabase.java @@ -0,0 +1,53 @@ +package net.grandtheftmc.Bungee.database; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +/** + * A generic database handler that acts as a singleton so we can reference it + * anywhere. + * + * @author sbahr + */ +public class BaseDatabase extends DatabaseHandler { + + /** Singleton instance for this class */ + private static BaseDatabase instance; + + /** + * Private constructor as singleton's cannot be instantiated. + */ + private BaseDatabase() { + // Note: DatabaseHandler doesn't have a constructor for a reason + } + + /** + * Get the singleton instance of this class. + *

+ * This allows you to call {@link #getConnection()}. + *

+ * + * @return The instance of this database. + */ + public static BaseDatabase getInstance() { + if (instance == null) { + instance = new BaseDatabase(); + } + + return instance; + } + + public static boolean runCustomQuery(String query) { + try (Connection connection = getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement(query)) { + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } +} \ No newline at end of file diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/database/DatabaseHandler.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/database/DatabaseHandler.java new file mode 100644 index 0000000..8575df3 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/database/DatabaseHandler.java @@ -0,0 +1,193 @@ +package net.grandtheftmc.Bungee.database; + +import java.io.PrintWriter; +import java.sql.Connection; +import java.sql.SQLException; + +import com.zaxxer.hikari.HikariDataSource; + +import net.grandtheftmc.Bungee.database.component.Database; +import net.grandtheftmc.Bungee.database.component.DatabaseCredentials; + +/** + * A generic database handler that holds a HikariCP data source so we can have + * multiple database connection. + * + * Note: This should be init() with either the Plugin/Config path to load + * settings, or can be init() with just database credentials, which uses default + * HikariCP settings. + * + * @author sbahr + */ +public class DatabaseHandler implements Database { + + /** The default MySQL driver */ + private static final String DEFAULT_MYSQL_DRIVER = "com.mysql.jdbc.Driver"; + /** The database credentials */ + private DatabaseCredentials dbCreds; + /** Data source connection pool from HikariCP */ + private HikariDataSource hikariSource = new HikariDataSource(); + + // NOTE: HikariCP performs best at fixed pool size, minIdle=maxConns + // https://github.com/brettwooldridge/HikariCP + + /** How many minimum idle connections should we always have (2) */ + protected int minIdle = 2; + /** How many max connections should exist in pool (2) */ + protected int maxPoolSize = 2; + /** How long, in millis, we stop waiting for new connection (15 secs) */ + protected int connectionTimeoutMs = 15 * 1000; + /** How long, in millis, before connections timeout (45 secs) */ + protected int idleTimeoutMs = 45 * 1000; + /** How long, in millis, this connection can be alive for (30 mins) */ + protected int maxLifetimeMs = 30 * 60 * 1000; + /** How long, in millis, can a connection be gone from a pool (4 secs) */ + protected int leakDetectionThresholdMs = 4 * 1000; + /** The ping alive query */ + protected String connectionTestQuery = "SELECT 1"; + /** Should the connection cache prepared statements */ + protected boolean cachePreparedStatements = true; + /** Number of prepared statements to cache per connection */ + protected int preparedStatementCache = 250; + /** Max number of prepared statements to have */ + protected int maxPreparedStatementCache = 2048; + /** The log writer for Hikari */ + protected PrintWriter logWriter = new PrintWriter(System.out); + + /** + * Initialize the handler with the specified database credentials. + *

+ * Sets up the configuration for the connection pool and default settings. + *

+ * + * @param dbCreds - the credentials for the database + * @param driver - the driver class + */ + public void init(DatabaseCredentials dbCreds, String driver) { + this.dbCreds = dbCreds; + + // set the driver name for the connection driver + hikariSource.setDriverClassName(driver); + + // assume host/port combo together, or could just be without port + String connURL = dbCreds.getHost(); + + // if a port is defined + if (dbCreds.getPort() > 0) { + connURL = dbCreds.getHost() + ":" + dbCreds.getPort(); + } + + // set the jdbc url, note the character encoding + // https://stackoverflow.com/questions/3040597/jdbc-character-encoding + hikariSource.setJdbcUrl("jdbc:mysql://" + connURL + "/" + dbCreds.getName() + "?characterEncoding=UTF-8"); + + // set user/pass + hikariSource.setUsername(dbCreds.getUser()); + hikariSource.setPassword(dbCreds.getPass()); + + /** General conf settings for hikari */ + // works best when minIdle=maxPoolSize + hikariSource.setMinimumIdle(minIdle); + hikariSource.setMaximumPoolSize(maxPoolSize); + + // how long to wait, for a new connection + hikariSource.setConnectionTimeout(connectionTimeoutMs); + // how long before idle connection is destroyed + hikariSource.setIdleTimeout(idleTimeoutMs); + // how long can a connection exist + hikariSource.setMaxLifetime(maxLifetimeMs); + // how long connection is away from a pool before saying uh oh + hikariSource.setLeakDetectionThreshold(leakDetectionThresholdMs); + // test query to confirm alive + hikariSource.setConnectionTestQuery(connectionTestQuery); + // should we cache prepared statements + hikariSource.addDataSourceProperty("cachePrepStmts", "" + cachePreparedStatements); + // the size of the prepared statement cache + hikariSource.addDataSourceProperty("prepStmtCacheSize", "" + preparedStatementCache); + // the maximum cache limit + hikariSource.addDataSourceProperty("prepStmtCacheSqlLimit", "" + maxPreparedStatementCache); + + // MUST set log writer + try { + hikariSource.setLogWriter(new PrintWriter(System.out)); + } + catch (SQLException e) { + e.printStackTrace(); + } + } + + /** + * Initialize the database handler given the credentials. + * + * @param credentials - the login details to this database + */ + protected void init(DatabaseCredentials credentials) { + this.init(credentials, DEFAULT_MYSQL_DRIVER); + } + + /** + * Load the settings for HikariCP from the yaml config and stores them + * locally in the object, then initializes the database handler. + */ + public void init(String host, int port, String dbName, String user, String pass) { +// +// String host = config.getString(path + ".host", "localhost"); +// int port = config.getInt(path + ".port", 3306); +// String dbName = config.getString(path + ".database", "hyphenical"); +// String username = config.getString(path + ".user", "user"); +// String password = config.getString(path + ".password", "pass123"); +// +// // connection stats +// int minIdle = config.getInt(path + ".min-idle", 2); +// int maxConns = config.getInt(path + ".max-conn", 2); +// +// // load local fields +// this.minIdle = minIdle < 0 ? 1 : minIdle; +// this.maxPoolSize = maxConns < 1 ? 1 : maxConns; +// +// // create database credentials + DatabaseCredentials creds = new DatabaseCredentials(host, port, dbName, user, pass); + +// // initialize hikari cp + init(creds); + } + + /** + * Close HikariCP connection pool, and all the connections. + *

+ * Note: This should be called whenever the plugin turns off! + *

+ */ + public void close() { + if (hikariSource != null && !hikariSource.isClosed()) { + hikariSource.close(); + } + } + + /** + * {@inheritDoc} + */ + @Override + public DatabaseCredentials getCredentials() { + return dbCreds; + } + + /** + * {@inheritDoc} + */ + @Override + public Connection getConnection() { + if (hikariSource != null) { + try { + Connection conn = hikariSource.getConnection(); + return conn; + } + catch (Exception e) { + System.out.println("[DatabaseHandler] Unable to grab a connection from the connection pool!"); + e.printStackTrace(); + } + } + + return null; + } +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/database/component/Database.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/database/component/Database.java new file mode 100644 index 0000000..1c7e027 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/database/component/Database.java @@ -0,0 +1,26 @@ +package net.grandtheftmc.Bungee.database.component; + +import java.sql.Connection; + +/** + * An interface that represents a database (and it's credentials). + * + * @author sbahr + */ +public interface Database { + + /** + * Get the credentials for the database. + * + * @return The credentials for the database. + */ + DatabaseCredentials getCredentials(); + + /** + * Get the connection for the database. + * + * @return The connection for the database. + */ + Connection getConnection(); + +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/database/component/DatabaseCredentials.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/database/component/DatabaseCredentials.java new file mode 100644 index 0000000..52c737f --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/database/component/DatabaseCredentials.java @@ -0,0 +1,112 @@ +package net.grandtheftmc.Bungee.database.component; + +/** + * Represents an immutable data object containing information about a connection + * to the database. + * + * @author sbahr + */ +public class DatabaseCredentials { + + /** The host of the db, ex: example.com */ + private final String host; + /** The port associated, ex: 3306 */ + private final int port; + /** The name of the database to use, ex: test_db */ + private final String dbName; + /** The name of the user that has access to the db, ex: user123 */ + private final String dbUser; + /** The password for the user, ex: pass123 */ + private final String dbPass; + + /** + * Construct a new DatabaseCredentials object. + * + * @param host - the host of the db, ex: example.com + * @param port - the port for the db, ex: 3306 + * @param dbName - the name of the db to use, ex: test_db + * @param dbUser - the user of the db, ex: user123 + * @param dbPass - the pass for the user, ex: pass123 + */ + public DatabaseCredentials(String host, int port, String dbName, String dbUser, String dbPass) { + this.host = host; + this.port = port; + this.dbName = dbName; + this.dbUser = dbUser; + this.dbPass = dbPass; + } + + /** + * Construct a new DatabaseCredentials object. + *

+ * The port for the host is not defined as an argument and either should be + * supplied in the host argument or use a different constructor. If no port + * is defined, we'll use the default port. + *

+ * + * @param host - the host of the db, ex: example.com + * @param dbName - the name of the db to use, ex: test_db + * @param dbUser - the user of the db, ex: user123 + * @param dbPass - the pass for the user, ex: pass123 + */ + public DatabaseCredentials(String host, String dbName, String dbUser, String dbPass) { + this(host, -1, dbName, dbUser, dbPass); + } + + /** + * Get the host associated with this database credentials. + *

+ * The host URL, ex: www.example.com + *

+ * + * @return The host URL for the database. + */ + public final String getHost() { + return host; + } + + /** + * Get the port number for the database. + *

+ * The port number could be irrelevant if defined in {@link #getHost()}. If + * the port number is -1, use the default port. + *

+ * + * @return The port number for the database. + */ + public final int getPort() { + return port; + } + + /** + * Get the name of the database that we are using. + *

+ * This is the name of the database, as there can be multiple databases + * within one database. + *

+ * + * @return The name of the database we are using. + */ + public final String getName() { + return dbName; + } + + /** + * Get the username of the user that has access to the database. + * + * @return The name for the user that has access to this database. + */ + public final String getUser() { + return dbUser; + } + + /** + * Get the password of the user that has access to the database. + * + * @return The password, associated with the user, that has access to this + * database. + */ + public final String getPass() { + return dbPass; + } +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/help/HelpCore.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/help/HelpCore.java new file mode 100644 index 0000000..d898e09 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/help/HelpCore.java @@ -0,0 +1,203 @@ +package net.grandtheftmc.Bungee.help; + +import net.grandtheftmc.Bungee.Bungee; +import net.grandtheftmc.Bungee.Utils; +import net.grandtheftmc.Bungee.help.data.HelpCategory; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.config.Configuration; + +import java.util.*; + +/** + * Created by Adam on 05/06/2017. + */ +public class HelpCore { + + /* + Sample Data: (Tab to delimit keys for multiple checks) + ------------------------------------------------------ + + help: + topic: + matches: [] + help: [] + subtopic: + matches: [] + help: [] - Can be empty or not, doesn't matter + + Example: + -------- + + help: + Vehicles: + matches: vehicle,vehicles + help: [] + Jetpacks: + matches: + - 'jetpack' + - 'jetpacks' + help: + - 'Jetpacks are cool.' + - 'Go buy a Jetpack.' + Wingsuits: + matches: + - 'fly' + - 'wingsuit' + - 'wingsuits' + - 'wings' + help: + - 'Wingsuits are faster than JetPacks.' + - 'Or, are they' + + + */ + + /** + * A list of all the root categories. + */ + private List rootCategories; + + private List footer; + private List header; + private String pathString, pathDelim, relatedString, title, cats, helpPath, helpMatch, sendHelp; + + /** + * Map match strings to each help category. + */ + private Map mappings = new HashMap<>(); + + private List mainHelpMenu; + + /** + * Create an instance of the help core, load in all the keywords from a config. + * + * @param io The config to load the help data from. + */ + public HelpCore(Configuration io) { + load(io); + } + + public void reload() { + rootCategories.clear(); + header.clear(); + footer.clear(); + mappings.clear(); + mainHelpMenu = null; + + Bungee.getSettings().setHelpConfig(Utils.loadConfig("help")); + load(Bungee.getSettings().getHelpConfiguration()); + } + + private void load(Configuration io) { + + rootCategories = new ArrayList<>(); + + header = io.getStringList("formatting.header"); + footer = io.getStringList("formatting.footer"); + pathString = Utils.f(io.getString("formatting.path")); + pathDelim = Utils.f(io.getString("formatting.pathdelimiter")); + relatedString = Utils.f(io.getString("formatting.related")); + title = Utils.f(io.getString("formatting.title")); + cats = Utils.f(io.getString("formatting.categories")); + helpPath = Utils.f(io.getString("formatting.helppath")); + helpMatch = Utils.f(io.getString("formatting.helpmatch")); + sendHelp = Utils.f(io.getString("formatting.sendhelp")); + + for (String s : io.getSection("help").getKeys()) { + //Each key here is a root category + + HelpCategory rootCategory = new HelpCategory(io.getSection("help." + s), null, s); + rootCategories.add(rootCategory); + } + + //Now traverse the tree to add all matches + for (HelpCategory rootCat : rootCategories) { + associateMappings(rootCat); + } + } + + private void associateMappings(HelpCategory category) { + //Associate mappings with this category + for (String s : category.getMatches()) { + mappings.put(s, category); + } + + //Now do the same for all children, recursively... + category.getChildren().forEach(this::associateMappings); + } + + /** + * Return the help category associated with this search string. + * + * @param s The string to check for matches. + * @return The associated help category. + */ + public HelpCategory getAssociatedCategory(String s) { + return mappings.get(s.toLowerCase()); + } + + public List getMainHelpMenu() { + if (mainHelpMenu == null) { + mainHelpMenu = new ArrayList<>(); + + //add headers + getHeader().forEach(h -> mainHelpMenu.add(new ComponentBuilder(Utils.f(h)).create())); + mainHelpMenu.add(new ComponentBuilder(" " + title).create()); + + //related Categories + ComponentBuilder builder = new ComponentBuilder(" " + cats); + + for (int i = 0; i < rootCategories.size(); i++) { + HelpCategory cat = rootCategories.get(i); + builder.append(cat.getDisplayName()).event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/help " + cat.getSectionName())); + + if ((i + 1) != rootCategories.size()) { + //comma delimiters + builder.append(", ").color(ChatColor.WHITE); + } + } + //add categories + mainHelpMenu.add(builder.create()); + + //add footers + getFooter().forEach(h -> mainHelpMenu.add(new ComponentBuilder(Utils.f(h)).create())); + } + + return mainHelpMenu; + } + + public List getFooter() { + return footer; + } + + public List getHeader() { + return header; + } + + public String getPathString() { + return pathString; + } + + public String getPathDelim() { + return pathDelim; + } + + public String getRelatedString() { + return relatedString; + } + + public String getHelpPath() { + return helpPath; + } + + public String getHelpMatch() { + return helpMatch; + } + + public String getSendHelp() { + return sendHelp; + } +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/help/data/HelpCategory.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/help/data/HelpCategory.java new file mode 100644 index 0000000..15b9def --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/help/data/HelpCategory.java @@ -0,0 +1,224 @@ +package net.grandtheftmc.Bungee.help.data; + +import net.grandtheftmc.Bungee.Bungee; +import net.grandtheftmc.Bungee.Utils; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.config.Configuration; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +/** + * Created by Adam on 05/06/2017. + */ +public class HelpCategory { + + /** + * A name representing this section. Eg: Vehicles. + */ + private String sectionName; + + /** + * The display string to show in the menus. + */ + private String displayName; + + /** + * A list of help categories for this node, to support sub-categories. + */ + private List subCategories = new ArrayList<>(); + + /** + * All lowercase, any strings in this set will be used to check matches for automated help. + */ + private String[] matches; + + /** + * A list of help messages for this topic. + */ + private String[] help; + + /** + * The parent help category of this child, null if a root. + */ + private HelpCategory parent; + + /** + * A Path representing the relative location of this category. + * Like Vehicles > Cars > Lambourghini + */ + private BaseComponent[] path; + + /** + * A list of display components, pre-compiled on first request. + */ + private List display; + + public HelpCategory(Configuration section, HelpCategory parent, String name) { + //Always pass in the root of whatever config section we are processing. + + this.sectionName = name; + this.parent = parent; + this.displayName = section.contains("display") ? ChatColor.translateAlternateColorCodes('&', section.getString("display")) : name; + + //Load Help + List helpList = section.getStringList("help"); + help = helpList.toArray(new String[helpList.size()]); + + //Load Matches + List helpMatches = section.getStringList("matches"); + //Ensure all values are lowercase. + helpMatches.forEach(m -> m = m.toLowerCase()); + matches = helpMatches.toArray(new String[helpMatches.size()]); + + //Bungee.getInstance().getLogger().info("Loading category: " + sectionName); + //Bungee.getInstance().getLogger().info("Loading related subcategories..."); + + //Load SubCategories Recursively + for (String s : section.getKeys()) { + //Bungee.getInstance().getLogger().info("Key = " + s); + if (!s.equalsIgnoreCase("help") && !s.equalsIgnoreCase("matches") && !s.equalsIgnoreCase("display")) { + //we have found a sub category + //Bungee.getInstance().getLogger().info("Loading subcategory: " + sectionName + "->" + s); + HelpCategory cat = new HelpCategory(section.getSection(s), this, s); + subCategories.add(cat); + } + } + + //Bungee.getInstance().getLogger().info("Loading category: " + sectionName + " = COMPLETE"); + } + + public List getChildren() { + return subCategories; + } + + public String[] getMatches() { + return matches; + } + + public HelpCategory getParent() { + return parent; + } + + public boolean hasParent() { + return parent != null; + } + + public String getDisplayName(){ + return displayName; + } + + public String getSectionName() { + return sectionName; + } + + /** + * Get a display list of text components to show to the player. + * + * @return A list of display components. + */ + public List getDisplay() { + + if (display == null) { + display = new ArrayList<>(); + + //add headers + Bungee.getInstance().getHelpCore().getHeader().forEach(h -> display.add(new ComponentBuilder(Utils.f(h)).create())); + display.add(getPath()); + + //related Categories + ComponentBuilder builder = new ComponentBuilder(" " + Bungee.getInstance().getHelpCore().getRelatedString()); + + for (int i = 0; i < getChildren().size(); i++) { + HelpCategory cat = getChildren().get(i); + builder.append(cat.getDisplayName()).event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/help " + cat.getSectionName())); + + if ((i + 1) != getChildren().size()) { + //comma delimiters + builder.append(", ").color(ChatColor.WHITE); + } + } + //add categories + if (!getChildren().isEmpty()) { + //only show related categories if there are children + display.add(builder.create()); + } + + //display remaining help + if (help != null && help.length > 0) { + //Only show help if there's some. + for (String s : help) { + display.add(new ComponentBuilder(" " + ChatColor.translateAlternateColorCodes('&', s)).create()); + } + } + + //add footer + Bungee.getInstance().getHelpCore().getFooter().forEach(h -> display.add(new ComponentBuilder(Utils.f(h)).create())); + } + + return display; + } + + /** + * Get a path display string of the current route for this help category. + * + * @return + */ + public BaseComponent[] getPath() { + if (path == null) { + //build path + List route = new ArrayList<>(); + List displayRoute = new ArrayList<>(); + route.add(sectionName); + displayRoute.add(displayName); + + HelpCategory currentCat = this; + + while (currentCat.hasParent()) { + route.add(currentCat.getParent().getSectionName()); + displayRoute.add(currentCat.getParent().getDisplayName()); + currentCat = currentCat.getParent(); + } + + //Add core help. + route.add("Help"); + displayRoute.add(Bungee.getInstance().getHelpCore().getHelpPath()); + + Collections.reverse(route); + Collections.reverse(displayRoute); + + StringBuilder b = new StringBuilder(); + route.stream().forEach(p -> b.append(p).append(" > ")); + //Trim trailing path markers + b.setLength(b.length() - Bungee.getInstance().getHelpCore().getPathDelim().length()); + + ComponentBuilder builder = new ComponentBuilder(" " + Bungee.getInstance().getHelpCore().getPathString()); + for (int i = 0; i < route.size(); i++) { + String r = route.get(i); + //add displayRoute.get(i) + builder.append(displayRoute.get(i)); + + if ((i + 1) != route.size()) { + //path flow object + builder.event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/help " + r)); + builder.append(Bungee.getInstance().getHelpCore().getPathDelim()); + } else { + //We don't want them to be able to click the last thing, so use this tag to negate it + builder.event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/help view-null")); + } + } + + path = builder.create(); + } + + return path; + } + + +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/listeners/Chat.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/listeners/Chat.java new file mode 100644 index 0000000..736b626 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/listeners/Chat.java @@ -0,0 +1,46 @@ +package net.grandtheftmc.Bungee.listeners; + +import net.grandtheftmc.Bungee.Bungee; +import net.grandtheftmc.Bungee.Utils; +import net.grandtheftmc.Bungee.users.User; +import net.grandtheftmc.Bungee.users.UserRank; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.event.ChatEvent; +import net.md_5.bungee.api.plugin.Listener; +import net.md_5.bungee.event.EventHandler; + +import java.util.Optional; + +public class Chat implements Listener { + + @EventHandler + public void onChat(ChatEvent event) { + try { + if (event.isCancelled() || !(event.getSender() instanceof ProxiedPlayer)) return; + ProxiedPlayer player = (ProxiedPlayer) event.getSender(); + Optional userOptional = Bungee.getUserManager().getLoadedUser(player.getUniqueId()); + userOptional.ifPresent(user -> { + if (!user.isAuthyVerified()) { + if (event.isCommand() && event.getMessage().startsWith("/authy")) return; + event.setCancelled(true); + return; + } + + if (user.isRank(UserRank.HELPOP)) { + Utils.redisChatLog(player.getName(), event.getMessage()); + } + + if (event.isCommand()) return; + + if (player.hasPermission("staffchat.use") && (user.getStaffChat() || event.getMessage().startsWith("#"))) { + event.setCancelled(true); + String msg = event.getMessage().startsWith("#") ? event.getMessage().substring(1) : event.getMessage(); + Utils.redisStaffChat(user.getColoredName(player), msg); + } + }); + } catch(Exception exception) { + exception.printStackTrace(); + } + } + +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/listeners/Connect.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/listeners/Connect.java new file mode 100644 index 0000000..455bdf4 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/listeners/Connect.java @@ -0,0 +1,78 @@ +package net.grandtheftmc.Bungee.listeners; + +import net.grandtheftmc.Bungee.Bungee; +import net.grandtheftmc.Bungee.Utils; +import net.grandtheftmc.Bungee.redisbungee.data.DataType; +import net.grandtheftmc.Bungee.users.User; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.event.ServerConnectEvent; +import net.md_5.bungee.api.plugin.Listener; +import net.md_5.bungee.event.EventHandler; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +public class Connect implements Listener { + + @EventHandler + public void onConnect(ServerConnectEvent event) { + + // grab event variables + ProxiedPlayer player = event.getPlayer(); + + // TODO test messages remove + System.out.println("target: " + event.getTarget()); + System.out.println("player server: " + player.getServer()); + + Optional userOptional = Bungee.getUserManager().getLoadedUser(player.getUniqueId()); + userOptional.ifPresent(user -> { + user.update(); + Bungee.getUserManager().setPerms(player, user.getUserRank()); + + if (!user.isAuthyVerified() && player.getServer() != null) { + event.setCancelled(true); + return; + } + + Map map = new HashMap<>(); + map.put("uuid", player.getUniqueId().toString()); + + String ser = Bungee.getRedisManager().serialize(DataType.STAFF_JOIN, map); + //Send this serialised object to other redis servers for handling... + Bungee.getRedisManager().sendMessage(ser); + }); + + // if the player is currently not on a server + if (player.getServer() == null) { + + // NOTE: The below attempted to allow force hosts to connect directly through + // This failed because force_default_server in bungee MUST be false to allow + // players to use force hosts. However, force_default_server being false means + // players will joining without a force hosts will ALWAYS go back to the + // server they last connected to + + // if no target + if (event.getTarget() == null) { + event.setTarget(Utils.getRandomHub()); + } + + else { + // if they are attempting to join ANY hub, pick a random one + if (event.getTarget().getName().contains("hub")) { + event.setTarget(Utils.getRandomHub()); + } else { + // do nothing, as this should let + // the player force host through + + // if case force default fails, set their "rejoin server" + // as a random hub + player.setReconnectServer(Utils.getRandomHub()); + } + } + } + + // TODO remove test messages + System.out.println("target server after: " + event.getTarget()); + } +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/listeners/Disconnect.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/listeners/Disconnect.java new file mode 100644 index 0000000..fb3ec7f --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/listeners/Disconnect.java @@ -0,0 +1,59 @@ +package net.grandtheftmc.Bungee.listeners; + +import net.grandtheftmc.Bungee.Bungee; +import net.grandtheftmc.Bungee.Utils; +import net.grandtheftmc.Bungee.redisbungee.data.DataType; +import net.grandtheftmc.Bungee.users.User; +import net.grandtheftmc.Bungee.utils.HelpLog; +import net.grandtheftmc.Bungee.utils.PlaytimeManager; +import net.grandtheftmc.Bungee.utils.TimeFormatter; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.event.PlayerDisconnectEvent; +import net.md_5.bungee.api.plugin.Listener; +import net.md_5.bungee.event.EventHandler; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.TimeUnit; + +public class Disconnect implements Listener { + + @EventHandler + public void onDisconnect(PlayerDisconnectEvent event) { + ProxiedPlayer player = event.getPlayer(); + + //Stop tracking playtime + PlaytimeManager.endSession(player); + + if (HelpLog.helpTicketExists(player.getName())) { + //send a close + Map map = new HashMap<>(); + map.put("helper", "null"); + map.put("sender", player.getName()); + String ser = Bungee.getRedisManager().serialize(DataType.HELP_CLOSE, map); + //Send this serialised object to other redis servers for handling... + Bungee.getRedisManager().sendMessage(ser); + } + + Optional userOptional = Bungee.getUserManager().getLoadedUser(player.getUniqueId()); + userOptional.ifPresent(user -> { + user.setLastQuit(System.currentTimeMillis()); + Long session = user.getLastQuit() - user.getLastJoin(); + user.setPlaytime(user.getPlaytime() + session); + TimeFormatter timeFormatter = new TimeFormatter(TimeUnit.MILLISECONDS, session); + String msg = "[QUIT] played for " + timeFormatter.getHours() + + "h " + timeFormatter.getMinutes() + "m " + timeFormatter.getSeconds() + "s"; + Utils.chatLog(player.getName(), msg); + }); + +// Bungee.getInstance().getProxy().getScheduler().runAsync(Bungee.getInstance(), () -> { +// try (PreparedStatement statement = Bungee.getSQL().prepareStatement("DELETE FROM user_respack WHERE user=UNHEX(?);")) { +// statement.setString(1, player.getUniqueId().toString().replaceAll("-", "")); +// statement.execute(); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// }); + } +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/listeners/Kick.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/listeners/Kick.java new file mode 100644 index 0000000..aa01549 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/listeners/Kick.java @@ -0,0 +1,41 @@ +package net.grandtheftmc.Bungee.listeners; + +import net.grandtheftmc.Bungee.Bungee; +import net.grandtheftmc.Bungee.Utils; +import net.md_5.bungee.api.AbstractReconnectHandler; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.event.ServerKickEvent; +import net.md_5.bungee.api.plugin.Listener; +import net.md_5.bungee.event.EventHandler; + +import java.util.Objects; + +public class Kick implements Listener { + + @EventHandler + public void onServerKick(ServerKickEvent event) { + ProxiedPlayer player = event.getPlayer(); + ProxyServer proxy = Bungee.getInstance().getProxy(); + ServerInfo kickedFrom; + + if (event.getPlayer().getServer() != null) { + kickedFrom = event.getPlayer().getServer().getInfo(); + } + else if (proxy.getReconnectHandler() != null) { + kickedFrom = proxy.getReconnectHandler().getServer(event.getPlayer()); + } + else { + kickedFrom = AbstractReconnectHandler.getForcedHost(event.getPlayer().getPendingConnection()); + if (kickedFrom == null) + kickedFrom = proxy.getServerInfo(event.getPlayer().getPendingConnection().getListener().getServerPriority().get(0)); + } + + ServerInfo kickTo = Utils.getRandomHub(); + if (Objects.equals(kickedFrom, kickTo)) return; + event.setCancelled(true); + event.setCancelServer(kickTo); + player.sendMessage(event.getKickReasonComponent()); + } +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/listeners/Login.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/listeners/Login.java new file mode 100644 index 0000000..3658b7b --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/listeners/Login.java @@ -0,0 +1,52 @@ +package net.grandtheftmc.Bungee.listeners; + +import net.grandtheftmc.Bungee.Bungee; +import net.grandtheftmc.Bungee.Utils; +import net.grandtheftmc.Bungee.users.User; +import net.grandtheftmc.Bungee.users.UserRank; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.event.LoginEvent; +import net.md_5.bungee.api.plugin.Listener; +import net.md_5.bungee.event.EventHandler; + +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; + +public class Login implements Listener { + + @EventHandler + public void onLogin(LoginEvent event) { + UUID uuid = event.getConnection().getUniqueId(); + Optional userOptional = Bungee.getUserManager().getLoadedUser(uuid); + userOptional.ifPresent(user -> { + if (!Objects.equals(user.getUsername(), event.getConnection().getName())) + user.setUsername(event.getConnection().getName()); + + user.setLastJoin(System.currentTimeMillis()); + + if (user.isRank(UserRank.BUILDER)) { + String address = event.getConnection().getAddress().getAddress().getHostAddress(); + if (user.getLastIPAddress().equals(address)) + user.setAuthyVerified(true); + + else { + Utils.redisChatLog(user.getUsername(), "logged in with unknown IP address " + address); + if (user.getAuthyId() != 0) Bungee.getAuthyManager().sendSMSToken(user.getAuthyId()); + user.setAuthyVerified(false); + } + } + }); + + event.registerIntent(Bungee.getInstance()); + ProxyServer.getInstance().getScheduler().runAsync(Bungee.getInstance(), () -> { + ProxiedPlayer player = ProxyServer.getInstance().getPlayer(uuid); + if (player != null) + Bungee.getUserManager().setPerms(player, userOptional.isPresent() ? userOptional.get().getUserRank() : UserRank.DEFAULT); + + event.completeIntent(Bungee.getInstance()); + }); + } +} + diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/listeners/Ping.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/listeners/Ping.java new file mode 100644 index 0000000..05c1dd5 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/listeners/Ping.java @@ -0,0 +1,31 @@ +package net.grandtheftmc.Bungee.listeners; + +import net.grandtheftmc.Bungee.Bungee; +import net.grandtheftmc.Bungee.Utils; +import net.md_5.bungee.api.ServerPing; +import net.md_5.bungee.api.event.ProxyPingEvent; +import net.md_5.bungee.api.plugin.Listener; +import net.md_5.bungee.event.EventHandler; + +public class Ping implements Listener { + +// private static final int[] prez_is_12 = new int[]{420, 69, 6969, 666}; + + @EventHandler + public void onPing(ProxyPingEvent event) { + ServerPing ping = event.getResponse(); + + ServerPing.Players players = ping.getPlayers(); + //Set online players to equal the number on all servers distributed across redis. + int online = Bungee.getRedisManager().getRedisAPI().getPlayersOnline().size(); + players.setOnline(online); + //Was here before, but not exactly sure why, guessing you have no max cap? +// players.setMax(prez_is_12[ThreadLocalRandom.current().nextInt(0, prez_is_12.length-1)]); + players.setMax(1500); + + if (Bungee.getSettings().getMotd() != null) { + //Set our MOTD if one exists + ping.setDescriptionComponent(Utils.ft(Bungee.getSettings().getMotd())); + } + } +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/redisbungee/RedisListener.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/redisbungee/RedisListener.java new file mode 100644 index 0000000..0a3a547 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/redisbungee/RedisListener.java @@ -0,0 +1,258 @@ +package net.grandtheftmc.Bungee.redisbungee; + +import com.imaginarycode.minecraft.redisbungee.events.PubSubMessageEvent; +import net.grandtheftmc.Bungee.Bungee; +import net.grandtheftmc.Bungee.Lang; +import net.grandtheftmc.Bungee.Utils; +import net.grandtheftmc.Bungee.database.BaseDatabase; +import net.grandtheftmc.Bungee.redisbungee.data.DataType; +import net.grandtheftmc.Bungee.users.User; +import net.grandtheftmc.Bungee.users.UserRank; +import net.grandtheftmc.Bungee.utils.HelpLog; +import net.grandtheftmc.Bungee.utils.PlaytimeManager; +import net.grandtheftmc.Bungee.utils.UUIDUtil; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.plugin.Listener; +import net.md_5.bungee.event.EventHandler; +import org.json.JSONObject; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; + +public class RedisListener implements Listener { + + @EventHandler + public void onPubSubMessage(PubSubMessageEvent event) { + if (event.getChannel().equalsIgnoreCase(Bungee.getRedisManager().getMessageChannel())) { + JSONObject serialized = new JSONObject(event.getMessage()); + + String dataTypeString = serialized.getString("datatype"); + DataType typeEnum = DataType.valueOf(dataTypeString); + + if (typeEnum == null) { + //Invalid datatype + return; + } + + DataType dataType = DataType.valueOf(serialized.getString("datatype")); + + switch (dataType) { + case GMSG: + String target = serialized.getString("target"); + if (Bungee.getInstance().getProxy().getPlayer(target) == null) return; + String sender = serialized.getString("sender"); + String message = serialized.getString("message"); + String senderColName = Utils.f(serialized.getString("senderCol")); + ProxiedPlayer targetPlayer = Bungee.getInstance().getProxy().getPlayer(target); + String url = ""; + for (String string : message.split(" ")) { + if (string.matches("^((https?|ftp)://|(www|ftp)\\.)?[a-z0-9-]+(\\.[a-z0-9-]+)+([/?].*)?$")) { + url = string; + break; + } + } + BaseComponent[] a = new ComponentBuilder(Lang.GMSG.f("&7[" + senderColName + "&7 -> me] &r" + message)) + .event(url.isEmpty() ? new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/gmsg " + sender + " ") + : new ClickEvent(ClickEvent.Action.OPEN_URL, url)) + .create(); + targetPlayer.sendMessage(a); + break; + + case STAFFCHAT: + //A message has been distributed to the staff chat, send this message to all online staff + Utils.staffChat(serialized.getString("sender"), serialized.getString("message")); + break; + + case STAFF_JOIN: + PlaytimeManager.beginSession(serialized.getString("uuid")); + break; + + case HELP_CLOSE: + String staffResponseName = serialized.getString("helper"); + + String helpRequester = serialized.getString("sender"); + + if (staffResponseName.equalsIgnoreCase("null")) { + //If a player logs out their ticket is automatically closed. + HelpLog.closeHelpTicket(helpRequester); + return; + } + + String staffResponseUUID = serialized.getString("helperUUID"); + + //If no ticket exists skip this part. + if (!HelpLog.helpTicketExists(helpRequester)) return; + + boolean receiveTokens = HelpLog.closeHelpTicket(helpRequester); + + ProxiedPlayer pp = Bungee.getInstance().getProxy().getPlayer(UUID.fromString(staffResponseUUID)); + + ProxyServer.getInstance().getPlayers() + .stream() + .filter(player -> player.hasPermission("staffchat.use")) + .forEach(player -> + player.sendMessage(Lang.HELP.ft(staffResponseName + + " &7answered " + helpRequester))); + + if (pp == null) { + Bungee.log(staffResponseUUID); + return; + } + + if (receiveTokens) { + Optional userOptional = Bungee.getUserManager().getLoadedUser(pp.getUniqueId()); + userOptional.ifPresent(user -> { + Bungee.getInstance().getProxy().getScheduler().runAsync(Bungee.getInstance(), () -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("update users set tokens=tokens+" + 1 + " where uuid=?;")) { + statement.setString(1, pp.getUniqueId().toString()); + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + } + }); + }); + } + break; + + case HELP: + String playerName = serialized.getString("sender"), + server = serialized.getString("server"), + msg = serialized.getString("message"); + Utils.redisHelp(playerName, msg, server); + HelpLog.requestHelp(playerName); + break; + + case SOCIALSPY: + String mess = Utils.f(serialized.getString("message")); + String[] exclude = serialized.getString("exclude").split(","); + Set ex = new HashSet<>(); + Arrays.stream(exclude).forEach(e -> ex.add(e.toLowerCase())); + //Stop players receiving social spy msgs if they have been msged or sent the msg + + for (ProxiedPlayer proxP : ProxyServer.getInstance().getPlayers()) { + Optional u = Bungee.getUserManager().getLoadedUser(proxP.getUniqueId()); + if (u.isPresent() && u.get().getSocialSpy()) { + //User is non null has has social spy enabled. + proxP.sendMessage(mess); + } + } + break; + + case MOTD: + sender = serialized.getString("sender"); + if (serialized.has("reload") && serialized.getBoolean("reload")) { + //we want to reload the MOTD from the config. + Bungee.getSettings().setMotdConfig(Utils.loadConfig("motd")); + Bungee.getSettings().setMotd(Bungee.getSettings().getMotdConfig().getString("motd")); + + if (sender.equals("CONSOLE")) { + Bungee.getInstance().getLogger().info("MOTD was reloaded successfully."); + } else { + pp = Bungee.getInstance().getProxy().getPlayer(sender); + + if (pp == null) return; + + pp.sendMessage(Utils.ft("&7Bungee MOTD reloaded successfully.")); + } + } else if (serialized.has("motd")) { + //we want to set a new MOTD, colour codes are translated in the ping event so we dont do that here. + String motd = serialized.getString("motd"); + Bungee.getSettings().setMotd(motd); + + if (sender.equals("CONSOLE")) { + Bungee.getInstance().getLogger().info("You have set a temporary MOTD! Note that it will reset to the motd.yml value when Bungee restarts."); + Bungee.getInstance().getLogger().info(motd); + } else { + pp = Bungee.getInstance().getProxy().getPlayer(sender); + + if (pp == null) return; + + pp.sendMessage(Utils.ft("&7You have set a temporary MOTD! Note that it will reset to the motd.yml value when Bungee restarts.")); + pp.sendMessage(Utils.ft(motd)); + } + } + break; + + case PERMS: + String issuer = serialized.getString("sender"); + pp = Bungee.getInstance().getProxy().getPlayer(issuer); + + if (serialized.has("reload") && serialized.getBoolean("reload")) { + Bungee.getSettings().setPermsConfig(Utils.loadConfig("perms")); + Bungee.getUserManager().loadPerms(); + + if (pp != null) { + pp.sendMessage(Utils.ft("&7GPerms config reloaded.")); + } else { + Bungee.getInstance().getLogger().info("Perms config reloaded."); + } + + } else if (serialized.has("target")) { + String targetUser = serialized.getString("target"); + + ProxiedPlayer targ = Bungee.getInstance().getProxy().getPlayer(targetUser); + + if (pp != null) { + pp.sendMessage(Lang.PERMS.ft("&a" + targetUser + " &aupdated.")); + } else { + Bungee.getInstance().getLogger().info(targ.getDisplayName() + " updated."); + } + + if (targ != null) { + Optional userOptional = Bungee.getUserManager().getLoadedUser(targ.getUniqueId()); + if (userOptional.isPresent()) { + userOptional.get().update(); + } else { + Bungee.getInstance().getProxy().getScheduler().runAsync(Bungee.getInstance(), () -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT HEX(UP.uuid) AS uid, UP.rank, U.name FROM user_profile UP, user U WHERE UP.uuid=UNHEX(?) AND UP.uuid=U.uuid;")) { + statement.setString(1, targ.getUniqueId().toString().replaceAll("-", "")); + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + String username = result.getString("name"); + UUID uuid = UUIDUtil.createUUID(result.getString("uid")).orElse(null); + UserRank ur = UserRank.getUserRank(result.getString("rank")); + + User user = Bungee.getUserManager().getLoadedUsersMap().computeIfAbsent(uuid, User::new); + + user.setUserRank(ur); + user.setUsername(username); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } + } + } + break; + + case LOG: + String logType = serialized.getString("type"); + + if (logType.equals("staff")) { + String logSender = serialized.getString("sender"); + String logMessage = serialized.getString("message"); + Utils.chatLog(logSender, logMessage); + } else { + String logMessage = serialized.getString("message"); + String logName = serialized.getString("logname"); + Utils.log(logMessage, logName); + } + default: + break; + } + } + } +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/redisbungee/RedisManager.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/redisbungee/RedisManager.java new file mode 100644 index 0000000..13b9a37 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/redisbungee/RedisManager.java @@ -0,0 +1,46 @@ +package net.grandtheftmc.Bungee.redisbungee; + +import com.imaginarycode.minecraft.redisbungee.RedisBungeeAPI; +import net.grandtheftmc.Bungee.redisbungee.data.DataType; +import org.json.JSONObject; + +import java.util.Map; +import java.util.UUID; + +public class RedisManager { + private final String messageChannel = "gtm_messages"; + private final RedisBungeeAPI redisBungeeAPI; + + public RedisManager(RedisBungeeAPI redisBungeeAPI) { + this.redisBungeeAPI = redisBungeeAPI; + } + + public void sendMessage(String serialized) { + this.redisBungeeAPI.sendChannelMessage(this.messageChannel, serialized); + } + + public UUID getUUIDFromName(String name) { + return this.redisBungeeAPI.getUuidFromName(name, false); + } + + public boolean isPlayerOnline(String name) { + UUID uuid = getUUIDFromName(name); + if (uuid == null) return false; + return this.redisBungeeAPI.isPlayerOnline(uuid); + } + + public RedisBungeeAPI getRedisAPI() { + return this.redisBungeeAPI; + } + + public String getMessageChannel() { + return this.messageChannel; + } + + public String serialize(DataType dataType, Map data) { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("datatype", dataType.name()); + data.keySet().forEach(key -> jsonObject.put(key, data.get(key))); + return jsonObject.toString(); + } +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/redisbungee/data/DataType.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/redisbungee/data/DataType.java new file mode 100644 index 0000000..a318119 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/redisbungee/data/DataType.java @@ -0,0 +1,13 @@ +package net.grandtheftmc.Bungee.redisbungee.data; + +public enum DataType { + + GMSG("GMSG"), STAFFCHAT("STAFFCHAT"), HELP("HELP"), HELP_CLOSE("HELP_C"), SOCIALSPY("SOCIALSPY"), MOTD("MOTD"), + PERMS("PERMS"), STAFF_JOIN("STAFFJOIN"), LOG("LOG"); + + private final String identifier; + + DataType(String identifier) { + this.identifier = identifier; + } +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/tasks/AnnouncerTask.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/tasks/AnnouncerTask.java new file mode 100644 index 0000000..252ddf1 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/tasks/AnnouncerTask.java @@ -0,0 +1,28 @@ +package net.grandtheftmc.Bungee.tasks; + +import net.grandtheftmc.Bungee.Bungee; +import net.grandtheftmc.Bungee.Lang; +import net.grandtheftmc.Bungee.users.User; +import net.md_5.bungee.api.connection.ProxiedPlayer; + +import java.util.*; +import java.util.concurrent.TimeUnit; + +public class AnnouncerTask { + + public AnnouncerTask() { + Bungee.getInstance().getProxy().getScheduler().schedule(Bungee.getInstance(), () -> { + int count = 0; + + for (UUID uuid : Bungee.getRedisManager().getRedisAPI().getPlayersOnline()) { + Optional userOptional = Bungee.getUserManager().getLoadedUser(uuid); + if (userOptional.isPresent()) { + count++; + } + } + + if (count <= 1) return; + Bungee.getInstance().getProxy().broadcast(Lang.GTM.f("&e&lThere are currently " + count + " staff members online! Need help? Use &a&l/help ")); + }, 300, 700, TimeUnit.SECONDS); + } +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/tasks/AuthyTask.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/tasks/AuthyTask.java new file mode 100644 index 0000000..1f0d990 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/tasks/AuthyTask.java @@ -0,0 +1,38 @@ +package net.grandtheftmc.Bungee.tasks; + +import net.grandtheftmc.Bungee.Bungee; +import net.grandtheftmc.Bungee.Lang; +import net.grandtheftmc.Bungee.users.UserRank; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.api.connection.ProxiedPlayer; + +import java.util.concurrent.TimeUnit; + +public class AuthyTask { + + public AuthyTask() { + Bungee.getInstance().getProxy().getScheduler().schedule(Bungee.getInstance(), () -> { + Bungee.getUserManager().getLoadedUsers().forEach(user -> { + if (!user.isRank(UserRank.BUILDER)) return; + + ProxiedPlayer player = Bungee.getInstance().getProxy().getPlayer(user.getUUID()); + if (player == null) return; + + if (!user.isAuthyVerified()) { + if (user.getAuthyId() == 0) { + player.sendMessage(Lang.VERIFICATION.ft("&7You must register with 2FA &7before &7continuing! " + + "&a/authy register &a " + + "&7Need help? &a/authy help &7or contact a &4&lManager")); + } + + else { + TextComponent textComponent = Lang.VERIFICATION.ft("&7Please enter your 2 factor authentication &7code before continuing! &a/authy verify "); + textComponent.setColor(ChatColor.GRAY); + player.sendMessage(textComponent); + } + } + }); + }, 0, 10, TimeUnit.SECONDS); + } +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/tasks/PlaytimePurgeTask.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/tasks/PlaytimePurgeTask.java new file mode 100644 index 0000000..b97e912 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/tasks/PlaytimePurgeTask.java @@ -0,0 +1,17 @@ +package net.grandtheftmc.Bungee.tasks; + +import net.grandtheftmc.Bungee.Bungee; +import net.grandtheftmc.Bungee.Lang; +import net.grandtheftmc.Bungee.users.User; +import net.grandtheftmc.Bungee.utils.PlaytimeManager; + +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +public class PlaytimePurgeTask { + + public PlaytimePurgeTask() { + Bungee.getInstance().getProxy().getScheduler().schedule(Bungee.getInstance(), PlaytimeManager::purgeOldSessions, 0, 1, TimeUnit.DAYS); + } +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/tasks/ServerStatusTask.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/tasks/ServerStatusTask.java new file mode 100644 index 0000000..86b456b --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/tasks/ServerStatusTask.java @@ -0,0 +1,20 @@ +package net.grandtheftmc.Bungee.tasks; + +import net.grandtheftmc.Bungee.Bungee; +import net.grandtheftmc.Bungee.utils.ServerStatus; + +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.TimeUnit; + +public class ServerStatusTask { + + public ServerStatusTask() { + Bungee.getInstance().getProxy().getScheduler().schedule(Bungee.getInstance(), () -> Bungee.getInstance().getProxy().getServers().values().forEach(serverInfo -> { + try { + ServerStatus serverStatus = ServerStatus.getServerStatus(serverInfo); + serverStatus.updateStatus(); + } + catch (RejectedExecutionException ignored) {} + }), 1, 15, TimeUnit.SECONDS); + } +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/users/User.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/users/User.java new file mode 100644 index 0000000..0236541 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/users/User.java @@ -0,0 +1,212 @@ +package net.grandtheftmc.Bungee.users; + +import net.grandtheftmc.Bungee.Bungee; +import net.grandtheftmc.Bungee.database.BaseDatabase; +import net.md_5.bungee.api.connection.ProxiedPlayer; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.UUID; + +public class User { + private final UUID uuid; + private String username; + private UserRank ur; + private int authyId = 0; + private boolean authyVerified; + private String lastIPAddress = "0"; + + private boolean staffChat; + private boolean socialSpy; + private long lastJoin; + private long lastQuit; + private long playtime; + + public User(UUID uuid) { + this.uuid = uuid; + this.dataCheck(); + } + + public void dataCheck() { + this.update(); + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO Authy (uuid,authyId) VALUES (?, ?) ON DUPLICATE KEY UPDATE uuid=?;")) { + statement.setString(1, this.uuid.toString()); + statement.setInt(2, this.authyId); + statement.setString(3, this.uuid.toString()); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + } + } + + public UUID getUUID() { + return this.uuid; + } + + public String getUsername() { + return this.username; + } + + public void setUsername(String username) { + this.username = username; + } + + public UserRank getUserRank() { + return this.ur; + } + + public void setUserRank(UserRank ur) { + this.ur = ur; + } + + public boolean isRank(UserRank userRank) { + return userRank == this.ur || this.ur.isHigherThan(userRank); + } + + public boolean isSpecial() { + return this.ur != UserRank.DEFAULT; + } + + public int getAuthyId() { + return this.authyId; + } + + public void setAuthyId(int authyId) { + this.authyId = authyId; + + Bungee.getInstance().getProxy().getScheduler().runAsync(Bungee.getInstance(), () -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE Authy SET authyId=? WHERE uuid=?;")) { + statement.setInt(1, this.authyId); + statement.setString(2, this.uuid.toString()); + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } + + public boolean isAuthyVerified() { + if (!this.isRank(UserRank.BUILDER)) return true; + return authyVerified; + } + + public void setAuthyVerified(boolean authyVerified) { + this.authyVerified = authyVerified; + } + + public String getLastIPAddress() { + return this.lastIPAddress; + } + + public void setLastIPAddress(String lastIPAddress) { + this.lastIPAddress = lastIPAddress; + + Bungee.getInstance().getProxy().getScheduler().runAsync(Bungee.getInstance(), () -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE Authy SET lastIPAddress=? WHERE uuid=?;")) { + statement.setString(1, this.lastIPAddress); + statement.setString(2, this.uuid.toString()); + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } + + public boolean getStaffChat() { + return this.staffChat; + } + + public void setStaffChat(boolean b) { + this.staffChat = b; + } + + public void toggleStaffChat() { + this.staffChat = !this.staffChat; + } + + public boolean getSocialSpy() { + return this.socialSpy; + } + + public void setSocialSpy(boolean b) { + this.socialSpy = b; + } + + public Long getLastJoin() { + return this.lastJoin; + } + + public void setLastJoin(Long lastJoin) { + this.lastJoin = lastJoin; + } + + public long getLastQuit() { + return this.lastQuit; + } + + public void setLastQuit(long lastQuit) { + this.lastQuit = lastQuit; + } + + public Long getPlaytime() { + return this.playtime; + } + + public void setPlaytime(Long playtime) { + this.playtime = playtime; + } + + public String getColoredName(ProxiedPlayer player) { + return this.ur.getColor() + (this.ur == UserRank.DEFAULT ? "" : "&l") + player.getName(); + } + + public String getColoredName() { + return this.ur.getColor() + (this.ur == UserRank.DEFAULT ? "" : "&l") + this.username; + } + + public void update() { + Bungee.getInstance().getProxy().getScheduler().runAsync(Bungee.getInstance(), () -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT UP.rank, U.name FROM user_profile UP, user U WHERE UP.uuid=UNHEX(?) AND UP.uuid=U.uuid;")) { + statement.setString(1, this.uuid.toString().replaceAll("-", "")); + try (ResultSet result = statement.executeQuery()) { + if (result.next()) { + UserRank ur = UserRank.getUserRank(result.getString("rank")); + if (!ur.isHigherThan(UserRank.YOUTUBER)) { + Bungee.getUserManager().getLoadedUsers().remove(this); + return; + } + this.ur = ur; + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT authyId,lastIPAddress FROM Authy WHERE uuid=? LIMIT 1;")) { + statement.setString(1, this.uuid.toString()); + try (ResultSet result = statement.executeQuery()) { + if (result.next()) { + this.authyId = result.getInt("authyId"); + this.lastIPAddress = result.getString("lastIPAddress"); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/users/UserManager.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/users/UserManager.java new file mode 100644 index 0000000..7fb37b7 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/users/UserManager.java @@ -0,0 +1,327 @@ +package net.grandtheftmc.Bungee.users; + +import com.google.common.collect.Maps; +import net.grandtheftmc.Bungee.Bungee; +import net.grandtheftmc.Bungee.database.BaseDatabase; +import net.grandtheftmc.Bungee.utils.Callback; +import net.grandtheftmc.Bungee.utils.UUIDUtil; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.config.Configuration; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; +import java.util.stream.Collectors; + +public class UserManager { + + private final Map loadedUsers = new HashMap<>(); + + /** + * Default set of permissions, loaded from configuration + * + * @see #loadPerms() + */ + private final Map> perms = new HashMap<>(); + + public UserManager() { + this.loadPerms(); + this.loadUsers(); + } + + /** + * Load permissions ranks from configuration file. + */ + public void loadPerms() { + Configuration c = Bungee.getSettings().getPermsConfig(); + for (String s : c.getKeys()) { + UserRank rank = UserRank.getUserRankOrNull(s); + if (rank != null) this.perms.put(rank, c.getStringList(s)); + } + this.setPerms(); + } + + /** + * Load a default set of users into redis memory from MySQL storage. + *

+ * The default set is of all staff members, additional users are loaded on demand. + */ + public void loadUsers() { + Bungee.getInstance().getProxy().getScheduler().runAsync(Bungee.getInstance(), () -> { + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + this.step1(connection, obj -> { + this.step2(connection, obj); + }); + } catch (SQLException e) { + e.printStackTrace(); + } + +// try (Connection connection = BaseDatabase.getInstance().getConnection()) { +// try (PreparedStatement statement = connection.prepareStatement("SELECT HEX(uuid) AS uid,rank FROM `user_profile` WHERE rank IN ('builder', 'helpop', 'mod', 'srmod', 'admin', 'dev', 'manager', 'owner');")) { +// try (ResultSet result = statement.executeQuery()) { +// HashMap map = Maps.newHashMap(); +// while (result.next()) { +// UUID u = UUIDUtil.createUUID(result.getString("uid")).orElse(null); +// if (u == null) continue; +// map.put(u, UserRank.getUserRank(result.getString("rank"))); +// } +// +// UUID uuid = null; +// for (UUID uid : map.keySet()) { +// uuid = uid; +// try (PreparedStatement statement2 = connection.prepareStatement("SELECT lastname,socialSpy FROM `users` WHERE `uuid`=?;")) { +// statement2.setString(1, uid.toString()); +// try (ResultSet result2 = statement2.executeQuery()) { +// if (result2.next()) { +// String username = result2.getString("lastname"); +// boolean socialSpy = result2.getBoolean("socialSpy"); +// +// //Add user key to hashmap. +// User user = this.loadedUsers.computeIfAbsent(uid, k -> { +// User u = new User(k); +// Bungee.getInstance().getLogger().info("Successfully cached user " + u.getUUID()); +// return u; +// }); +// +// //Set ranks and other miscellaneous data. +// user.setUserRank(map.get(uid)); +// user.setSocialSpy(socialSpy); +// user.setUsername(username); +// } +// } +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// } +// +// ResultSet rs = Bungee.getSQL().query("SELECT authyId,lastIPAddress FROM Authy WHERE uuid='" + uuid.toString() + "' LIMIT 1;"); +// Optional user = getLoadedUser(uuid); +// if (!user.isPresent()) { +// rs.close(); +// return; +// } +// +// int authyId = 0; +// String ipAddress = "0"; +// if (rs.next()) { +// authyId = rs.getInt("authyId"); +// ipAddress = rs.getString("lastIPAddress"); +// } +// user.get().setAuthyId(authyId); +// user.get().setLastIPAddress(ipAddress); +// rs.close(); +// } +// } +// } catch (SQLException e) { +// e.printStackTrace(); +// } + +// try { +// ResultSet resultSet = Bungee.getSQL().query("SELECT HEX(uuid) AS uid,rank FROM `user_profile` WHERE rank IN ('builder', 'helpop', 'mod', 'srmod', 'admin', 'dev', 'manager', 'owner');"); +// HashMap map = Maps.newHashMap(); +// while (resultSet.next()) { +// UUID u = UUIDUtil.createUUID(resultSet.getString("uid")).orElse(null); +// if (u == null) continue; +// map.put(u, UserRank.getUserRank(resultSet.getString("rank"))); +// } +// resultSet.close(); + +// UUID uuid = null; +// for (UUID uid : map.keySet()) { +// uuid = uid; +// try (PreparedStatement statement = Bungee.getSQL().prepareStatement("SELECT lastname,socialSpy FROM `users` WHERE `uuid`=?;")) { +// statement.setString(1, uid.toString()); +// try (ResultSet set = statement.executeQuery()) { +// if (set.next()) { +// String username = set.getString("lastname"); +// boolean socialSpy = set.getBoolean("socialSpy"); +// +// //Add user key to hashmap. +// User user = this.loadedUsers.computeIfAbsent(uid, k -> { +// User u = new User(k); +// Bungee.getInstance().getLogger().info("Successfully cached user " + u.getUUID()); +// return u; +// }); +// +// //Set ranks and other miscellaneous data. +// user.setUserRank(map.get(uid)); +// user.setSocialSpy(socialSpy); +// user.setUsername(username); +// } +// } +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// } + +// ResultSet rs = Bungee.getSQL().query("SELECT authyId,lastIPAddress FROM Authy WHERE uuid='" + uuid.toString() + "' LIMIT 1;"); +// Optional user = getLoadedUser(uuid); +// if (!user.isPresent()) { +// rs.close(); +// return; +// } +// +// int authyId = 0; +// String ipAddress = "0"; +// if (rs.next()) { +// authyId = rs.getInt("authyId"); +// ipAddress = rs.getString("lastIPAddress"); +// } +// user.get().setAuthyId(authyId); +// user.get().setLastIPAddress(ipAddress); +// rs.close(); +// } catch (SQLException exception) { +// exception.printStackTrace(); +// } + }); + } + + private void step1(Connection connection, Callback> callback) { + try (PreparedStatement statement = connection.prepareStatement("SELECT HEX(uuid) AS uid,rank FROM `user_profile` WHERE rank IN ('builder', 'helpop', 'mod', 'srmod', 'admin', 'dev', 'manager', 'owner');")) { + try (ResultSet result = statement.executeQuery()) { + HashMap map = Maps.newHashMap(); + while (result.next()) { + UUID u = UUIDUtil.createUUID(result.getString("uid")).orElse(null); + if (u == null) continue; + map.put(u, UserRank.getUserRank(result.getString("rank"))); + } + + callback.call(map); + } + } catch (SQLException e) { + e.printStackTrace(); + } + } + + private void step2(Connection connection, HashMap map) { + UUID uuid; + for (UUID uid : map.keySet()) { + uuid = uid; + try (PreparedStatement statement2 = connection.prepareStatement("SELECT lastname,socialSpy FROM `users` WHERE `uuid`=?;")) { + statement2.setString(1, uid.toString()); + try (ResultSet result2 = statement2.executeQuery()) { + if (result2.next()) { + String username = result2.getString("lastname"); + boolean socialSpy = result2.getBoolean("socialSpy"); + + //Add user key to hashmap. + User user = this.loadedUsers.computeIfAbsent(uid, k -> { + User u = new User(k); + Bungee.getInstance().getLogger().info("Successfully cached user " + u.getUUID()); + return u; + }); + + //Set ranks and other miscellaneous data. + user.setUserRank(map.get(uid)); + user.setSocialSpy(socialSpy); + user.setUsername(username); + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + + this.step3(connection, uuid); + } + } + + private void step3(Connection connection, UUID uuid) { + try (PreparedStatement statement2 = connection.prepareStatement("SELECT authyId,lastIPAddress FROM Authy WHERE uuid='" + uuid.toString() + "' LIMIT 1;")) { + try (ResultSet result = statement2.executeQuery()) { + Optional user = getLoadedUser(uuid); + if (!user.isPresent()) { + result.close(); + return; + } + + int authyId = 0; + String ipAddress = "0"; + if (result.next()) { + authyId = result.getInt("authyId"); + ipAddress = result.getString("lastIPAddress"); + } + user.get().setAuthyId(authyId); + user.get().setLastIPAddress(ipAddress); + } + } catch (SQLException e) { + e.printStackTrace(); + } + } + + public void setPerms() { + for (ProxiedPlayer player : ProxyServer.getInstance().getPlayers()) { + this.getLoadedUser(player.getUniqueId()).ifPresent(user -> this.setPerms(player, user.getUserRank())); + } + } + + public void setPerms(ProxiedPlayer player, UserRank rank) { + if (rank == null) return; + for (String perm : new ArrayList<>(player.getPermissions())) + player.setPermission(perm, false); + + for (String perm : this.getPermsAndLower(rank)) + player.setPermission(perm, true); + } + + private List getPermsAndLower(UserRank rank) { + List perms = new ArrayList<>(); + if (rank != null) + for (UserRank r : UserRank.values()) { + List l = this.perms.get(r); + if (l != null && !l.isEmpty()) + perms.addAll(l); + if (r == rank) break; + } + return perms; + } + + public Map getLoadedUsersMap() { + return loadedUsers; + } + + public Collection getLoadedUsers() { + return this.loadedUsers.values(); + } + + public List getSortedUsers() { + Collection users = Bungee.getUserManager().getLoadedUsers(); + List userList = new ArrayList<>(); + for (UserRank userRank : UserRank.values()) { + userList.addAll(users.stream().filter(user -> user.getUserRank() == userRank).collect(Collectors.toList())); + } + return userList; + } + + /** + * Get the User object of the player with the specified UUID. + * + * @param uuid + * @return + */ + public Optional getLoadedUser(UUID uuid) { + if (uuid == null) return null; + return Optional.ofNullable(this.loadedUsers.get(uuid)); + } + + /** + * Get the User object of the player with the specified username. + * + * @param username + * @return + */ + public Optional getLoadedUser(String username) { + if (username == null) return null; + List users = new ArrayList<>(); + this.loadedUsers.forEach((uuid, user) -> { + if (user.getUsername().equalsIgnoreCase(username)) { + users.add(user); + return; + } + }); + return users.isEmpty() ? Optional.empty() : Optional.of(users.get(0)); + } +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/users/UserRank.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/users/UserRank.java new file mode 100644 index 0000000..2b19d65 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/users/UserRank.java @@ -0,0 +1,99 @@ +package net.grandtheftmc.Bungee.users; + +import net.grandtheftmc.Bungee.Utils; +import net.md_5.bungee.api.ChatColor; + +import java.util.Objects; + +public enum UserRank { + + DEFAULT("&8"), VIP("&6"), PREMIUM("&a"), ELITE("&b"), SPONSOR("&5"), SUPREME("&c"), + YOUTUBER("&r"), HELPOP("&d"), MOD("&9"), SRMOD("&9"), BUILDER("&f"), ADMIN("&c"), + DEV("&9"), MANAGER("&4"), OWNER("&4"); + + private final String color; + + UserRank(String color) { + this.color = color; + } + + public static UserRank[] getUserRanks() { + return UserRank.class.getEnumConstants(); + } + + public static UserRank getUserRank(String name) { + if (name == null) return UserRank.DEFAULT; + for (UserRank ur : getUserRanks()) + if (ur.getName().equalsIgnoreCase(name)) + return ur; + return UserRank.DEFAULT; + } + + public static UserRank getUserRankOrNull(String name) { + if (name == null) + return null; + for (UserRank ur : getUserRanks()) + if (ur.getName().equalsIgnoreCase(name)) + return ur; + return null; + } + + public static UserRank getUserRankExact(String name) { + if (name == null) + return null; + for (UserRank ur : getUserRanks()) + if (ur.getName().equalsIgnoreCase(name)) + return ur; + return null; + } + + public static UserRank[] getDonorRanks() { + return new UserRank[] { VIP, PREMIUM, ELITE, SPONSOR, SUPREME }; + } + + public String getName() { + return this.toString(); + } + + public String getColor() { + return Utils.f(this.isHigherThan(UserRank.YOUTUBER) ? this.color + ChatColor.BOLD : this.color); + } + + public String getColoredName() { + return Utils.f(this == UserRank.YOUTUBER ? "&rYOU&4TUBER" : this.color + this.getName()); + } + + public String getColoredNameBold() { + return Utils.f(this == UserRank.YOUTUBER ? "&r&lYOU&4&lTUBER" : this.color + "&l" + this.getName()); + } + + public String getTabPrefix() { + return Utils.f(this == UserRank.YOUTUBER ? "&r&lY&4&lT" : this.color + "&l" + this.getName()); + } + + public String getPrefix() { + if (!Objects.equals(this.getName(), "DEFAULT")) + return Utils.f(' ' + this.getColoredNameBold() + "&8&l>"); + return ""; + } + + public UserRank getNext() { + boolean picknext = false; + for (UserRank u : getUserRanks()) { + if (picknext) + return u; + if (Objects.equals(u.getName(), this.getName())) + picknext = true; + } + return UserRank.DEFAULT; + } + + public boolean isHigherThan(UserRank rank) { + for (UserRank r : getUserRanks()) + if (r == this) + return false; + else if (r == rank) + return true; + return false; + } +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/utils/Callback.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/utils/Callback.java new file mode 100644 index 0000000..0bb6932 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/utils/Callback.java @@ -0,0 +1,5 @@ +package net.grandtheftmc.Bungee.utils; + +public interface Callback { + void call(T obj); +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/utils/DefaultFontInfo.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/utils/DefaultFontInfo.java new file mode 100644 index 0000000..1e47c5a --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/utils/DefaultFontInfo.java @@ -0,0 +1,133 @@ +package net.grandtheftmc.Bungee.utils; + +import java.util.Arrays; +import java.util.Optional; + +/** + * Created by Adam on 05/06/2017. + */ +public enum DefaultFontInfo { + + A_UPPER('A', 5), + A_LOWER('a', 5), + B_UPPER('B', 5), + B_LOWER('b', 5), + C_UPPER('C', 5), + C_LOWER('c', 5), + D_UPPER('D', 5), + D_LOWER('d', 5), + E_UPPER('E', 5), + E_LOWER('e', 5), + F_UPPER('F', 5), + F_LOWER('f', 4), + G_UPPER('G', 5), + G_LOWER('g', 5), + H_UPPER('H', 5), + H_LOWER('h', 5), + I_UPPER('I', 3), + I_LOWER('i', 1), + J_UPPER('J', 5), + J_LOWER('j', 5), + K_UPPER('K', 5), + K_LOWER('k', 4), + L_UPPER('L', 5), + L_LOWER('l', 1), + M_UPPER('M', 5), + M_LOWER('m', 5), + N_UPPER('N', 5), + N_LOWER('n', 5), + O_UPPER('O', 5), + O_LOWER('o', 5), + P_UPPER('P', 5), + P_LOWER('p', 5), + Q_UPPER('Q', 5), + Q_LOWER('q', 5), + R_UPPER('R', 5), + R_LOWER('r', 5), + S_UPPER('S', 5), + S_LOWER('s', 5), + T_UPPER('T', 5), + T_LOWER('t', 4), + U_UPPER('U', 5), + U_LOWER('u', 5), + V_UPPER('V', 5), + V_LOWER('v', 5), + W_UPPER('W', 5), + W_LOWER('w', 5), + X_UPPER('X', 5), + X_LOWER('x', 5), + Y_UPPER('Y', 5), + Y_LOWER('y', 5), + Z_UPPER('Z', 5), + Z_LOWER('z', 5), + NUM_1('1', 5), + NUM_2('2', 5), + NUM_3('3', 5), + NUM_4('4', 5), + NUM_5('5', 5), + NUM_6('6', 5), + NUM_7('7', 5), + NUM_8('8', 5), + NUM_9('9', 5), + NUM_0('0', 5), + EXCLAMATION_POINT('!', 1), + AT_SYMBOL('@', 6), + NUM_SIGN('#', 5), + DOLLAR_SIGN('$', 5), + PERCENT('%', 5), + UP_ARROW('^', 5), + AMPERSAND('&', 5), + ASTERISK('*', 5), + LEFT_PARENTHESIS('(', 4), + RIGHT_PERENTHESIS(')', 4), + MINUS('-', 5), + UNDERSCORE('_', 5), + PLUS_SIGN('+', 5), + EQUALS_SIGN('=', 5), + LEFT_CURL_BRACE('{', 4), + RIGHT_CURL_BRACE('}', 4), + LEFT_BRACKET('[', 3), + RIGHT_BRACKET(']', 3), + COLON(':', 1), + SEMI_COLON(';', 1), + DOUBLE_QUOTE('"', 3), + SINGLE_QUOTE('\'', 1), + LEFT_ARROW('<', 4), + RIGHT_ARROW('>', 4), + QUESTION_MARK('?', 5), + SLASH('/', 5), + BACK_SLASH('\\', 5), + LINE('|', 1), + TILDE('~', 5), + TICK('`', 2), + PERIOD('.', 1), + COMMA(',', 1), + SPACE(' ', 3), + DEFAULT('a', 4); + + private final char character; + private final int length; + + DefaultFontInfo(char character, int length) { + this.character = character; + this.length = length; + } + + public char getCharacter() { + return this.character; + } + + public int getLength() { + return this.length; + } + + public int getBoldLength() { + if (this == SPACE) return this.length; + return this.length + 1; + } + + public static DefaultFontInfo getDefaultFontInfo(char c) { + Optional defaultFontInfo = Arrays.stream(values()).filter(d -> d.character == c).findFirst(); + return defaultFontInfo.orElse(DEFAULT); + } +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/utils/HelpLog.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/utils/HelpLog.java new file mode 100644 index 0000000..88f08d0 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/utils/HelpLog.java @@ -0,0 +1,57 @@ +package net.grandtheftmc.Bungee.utils; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * Created by Adam on 03/06/2017. + */ +public class HelpLog { + + //A list of users who have requested help. + private static Map helpReqs = new HashMap<>(); + + //1 Minutes timeout for receiving tokens. + private static final int HELP_TOKENS_TIMEOUT = 1000 * 60 * 1; + + /** + * Invoked from RedisListener when a player requests help and this gets forwarded to the staff chat. + * + * @param name + */ + public static void requestHelp(String name) { + helpReqs.put(name.toLowerCase(), System.currentTimeMillis()); + } + + /** + * Invoked whenever a staff member messages a player who requested help. + * + * @param name The name of the player the staff member has gmsg'ed. + * @return True if they should receive tokens. Let's set a 15 minute timeout on help requests in order to receive tokens. + */ + public static boolean closeHelpTicket(String name) { + name = name.toLowerCase(); + if (helpReqs.containsKey(name)) { + long t = helpReqs.remove(name); + long msElapsed = System.currentTimeMillis() - t; + return msElapsed <= HELP_TOKENS_TIMEOUT; + } + + else { + return false; + } + } + + /** + * Check whether the target of gmsg has an open help ticket. + * + * @param name + * @return + */ + public static boolean helpTicketExists(String name) { + return name != null && helpReqs.containsKey(name.toLowerCase()); + } + +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/utils/PlaytimeManager.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/utils/PlaytimeManager.java new file mode 100644 index 0000000..40ee3ae --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/utils/PlaytimeManager.java @@ -0,0 +1,116 @@ +package net.grandtheftmc.Bungee.utils; + +import net.grandtheftmc.Bungee.Bungee; +import net.grandtheftmc.Bungee.Utils; +import net.grandtheftmc.Bungee.database.BaseDatabase; +import net.grandtheftmc.Bungee.users.User; +import net.md_5.bungee.api.connection.ProxiedPlayer; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; + +public class PlaytimeManager { + + //How many days to store session history for. + private static final int sessionHistoryDays = 7; + private static final String tableName = "playtime"; + //Map UUID -> Millis() At connect time to track session time. + private static Map sessions = new HashMap<>(); + + /** + * Mark the beginning of a playtime session for the connecting player. + * + * @param uuid The player whose playtime we wish to track. + */ + public static void beginSession(String uuid) { + sessions.put(UUID.fromString(uuid), System.currentTimeMillis()); + } + + /** + * End the playtime session, and store the result in the database. + * + * @param proxiedPlayer The player whose playtime we wish to track. + */ + public static void endSession(ProxiedPlayer proxiedPlayer) { + if (sessions.containsKey(proxiedPlayer.getUniqueId())) { + long now = System.currentTimeMillis(); + long elapsed = now - sessions.remove(proxiedPlayer.getUniqueId()); + + Bungee.getInstance().getProxy().getScheduler().runAsync(Bungee.getInstance(), () -> { + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + String query = "INSERT INTO " + tableName + " (lastname,uuid,sessiontime,sessiondate) VALUES (?, ?, ?, ?);"; + try (PreparedStatement statement = connection.prepareStatement(query)) { + statement.setString(1, proxiedPlayer.getName()); + statement.setString(2, proxiedPlayer.getUniqueId().toString()); + statement.setLong(3, elapsed); + statement.setLong(4, now); + statement.executeUpdate(); + } + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } + } + + /** + * This function will delete any rows in the DB with session dates older than a week. + * Call this every 24hr and on startup. + */ + public static void purgeOldSessions() { + Bungee.getInstance().getProxy().getScheduler().runAsync(Bungee.getInstance(), () -> { + long threshold = System.currentTimeMillis() - (1000 * 60 * 60 * 24 * sessionHistoryDays); + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("DELETE FROM " + tableName + " WHERE sessionDate<=" + threshold)) { + statement.executeUpdate(); + } + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } + + /** + * Query the playtime of another user. + * + * @param p The player issuing the command. + * @param target The name of the user to lookup. + */ + public static void lookupPlaytime(ProxiedPlayer p, String target) { + Bungee.getInstance().getProxy().getScheduler().runAsync(Bungee.getInstance(), () -> { + + long threshold = System.currentTimeMillis() - (1000 * 60 * 60 * 24 * sessionHistoryDays); + long totalTime = 0; + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT lastname,sessiontime,sessiondate FROM " + tableName + " WHERE lastname='" + target + "' AND sessiondate>" + threshold + ";")) { + try (ResultSet result = statement.executeQuery()) { + if (result.isBeforeFirst()) { + while (result.next()) { + totalTime += result.getLong("sessiontime"); + } + + Optional userOptional = Bungee.getUserManager().getLoadedUser(target); + if (!userOptional.isPresent()) return; + + String s = Utils.formatPlaytime(totalTime); + p.sendMessage(Utils.f(userOptional.get().getColoredName() + " &7has played for &a" + s + " &7in the last week.")); + } else { + p.sendMessage(Utils.f("&cThe player " + target + " either doesn't exist, or hasn't played in the last week.")); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/utils/RequestRateLimiter.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/utils/RequestRateLimiter.java new file mode 100644 index 0000000..8a773ca --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/utils/RequestRateLimiter.java @@ -0,0 +1,48 @@ +package net.grandtheftmc.Bungee.utils; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +/** + * Created by Adam on 05/06/2017. + */ +public class RequestRateLimiter { + + /* + This class serves to limit requests made by staff members to the database. + + No more than 1 execution every second. + + Still allows frequent use, but without spamming. + + Only applies to the /seen, /alt commands + */ + + //Store the issuing player and the time of the last command + private static Map lastReq = new HashMap<>(); + + /** + * Attempt to make a request to execute a database related command. + * @param u The UUID of the player executing the command. + * @return A boolean representing whether they have been granted use of said command or not. + */ + public static boolean requestCmd(UUID u) { + long t = System.currentTimeMillis(); + + if (!lastReq.containsKey(u)) { + lastReq.put(u, t); + return true; + } + + long last = lastReq.get(u); + if (t - last >= 1000) { + //if at least 1 second has passed allow the command. + lastReq.put(u, t); + return true; + } + + return false; + } + +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/utils/ServerStatus.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/utils/ServerStatus.java new file mode 100644 index 0000000..2c34fd1 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/utils/ServerStatus.java @@ -0,0 +1,45 @@ +package net.grandtheftmc.Bungee.utils; + +import io.netty.util.internal.ConcurrentSet; +import net.md_5.bungee.api.Callback; +import net.md_5.bungee.api.ServerPing; +import net.md_5.bungee.api.config.ServerInfo; + +import java.util.HashSet; +import java.util.Set; + +public class ServerStatus implements Callback { + private static final ConcurrentSet serverStatuses = new ConcurrentSet<>(); + private final ServerInfo serverInfo; + private boolean online; + + + public ServerStatus(ServerInfo serverInfo) { + this.serverInfo = serverInfo; + serverStatuses.add(this); + } + + public static ServerStatus getServerStatus(ServerInfo serverInfo) { + Set tempStatuses = new HashSet<>(serverStatuses); + return tempStatuses.stream() + .filter(serverStatus -> serverStatus.getServerInfo() == serverInfo) + .findFirst().orElse(new ServerStatus(serverInfo)); + } + + @Override + public void done(ServerPing serverPing, Throwable throwable) { + this.online = throwable == null; + } + + public void updateStatus() { + this.serverInfo.ping(this); + } + + public boolean isOnline() { + return this.online; + } + + public ServerInfo getServerInfo() { + return this.serverInfo; + } +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/utils/TabComplete.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/utils/TabComplete.java new file mode 100644 index 0000000..478e507 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/utils/TabComplete.java @@ -0,0 +1,40 @@ +package net.grandtheftmc.Bungee.utils; + +import com.google.common.collect.ImmutableSet; +import net.grandtheftmc.Bungee.Bungee; +import net.md_5.bungee.api.CommandSender; + +import java.util.HashSet; +import java.util.Set; + +/** + * Created by Adam on 02/06/2017. + */ +public class TabComplete { + + /** + * Match a list of players to a search string accross the Redis network. + * @param sender Who executed the command. + * @param args Arguments of player to search + * @return A Set of potential matches. + */ + public static Set onTabComplete(CommandSender sender, String[] args){ + if (args.length > 2 || args.length == 0) + return ImmutableSet.of(); + + Set matches = new HashSet<>(); + + if (args.length == 1) { + String search = args[0].toLowerCase(); + + //We search all redis online players for the autocomplete + for (String name : Bungee.getRedisManager().getRedisAPI().getHumanPlayersOnline()) { + if (name.toLowerCase().startsWith(search)) { + matches.add(name); + } + } + } + + return matches; + } +} diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/utils/TimeFormatter.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/utils/TimeFormatter.java new file mode 100644 index 0000000..5373564 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/utils/TimeFormatter.java @@ -0,0 +1,45 @@ +package net.grandtheftmc.Bungee.utils; + +import java.util.concurrent.TimeUnit; + +public class TimeFormatter { + private final TimeUnit timeUnit; + private Long time; + + public TimeFormatter(TimeUnit timeUnit, Long time) { + this.timeUnit = timeUnit; + this.time = time; + } + + public Long getTime() { + return new Long(this.time); + } + + public void setTime(Long time) { + this.time = time; + } + + public TimeUnit getTimeUnit() { + return this.timeUnit; + } + + public Long getSeconds() { + return this.timeUnit.toSeconds(this.time) - (this.timeUnit.toMinutes(this.time) * 60); + } + + public Long getMinutes() { + return this.timeUnit.toMinutes(this.time) - (this.timeUnit.toHours(this.time) * 60); + } + + public Long getHours() { + return this.timeUnit.toHours(this.time) - (this.timeUnit.toDays(this.time) * 24); + } + + public Long getDays() { + return this.timeUnit.toDays(this.time); + } + + public Long getMillis() { + return this.timeUnit.toMillis(this.time); + } +} \ No newline at end of file diff --git a/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/utils/UUIDUtil.java b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/utils/UUIDUtil.java new file mode 100644 index 0000000..caccfc8 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/java/net/grandtheftmc/Bungee/utils/UUIDUtil.java @@ -0,0 +1,69 @@ +package net.grandtheftmc.Bungee.utils; + +import java.util.Optional; +import java.util.UUID; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Created by Stephen + */ +public class UUIDUtil { + + /** + * A {@link Pattern} used to identify and/or split full UUIDs + */ + private static final Pattern PATTERN_UUID = Pattern.compile("^[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}$", Pattern.CASE_INSENSITIVE); + /** + * A {@link Pattern} used to identify and/or split trimmed UUIDs + */ + private static final Pattern PATTERN_TRIMMED_UUID = Pattern.compile("^([a-z0-9]{8})([a-z0-9]{4})([a-z0-9]{4})([a-z0-9]{4})([a-z0-9]{12})$", Pattern.CASE_INSENSITIVE); + + + /** + * Create a UUID safely from a {@link String}. + * + * @param string The {@link String} to deserialize into an {@link UUID} object. + * @return {@link Optional#empty()} if the provided {@link String} is illegal, otherwise an {@link Optional} + * containing the deserialized {@link UUID} object. + */ + public static Optional createUUID(String string) { + if (string == null) { + return Optional.empty(); + } + + UUID result = null; + + try { + // Is it a valid UUID? + if (!PATTERN_UUID.matcher(string).matches()) { + // Un-trim UUID if it is trimmed + Matcher matcher = PATTERN_TRIMMED_UUID.matcher(string); + if (matcher.matches()) { + StringBuilder sb = new StringBuilder(); + + for (int i = 1; i <= matcher.groupCount(); i++) { + if (i != 1) { + sb.append("-"); + } + + sb.append(matcher.group(i)); + } + + string = sb.toString(); + } else { + // Invalid UUID + string = null; + } + } + + if (string != null) { + result = UUID.fromString(string); + } + } catch (IllegalArgumentException ignored) { + // Useless data passed + } + + return Optional.ofNullable(result); + } +} diff --git a/bungee-master@696956eaecd/src/main/resources/plugin.yml b/bungee-master@696956eaecd/src/main/resources/plugin.yml new file mode 100644 index 0000000..e25eb50 --- /dev/null +++ b/bungee-master@696956eaecd/src/main/resources/plugin.yml @@ -0,0 +1,4 @@ +name: Bungee +main: net.grandtheftmc.Bungee.Bungee +version: 1.3 +author: GTMDevs diff --git a/cartels-master@e4f5c2ecec5/.gitignore b/cartels-master@e4f5c2ecec5/.gitignore new file mode 100644 index 0000000..ad7f541 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/.gitignore @@ -0,0 +1,8 @@ + +\.idea/ + +target/classes/ + +target/ + +*.iml \ No newline at end of file diff --git a/cartels-master@e4f5c2ecec5/README.md b/cartels-master@e4f5c2ecec5/README.md new file mode 100644 index 0000000..fdaec0e --- /dev/null +++ b/cartels-master@e4f5c2ecec5/README.md @@ -0,0 +1 @@ +First commit. \ No newline at end of file diff --git a/cartels-master@e4f5c2ecec5/licenses/LGPL.txt b/cartels-master@e4f5c2ecec5/licenses/LGPL.txt new file mode 100644 index 0000000..65c5ca8 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/licenses/LGPL.txt @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/cartels-master@e4f5c2ecec5/licenses/LICENCE.txt b/cartels-master@e4f5c2ecec5/licenses/LICENCE.txt new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/licenses/LICENCE.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/cartels-master@e4f5c2ecec5/licenses/gson-license.txt b/cartels-master@e4f5c2ecec5/licenses/gson-license.txt new file mode 100644 index 0000000..634d1aa --- /dev/null +++ b/cartels-master@e4f5c2ecec5/licenses/gson-license.txt @@ -0,0 +1,13 @@ +Copyright (c) 2008-2009 Google Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/cartels-master@e4f5c2ecec5/pom.xml b/cartels-master@e4f5c2ecec5/pom.xml new file mode 100644 index 0000000..b48e75f --- /dev/null +++ b/cartels-master@e4f5c2ecec5/pom.xml @@ -0,0 +1,384 @@ + + 4.0.0 + + com.massivecraft + Cartels + 1.7.1 + jar + Cartels + + + + vault-repo + http://nexus.hc.to/content/repositories/pub_releases + + + ess-repo + http://repo.ess3.net/content/groups/essentials + + + spigot-repo + https://hub.spigotmc.org/nexus/content/groups/public/ + + + maven.sk89q.com + http://maven.sk89q.com/repo/ + + + repo.mikeprimm.com + http://repo.mikeprimm.com/ + + + playervaults + https://ci.drtshock.net/plugin/repository + + + dmulloy2-repo + http://repo.dmulloy2.net/nexus/repository/public/ + + + nexus-release + https://nexus.grandtheftmc.net/content/repositories/releases/ + + + + + + nexus-release + Internal Releases + https://nexus.grandtheftmc.net/content/repositories/releases/ + + + nexus-snapshot + Internal Snapshots + https://nexus.grandtheftmc.net/content/repositories/snapshots/ + + + + + UTF-8 + + + + + org.spigotmc + spigot-api + 1.12-R0.1-SNAPSHOT + provided + + + bungeecord-chat + net.md-5 + + + persistence-api + javax.persistence + + + junit + junit + + + guava + com.google.guava + + + gson + com.google.code.gson + + + + + net.milkbowl.vault + VaultAPI + 1.6 + provided + + + bukkit + org.bukkit + + + + + com.sk89q + worldguard + 6.1.1-SNAPSHOT + provided + + + bukkit + org.bukkit + + + bukkit-classloader-check + com.sk89q.spigot + + + commandbook + com.sk89q + + + jsr305 + com.google.code.findbugs + + + js + rhino + + + truezip + de.schlichtherle + + + jchronic + com.sk89q + + + worldedit + com.sk89q + + + + + com.sk89q.worldedit + worldedit-bukkit + 6.1.1-SNAPSHOT + provided + + + bukkit + org.bukkit + + + jsr305 + com.google.code.findbugs + + + bukkit-classloader-check + org.sk89q.bukkit + + + dummypermscompat + com.sk89q + + + jchronic + com.sk89q + + + js + rhino + + + truezip + de.schlichtherle + + + jlibnoise + com.sk89q.lib + + + paranamer + com.thoughtworks.paranamer + + + guava + com.google.guava + + + gson + com.google.code.gson + + + snakeyaml + org.yaml + + + + + com.google.guava + guava + 10.0.1 + provided + + + jsr305 + com.google.code.findbugs + + + + + net.ess3 + Essentials + 2.13-SNAPSHOT + provided + + + net.ess3 + EssentialsChat + 2.13-SNAPSHOT + provided + + + bukkit + org.bukkit + + + lombok + org.projectlombok + + + Essentials + net.ess3 + + + + + mkremins + fanciful + 0.4.0 + compile + + + gson + com.google.code.gson + + + + + org.dynmap + dynmap + 2.0 + provided + + + bukkit + org.bukkit + + + Permissions + com.nijikokun.bukkit + + + bPermissions + de.bananaco + + + EssentialsGroupManager + org.anjocaido + + + spoutpluginapi + org.getspout + + + PermissionsBukkit + com.platymuus.bukkit.permissions + + + PermissionsEx + ru.tehkode + + + + + com.google.code.gson + gson + 2.6.2 + compile + + + + net.grandtheftmc + core + 1.0.5 + provided + + + net.grandtheftmc + vice + 1.0.2 + provided + + + + + clean package install + ${project.name} + src/main/java + + + true + src/main/resources/ + + + + + maven-compiler-plugin + 3.5.1 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-shade-plugin + 2.4.3 + + false + + + + mkremins.fanciful + com.massivecraft.factions.shade.mkremins.fanciful + + + com.google.gson + com.massivecraft.factions.shade.com.google.gson + + + + + + package + + shade + + + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.8 + true + + + default-deploy + deploy + + deploy + + + + + nexus + https://nexus.grandtheftmc.net/ + true + + + + + diff --git a/cartels-master@e4f5c2ecec5/src/main/assembly/package.xml b/cartels-master@e4f5c2ecec5/src/main/assembly/package.xml new file mode 100644 index 0000000..8f3491c --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/assembly/package.xml @@ -0,0 +1,16 @@ + + bin + false + + zip + + + + ${project.build.directory}/${artifactId}.jar + / + ${artifactId}.jar + + + \ No newline at end of file diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/Board.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/Board.java new file mode 100644 index 0000000..98b25be --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/Board.java @@ -0,0 +1,86 @@ +package com.massivecraft.factions; + +import com.massivecraft.factions.zcore.persist.json.JSONBoard; + +import java.util.ArrayList; +import java.util.Set; + + +public abstract class Board { + protected static Board instance = getBoardImpl(); + + //----------------------------------------------// + // Get and Set + //----------------------------------------------// + public abstract String getIdAt(FLocation flocation); + + private static Board getBoardImpl() { + switch (Conf.backEnd) { + case JSON: + return new JSONBoard(); + } + return null; + } + + public static Board getInstance() { + return instance; + } + + public abstract Faction getFactionAt(FLocation flocation); + + public abstract void setIdAt(String id, FLocation flocation); + + public abstract void setFactionAt(Faction faction, FLocation flocation); + + public abstract void removeAt(FLocation flocation); + + public abstract Set getAllClaims(String factionId); + + public abstract Set getAllClaims(Faction faction); + + // anot to be confused with claims, ownership referring to further member-specific ownership of a claim + public abstract void clearOwnershipAt(FLocation flocation); + + public abstract void unclaimAll(String factionId); + + // Is this coord NOT completely surrounded by coords claimed by the same faction? + // Simpler: Is there any nearby coord with a faction other than the faction here? + public abstract boolean isBorderLocation(FLocation flocation); + + // Is this coord connected to any coord claimed by the specified faction? + public abstract boolean isConnectedLocation(FLocation flocation, Faction faction); + + public abstract boolean hasFactionWithin(FLocation flocation, Faction faction, int radius); + + //----------------------------------------------// + // Cleaner. Remove orphaned foreign keys + //----------------------------------------------// + + public abstract void clean(); + + //----------------------------------------------// + // Coord count + //----------------------------------------------// + + public abstract int getFactionCoordCount(String factionId); + + public abstract int getFactionCoordCount(Faction faction); + + public abstract int getFactionCoordCountInWorld(Faction faction, String worldName); + + //----------------------------------------------// + // Map generation + //----------------------------------------------// + + /** + * The map is relative to a coord and a faction north is in the direction of decreasing x east is in the direction + * of decreasing z + */ + public abstract ArrayList getMap(Faction faction, FLocation flocation, double inDegrees); + + public abstract void forceSave(); + + public abstract void forceSave(boolean sync); + + public abstract boolean load(); +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/Conf.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/Conf.java new file mode 100644 index 0000000..d166a1e --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/Conf.java @@ -0,0 +1,467 @@ +package com.massivecraft.factions; + +import com.google.common.collect.ImmutableMap; +import com.massivecraft.factions.integration.dynmap.DynmapStyle; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.EntityType; + +import java.util.*; + +public class Conf { + + public static List baseCommandAliases = new ArrayList(); + public static boolean allowNoSlashCommand = true; + + // Colors + public static ChatColor colorMember = ChatColor.GREEN; + public static ChatColor colorAlly = ChatColor.LIGHT_PURPLE; + public static ChatColor colorTruce = ChatColor.DARK_PURPLE; + public static ChatColor colorNeutral = ChatColor.WHITE; + public static ChatColor colorEnemy = ChatColor.RED; + + public static ChatColor colorPeaceful = ChatColor.GOLD; + public static ChatColor colorWar = ChatColor.DARK_RED; + + // Power + public static double powerPlayerMax = 10.0; + public static double powerPlayerMin = -10.0; + public static double powerPlayerStarting = 0.0; + public static double powerPerMinute = 0.2; // Default health rate... it takes 5 min to heal one power + public static double powerPerDeath = 4.0; // A death makes you lose 4 power + public static boolean powerRegenOffline = false; // does player power regenerate even while they're offline? + public static double powerOfflineLossPerDay = 0.0; // players will lose this much power per day offline + public static double powerOfflineLossLimit = 0.0; // players will no longer lose power from being offline once their power drops to this amount or less + public static double powerFactionMax = 0.0; // if greater than 0, the cap on how much power a faction can have (additional power from players beyond that will act as a "buffer" of sorts) + + public static String prefixAdmin = "[DrugLord] ";//** + public static String prefixMod = "[Lieutenant] ";//* + + public static int factionTagLengthMin = 3; + public static int factionTagLengthMax = 10; + public static boolean factionTagForceUpperCase = false; + + public static boolean newFactionsDefaultOpen = false; + + // when faction membership hits this limit, players will no longer be able to join using /f join; default is 0, no limit + public static int factionMemberLimit = 0; + + // what faction ID to start new players in when they first join the server; default is 0, "no faction" + public static String newPlayerStartingFactionID = "0"; + + public static boolean showMapFactionKey = true; + public static boolean showNeutralFactionsOnMap = true; + public static boolean showEnemyFactionsOnMap = true; + + // Disallow joining/leaving/kicking while power is negative + public static boolean canLeaveWithNegativePower = true; + + // Configuration for faction-only chat + public static boolean factionOnlyChat = true; + // Configuration on the Faction tag in chat messages. + public static boolean chatTagEnabled = true; + public static transient boolean chatTagHandledByAnotherPlugin = false; + public static boolean chatTagRelationColored = true; + public static String chatTagReplaceString = "[CARTEL]"; + public static String chatTagInsertAfterString = ""; + public static String chatTagInsertBeforeString = ""; + public static int chatTagInsertIndex = 0; + public static boolean chatTagPadBefore = false; + public static boolean chatTagPadAfter = true; + public static String chatTagFormat = "%s" + ChatColor.WHITE; + public static String factionChatFormat = "%s:" + ChatColor.WHITE + " %s"; + public static String allianceChatFormat = ChatColor.LIGHT_PURPLE + "%s:" + ChatColor.WHITE + " %s"; + public static String truceChatFormat = ChatColor.DARK_PURPLE + "%s:" + ChatColor.WHITE + " %s"; + + public static boolean broadcastDescriptionChanges = false; + public static boolean broadcastTagChanges = false; + + public static double saveToFileEveryXMinutes = 30.0; + + public static double autoLeaveAfterDaysOfInactivity = 10.0; + public static double autoLeaveRoutineRunsEveryXMinutes = 5.0; + public static int autoLeaveRoutineMaxMillisecondsPerTick = 5; // 1 server tick is roughly 50ms, so default max 10% of a tick + public static boolean removePlayerDataWhenBanned = true; + public static boolean autoLeaveDeleteFPlayerData = true; // Let them just remove player from Faction. + + public static boolean worldGuardChecking = false; + public static boolean worldGuardBuildPriority = false; + + // server logging options + public static boolean logFactionCreate = true; + public static boolean logFactionDisband = true; + public static boolean logFactionJoin = true; + public static boolean logFactionKick = true; + public static boolean logFactionLeave = true; + public static boolean logLandClaims = true; + public static boolean logLandUnclaims = true; + public static boolean logMoneyTransactions = true; + public static boolean logPlayerCommands = true; + + // prevent some potential exploits + public static boolean handleExploitObsidianGenerators = true; + public static boolean handleExploitEnderPearlClipping = true; + public static boolean handleExploitInteractionSpam = true; + public static boolean handleExploitTNTWaterlog = false; + public static boolean handleExploitLiquidFlow = false; + + public static boolean homesEnabled = true; + public static boolean homesMustBeInClaimedTerritory = true; + public static boolean homesTeleportToOnDeath = true; + public static boolean homesRespawnFromNoPowerLossWorlds = true; + public static boolean homesTeleportCommandEnabled = true; + public static boolean homesTeleportCommandEssentialsIntegration = true; + public static boolean homesTeleportCommandSmokeEffectEnabled = true; + public static float homesTeleportCommandSmokeEffectThickness = 3f; + public static boolean homesTeleportAllowedFromEnemyTerritory = true; + public static boolean homesTeleportAllowedFromDifferentWorld = true; + public static double homesTeleportAllowedEnemyDistance = 32.0; + public static boolean homesTeleportIgnoreEnemiesIfInOwnTerritory = true; + + public static boolean disablePVPBetweenNeutralFactions = false; + public static boolean disablePVPForFactionlessPlayers = false; + public static boolean enablePVPAgainstFactionlessInAttackersLand = false; + + public static int noPVPDamageToOthersForXSecondsAfterLogin = 3; + + public static boolean peacefulTerritoryDisablePVP = true; + public static boolean peacefulTerritoryDisableMonsters = false; + public static boolean peacefulTerritoryDisableBoom = false; + public static boolean peacefulMembersDisablePowerLoss = true; + + public static boolean permanentFactionsDisableLeaderPromotion = false; + + public static boolean claimsMustBeConnected = false; + public static boolean claimsCanBeUnconnectedIfOwnedByOtherFaction = true; + public static int claimsRequireMinFactionMembers = 1; + public static int claimedLandsMax = 0; + public static int lineClaimLimit = 5; + + // if someone is doing a radius claim and the process fails to claim land this many times in a row, it will exit + public static int radiusClaimFailureLimit = 9; + + public static double considerFactionsReallyOfflineAfterXMinutes = 0.0; + + public static int actionDeniedPainAmount = 1; + + // commands which will be prevented if the player is a member of a permanent faction + public static Set permanentFactionMemberDenyCommands = new LinkedHashSet(); + + // commands which will be prevented when in claimed territory of another faction + public static Set territoryNeutralDenyCommands = new LinkedHashSet(); + public static Set territoryEnemyDenyCommands = new LinkedHashSet(); + public static Set territoryAllyDenyCommands = new LinkedHashSet(); + public static Set warzoneDenyCommands = new LinkedHashSet(); + public static Set wildernessDenyCommands = new LinkedHashSet(); + + public static boolean territoryDenyBuild = true; + public static boolean territoryDenyBuildWhenOffline = true; + public static boolean territoryPainBuild = false; + public static boolean territoryPainBuildWhenOffline = false; + public static boolean territoryDenyUseage = true; + public static boolean territoryEnemyDenyBuild = true; + public static boolean territoryEnemyDenyBuildWhenOffline = true; + public static boolean territoryEnemyPainBuild = false; + public static boolean territoryEnemyPainBuildWhenOffline = false; + public static boolean territoryEnemyDenyUseage = true; + public static boolean territoryEnemyProtectMaterials = true; + public static boolean territoryAllyDenyBuild = true; + public static boolean territoryAllyDenyBuildWhenOffline = true; + public static boolean territoryAllyPainBuild = false; + public static boolean territoryAllyPainBuildWhenOffline = false; + public static boolean territoryAllyDenyUseage = true; + public static boolean territoryAllyProtectMaterials = true; + public static boolean territoryTruceDenyBuild = true; + public static boolean territoryTruceDenyBuildWhenOffline = true; + public static boolean territoryTrucePainBuild = false; + public static boolean territoryTrucePainBuildWhenOffline = false; + public static boolean territoryTruceDenyUseage = true; + public static boolean territoryTruceProtectMaterials = true; + public static boolean territoryBlockCreepers = false; + public static boolean territoryBlockCreepersWhenOffline = false; + public static boolean territoryBlockFireballs = false; + public static boolean territoryBlockFireballsWhenOffline = false; + public static boolean territoryBlockTNT = false; + public static boolean territoryBlockTNTWhenOffline = false; + public static boolean territoryDenyEndermanBlocks = true; + public static boolean territoryDenyEndermanBlocksWhenOffline = true; + + public static boolean safeZoneDenyBuild = true; + public static boolean safeZoneDenyUseage = true; + public static boolean safeZoneBlockTNT = true; + public static boolean safeZonePreventAllDamageToPlayers = false; + public static boolean safeZoneDenyEndermanBlocks = true; + + public static boolean warZoneDenyBuild = true; + public static boolean warZoneDenyUseage = true; + public static boolean warZoneBlockCreepers = false; + public static boolean warZoneBlockFireballs = false; + public static boolean warZoneBlockTNT = true; + public static boolean warZonePowerLoss = true; + public static boolean warZoneFriendlyFire = false; + public static boolean warZoneDenyEndermanBlocks = true; + + public static boolean wildernessDenyBuild = false; + public static boolean wildernessDenyUseage = false; + public static boolean wildernessBlockCreepers = false; + public static boolean wildernessBlockFireballs = false; + public static boolean wildernessBlockTNT = false; + public static boolean wildernessPowerLoss = true; + public static boolean wildernessDenyEndermanBlocks = false; + + // for claimed areas where further faction-member ownership can be defined + public static boolean ownedAreasEnabled = true; + public static int ownedAreasLimitPerFaction = 0; + public static boolean ownedAreasModeratorsCanSet = false; + public static boolean ownedAreaModeratorsBypass = true; + public static boolean ownedAreaDenyBuild = true; + public static boolean ownedAreaPainBuild = false; + public static boolean ownedAreaProtectMaterials = true; + public static boolean ownedAreaDenyUseage = true; + + public static boolean ownedMessageOnBorder = true; + public static boolean ownedMessageInsideTerritory = true; + public static boolean ownedMessageByChunk = false; + + public static boolean pistonProtectionThroughDenyBuild = true; + + public static Set territoryProtectedMaterials = EnumSet.noneOf(Material.class); + public static Set territoryDenyUseageMaterials = EnumSet.noneOf(Material.class); + public static Set territoryProtectedMaterialsWhenOffline = EnumSet.noneOf(Material.class); + public static Set territoryDenyUseageMaterialsWhenOffline = EnumSet.noneOf(Material.class); + + public static transient Set safeZoneNerfedCreatureTypes = EnumSet.noneOf(EntityType.class); + // Economy settings + public static boolean econEnabled = true; + public static String econUniverseAccount = ""; + public static double econCostClaimWilderness = 50000.0;//30.0 + public static double econCostClaimFromFactionBonus = 0.0;//30.0 + public static double econOverclaimRewardMultiplier = 0.0; + public static double econClaimAdditionalMultiplier = 0.05;//0.5 + public static double econClaimRefundMultiplier = 0.0;//0.7 + public static double econClaimUnconnectedFee = 0.0; + public static double econCostCreate = 1000000.0;//100.0 + public static double econCostOwner = 0.0;//15.0 + public static double econCostSethome = 100000.0;//30.0 + public static double econCostJoin = 0.0; + public static double econCostLeave = 0.0; + public static double econCostKick = 0.0; + public static double econCostInvite = 50000.0; + public static double econCostHome = 0.0; + public static double econCostTag = 100000.0; + public static double econCostDesc = 0.0; + public static double econCostTitle = 0.0; + public static double econCostList = 0.0; + public static double econCostMap = 0.0; + public static double econCostPower = 0.0; + public static double econCostShow = 0.0; + public static double econCostStuck = 0.0; + public static double econCostOpen = 0.0; + public static double econCostAlly = 0.0; + public static double econCostTruce = 0.0; + public static double econCostEnemy = 0.0; + public static double econCostNeutral = 0.0; + public static double econCostNoBoom = 0.0; + + + // -------------------------------------------- // + // INTEGRATION: DYNMAP + // -------------------------------------------- // + + // Should the dynmap intagration be used? + public static boolean dynmapUse = false; + + // Name of the Factions layer + public static String dynmapLayerName = "Factions"; + + // Should the layer be visible per default + public static boolean dynmapLayerVisible = true; + + // Ordering priority in layer menu (low goes before high - default is 0) + public static int dynmapLayerPriority = 2; + + // (optional) set minimum zoom level before layer is visible (0 = default, always visible) + public static int dynmapLayerMinimumZoom = 0; + + // Format for popup - substitute values for macros + public static String dynmapDescription = + "

\n" + + "%name%
\n" + + "%description%
" + + "
\n" + + "Leader: %players.leader%
\n" + + "Admins: %players.admins.count%
\n" + + "Moderators: %players.moderators.count%
\n" + + "Members: %players.normals.count%
\n" + + "TOTAL: %players.count%
\n" + + "
\n" + + "Bank: %money%
\n" + + "
\n" + + "
"; + + // Enable the %money% macro. Only do this if you know your economy manager is thread-safe. + public static boolean dynmapDescriptionMoney = false; + + // Allow players in faction to see one another on Dynmap (only relevant if Dynmap has 'player-info-protected' enabled) + public static boolean dynmapVisibilityByFaction = true; + + // Optional setting to limit which regions to show. + // If empty all regions are shown. + // Specify Faction either by name or UUID. + // To show all regions on a given world, add 'world:' to the list. + public static Set dynmapVisibleFactions = new HashSet(); + + // Optional setting to hide specific Factions. + // Specify Faction either by name or UUID. + // To hide all regions on a given world, add 'world:' to the list. + public static Set dynmapHiddenFactions = new HashSet(); + + // Region Style + public static final transient String DYNMAP_STYLE_LINE_COLOR = "#00FF00"; + public static final transient double DYNMAP_STYLE_LINE_OPACITY = 0.8D; + public static final transient int DYNMAP_STYLE_LINE_WEIGHT = 3; + public static final transient String DYNMAP_STYLE_FILL_COLOR = "#00FF00"; + public static final transient double DYNMAP_STYLE_FILL_OPACITY = 0.35D; + public static final transient String DYNMAP_STYLE_HOME_MARKER = "greenflag"; + public static final transient boolean DYNMAP_STYLE_BOOST = false; + + public static DynmapStyle dynmapDefaultStyle = new DynmapStyle() + .setStrokeColor(DYNMAP_STYLE_LINE_COLOR) + .setLineOpacity(DYNMAP_STYLE_LINE_OPACITY) + .setLineWeight(DYNMAP_STYLE_LINE_WEIGHT) + .setFillColor(DYNMAP_STYLE_FILL_COLOR) + .setFillOpacity(DYNMAP_STYLE_FILL_OPACITY) + .setHomeMarker(DYNMAP_STYLE_HOME_MARKER) + .setBoost(DYNMAP_STYLE_BOOST); + + // Optional per Faction style overrides. Any defined replace those in dynmapDefaultStyle. + // Specify Faction either by name or UUID. + public static Map dynmapFactionStyles = ImmutableMap.of( + "SafeZone", new DynmapStyle().setStrokeColor("#FF00FF").setFillColor("#FF00FF").setBoost(false), + "WarZone", new DynmapStyle().setStrokeColor("#FF0000").setFillColor("#FF0000").setBoost(false) + ); + + + //Faction banks, to pay for land claiming and other costs instead of individuals paying for them + public static boolean bankEnabled = true; + public static boolean bankMembersCanWithdraw = false; //Have to be at least moderator to withdraw or pay money to another faction + public static boolean bankFactionPaysCosts = true; //The faction pays for faction command costs, such as sethome + public static boolean bankFactionPaysLandCosts = true; //The faction pays for land claiming costs. + + // mainly for other plugins/mods that use a fake player to take actions, which shouldn't be subject to our protections + public static Set playersWhoBypassAllProtection = new LinkedHashSet(); + + public static Set worldsNoClaiming = new LinkedHashSet(); + public static Set worldsNoPowerLoss = new LinkedHashSet(); + public static Set worldsIgnorePvP = new LinkedHashSet(); + public static Set worldsNoWildernessProtection = new LinkedHashSet(); + + // faction- + public static String vaultPrefix = "faction-%s"; + public static int defaultMaxVaults = 0; + + public static Backend backEnd = Backend.JSON; + + public static transient int mapHeight = 8; + public static transient int mapWidth = 19; + public static transient char[] mapKeyChrs = "\\/#$%=&^ABCDEFGHJKLMNOPQRSTUVWXYZ1234567890abcdeghjmnopqrsuvwxyz?".toCharArray(); + + static { + baseCommandAliases.add("f"); + + territoryEnemyDenyCommands.add("home"); + territoryEnemyDenyCommands.add("sethome"); + territoryEnemyDenyCommands.add("spawn"); + territoryEnemyDenyCommands.add("tpahere"); + territoryEnemyDenyCommands.add("tpaccept"); + territoryEnemyDenyCommands.add("tpa"); + + territoryProtectedMaterials.add(Material.WOODEN_DOOR); + territoryProtectedMaterials.add(Material.TRAP_DOOR); + territoryProtectedMaterials.add(Material.FENCE_GATE); + territoryProtectedMaterials.add(Material.DISPENSER); + territoryProtectedMaterials.add(Material.CHEST); + territoryProtectedMaterials.add(Material.FURNACE); + territoryProtectedMaterials.add(Material.BURNING_FURNACE); + territoryProtectedMaterials.add(Material.DIODE_BLOCK_OFF); + territoryProtectedMaterials.add(Material.DIODE_BLOCK_ON); + territoryProtectedMaterials.add(Material.JUKEBOX); + territoryProtectedMaterials.add(Material.BREWING_STAND); + territoryProtectedMaterials.add(Material.ENCHANTMENT_TABLE); + territoryProtectedMaterials.add(Material.CAULDRON); + territoryProtectedMaterials.add(Material.SOIL); + territoryProtectedMaterials.add(Material.BEACON); + territoryProtectedMaterials.add(Material.ANVIL); + territoryProtectedMaterials.add(Material.TRAPPED_CHEST); + territoryProtectedMaterials.add(Material.DROPPER); + territoryProtectedMaterials.add(Material.HOPPER); + + territoryDenyUseageMaterials.add(Material.FIREBALL); + territoryDenyUseageMaterials.add(Material.FLINT_AND_STEEL); + territoryDenyUseageMaterials.add(Material.BUCKET); + territoryDenyUseageMaterials.add(Material.WATER_BUCKET); + territoryDenyUseageMaterials.add(Material.LAVA_BUCKET); + + territoryProtectedMaterialsWhenOffline.add(Material.WOODEN_DOOR); + territoryProtectedMaterialsWhenOffline.add(Material.TRAP_DOOR); + territoryProtectedMaterialsWhenOffline.add(Material.FENCE_GATE); + territoryProtectedMaterialsWhenOffline.add(Material.DISPENSER); + territoryProtectedMaterialsWhenOffline.add(Material.CHEST); + territoryProtectedMaterialsWhenOffline.add(Material.FURNACE); + territoryProtectedMaterialsWhenOffline.add(Material.BURNING_FURNACE); + territoryProtectedMaterialsWhenOffline.add(Material.DIODE_BLOCK_OFF); + territoryProtectedMaterialsWhenOffline.add(Material.DIODE_BLOCK_ON); + territoryProtectedMaterialsWhenOffline.add(Material.JUKEBOX); + territoryProtectedMaterialsWhenOffline.add(Material.BREWING_STAND); + territoryProtectedMaterialsWhenOffline.add(Material.ENCHANTMENT_TABLE); + territoryProtectedMaterialsWhenOffline.add(Material.CAULDRON); + territoryProtectedMaterialsWhenOffline.add(Material.SOIL); + territoryProtectedMaterialsWhenOffline.add(Material.BEACON); + territoryProtectedMaterialsWhenOffline.add(Material.ANVIL); + territoryProtectedMaterialsWhenOffline.add(Material.TRAPPED_CHEST); + territoryProtectedMaterialsWhenOffline.add(Material.DROPPER); + territoryProtectedMaterialsWhenOffline.add(Material.HOPPER); + + territoryDenyUseageMaterialsWhenOffline.add(Material.FIREBALL); + territoryDenyUseageMaterialsWhenOffline.add(Material.FLINT_AND_STEEL); + territoryDenyUseageMaterialsWhenOffline.add(Material.BUCKET); + territoryDenyUseageMaterialsWhenOffline.add(Material.WATER_BUCKET); + territoryDenyUseageMaterialsWhenOffline.add(Material.LAVA_BUCKET); + + safeZoneNerfedCreatureTypes.add(EntityType.BLAZE); + safeZoneNerfedCreatureTypes.add(EntityType.CAVE_SPIDER); + safeZoneNerfedCreatureTypes.add(EntityType.CREEPER); + safeZoneNerfedCreatureTypes.add(EntityType.ENDER_DRAGON); + safeZoneNerfedCreatureTypes.add(EntityType.ENDERMAN); + safeZoneNerfedCreatureTypes.add(EntityType.GHAST); + safeZoneNerfedCreatureTypes.add(EntityType.MAGMA_CUBE); + safeZoneNerfedCreatureTypes.add(EntityType.PIG_ZOMBIE); + safeZoneNerfedCreatureTypes.add(EntityType.SILVERFISH); + safeZoneNerfedCreatureTypes.add(EntityType.SKELETON); + safeZoneNerfedCreatureTypes.add(EntityType.SPIDER); + safeZoneNerfedCreatureTypes.add(EntityType.SLIME); + safeZoneNerfedCreatureTypes.add(EntityType.WITCH); + safeZoneNerfedCreatureTypes.add(EntityType.WITHER); + safeZoneNerfedCreatureTypes.add(EntityType.ZOMBIE); + } + + // -------------------------------------------- // + // Persistance + // -------------------------------------------- // + private static transient Conf i = new Conf(); + + public static void load() { + P.p.persist.loadOrSaveDefault(i, Conf.class, "conf"); + } + + public static void save() { + P.p.persist.save(i); + } + + public enum Backend { + JSON, + //MYSQL, TODO + ; + } +} + diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/FLocation.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/FLocation.java new file mode 100644 index 0000000..790ddac --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/FLocation.java @@ -0,0 +1,251 @@ +package com.massivecraft.factions; + +import com.massivecraft.factions.util.MiscUtil; +import org.bukkit.*; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; + +import java.io.Serializable; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Set; + +public class FLocation implements Serializable { + private static final long serialVersionUID = -8292915234027387983L; + private static final boolean worldBorderSupport; + private String worldName = "world"; + private int x = 0; + private int z = 0; + + static { + boolean worldBorderClassPresent = false; + try { + Class.forName("org.bukkit.WorldBorder"); + worldBorderClassPresent = true; + } catch (ClassNotFoundException ignored) {} + + worldBorderSupport = worldBorderClassPresent; + } + + //----------------------------------------------// + // Constructors + //----------------------------------------------// + + public FLocation() { + + } + + public FLocation(String worldName, int x, int z) { + this.worldName = worldName; + this.x = x; + this.z = z; + } + + public FLocation(Location location) { + this(location.getWorld().getName(), blockToChunk(location.getBlockX()), blockToChunk(location.getBlockZ())); + } + + public FLocation(Player player) { + this(player.getLocation()); + } + + public FLocation(FPlayer fplayer) { + this(fplayer.getPlayer()); + } + + public FLocation(Block block) { + this(block.getLocation()); + } + + //----------------------------------------------// + // Getters and Setters + //----------------------------------------------// + + public String getWorldName() { + return worldName; + } + + public World getWorld() { + return Bukkit.getWorld(worldName); + } + + public void setWorldName(String worldName) { + this.worldName = worldName; + } + + public long getX() { + return x; + } + + public void setX(int x) { + this.x = x; + } + + public long getZ() { + return z; + } + + public void setZ(int z) { + this.z = z; + } + + public String getCoordString() { + return "" + x + "," + z; + } + + @Override + public String toString() { + return "[" + this.getWorldName() + "," + this.getCoordString() + "]"; + } + + public static FLocation fromString(String string) { + int index = string.indexOf(",", 0); + int start = 1; + String worldName = string.substring(start, index); + start = index + 1; + index = string.indexOf(",", start); + int x = Integer.valueOf(string.substring(start, index)); + int y = Integer.valueOf(string.substring(index + 1, string.length() - 1)); + return new FLocation(worldName, x, y); + } + + //----------------------------------------------// + // Block/Chunk/Region Value Transformation + //----------------------------------------------// + + // bit-shifting is used because it's much faster than standard division and multiplication + public static int blockToChunk(int blockVal) { // 1 chunk is 16x16 blocks + return blockVal >> 4; // ">> 4" == "/ 16" + } + + public static int blockToRegion(int blockVal) { // 1 region is 512x512 blocks + return blockVal >> 9; // ">> 9" == "/ 512" + } + + public static int chunkToRegion(int chunkVal) { // 1 region is 32x32 chunks + return chunkVal >> 5; // ">> 5" == "/ 32" + } + + public static int chunkToBlock(int chunkVal) { + return chunkVal << 4; // "<< 4" == "* 16" + } + + public static int regionToBlock(int regionVal) { + return regionVal << 9; // "<< 9" == "* 512" + } + + public static int regionToChunk(int regionVal) { + return regionVal << 5; // "<< 5" == "* 32" + } + + //----------------------------------------------// + // Misc Geometry + //----------------------------------------------// + + public FLocation getRelative(int dx, int dz) { + return new FLocation(this.worldName, this.x + dx, this.z + dz); + } + + public double getDistanceTo(FLocation that) { + double dx = that.x - this.x; + double dz = that.z - this.z; + return Math.sqrt(dx * dx + dz * dz); + } + + public double getDistanceSquaredTo(FLocation that) { + double dx = that.x - this.x; + double dz = that.z - this.z; + return dx * dx + dz * dz; + } + + public boolean isInChunk(Location loc) { + if (loc == null) { + return false; + } + Chunk chunk = loc.getChunk(); + return loc.getWorld().getName().equalsIgnoreCase(getWorldName()) && chunk.getX() == x && chunk.getZ() == z; + } + + /** + * Checks if the chunk represented by this FLocation is outside the world border + * + * @param buffer the number of chunks from the border that will be treated as "outside" + * @return whether this location is outside of the border + */ + public boolean isOutsideWorldBorder(int buffer) { + if (!worldBorderSupport) { + return false; + } + + WorldBorder border = getWorld().getWorldBorder(); + Chunk chunk = border.getCenter().getChunk(); + + int lim = FLocation.chunkToRegion((int) border.getSize()) - buffer; + int diffX = Math.abs(chunk.getX() - x); + int diffZ = Math.abs(chunk.getZ() - z); + return diffX > lim || diffZ > lim; + } + + //----------------------------------------------// + // Some Geometry + //----------------------------------------------// + public Set getCircle(double radius) { + double radiusSquared = radius * radius; + + Set ret = new LinkedHashSet(); + if (radius <= 0) { + return ret; + } + + int xfrom = (int) Math.floor(this.x - radius); + int xto = (int) Math.ceil(this.x + radius); + int zfrom = (int) Math.floor(this.z - radius); + int zto = (int) Math.ceil(this.z + radius); + + for (int x = xfrom; x <= xto; x++) { + for (int z = zfrom; z <= zto; z++) { + FLocation potential = new FLocation(this.worldName, x, z); + if (this.getDistanceSquaredTo(potential) <= radiusSquared) { + ret.add(potential); + } + } + } + + return ret; + } + + public static HashSet getArea(FLocation from, FLocation to) { + HashSet ret = new HashSet(); + + for (long x : MiscUtil.range(from.getX(), to.getX())) { + for (long z : MiscUtil.range(from.getZ(), to.getZ())) { + ret.add(new FLocation(from.getWorldName(), (int) x, (int) z)); + } + } + + return ret; + } + + //----------------------------------------------// + // Comparison + //----------------------------------------------// + + @Override + public int hashCode() { + // should be fast, with good range and few hash collisions: (x * 512) + z + worldName.hashCode + return (this.x << 9) + this.z + (this.worldName != null ? this.worldName.hashCode() : 0); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof FLocation)) { + return false; + } + + FLocation that = (FLocation) obj; + return this.x == that.x && this.z == that.z && (this.worldName == null ? that.worldName == null : this.worldName.equals(that.worldName)); + } +} \ No newline at end of file diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/FPlayer.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/FPlayer.java new file mode 100644 index 0000000..3c54b6a --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/FPlayer.java @@ -0,0 +1,264 @@ +package com.massivecraft.factions; + +import com.massivecraft.factions.iface.EconomyParticipator; +import com.massivecraft.factions.iface.RelationParticipator; +import com.massivecraft.factions.struct.ChatMode; +import com.massivecraft.factions.struct.Relation; +import com.massivecraft.factions.struct.Role; +import com.massivecraft.factions.util.WarmUpUtil; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.entity.Player; + +import java.util.List; + + +/** + * Logged in players always have exactly one FPlayer instance. Logged out players may or may not have an FPlayer + * instance. They will always have one if they are part of a faction. This is because only players with a faction are + * saved to disk (in order to not waste disk space). + *

+ * The FPlayer is linked to a minecraft player using the player name. + *

+ * The same instance is always returned for the same player. This means you can use the == operator. No .equals method + * necessary. + */ + +public interface FPlayer extends EconomyParticipator { + public void login(); + + public void logout(); + + public Faction getFaction(); + + public String getFactionId(); + + public boolean hasFaction(); + + public void setFaction(Faction faction); + + public boolean willAutoLeave(); + + public void setAutoLeave(boolean autoLeave); + + public long getLastFrostwalkerMessage(); + + public void setLastFrostwalkerMessage(); + + public void setMonitorJoins(boolean monitor); + + public boolean isMonitoringJoins(); + + public Role getRole(); + + public void setRole(Role role); + + public double getPowerBoost(); + + public void setPowerBoost(double powerBoost); + + public Faction getAutoClaimFor(); + + public void setAutoClaimFor(Faction faction); + + public boolean isAutoSafeClaimEnabled(); + + public void setIsAutoSafeClaimEnabled(boolean enabled); + + public boolean isAutoWarClaimEnabled(); + + public void setIsAutoWarClaimEnabled(boolean enabled); + + public boolean isAdminBypassing(); + + public boolean isVanished(); + + public void setIsAdminBypassing(boolean val); + + public void setChatMode(ChatMode chatMode); + + public ChatMode getChatMode(); + + public void setIgnoreAllianceChat(boolean ignore); + + public boolean isIgnoreAllianceChat(); + + public void setSpyingChat(boolean chatSpying); + + public boolean isSpyingChat(); + + public boolean showScoreboard(); + + public void setShowScoreboard(boolean show); + + // FIELD: account + public String getAccountId(); + + public void resetFactionData(boolean doSpoutUpdate); + + public void resetFactionData(); + + public long getLastLoginTime(); + + public void setLastLoginTime(long lastLoginTime); + + public boolean isMapAutoUpdating(); + + public void setMapAutoUpdating(boolean mapAutoUpdating); + + public boolean hasLoginPvpDisabled(); + + public FLocation getLastStoodAt(); + + public void setLastStoodAt(FLocation flocation); + + public String getTitle(); + + public void setTitle(String title); + + public String getName(); + + public String getTag(); + + // Base concatenations: + + public String getNameAndSomething(String something); + + public String getNameAndTitle(); + + public String getNameAndTag(); + + // Colored concatenations: + // These are used in information messages + + public String getNameAndTitle(Faction faction); + + public String getNameAndTitle(FPlayer fplayer); + + // Chat CoreTag: + // These are injected into the format of global chat messages. + + public String getChatTag(); + + // Colored Chat CoreTag + public String getChatTag(Faction faction); + + public String getChatTag(FPlayer fplayer); + + public int getKills(); + + public int getDeaths(); + + + // ------------------------------- + // Relation and relation colors + // ------------------------------- + + @Override + public String describeTo(RelationParticipator that, boolean ucfirst); + + @Override + public String describeTo(RelationParticipator that); + + @Override + public Relation getRelationTo(RelationParticipator rp); + + @Override + public Relation getRelationTo(RelationParticipator rp, boolean ignorePeaceful); + + public Relation getRelationToLocation(); + + @Override + public ChatColor getColorTo(RelationParticipator rp); + + //----------------------------------------------// + // Health + //----------------------------------------------// + public void heal(int amnt); + + + //----------------------------------------------// + // Power + //----------------------------------------------// + public double getPower(); + + public void alterPower(double delta); + + public double getPowerMax(); + + public double getPowerMin(); + + public int getPowerRounded(); + + public int getPowerMaxRounded(); + + public int getPowerMinRounded(); + + public void updatePower(); + + public void losePowerFromBeingOffline(); + + public void onDeath(); + + //----------------------------------------------// + // Territory + //----------------------------------------------// + public boolean isInOwnTerritory(); + + public boolean isInOthersTerritory(); + + public boolean isInAllyTerritory(); + + public boolean isInNeutralTerritory(); + + public boolean isInEnemyTerritory(); + + public void sendFactionHereMessage(Faction from); + + // ------------------------------- + // Actions + // ------------------------------- + + public void leave(boolean makePay); + + public boolean canClaimForFaction(Faction forFaction); + + public boolean canClaimForFactionAtLocation(Faction forFaction, Location location, boolean notifyFailure); + + public boolean attemptClaim(Faction forFaction, Location location, boolean notifyFailure); + + public void msg(String str, Object... args); + + public String getId(); + + public Player getPlayer(); + + public boolean isOnline(); + + public void sendMessage(String message); + + public void sendMessage(List messages); + + public boolean isOnlineAndVisibleTo(Player me); + + public void remove(); + + public boolean isOffline(); + + public void setId(String id); + + // ------------------------------- + // Warmups + // ------------------------------- + + public boolean isWarmingUp(); + + public WarmUpUtil.Warmup getWarmupType(); + + public void addWarmup(WarmUpUtil.Warmup warmup, int taskId); + + public void stopWarmup(); + + public void clearWarmup(); + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/FPlayers.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/FPlayers.java new file mode 100644 index 0000000..fb56eff --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/FPlayers.java @@ -0,0 +1,41 @@ +package com.massivecraft.factions; + +import com.massivecraft.factions.zcore.persist.json.JSONFPlayers; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; + +import java.util.Collection; + +public abstract class FPlayers { + protected static FPlayers instance = getFPlayersImpl(); + + public abstract void clean(); + + public static FPlayers getInstance() { + return instance; + } + + private static FPlayers getFPlayersImpl() { + switch (Conf.backEnd) { + case JSON: + return new JSONFPlayers(); + } + return null; + } + + public abstract Collection getOnlinePlayers(); + + public abstract FPlayer getByPlayer(Player player); + + public abstract Collection getAllFPlayers(); + + public abstract void forceSave(); + + public abstract void forceSave(boolean sync); + + public abstract FPlayer getByOfflinePlayer(OfflinePlayer player); + + public abstract FPlayer getById(String string); + + public abstract void load(); +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/Faction.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/Faction.java new file mode 100644 index 0000000..7b4b056 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/Faction.java @@ -0,0 +1,265 @@ +package com.massivecraft.factions; + +import com.massivecraft.factions.eco.EcoResult; +import com.massivecraft.factions.iface.EconomyParticipator; +import com.massivecraft.factions.iface.RelationParticipator; +import com.massivecraft.factions.struct.Relation; +import com.massivecraft.factions.struct.Role; +import com.massivecraft.factions.util.LazyLocation; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.entity.Player; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +public interface Faction extends EconomyParticipator { + public HashMap> getAnnouncements(); + + public ConcurrentHashMap getWarps(); + + public LazyLocation getWarp(String name); + + public void setWarp(String name, LazyLocation loc); + + public boolean isWarp(String name); + + public boolean removeWarp(String name); + + public void clearWarps(); + + public int getMaxVaults(); + + public void setMaxVaults(int value); + + public void addAnnouncement(FPlayer fPlayer, String msg); + + public void sendUnreadAnnouncements(FPlayer fPlayer); + + public void removeAnnouncements(FPlayer fPlayer); + + public Set getInvites(); + + public String getId(); + + public void invite(FPlayer fplayer); + + public void deinvite(FPlayer fplayer); + + public boolean isInvited(FPlayer fplayer); + + public boolean getOpen(); + + public void setOpen(boolean isOpen); + + public boolean isPeaceful(); + + public void setPeaceful(boolean isPeaceful); + + public void setPeacefulExplosionsEnabled(boolean val); + + public boolean getPeacefulExplosionsEnabled(); + + public boolean noExplosionsInTerritory(); + + public boolean isPermanent(); + + public void setPermanent(boolean isPermanent); + + public String getTag(); + + public String getTag(String prefix); + + public String getTag(Faction otherFaction); + + public String getTag(FPlayer otherFplayer); + + public void setTag(String str); + + public String getComparisonTag(); + + public String getDescription(); + + public void setDescription(String value); + + public void setHome(Location home); + + public boolean hasHome(); + + public Location getHome(); + + public long getFoundedDate(); + + public void setFoundedDate(long newDate); + + public void confirmValidHome(); + + public String getAccountId(); + + public Integer getPermanentPower(); + + public void setPermanentPower(Integer permanentPower); + + public boolean hasPermanentPower(); + + public double getPowerBoost(); + + public void setPowerBoost(double powerBoost); + + public boolean noPvPInTerritory(); + + public boolean noMonstersInTerritory(); + + public boolean isNormal(); + + @Deprecated + public boolean isNone(); + + public boolean isWilderness(); + + public boolean isSafeZone(); + + public boolean isWarZone(); + + public boolean isPlayerFreeType(); + + public boolean isPowerFrozen(); + + public void setLastDeath(long time); + + public int getKills(); + + public int getDeaths(); + + // ------------------------------- + // Relation and relation colors + // ------------------------------- + + @Override + public String describeTo(RelationParticipator that, boolean ucfirst); + + @Override + public String describeTo(RelationParticipator that); + + @Override + public Relation getRelationTo(RelationParticipator rp); + + @Override + public Relation getRelationTo(RelationParticipator rp, boolean ignorePeaceful); + + @Override + public ChatColor getColorTo(RelationParticipator rp); + + public Relation getRelationWish(Faction otherFaction); + + public void setRelationWish(Faction otherFaction, Relation relation); + + public int getRelationCount(Relation relation); + + // ----------------------------------------------// + // Power + // ----------------------------------------------// + public double getPower(); + + public double getPowerMax(); + + public int getPowerRounded(); + + public int getPowerMaxRounded(); + + public int getLandRounded(); + + public int getLandRoundedInWorld(String worldName); + + public boolean hasLandInflation(); + + // ------------------------------- + // FPlayers + // ------------------------------- + + // maintain the reference list of FPlayers in this faction + public void refreshFPlayers(); + + public boolean addFPlayer(FPlayer fplayer); + + public boolean removeFPlayer(FPlayer fplayer); + + public int getSize(); + + public Set getFPlayers(); + + public Set getFPlayersWhereOnline(boolean online); + + public FPlayer getFPlayerAdmin(); + + public ArrayList getFPlayersWhereRole(Role role); + + public ArrayList getOnlinePlayers(); + + // slightly faster check than getOnlinePlayers() if you just want to see if + // there are any players online + public boolean hasPlayersOnline(); + + public void memberLoggedOff(); + + // used when current leader is about to be removed from the faction; + // promotes new leader, or disbands faction if no other members left + public void promoteNewLeader(); + + // ----------------------------------------------// + // Messages + // ----------------------------------------------// + public void msg(String message, Object... args); + + public void sendMessage(String message); + + public void sendMessage(List messages); + + // ----------------------------------------------// + // Ownership of specific claims + // ----------------------------------------------// + + public Map> getClaimOwnership(); + + public void clearAllClaimOwnership(); + + public void clearClaimOwnership(FLocation loc); + + public void clearClaimOwnership(FPlayer player); + + public int getCountOfClaimsWithOwners(); + + public boolean doesLocationHaveOwnersSet(FLocation loc); + + public boolean isPlayerInOwnerList(FPlayer player, FLocation loc); + + public void setPlayerAsOwner(FPlayer player, FLocation loc); + + public void removePlayerAsOwner(FPlayer player, FLocation loc); + + public Set getOwnerList(FLocation loc); + + public String getOwnerListString(FLocation loc); + + public boolean playerHasOwnershipRights(FPlayer fplayer, FLocation loc); + + // ----------------------------------------------// + // Persistance and entity management + // ----------------------------------------------// + public void remove(); + + public Set getAllClaims(); + + public void setId(String id); + + // ----------------------------------------------// + // Economy Faction stash + // ----------------------------------------------// + public double getStash(); + + public EcoResult addToStash(double amount); + + public EcoResult takeFromStash(double amount); + + public void setStash(double amount); +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/Factions.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/Factions.java new file mode 100644 index 0000000..5459b6d --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/Factions.java @@ -0,0 +1,55 @@ +package com.massivecraft.factions; + +import com.massivecraft.factions.zcore.persist.json.JSONFactions; + +import java.util.ArrayList; +import java.util.Set; + +public abstract class Factions { + protected static Factions instance = getFactionsImpl(); + + public abstract Faction getFactionById(String id); + + public abstract Faction getByTag(String str); + + public abstract Faction getBestTagMatch(String start); + + public abstract boolean isTagTaken(String str); + + public abstract boolean isValidFactionId(String id); + + public abstract Faction createFaction(); + + public abstract void removeFaction(String id); + + public abstract Set getFactionTags(); + + public abstract ArrayList getAllFactions(); + + @Deprecated + public abstract Faction getNone(); + + public abstract Faction getWilderness(); + + public abstract Faction getSafeZone(); + + public abstract Faction getWarZone(); + + public abstract void forceSave(); + + public abstract void forceSave(boolean sync); + + public static Factions getInstance() { + return instance; + } + + private static Factions getFactionsImpl() { + switch (Conf.backEnd) { + case JSON: + return new JSONFactions(); + } + return null; + } + + public abstract void load(); +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/P.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/P.java new file mode 100644 index 0000000..864d78e --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/P.java @@ -0,0 +1,334 @@ +package com.massivecraft.factions; + +import com.google.gson.GsonBuilder; +import com.google.gson.reflect.TypeToken; +import com.massivecraft.factions.cmd.CmdAutoHelp; +import com.massivecraft.factions.cmd.FCmdRoot; +import com.massivecraft.factions.integration.Econ; +import com.massivecraft.factions.integration.Essentials; +import com.massivecraft.factions.integration.Worldguard; +import com.massivecraft.factions.integration.dynmap.EngineDynmap; +import com.massivecraft.factions.listeners.*; +import com.massivecraft.factions.struct.ChatMode; +import com.massivecraft.factions.util.*; +import com.massivecraft.factions.zcore.MPlugin; +import com.massivecraft.factions.zcore.util.TextUtil; +import net.grandtheftmc.core.menus.MenuManager; +import net.milkbowl.vault.permission.Permission; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.plugin.RegisteredServiceProvider; + +import java.lang.reflect.Modifier; +import java.lang.reflect.Type; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; + + +public class P extends MPlugin { + + // Our single plugin instance. + // Single 4 life. + public static P p; + public static Permission perms = null; + + // Persistence related + private boolean locked = false; + + public boolean getLocked() { + return this.locked; + } + + public void setLocked(boolean val) { + this.locked = val; + this.setAutoSave(val); + } + + private Integer AutoLeaveTask = null; + + // Commands + public FCmdRoot cmdBase; + public CmdAutoHelp cmdAutoHelp; + + private boolean hookedPlayervaults; + + public P() { + p = this; + } + + @Override + public void onEnable() { + if (!preEnable()) { + return; + } + this.loadSuccessful = false; + saveDefaultConfig(); + + // Load Conf from disk + Conf.load(); + Essentials.setup(); + FPlayers.getInstance().load(); + Factions.getInstance().load(); + for (FPlayer fPlayer : FPlayers.getInstance().getAllFPlayers()) { + Faction faction = Factions.getInstance().getFactionById(fPlayer.getFactionId()); + if (faction == null) { + log("Invalid cartel id on " + fPlayer.getName() + ":" + fPlayer.getFactionId()); + fPlayer.resetFactionData(false); + continue; + } + faction.addFPlayer(fPlayer); + } + Board.getInstance().load(); + Board.getInstance().clean(); + + // Add Base Commands + this.cmdBase = new FCmdRoot(); + this.cmdAutoHelp = new CmdAutoHelp(); + this.getBaseCommands().add(cmdBase); + + Econ.setup(); + setupPermissions(); + + if (Conf.worldGuardChecking || Conf.worldGuardBuildPriority) { + Worldguard.init(this); + } + + EngineDynmap.getInstance().init(); + + // start up task which runs the autoLeaveAfterDaysOfInactivity routine + startAutoLeaveTask(false); + + // Register Event Handlers + getServer().getPluginManager().registerEvents(new FactionsPlayerListener(this), this); + getServer().getPluginManager().registerEvents(new FactionsChatListener(this), this); + getServer().getPluginManager().registerEvents(new FactionsEntityListener(this), this); + getServer().getPluginManager().registerEvents(new FactionsExploitListener(), this); + getServer().getPluginManager().registerEvents(new FactionsBlockListener(this), this); + getServer().getPluginManager().registerEvents(new MenuListener(), this); + + // since some other plugins execute commands directly through this command interface, provide it + this.getCommand(this.refCommand).setExecutor(this); + + MenuManager.addMenu("carteltop", 54, "&cTop Cartels"); + + postEnable(); + this.loadSuccessful = true; + } + + private boolean setupPermissions() { + try { + RegisteredServiceProvider rsp = getServer().getServicesManager().getRegistration(Permission.class); + if (rsp != null) { + perms = rsp.getProvider(); + } + } catch (NoClassDefFoundError ex) { + return false; + } + return perms != null; + } + + @Override + public GsonBuilder getGsonBuilder() { + Type mapFLocToStringSetType = new TypeToken>>() { + }.getType(); + + return new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().excludeFieldsWithModifiers(Modifier.TRANSIENT, Modifier.VOLATILE).registerTypeAdapter(LazyLocation.class, new MyLocationTypeAdapter()).registerTypeAdapter(mapFLocToStringSetType, new MapFLocToStringSetTypeAdapter()).registerTypeAdapterFactory(EnumTypeAdapter.ENUM_FACTORY); + } + + @Override + public void onDisable() { + // only save data if plugin actually completely loaded successfully + if (this.loadSuccessful) { + Conf.save(); + } + if (AutoLeaveTask != null) { + this.getServer().getScheduler().cancelTask(AutoLeaveTask); + AutoLeaveTask = null; + } + + super.onDisable(); + } + + public void startAutoLeaveTask(boolean restartIfRunning) { + if (AutoLeaveTask != null) { + if (!restartIfRunning) { + return; + } + this.getServer().getScheduler().cancelTask(AutoLeaveTask); + } + + if (Conf.autoLeaveRoutineRunsEveryXMinutes > 0.0) { + long ticks = (long) (20 * 60 * Conf.autoLeaveRoutineRunsEveryXMinutes); + AutoLeaveTask = getServer().getScheduler().scheduleSyncRepeatingTask(this, new AutoLeaveTask(), ticks, ticks); + } + } + + @Override + public void postAutoSave() { + //Board.getInstance().forceSave(); Not sure why this was there as it's called after the board is already saved. + Conf.save(); + } + + @Override + public boolean logPlayerCommands() { + return Conf.logPlayerCommands; + } + + @Override + public boolean handleCommand(CommandSender sender, String commandString, boolean testOnly) { + return sender instanceof Player && FactionsPlayerListener.preventCommand(commandString, (Player) sender) || super.handleCommand(sender, commandString, testOnly); + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] split) { + if (split.length == 0) { + return handleCommand(sender, "/c help", false); + } + + // otherwise, needs to be handled; presumably another plugin directly ran the command + String cmd = Conf.baseCommandAliases.isEmpty() ? "/c" : "/" + Conf.baseCommandAliases.get(0); + return handleCommand(sender, cmd + " " + TextUtil.implode(Arrays.asList(split), " "), false); + } + + + // -------------------------------------------- // + // Functions for other plugins to hook into + // -------------------------------------------- // + + // This value will be updated whenever new hooks are added + public int hookSupportVersion() { + return 3; + } + + // If another plugin is handling insertion of chat tags, this should be used to notify Factions + public void handleFactionTagExternally(boolean notByFactions) { + Conf.chatTagHandledByAnotherPlugin = notByFactions; + } + + // Simply put, should this chat event be left for Factions to handle? For now, that means players with Faction Chat + // enabled or use of the Factions f command without a slash; combination of isPlayerFactionChatting() and isFactionsCommand() + + public boolean shouldLetFactionsHandleThisChat(AsyncPlayerChatEvent event) { + return event != null && (isPlayerFactionChatting(event.getPlayer()) || isFactionsCommand(event.getMessage())); + } + + // Does player have Faction Chat enabled? If so, chat plugins should preferably not do channels, + // local chat, or anything else which targets individual recipients, so Faction Chat can be done + public boolean isPlayerFactionChatting(Player player) { + if (player == null) { + return false; + } + FPlayer me = FPlayers.getInstance().getByPlayer(player); + + return me != null && me.getChatMode().isAtLeast(ChatMode.ALLIANCE); + } + + // Is this chat message actually a Factions command, and thus should be left alone by other plugins? + + // TODO: GET THIS BACK AND WORKING + + public boolean isFactionsCommand(String check) { + return !(check == null || check.isEmpty()) && this.handleCommand(null, check, true); + } + + // Get a player's faction tag (faction name), mainly for usage by chat plugins for local/channel chat + public String getPlayerFactionTag(Player player) { + return getPlayerFactionTagRelation(player, null); + } + + // Same as above, but with relation (enemy/neutral/ally) coloring potentially added to the tag + public String getPlayerFactionTagRelation(Player speaker, Player listener) { + String tag = "~"; + + if (speaker == null) { + return tag; + } + + FPlayer me = FPlayers.getInstance().getByPlayer(speaker); + if (me == null) { + return tag; + } + + // if listener isn't set, or config option is disabled, give back uncolored tag + if (listener == null || !Conf.chatTagRelationColored) { + tag = me.getChatTag().trim(); + } else { + FPlayer you = FPlayers.getInstance().getByPlayer(listener); + if (you == null) { + tag = me.getChatTag().trim(); + } else // everything checks out, give the colored tag + { + tag = me.getChatTag(you).trim(); + } + } + if (tag.isEmpty()) { + tag = "~"; + } + + return tag; + } + + // Get a player's title within their faction, mainly for usage by chat plugins for local/channel chat + public String getPlayerTitle(Player player) { + if (player == null) { + return ""; + } + + FPlayer me = FPlayers.getInstance().getByPlayer(player); + if (me == null) { + return ""; + } + + return me.getTitle().trim(); + } + + // Get a list of all faction tags (names) + public Set getFactionTags() { + return Factions.getInstance().getFactionTags(); + } + + // Get a list of all players in the specified faction + public Set getPlayersInFaction(String factionTag) { + Set players = new HashSet(); + Faction faction = Factions.getInstance().getByTag(factionTag); + if (faction != null) { + for (FPlayer fplayer : faction.getFPlayers()) { + players.add(fplayer.getName()); + } + } + return players; + } + + // Get a list of all online players in the specified faction + public Set getOnlinePlayersInFaction(String factionTag) { + Set players = new HashSet(); + Faction faction = Factions.getInstance().getByTag(factionTag); + if (faction != null) { + for (FPlayer fplayer : faction.getFPlayersWhereOnline(true)) { + players.add(fplayer.getName()); + } + } + return players; + } + + public String getPrimaryGroup(OfflinePlayer player) { + return perms == null || !perms.hasGroupSupport() ? " " : perms.getPrimaryGroup(Bukkit.getWorlds().get(0).toString(), player); + } + + public void debug(Level level, String s) { + if (getConfig().getBoolean("debug", false)) { + getLogger().log(level, s); + } + } + + public void debug(String s) { + debug(Level.INFO, s); + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdAHome.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdAHome.java new file mode 100644 index 0000000..f9a2bdc --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdAHome.java @@ -0,0 +1,52 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; +import org.bukkit.event.player.PlayerTeleportEvent; + +public class CmdAHome extends FCommand { + + public CmdAHome() { + super(); + this.aliases.add("ahome"); + + this.requiredArgs.add("player name"); + + this.permission = Permission.AHOME.node; + this.disableOnLock = false; + + senderMustBePlayer = false; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + FPlayer target = argAsBestFPlayerMatch(0); + if (target == null) { + msg(TL.GENERIC_NOPLAYERMATCH, argAsString(0)); + return; + } + + if (target.isOnline()) { + Faction faction = target.getFaction(); + if (faction.hasHome()) { + target.getPlayer().teleport(faction.getHome(), PlayerTeleportEvent.TeleportCause.PLUGIN); + msg(TL.COMMAND_AHOME_SUCCESS, target.getName()); + target.msg(TL.COMMAND_AHOME_TARGET); + } else { + msg(TL.COMMAND_AHOME_NOHOME, target.getName()); + } + } else { + msg(TL.COMMAND_AHOME_OFFLINE, target.getName()); + } + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_AHOME_DESCRIPTION; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdAdmin.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdAdmin.java new file mode 100644 index 0000000..f493b28 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdAdmin.java @@ -0,0 +1,96 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.FPlayers; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.event.FPlayerJoinEvent; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.struct.Role; +import com.massivecraft.factions.zcore.util.TL; +import org.bukkit.Bukkit; + +public class CmdAdmin extends FCommand { + + public CmdAdmin() { + super(); + this.aliases.add("boss"); + this.aliases.add("setboss"); + this.aliases.add("admin"); + this.aliases.add("setadmin"); + this.aliases.add("leader"); + this.aliases.add("setleader"); + + this.requiredArgs.add("player name"); + //this.optionalArgs.put("", ""); + + this.permission = Permission.ADMIN.node; + this.disableOnLock = true; + + senderMustBePlayer = false; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + FPlayer fyou = this.argAsBestFPlayerMatch(0); + if (fyou == null) { + return; + } + + boolean permAny = Permission.ADMIN_ANY.has(sender, false); + Faction targetFaction = fyou.getFaction(); + + if (targetFaction != myFaction && !permAny) { + msg(TL.COMMAND_ADMIN_NOTMEMBER, fyou.describeTo(fme, true)); + return; + } + + if (fme != null && fme.getRole() != Role.ADMIN && !permAny) { + msg(TL.COMMAND_ADMIN_NOTADMIN); + return; + } + + if (fyou == fme && !permAny) { + msg(TL.COMMAND_ADMIN_TARGETSELF); + return; + } + + // only perform a FPlayerJoinEvent when newLeader isn't actually in the faction + if (fyou.getFaction() != targetFaction) { + FPlayerJoinEvent event = new FPlayerJoinEvent(FPlayers.getInstance().getByPlayer(me), targetFaction, FPlayerJoinEvent.PlayerJoinReason.LEADER); + Bukkit.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + return; + } + } + + FPlayer admin = targetFaction.getFPlayerAdmin(); + + // if target player is currently admin, demote and replace him + if (fyou == admin) { + targetFaction.promoteNewLeader(); + msg(TL.COMMAND_ADMIN_DEMOTES, fyou.describeTo(fme, true)); + fyou.msg(TL.COMMAND_ADMIN_DEMOTED, senderIsConsole ? TL.GENERIC_SERVERADMIN.toString() : fme.describeTo(fyou, true)); + return; + } + + // promote target player, and demote existing admin if one exists + if (admin != null) { + admin.setRole(Role.MODERATOR); + } + fyou.setRole(Role.ADMIN); + msg(TL.COMMAND_ADMIN_PROMOTES, fyou.describeTo(fme, true)); + + // Inform all players + for (FPlayer fplayer : FPlayers.getInstance().getOnlinePlayers()) { + fplayer.msg(TL.COMMAND_ADMIN_PROMOTED, senderIsConsole ? TL.GENERIC_SERVERADMIN.toString() : fme.describeTo(fplayer, true), fyou.describeTo(fplayer), targetFaction.describeTo(fplayer)); + } + } + + public TL getUsageTranslation() { + return TL.COMMAND_ADMIN_DESCRIPTION; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdAnnounce.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdAnnounce.java new file mode 100644 index 0000000..bc2c6bd --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdAnnounce.java @@ -0,0 +1,48 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; +import org.apache.commons.lang.StringUtils; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +public class CmdAnnounce extends FCommand { + + public CmdAnnounce() { + super(); + this.aliases.add("ann"); + this.aliases.add("announce"); + + this.requiredArgs.add("message"); + this.errorOnToManyArgs = false; + + this.permission = Permission.ANNOUNCE.node; + this.disableOnLock = false; + + senderMustBePlayer = true; + senderMustBeMember = true; + senderMustBeModerator = true; + } + + @Override + public void perform() { + String prefix = ChatColor.GREEN + myFaction.getTag() + ChatColor.YELLOW + " [" + ChatColor.GRAY + me.getName() + ChatColor.YELLOW + "] " + ChatColor.RESET; + String message = StringUtils.join(args, " "); + + for (Player player : myFaction.getOnlinePlayers()) { + player.sendMessage(prefix + message); + } + + // Add for offline players. + for (FPlayer fp : myFaction.getFPlayersWhereOnline(false)) { + myFaction.addAnnouncement(fp, prefix + message); + } + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_ANNOUNCE_DESCRIPTION; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdAutoClaim.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdAutoClaim.java new file mode 100644 index 0000000..f3fa7e2 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdAutoClaim.java @@ -0,0 +1,56 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.struct.Role; +import com.massivecraft.factions.zcore.util.TL; + +public class CmdAutoClaim extends FCommand { + + public CmdAutoClaim() { + super(); + this.aliases.add("autoclaim"); + + //this.requiredArgs.add(""); + this.optionalArgs.put("cartel", "your"); + + this.permission = Permission.AUTOCLAIM.node; + this.disableOnLock = true; + + senderMustBePlayer = true; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + Faction forFaction = this.argAsFaction(0, myFaction); + if (forFaction == null || forFaction == fme.getAutoClaimFor()) { + fme.setAutoClaimFor(null); + msg(TL.COMMAND_AUTOCLAIM_DISABLED); + return; + } + + if (!fme.canClaimForFaction(forFaction)) { + if (myFaction == forFaction) { + msg(TL.COMMAND_AUTOCLAIM_REQUIREDRANK, Role.MODERATOR.getTranslation()); + } else { + msg(TL.COMMAND_AUTOCLAIM_OTHERFACTION, forFaction.describeTo(fme)); + } + + return; + } + + fme.setAutoClaimFor(forFaction); + + msg(TL.COMMAND_AUTOCLAIM_ENABLED, forFaction.describeTo(fme)); + fme.attemptClaim(forFaction, me.getLocation(), true); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_AUTOCLAIM_DESCRIPTION; + } + +} \ No newline at end of file diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdAutoHelp.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdAutoHelp.java new file mode 100644 index 0000000..638d770 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdAutoHelp.java @@ -0,0 +1,47 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.P; +import com.massivecraft.factions.zcore.CommandVisibility; +import com.massivecraft.factions.zcore.MCommand; +import com.massivecraft.factions.zcore.util.TL; + +import java.util.ArrayList; + +public class CmdAutoHelp extends MCommand

{ + + public CmdAutoHelp() { + super(P.p); + this.aliases.add("?"); + this.aliases.add("h"); + this.aliases.add("help"); + + this.setHelpShort(""); + + this.optionalArgs.put("page", "1"); + } + + @Override + public void perform() { + if (this.commandChain.size() == 0) { + return; + } + MCommand pcmd = this.commandChain.get(this.commandChain.size() - 1); + + ArrayList lines = new ArrayList(); + + lines.addAll(pcmd.helpLong); + + for (MCommand scmd : pcmd.subCommands) { + if (scmd.visibility == CommandVisibility.VISIBLE || (scmd.visibility == CommandVisibility.SECRET && scmd.validSenderPermissions(sender, false))) { + lines.add(scmd.getUseageTemplate(this.commandChain, true)); + } + } + + sendMessage(p.txt.getPage(lines, this.argAsInt(0, 1), TL.COMMAND_AUTOHELP_HELPFOR.toString() + pcmd.aliases.get(0) + "\"")); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_HELP_DESCRIPTION; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdBoom.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdBoom.java new file mode 100644 index 0000000..7a579bf --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdBoom.java @@ -0,0 +1,51 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; + +public class CmdBoom extends FCommand { + + public CmdBoom() { + super(); + this.aliases.add("noboom"); + this.aliases.add("explosions"); + this.aliases.add("toggleexplosions"); + + //this.requiredArgs.add(""); + this.optionalArgs.put("on/off", "flip"); + + this.permission = Permission.NO_BOOM.node; + this.disableOnLock = true; + + senderMustBePlayer = true; + senderMustBeMember = false; + senderMustBeModerator = true; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + if (!myFaction.isPeaceful()) { + fme.msg(TL.COMMAND_BOOM_PEACEFULONLY); + return; + } + + // if economy is enabled, they're not on the bypass list, and this command has a cost set, make 'em pay + if (!payForCommand(Conf.econCostNoBoom, TL.COMMAND_BOOM_TOTOGGLE, TL.COMMAND_BOOM_FORTOGGLE)) { + return; + } + + myFaction.setPeacefulExplosionsEnabled(this.argAsBool(0, !myFaction.getPeacefulExplosionsEnabled())); + + String enabled = myFaction.noExplosionsInTerritory() ? TL.GENERIC_DISABLED.toString() : TL.GENERIC_ENABLED.toString(); + + // Inform + myFaction.msg(TL.COMMAND_BOOM_ENABLED, fme.describeTo(myFaction), enabled); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_BOOM_DESCRIPTION; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdBypass.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdBypass.java new file mode 100644 index 0000000..0104412 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdBypass.java @@ -0,0 +1,43 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.P; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; + +public class CmdBypass extends FCommand { + + public CmdBypass() { + super(); + this.aliases.add("bypass"); + + //this.requiredArgs.add(""); + this.optionalArgs.put("on/off", "flip"); + + this.permission = Permission.BYPASS.node; + this.disableOnLock = false; + + senderMustBePlayer = true; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + fme.setIsAdminBypassing(this.argAsBool(0, !fme.isAdminBypassing())); + + // TODO: Move this to a transient field in the model?? + if (fme.isAdminBypassing()) { + fme.msg(TL.COMMAND_BYPASS_ENABLE.toString()); + P.p.log(fme.getName() + TL.COMMAND_BYPASS_ENABLELOG.toString()); + } else { + fme.msg(TL.COMMAND_BYPASS_DISABLE.toString()); + P.p.log(fme.getName() + TL.COMMAND_BYPASS_DISABLELOG.toString()); + } + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_BYPASS_DESCRIPTION; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdChat.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdChat.java new file mode 100644 index 0000000..9b47a74 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdChat.java @@ -0,0 +1,70 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.struct.ChatMode; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; + +public class CmdChat extends FCommand { + + public CmdChat() { + super(); + this.aliases.add("c"); + this.aliases.add("chat"); + + //this.requiredArgs.add(""); + this.optionalArgs.put("mode", "next"); + + this.permission = Permission.CHAT.node; + this.disableOnLock = false; + + senderMustBePlayer = true; + senderMustBeMember = true; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + if (!Conf.factionOnlyChat) { + msg(TL.COMMAND_CHAT_DISABLED.toString()); + return; + } + + String modeString = this.argAsString(0); + ChatMode modeTarget = fme.getChatMode().getNext(); + + if (modeString != null) { + modeString = modeString.toLowerCase(); + if (modeString.startsWith("p")) { + modeTarget = ChatMode.PUBLIC; + } else if (modeString.startsWith("a")) { + modeTarget = ChatMode.ALLIANCE; + } else if (modeString.startsWith("f")) { + modeTarget = ChatMode.FACTION; + } else if (modeString.startsWith("t")) { + modeTarget = ChatMode.TRUCE; + } else { + msg(TL.COMMAND_CHAT_INVALIDMODE); + return; + } + } + + fme.setChatMode(modeTarget); + + if (fme.getChatMode() == ChatMode.PUBLIC) { + msg(TL.COMMAND_CHAT_MODE_PUBLIC); + } else if (fme.getChatMode() == ChatMode.ALLIANCE) { + msg(TL.COMMAND_CHAT_MODE_ALLIANCE); + } else if (fme.getChatMode() == ChatMode.TRUCE) { + msg(TL.COMMAND_CHAT_MODE_TRUCE); + } else { + msg(TL.COMMAND_CHAT_MODE_FACTION); + } + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_CHAT_DESCRIPTION; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdChatSpy.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdChatSpy.java new file mode 100644 index 0000000..c5e35fa --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdChatSpy.java @@ -0,0 +1,41 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.P; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; + +public class CmdChatSpy extends FCommand { + + public CmdChatSpy() { + super(); + this.aliases.add("chatspy"); + + this.optionalArgs.put("on/off", "flip"); + + this.permission = Permission.CHATSPY.node; + this.disableOnLock = false; + + senderMustBePlayer = true; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + fme.setSpyingChat(this.argAsBool(0, !fme.isSpyingChat())); + + if (fme.isSpyingChat()) { + fme.msg(TL.COMMAND_CHATSPY_ENABLE); + P.p.log(fme.getName() + TL.COMMAND_CHATSPY_ENABLELOG.toString()); + } else { + fme.msg(TL.COMMAND_CHATSPY_DISABLE); + P.p.log(fme.getName() + TL.COMMAND_CHATSPY_DISABLELOG.toString()); + } + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_CHATSPY_DESCRIPTION; + } +} \ No newline at end of file diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdClaim.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdClaim.java new file mode 100644 index 0000000..b956918 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdClaim.java @@ -0,0 +1,82 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.FLocation; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.util.SpiralTask; +import com.massivecraft.factions.zcore.util.TL; +import net.grandtheftmc.core.util.Utils; + + +public class CmdClaim extends FCommand { + + public CmdClaim() { + super(); + this.aliases.add("claim"); + + //this.requiredArgs.add(""); + this.optionalArgs.put("radius", "1"); + this.optionalArgs.put("cartel", "your"); + + this.permission = Permission.CLAIM.node; + this.disableOnLock = true; + + senderMustBePlayer = true; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + // Read and validate input + int radius = this.argAsInt(0, 1); // Default to 1 + final Faction forFaction = this.argAsFaction(1, myFaction); // Default to own + + if (radius < 1) { + msg(TL.COMMAND_CLAIM_INVALIDRADIUS); + return; + } + + if(me.getLocation().getWorld().getName().equals("spawn") && !this.sender.isOp()) { + me.sendMessage(Utils.f("&c&l Cartels&8&l> &cYou cannot claim in spawn area!")); + return; + } + + if (radius < 2) { + // single chunk + fme.attemptClaim(forFaction, me.getLocation(), true); + } else { + // radius claim + if (!Permission.CLAIM_RADIUS.has(sender, false)) { + msg(TL.COMMAND_CLAIM_DENIED); + return; + } + + new SpiralTask(new FLocation(me), radius) { + private int failCount = 0; + private final int limit = Conf.radiusClaimFailureLimit - 1; + + @Override + public boolean work() { + boolean success = fme.attemptClaim(forFaction, this.currentLocation(), true); + if (success) { + failCount = 0; + } else if (failCount++ >= limit) { + this.stop(); + return false; + } + + return true; + } + }; + } + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_CLAIM_DESCRIPTION; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdClaimLine.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdClaimLine.java new file mode 100644 index 0000000..39b86e2 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdClaimLine.java @@ -0,0 +1,82 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; +import net.grandtheftmc.core.util.Utils; +import org.bukkit.Location; +import org.bukkit.block.BlockFace; + +public class CmdClaimLine extends FCommand { + + public static final BlockFace[] axis = {BlockFace.SOUTH, BlockFace.WEST, BlockFace.NORTH, BlockFace.EAST}; + + public CmdClaimLine() { + + // Aliases + this.aliases.add("claimline"); + this.aliases.add("cl"); + + // Args + this.optionalArgs.put("amount", "1"); + this.optionalArgs.put("direction", "facing"); + this.optionalArgs.put("cartel", "you"); + + this.permission = Permission.CLAIM_LINE.node; + this.disableOnLock = true; + + senderMustBePlayer = true; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + // Args + Integer amount = this.argAsInt(0, 1); // Default to 1 + + if (amount > Conf.lineClaimLimit) { + fme.msg(TL.COMMAND_CLAIMLINE_ABOVEMAX, Conf.lineClaimLimit); + return; + } + + if(me.getLocation().getWorld().getName().equals("spawn") && !this.sender.isOp()) { + me.sendMessage(Utils.f("&c&l Cartels&8&l> &cYou cannot claim in spawn area!")); + return; + } + + String direction = this.argAsString(1); + BlockFace blockFace; + + if (direction == null) { + blockFace = axis[Math.round(me.getLocation().getYaw() / 90f) & 0x3]; + } else if (direction.equalsIgnoreCase("north")) { + blockFace = BlockFace.NORTH; + } else if (direction.equalsIgnoreCase("east")) { + blockFace = BlockFace.EAST; + } else if (direction.equalsIgnoreCase("south")) { + blockFace = BlockFace.SOUTH; + } else if (direction.equalsIgnoreCase("west")) { + blockFace = BlockFace.WEST; + } else { + fme.msg(TL.COMMAND_CLAIMLINE_NOTVALID, direction); + return; + } + + final Faction forFaction = this.argAsFaction(2, myFaction); + Location location = me.getLocation(); + + // TODO: make this a task like claiming a radius? + for (int i = 0; i < amount; i++) { + fme.attemptClaim(forFaction, location, true); + location = location.add(blockFace.getModX() * 16, 0, blockFace.getModZ() * 16); + } + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_CLAIMLINE_DESCRIPTION; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdConfig.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdConfig.java new file mode 100644 index 0000000..956b6b4 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdConfig.java @@ -0,0 +1,248 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.P; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import java.lang.reflect.Field; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Set; + +public class CmdConfig extends FCommand { + + private static HashMap properFieldNames = new HashMap(); + + public CmdConfig() { + super(); + this.aliases.add("config"); + + this.requiredArgs.add("setting"); + this.requiredArgs.add("value"); + this.errorOnToManyArgs = false; + + this.permission = Permission.CONFIG.node; + this.disableOnLock = true; + + senderMustBePlayer = false; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + // store a lookup map of lowercase field names paired with proper capitalization field names + // that way, if the person using this command messes up the capitalization, we can fix that + if (properFieldNames.isEmpty()) { + Field[] fields = Conf.class.getDeclaredFields(); + for (int i = 0; i < fields.length; i++) { + properFieldNames.put(fields[i].getName().toLowerCase(), fields[i].getName()); + } + } + + String field = this.argAsString(0).toLowerCase(); + if (field.startsWith("\"") && field.endsWith("\"")) { + field = field.substring(1, field.length() - 1); + } + String fieldName = properFieldNames.get(field); + + if (fieldName == null || fieldName.isEmpty()) { + msg(TL.COMMAND_CONFIG_NOEXIST, field); + return; + } + + String success; + + String value = args.get(1); + for (int i = 2; i < args.size(); i++) { + value += ' ' + args.get(i); + } + + try { + Field target = Conf.class.getField(fieldName); + + // boolean + if (target.getType() == boolean.class) { + boolean targetValue = this.strAsBool(value); + target.setBoolean(null, targetValue); + + if (targetValue) { + success = "\"" + fieldName + TL.COMMAND_CONFIG_SET_TRUE.toString(); + } else { + success = "\"" + fieldName + TL.COMMAND_CONFIG_SET_FALSE.toString(); + } + } + + // int + else if (target.getType() == int.class) { + try { + int intVal = Integer.parseInt(value); + target.setInt(null, intVal); + success = "\"" + fieldName + TL.COMMAND_CONFIG_OPTIONSET.toString() + intVal + "."; + } catch (NumberFormatException ex) { + sendMessage(TL.COMMAND_CONFIG_INTREQUIRED.format(fieldName)); + return; + } + } + + // long + else if (target.getType() == long.class) { + try { + long longVal = Long.parseLong(value); + target.setLong(null, longVal); + success = "\"" + fieldName + TL.COMMAND_CONFIG_OPTIONSET.toString() + longVal + "."; + } catch (NumberFormatException ex) { + sendMessage(TL.COMMAND_CONFIG_LONGREQUIRED.format(fieldName)); + return; + } + } + + // double + else if (target.getType() == double.class) { + try { + double doubleVal = Double.parseDouble(value); + target.setDouble(null, doubleVal); + success = "\"" + fieldName + TL.COMMAND_CONFIG_OPTIONSET.toString() + doubleVal + "."; + } catch (NumberFormatException ex) { + sendMessage(TL.COMMAND_CONFIG_DOUBLEREQUIRED.format(fieldName)); + return; + } + } + + // float + else if (target.getType() == float.class) { + try { + float floatVal = Float.parseFloat(value); + target.setFloat(null, floatVal); + success = "\"" + fieldName + TL.COMMAND_CONFIG_OPTIONSET.toString() + floatVal + "."; + } catch (NumberFormatException ex) { + sendMessage(TL.COMMAND_CONFIG_FLOATREQUIRED.format(fieldName)); + return; + } + } + + // String + else if (target.getType() == String.class) { + target.set(null, value); + success = "\"" + fieldName + TL.COMMAND_CONFIG_OPTIONSET.toString() + value + "\"."; + } + + // ChatColor + else if (target.getType() == ChatColor.class) { + ChatColor newColor = null; + try { + newColor = ChatColor.valueOf(value.toUpperCase()); + } catch (IllegalArgumentException ex) { + + } + if (newColor == null) { + sendMessage(TL.COMMAND_CONFIG_INVALID_COLOUR.format(fieldName, value.toUpperCase())); + return; + } + target.set(null, newColor); + success = "\"" + fieldName + TL.COMMAND_CONFIG_COLOURSET.toString() + value.toUpperCase() + "\"."; + } + + // Set or other parameterized collection + else if (target.getGenericType() instanceof ParameterizedType) { + ParameterizedType targSet = (ParameterizedType) target.getGenericType(); + Type innerType = targSet.getActualTypeArguments()[0]; + + // not a Set, somehow, and that should be the only collection we're using in Conf.java + if (targSet.getRawType() != Set.class) { + sendMessage(TL.COMMAND_CONFIG_INVALID_COLLECTION.format(fieldName)); + return; + } + + // Set + else if (innerType == Material.class) { + Material newMat = null; + try { + newMat = Material.valueOf(value.toUpperCase()); + } catch (IllegalArgumentException ex) { + + } + if (newMat == null) { + sendMessage(TL.COMMAND_CONFIG_INVALID_MATERIAL.format(fieldName, value.toUpperCase())); + return; + } + + @SuppressWarnings("unchecked") Set matSet = (Set) target.get(null); + + // Material already present, so remove it + if (matSet.contains(newMat)) { + matSet.remove(newMat); + target.set(null, matSet); + success = TL.COMMAND_CONFIG_MATERIAL_REMOVED.format(fieldName, value.toUpperCase()); + } + // Material not present yet, add it + else { + matSet.add(newMat); + target.set(null, matSet); + success = TL.COMMAND_CONFIG_MATERIAL_ADDED.format(fieldName, value.toUpperCase()); + } + } + + // Set + else if (innerType == String.class) { + @SuppressWarnings("unchecked") Set stringSet = (Set) target.get(null); + + // String already present, so remove it + if (stringSet.contains(value)) { + stringSet.remove(value); + target.set(null, stringSet); + success = TL.COMMAND_CONFIG_SET_REMOVED.format(fieldName, value); + } + // String not present yet, add it + else { + stringSet.add(value); + target.set(null, stringSet); + success = TL.COMMAND_CONFIG_SET_ADDED.format(fieldName, value); + } + } + + // Set of unknown type + else { + sendMessage(TL.COMMAND_CONFIG_INVALID_TYPESET.format(fieldName)); + return; + } + } + + // unknown type + else { + sendMessage(TL.COMMAND_CONFIG_ERROR_TYPE.format(fieldName, target.getClass().getName())); + return; + } + } catch (NoSuchFieldException ex) { + sendMessage(TL.COMMAND_CONFIG_ERROR_MATCHING.format(fieldName)); + return; + } catch (IllegalAccessException ex) { + sendMessage(TL.COMMAND_CONFIG_ERROR_SETTING.format(fieldName, value)); + return; + } + + if (!success.isEmpty()) { + if (sender instanceof Player) { + sendMessage(success); + P.p.log(success + TL.COMMAND_CONFIG_LOG.format((Player) sender)); + } else // using P.p.log() instead of sendMessage if run from server console so that "[Factions v#.#.#]" is prepended in server log + { + P.p.log(success); + } + } + // save change to disk + Conf.save(); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_CONFIG_DESCRIPTION; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdConvert.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdConvert.java new file mode 100644 index 0000000..42cf917 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdConvert.java @@ -0,0 +1,44 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.Conf.Backend; +import com.massivecraft.factions.zcore.persist.json.FactionsJSON; +import com.massivecraft.factions.zcore.util.TL; +import org.bukkit.command.ConsoleCommandSender; + +public class CmdConvert extends FCommand { + + public CmdConvert() { + this.aliases.add("convert"); + + this.requiredArgs.add("[MYSQL|JSON]"); + } + + @Override + public void perform() { + if (!(this.sender instanceof ConsoleCommandSender)) { + this.sender.sendMessage(TL.GENERIC_CONSOLEONLY.toString()); + } + Backend nb = Backend.valueOf(this.argAsString(0).toUpperCase()); + if (nb == Conf.backEnd) { + this.sender.sendMessage(TL.COMMAND_CONVERT_BACKEND_RUNNING.toString()); + return; + } + switch (nb) { + case JSON: + FactionsJSON.convertTo(); + break; + default: + this.sender.sendMessage(TL.COMMAND_CONVERT_BACKEND_INVALID.toString()); + return; + + } + Conf.backEnd = nb; + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_CONVERT_DESCRIPTION; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdCreate.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdCreate.java new file mode 100644 index 0000000..1de4aa1 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdCreate.java @@ -0,0 +1,124 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.*; +import com.massivecraft.factions.event.FPlayerJoinEvent; +import com.massivecraft.factions.event.FactionCreateEvent; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.struct.Role; +import com.massivecraft.factions.util.MiscUtil; +import com.massivecraft.factions.zcore.util.TL; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.util.NumeralUtil; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.ViceUser; +import org.bukkit.Bukkit; + +import java.util.ArrayList; +import java.util.Locale; + + +public class CmdCreate extends FCommand { + + public CmdCreate() { + super(); + this.aliases.add("create"); + + this.requiredArgs.add("cartel tag"); + //this.optionalArgs.put("", ""); + + this.permission = Permission.CREATE.node; + this.disableOnLock = true; + + senderMustBePlayer = true; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + String tag = this.argAsString(0); + + if (fme.hasFaction()) { + msg(TL.COMMAND_CREATE_MUSTLEAVE); + return; + } + + if (Factions.getInstance().isTagTaken(tag)) { + msg(TL.COMMAND_CREATE_INUSE); + return; + } + + ArrayList tagValidationErrors = MiscUtil.validateTag(tag); + if (tagValidationErrors.size() > 0) { + sendMessage(tagValidationErrors); + return; + } + + // if economy is enabled, they're not on the bypass list, and this command has a cost set, make sure they can pay +// if (!canAffordCommand(Conf.econCostCreate, TL.COMMAND_CREATE_TOCREATE.toString())) { +// return; +// } + + if(Conf.econCostCreate > 0) { + if (fme.getPlayer() == null) return; + ViceUser user = Vice.getUserManager().getLoadedUser(fme.getPlayer().getUniqueId()); + if (user == null) return; + if (!user.hasMoney(Conf.econCostCreate)) { + msg("you can't afford %s %s.", NumeralUtil.toCurrency(Conf.econCostCreate, Locale.US), TL.COMMAND_CREATE_TOCREATE.toString()); + return; + } + + user.takeMoney(Conf.econCostCreate); + sender.sendMessage(Utils.f("&c- " + NumeralUtil.toCurrency(Conf.econCostCreate, Locale.US))); + } + + // trigger the faction creation event (cancellable) + FactionCreateEvent createEvent = new FactionCreateEvent(me, tag); + Bukkit.getServer().getPluginManager().callEvent(createEvent); + if (createEvent.isCancelled()) { + return; + } + + // then make 'em pay (if applicable) +// if (!payForCommand(Conf.econCostCreate, TL.COMMAND_CREATE_TOCREATE, TL.COMMAND_CREATE_FORCREATE)) { +// return; +// } + + Faction faction = Factions.getInstance().createFaction(); + + // TODO: Why would this even happen??? Auto increment clash?? + if (faction == null) { + msg(TL.COMMAND_CREATE_ERROR); + return; + } + + // finish setting up the Faction + faction.setTag(tag); + + // trigger the faction join event for the creator + FPlayerJoinEvent joinEvent = new FPlayerJoinEvent(FPlayers.getInstance().getByPlayer(me), faction, FPlayerJoinEvent.PlayerJoinReason.CREATE); + Bukkit.getServer().getPluginManager().callEvent(joinEvent); + // join event cannot be cancelled or you'll have an empty faction + + // finish setting up the FPlayer + fme.setRole(Role.ADMIN); + fme.setFaction(faction); + + for (FPlayer follower : FPlayers.getInstance().getOnlinePlayers()) { + follower.msg(TL.COMMAND_CREATE_CREATED, fme.describeTo(follower, true), faction.getTag(follower)); + } + + msg(TL.COMMAND_CREATE_YOUSHOULD, p.cmdBase.cmdDescription.getUseageTemplate()); + + if (Conf.logFactionCreate) { + P.p.log(fme.getName() + TL.COMMAND_CREATE_CREATEDLOG.toString() + tag); + } + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_CREATE_DESCRIPTION; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdDeinvite.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdDeinvite.java new file mode 100644 index 0000000..4b60391 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdDeinvite.java @@ -0,0 +1,62 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.FPlayers; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; +import mkremins.fanciful.FancyMessage; +import org.bukkit.ChatColor; + +public class CmdDeinvite extends FCommand { + + public CmdDeinvite() { + super(); + this.aliases.add("deinvite"); + this.aliases.add("deinv"); + + this.optionalArgs.put("player name", "name"); + //this.optionalArgs.put("", ""); + + this.permission = Permission.DEINVITE.node; + this.disableOnLock = true; + + senderMustBePlayer = true; + senderMustBeMember = false; + senderMustBeModerator = true; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + FPlayer you = this.argAsBestFPlayerMatch(0); + if (you == null) { + FancyMessage msg = new FancyMessage(TL.COMMAND_DEINVITE_CANDEINVITE.toString()).color(ChatColor.GOLD); + for (String id : myFaction.getInvites()) { + FPlayer fp = FPlayers.getInstance().getById(id); + String name = fp != null ? fp.getName() : id; + msg.then(name + " ").color(ChatColor.WHITE).tooltip(TL.COMMAND_DEINVITE_CLICKTODEINVITE.format(name)).command("/" + Conf.baseCommandAliases.get(0) + " deinvite " + name); + } + sendFancyMessage(msg); + return; + } + + if (you.getFaction() == myFaction) { + msg(TL.COMMAND_DEINVITE_ALREADYMEMBER, you.getName(), myFaction.getTag()); + msg(TL.COMMAND_DEINVITE_MIGHTWANT, p.cmdBase.cmdKick.getUseageTemplate(false)); + return; + } + + myFaction.deinvite(you); + + you.msg(TL.COMMAND_DEINVITE_REVOKED, fme.describeTo(you), myFaction.describeTo(you)); + + myFaction.msg(TL.COMMAND_DEINVITE_REVOKES, fme.describeTo(myFaction), you.describeTo(myFaction)); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_DEINVITE_DESCRIPTION; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdDelFWarp.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdDelFWarp.java new file mode 100644 index 0000000..00583e2 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdDelFWarp.java @@ -0,0 +1,44 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.P; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; + +public class CmdDelFWarp extends FCommand { + + public CmdDelFWarp() { + super(); + this.aliases.add("delwarp"); + this.aliases.add("dw"); + this.aliases.add("deletewarp"); + this.requiredArgs.add("warp name"); + this.senderMustBeMember = true; + this.senderMustBeModerator = true; + this.senderMustBePlayer = true; + this.permission = Permission.SETWARP.node; + } + + @Override + public void perform() { + String warp = argAsString(0); + if (myFaction.isWarp(warp)) { + if (!transact(fme)) { + return; + } + myFaction.removeWarp(warp); + fme.msg(TL.COMMAND_DELFWARP_DELETED, warp); + } else { + fme.msg(TL.COMMAND_DELFWARP_INVALID, warp); + } + } + + private boolean transact(FPlayer player) { + return !P.p.getConfig().getBoolean("warp-cost.enabled", false) || player.isAdminBypassing() || payForCommand(P.p.getConfig().getDouble("warp-cost.delwarp", 5), TL.COMMAND_DELFWARP_TODELETE.toString(), TL.COMMAND_DELFWARP_FORDELETE.toString()); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_DELFWARP_DESCRIPTION; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdDescription.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdDescription.java new file mode 100644 index 0000000..7395e43 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdDescription.java @@ -0,0 +1,59 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.FPlayers; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; +import com.massivecraft.factions.zcore.util.TextUtil; + +public class CmdDescription extends FCommand { + + public CmdDescription() { + super(); + this.aliases.add("desc"); + this.aliases.add("description"); + + this.requiredArgs.add("desc"); + this.errorOnToManyArgs = false; + //this.optionalArgs + + this.permission = Permission.DESCRIPTION.node; + this.disableOnLock = true; + + senderMustBePlayer = true; + senderMustBeMember = false; + senderMustBeModerator = true; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + // if economy is enabled, they're not on the bypass list, and this command has a cost set, make 'em pay + if (!payForCommand(Conf.econCostDesc, TL.COMMAND_DESCRIPTION_TOCHANGE, TL.COMMAND_DESCRIPTION_FORCHANGE)) { + return; + } + + // since "&" color tags seem to work even through plain old FPlayer.sendMessage() for some reason, we need to break those up + // And replace all the % because it messes with string formatting and this is easy way around that. + myFaction.setDescription(TextUtil.implode(args, " ").replaceAll("%", "").replaceAll("(&([a-f0-9klmnor]))", "& $2")); + + if (!Conf.broadcastDescriptionChanges) { + fme.msg(TL.COMMAND_DESCRIPTION_CHANGED, myFaction.describeTo(fme)); + fme.sendMessage(myFaction.getDescription()); + return; + } + + // Broadcast the description to everyone + for (FPlayer fplayer : FPlayers.getInstance().getOnlinePlayers()) { + fplayer.msg(TL.COMMAND_DESCRIPTION_CHANGES, myFaction.describeTo(fplayer)); + fplayer.sendMessage(myFaction.getDescription()); // players can inject "&" or "`" or "" or whatever in their description; &k is particularly interesting looking + } + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_DESCRIPTION_DESCRIPTION; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdDisband.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdDisband.java new file mode 100644 index 0000000..0e8b4c3 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdDisband.java @@ -0,0 +1,107 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.*; +import com.massivecraft.factions.event.FPlayerLeaveEvent; +import com.massivecraft.factions.event.FactionDisbandEvent; +import com.massivecraft.factions.integration.Econ; +import com.massivecraft.factions.scoreboards.FTeamWrapper; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.struct.Role; +import com.massivecraft.factions.zcore.util.TL; +import org.bukkit.Bukkit; + + +public class CmdDisband extends FCommand { + + public CmdDisband() { + super(); + this.aliases.add("disband"); + + //this.requiredArgs.add(""); + this.optionalArgs.put("cartel tag", "yours"); + + this.permission = Permission.DISBAND.node; + this.disableOnLock = true; + + senderMustBePlayer = false; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + // The faction, default to your own.. but null if console sender. + Faction faction = this.argAsFaction(0, fme == null ? null : myFaction); + if (faction == null) { + return; + } + + boolean isMyFaction = fme == null ? false : faction == myFaction; + + if (isMyFaction) { + if (!assertMinRole(Role.ADMIN)) { + return; + } + } else { + if (!Permission.DISBAND_ANY.has(sender, true)) { + return; + } + } + + if (!faction.isNormal()) { + msg(TL.COMMAND_DISBAND_IMMUTABLE.toString()); + return; + } + if (faction.isPermanent()) { + msg(TL.COMMAND_DISBAND_MARKEDPERMANENT.toString()); + return; + } + + FactionDisbandEvent disbandEvent = new FactionDisbandEvent(me, faction.getId()); + Bukkit.getServer().getPluginManager().callEvent(disbandEvent); + if (disbandEvent.isCancelled()) { + return; + } + + // Send FPlayerLeaveEvent for each player in the faction + for (FPlayer fplayer : faction.getFPlayers()) { + Bukkit.getServer().getPluginManager().callEvent(new FPlayerLeaveEvent(fplayer, faction, FPlayerLeaveEvent.PlayerLeaveReason.DISBAND)); + } + + // Inform all players + for (FPlayer fplayer : FPlayers.getInstance().getOnlinePlayers()) { + String who = senderIsConsole ? TL.GENERIC_SERVERADMIN.toString() : fme.describeTo(fplayer); + if (fplayer.getFaction() == faction) { + fplayer.msg(TL.COMMAND_DISBAND_BROADCAST_YOURS, who); + } else { + fplayer.msg(TL.COMMAND_DISBAND_BROADCAST_NOTYOURS, who, faction.getTag(fplayer)); + } + } + if (Conf.logFactionDisband) { + //TODO: Format this correctly and translate. + P.p.log("The cartel " + faction.getTag() + " (" + faction.getId() + ") was disbanded by " + (senderIsConsole ? "console command" : fme.getName()) + "."); + } + + if (Econ.shouldBeUsed() && !senderIsConsole) { + //Give all the faction's money to the disbander + double amount = Econ.getBalance(faction.getAccountId()); + Econ.transferMoney(fme, faction, fme, amount, false); + + if (amount > 0.0) { + String amountString = Econ.moneyString(amount); + msg(TL.COMMAND_DISBAND_HOLDINGS, amountString); + //TODO: Format this correctly and translate + P.p.log(fme.getName() + " has been given bank holdings of " + amountString + " from disbanding " + faction.getTag() + "."); + } + } + + Factions.getInstance().removeFaction(faction.getId()); + FTeamWrapper.applyUpdates(faction); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_DISBAND_DESCRIPTION; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdFWarp.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdFWarp.java new file mode 100644 index 0000000..908f77d --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdFWarp.java @@ -0,0 +1,75 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.P; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.util.LazyLocation; +import com.massivecraft.factions.util.WarmUpUtil; +import com.massivecraft.factions.zcore.util.TL; +import mkremins.fanciful.FancyMessage; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +import java.util.Map; +import java.util.UUID; + +public class CmdFWarp extends FCommand { + + public CmdFWarp() { + super(); + this.aliases.add("warp"); + this.aliases.add("warps"); + this.optionalArgs.put("warpname", "warpname"); + + this.permission = Permission.WARP.node; + this.senderMustBeMember = true; + this.senderMustBeModerator = false; + } + + @Override + public void perform() { + //TODO: check if in combat. + if (args.size() == 0) { + FancyMessage msg = new FancyMessage(TL.COMMAND_FWARP_WARPS.toString()).color(ChatColor.GOLD); + Map warps = myFaction.getWarps(); + for (String s : warps.keySet()) { + msg.then(s + " ").tooltip(TL.COMMAND_FWARP_CLICKTOWARP.toString()).command("/" + Conf.baseCommandAliases.get(0) + " warp " + s).color(ChatColor.WHITE); + } + sendFancyMessage(msg); + } else if (args.size() > 1) { + fme.msg(TL.COMMAND_FWARP_COMMANDFORMAT); + } else { + final String warpName = argAsString(0); + if (myFaction.isWarp(argAsString(0))) { + if (!transact(fme)) { + return; + } + final FPlayer fPlayer = fme; + final UUID uuid = fme.getPlayer().getUniqueId(); + this.doWarmUp(WarmUpUtil.Warmup.WARP, TL.WARMUPS_NOTIFY_TELEPORT, warpName, new Runnable() { + @Override + public void run() { + Player player = Bukkit.getPlayer(uuid); + if (player != null) { + player.teleport(fPlayer.getFaction().getWarp(warpName).getLocation()); + fPlayer.msg(TL.COMMAND_FWARP_WARPED, warpName); + } + } + }, this.p.getConfig().getLong("warmups.f-warp", 0)); + } else { + fme.msg(TL.COMMAND_FWARP_INVALID, warpName); + } + } + } + + private boolean transact(FPlayer player) { + return !P.p.getConfig().getBoolean("warp-cost.enabled", false) || player.isAdminBypassing() || payForCommand(P.p.getConfig().getDouble("warp-cost.warp", 5), TL.COMMAND_FWARP_TOWARP.toString(), TL.COMMAND_FWARP_FORWARPING.toString()); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_FWARP_DESCRIPTION; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdHelp.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdHelp.java new file mode 100644 index 0000000..5a9f539 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdHelp.java @@ -0,0 +1,218 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.P; +import com.massivecraft.factions.integration.Econ; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; +import org.bukkit.configuration.ConfigurationSection; + +import java.util.ArrayList; +import java.util.List; + + +public class CmdHelp extends FCommand { + + public CmdHelp() { + super(); + this.aliases.add("help"); + this.aliases.add("h"); + this.aliases.add("?"); + + //this.requiredArgs.add(""); + this.optionalArgs.put("page", "1"); + + this.permission = Permission.HELP.node; + this.disableOnLock = false; + + senderMustBePlayer = false; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + if (P.p.getConfig().getBoolean("use-old-help", true)) { + if (helpPages == null) { + updateHelp(); + } + + int page = this.argAsInt(0, 1); + sendMessage(p.txt.titleize("Cartels Help (" + page + "/" + helpPages.size() + ")")); + + page -= 1; + + if (page < 0 || page >= helpPages.size()) { + msg(TL.COMMAND_HELP_404.format(String.valueOf(page))); + return; + } + sendMessage(helpPages.get(page)); + return; + } + ConfigurationSection help = P.p.getConfig().getConfigurationSection("help"); + if (help == null) { + help = P.p.getConfig().createSection("help"); // create new help section + List error = new ArrayList(); + error.add("&cUpdate help messages in config.yml!"); + error.add("&cSet use-old-help for legacy help messages"); + help.set("'1'", error); // add default error messages + } + String pageArg = this.argAsString(0, "1"); + List page = help.getStringList(pageArg); + if (page == null || page.isEmpty()) { + msg(TL.COMMAND_HELP_404.format(pageArg)); + return; + } + for (String helpLine : page) { + sendMessage(P.p.txt.parse(helpLine)); + } + } + + //----------------------------------------------// + // Build the help pages + //----------------------------------------------// + + public ArrayList> helpPages; + + public void updateHelp() { + helpPages = new ArrayList>(); + ArrayList pageLines; + + pageLines = new ArrayList(); + pageLines.add(p.cmdBase.cmdHelp.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdList.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdShow.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdPower.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdJoin.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdLeave.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdChat.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdToggleAllianceChat.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdHome.getUseageTemplate(true)); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_NEXTCREATE.toString())); + helpPages.add(pageLines); + + pageLines = new ArrayList(); + pageLines.add(p.cmdBase.cmdCreate.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdDescription.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdTag.getUseageTemplate(true)); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_INVITATIONS.toString())); + pageLines.add(p.cmdBase.cmdOpen.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdInvite.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdDeinvite.getUseageTemplate(true)); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_HOME.toString())); + pageLines.add(p.cmdBase.cmdSethome.getUseageTemplate(true)); + helpPages.add(pageLines); + + if (Econ.isSetup() && Conf.econEnabled && Conf.bankEnabled) { + pageLines = new ArrayList(); + pageLines.add(""); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_BANK_1.toString())); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_BANK_2.toString())); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_BANK_3.toString())); + pageLines.add(""); + pageLines.add(p.cmdBase.cmdMoney.getUseageTemplate(true)); + pageLines.add(""); + pageLines.add(""); + pageLines.add(""); + helpPages.add(pageLines); + } + + pageLines = new ArrayList(); + pageLines.add(p.cmdBase.cmdClaim.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdAutoClaim.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdUnclaim.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdUnclaimall.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdKick.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdMod.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdAdmin.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdTitle.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdSB.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdSeeChunk.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdStatus.getUseageTemplate(true)); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_PLAYERTITLES.toString())); + helpPages.add(pageLines); + + pageLines = new ArrayList(); + pageLines.add(p.cmdBase.cmdMap.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdBoom.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdOwner.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdOwnerList.getUseageTemplate(true)); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_OWNERSHIP_1.toString())); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_OWNERSHIP_2.toString())); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_OWNERSHIP_3.toString())); + helpPages.add(pageLines); + + pageLines = new ArrayList(); + pageLines.add(p.cmdBase.cmdDisband.getUseageTemplate(true)); + pageLines.add(""); + pageLines.add(p.cmdBase.cmdRelationAlly.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdRelationNeutral.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdRelationEnemy.getUseageTemplate(true)); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_RELATIONS_1.toString())); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_RELATIONS_2.toString())); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_RELATIONS_3.toString())); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_RELATIONS_4.toString())); + helpPages.add(pageLines); + + pageLines = new ArrayList(); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_RELATIONS_5.toString())); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_RELATIONS_6.toString())); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_RELATIONS_7.toString())); + pageLines.add(TL.COMMAND_HELP_RELATIONS_8.toString()); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_RELATIONS_9.toString())); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_RELATIONS_10.toString())); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_RELATIONS_11.toString())); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_RELATIONS_12.toString())); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_RELATIONS_13.toString())); + helpPages.add(pageLines); + + pageLines = new ArrayList(); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_PERMISSIONS_1.toString())); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_PERMISSIONS_2.toString())); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_PERMISSIONS_3.toString())); + pageLines.add(TL.COMMAND_HELP_PERMISSIONS_4.toString()); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_PERMISSIONS_5.toString())); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_PERMISSIONS_6.toString())); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_PERMISSIONS_7.toString())); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_PERMISSIONS_8.toString())); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_PERMISSIONS_9.toString())); + helpPages.add(pageLines); + + pageLines = new ArrayList(); + pageLines.add(TL.COMMAND_HELP_MOAR_1.toString()); + pageLines.add(p.cmdBase.cmdBypass.getUseageTemplate(true)); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_ADMIN_1.toString())); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_ADMIN_2.toString())); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_ADMIN_3.toString())); + pageLines.add(p.cmdBase.cmdSafeunclaimall.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdWarunclaimall.getUseageTemplate(true)); + //TODO:TL + pageLines.add(p.txt.parse("Note: " + p.cmdBase.cmdUnclaim.getUseageTemplate(false) + P.p.txt.parse("") + " works on safe/war zones as well.")); + pageLines.add(p.cmdBase.cmdPeaceful.getUseageTemplate(true)); + helpPages.add(pageLines); + + pageLines = new ArrayList(); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_MOAR_2.toString())); + pageLines.add(p.cmdBase.cmdChatSpy.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdPermanent.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdPermanentPower.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdPowerBoost.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdConfig.getUseageTemplate(true)); + helpPages.add(pageLines); + + pageLines = new ArrayList(); + pageLines.add(p.txt.parse(TL.COMMAND_HELP_MOAR_3.toString())); + pageLines.add(p.cmdBase.cmdLock.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdReload.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdSaveAll.getUseageTemplate(true)); + pageLines.add(p.cmdBase.cmdVersion.getUseageTemplate(true)); + helpPages.add(pageLines); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_HELP_DESCRIPTION; + } +} + diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdHome.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdHome.java new file mode 100644 index 0000000..4dfc1af --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdHome.java @@ -0,0 +1,137 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.*; +import com.massivecraft.factions.integration.Essentials; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.struct.Relation; +import com.massivecraft.factions.struct.Role; +import com.massivecraft.factions.util.WarmUpUtil; +import com.massivecraft.factions.zcore.util.SmokeUtil; +import com.massivecraft.factions.zcore.util.TL; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; + + +public class CmdHome extends FCommand { + + public CmdHome() { + super(); + this.aliases.add("home"); + + //this.requiredArgs.add(""); + //this.optionalArgs.put("", ""); + + this.permission = Permission.HOME.node; + this.disableOnLock = false; + + senderMustBePlayer = true; + senderMustBeMember = true; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + // TODO: Hide this command on help also. + if (!Conf.homesEnabled) { + fme.msg(TL.COMMAND_HOME_DISABLED); + return; + } + + if (!Conf.homesTeleportCommandEnabled) { + fme.msg(TL.COMMAND_HOME_TELEPORTDISABLED); + return; + } + + if (!myFaction.hasHome()) { + fme.msg(TL.COMMAND_HOME_NOHOME.toString() + (fme.getRole().value < Role.MODERATOR.value ? TL.GENERIC_ASKYOURLEADER.toString() : TL.GENERIC_YOUSHOULD.toString())); + fme.sendMessage(p.cmdBase.cmdSethome.getUseageTemplate()); + return; + } + + if (!Conf.homesTeleportAllowedFromEnemyTerritory && fme.isInEnemyTerritory()) { + fme.msg(TL.COMMAND_HOME_INENEMY); + return; + } + + if (!Conf.homesTeleportAllowedFromDifferentWorld && me.getWorld().getUID() != myFaction.getHome().getWorld().getUID()) { + fme.msg(TL.COMMAND_HOME_WRONGWORLD); + return; + } + + Faction faction = Board.getInstance().getFactionAt(new FLocation(me.getLocation())); + final Location loc = me.getLocation().clone(); + + // if player is not in a safe zone or their own faction territory, only allow teleport if no enemies are nearby + if (Conf.homesTeleportAllowedEnemyDistance > 0 && + !faction.isSafeZone() && + (!fme.isInOwnTerritory() || (fme.isInOwnTerritory() && !Conf.homesTeleportIgnoreEnemiesIfInOwnTerritory))) { + World w = loc.getWorld(); + double x = loc.getX(); + double y = loc.getY(); + double z = loc.getZ(); + + for (Player p : me.getServer().getOnlinePlayers()) { + if (p == null || !p.isOnline() || p.isDead() || p == me || p.getWorld() != w) { + continue; + } + + FPlayer fp = FPlayers.getInstance().getByPlayer(p); + if (fme.getRelationTo(fp) != Relation.ENEMY || fp.isVanished()) { + continue; + } + + Location l = p.getLocation(); + double dx = Math.abs(x - l.getX()); + double dy = Math.abs(y - l.getY()); + double dz = Math.abs(z - l.getZ()); + double max = Conf.homesTeleportAllowedEnemyDistance; + + // box-shaped distance check + if (dx > max || dy > max || dz > max) { + continue; + } + + fme.msg(TL.COMMAND_HOME_ENEMYNEAR, String.valueOf(Conf.homesTeleportAllowedEnemyDistance)); + return; + } + } + + // if economy is enabled, they're not on the bypass list, and this command has a cost set, make 'em pay + if (!payForCommand(Conf.econCostHome, TL.COMMAND_HOME_TOTELEPORT.toString(), TL.COMMAND_HOME_FORTELEPORT.toString())) { + return; + } + + // if Essentials teleport handling is enabled and available, pass the teleport off to it (for delay and cooldown) + if (Essentials.handleTeleport(me, myFaction.getHome())) { + return; + } + + this.doWarmUp(WarmUpUtil.Warmup.HOME, TL.WARMUPS_NOTIFY_TELEPORT, "Home", new Runnable() { + @Override + public void run() { + // Create a smoke effect + if (Conf.homesTeleportCommandSmokeEffectEnabled) { + List smokeLocations = new ArrayList(); + smokeLocations.add(loc); + smokeLocations.add(loc.add(0, 1, 0)); + smokeLocations.add(CmdHome.this.myFaction.getHome()); + smokeLocations.add(CmdHome.this.myFaction.getHome().clone().add(0, 1, 0)); + SmokeUtil.spawnCloudRandom(smokeLocations, Conf.homesTeleportCommandSmokeEffectThickness); + } + + CmdHome.this.me.teleport(CmdHome.this.myFaction.getHome()); + } + }, this.p.getConfig().getLong("warmups.f-home", 0)); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_HOME_DESCRIPTION; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdInvite.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdInvite.java new file mode 100644 index 0000000..aad855f --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdInvite.java @@ -0,0 +1,80 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.eco.EcoResult; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; +import mkremins.fanciful.FancyMessage; +import net.grandtheftmc.core.util.NumeralUtil; +import org.bukkit.ChatColor; + +import java.util.Locale; + +public class CmdInvite extends FCommand { + + public CmdInvite() { + super(); + this.aliases.add("invite"); + this.aliases.add("inv"); + + this.requiredArgs.add("player name"); + //this.optionalArgs.put("", ""); + + this.permission = Permission.INVITE.node; + this.disableOnLock = true; + + senderMustBePlayer = true; + senderMustBeMember = false; + senderMustBeModerator = true; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + FPlayer you = this.argAsBestFPlayerMatch(0); + if (you == null) { + return; + } + + if (you.getFaction() == myFaction) { + msg(TL.COMMAND_INVITE_ALREADYMEMBER, you.getName(), myFaction.getTag()); + msg(TL.GENERIC_YOUMAYWANT.toString() + p.cmdBase.cmdKick.getUseageTemplate(false)); + return; + } + + // if economy is enabled, they're not on the bypass list, and this command has a cost set, make 'em pay +// if (!payForCommand(Conf.econCostInvite, TL.COMMAND_INVITE_TOINVITE.toString(), TL.COMMAND_INVITE_FORINVITE.toString())) { +// return; +// } + + if(Conf.econCostInvite > 0) { + EcoResult result = myFaction.takeFromStash(Conf.econCostInvite); + if(result == EcoResult.LOW_FUNDS) { + fme.msg("%s can't afford %s %s.", myFaction.describeTo(myFaction, true), NumeralUtil.toCurrency(Conf.econCostInvite, Locale.US), TL.COMMAND_INVITE_TOINVITE); + return; + } + + if(result != EcoResult.SUCCESS) return; + } + + myFaction.invite(you); + if (!you.isOnline()) { + return; + } + + // Tooltips, colors, and commands only apply to the string immediately before it. + FancyMessage message = new FancyMessage(fme.describeTo(you, true)).tooltip(TL.COMMAND_INVITE_CLICKTOJOIN.toString()).command("/" + Conf.baseCommandAliases.get(0) + " join " + myFaction.getTag()).then(TL.COMMAND_INVITE_INVITEDYOU.toString()).color(ChatColor.YELLOW).tooltip(TL.COMMAND_INVITE_CLICKTOJOIN.toString()).command("/" + Conf.baseCommandAliases.get(0) + " join " + myFaction.getTag()).then(myFaction.describeTo(you)).tooltip(TL.COMMAND_INVITE_CLICKTOJOIN.toString()).command("/" + Conf.baseCommandAliases.get(0) + " join " + myFaction.getTag()); + + message.send(you.getPlayer()); + + //you.msg("%s invited you to %s", fme.describeTo(you, true), myFaction.describeTo(you)); + myFaction.msg(TL.COMMAND_INVITE_INVITED, fme.describeTo(myFaction, true), you.describeTo(myFaction)); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_INVITE_DESCRIPTION; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdJoin.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdJoin.java new file mode 100644 index 0000000..3aa0b3b --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdJoin.java @@ -0,0 +1,118 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.*; +import com.massivecraft.factions.event.FPlayerJoinEvent; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; +import org.bukkit.Bukkit; + +public class CmdJoin extends FCommand { + + public CmdJoin() { + super(); + this.aliases.add("join"); + + this.requiredArgs.add("cartel name"); + this.optionalArgs.put("player", "you"); + + this.permission = Permission.JOIN.node; + this.disableOnLock = true; + + senderMustBePlayer = true; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + Faction faction = this.argAsFaction(0); + if (faction == null) { + return; + } + + FPlayer fplayer = this.argAsBestFPlayerMatch(1, fme, false); + boolean samePlayer = fplayer == fme; + + if (!samePlayer && !Permission.JOIN_OTHERS.has(sender, false)) { + msg(TL.COMMAND_JOIN_CANNOTFORCE); + return; + } + + if (!faction.isNormal()) { + msg(TL.COMMAND_JOIN_SYSTEMFACTION); + return; + } + + if (faction == fplayer.getFaction()) { + //TODO:TL + msg(TL.COMMAND_JOIN_ALREADYMEMBER, fplayer.describeTo(fme, true), (samePlayer ? "are" : "is"), faction.getTag(fme)); + return; + } + + if (Conf.factionMemberLimit > 0 && faction.getFPlayers().size() >= Conf.factionMemberLimit) { + msg(TL.COMMAND_JOIN_ATLIMIT, faction.getTag(fme), Conf.factionMemberLimit, fplayer.describeTo(fme, false)); + return; + } + + if (fplayer.hasFaction()) { + //TODO:TL + msg(TL.COMMAND_JOIN_INOTHERFACTION, fplayer.describeTo(fme, true), (samePlayer ? "your" : "their")); + return; + } + + if (!Conf.canLeaveWithNegativePower && fplayer.getPower() < 0) { + msg(TL.COMMAND_JOIN_NEGATIVEPOWER, fplayer.describeTo(fme, true)); + return; + } + + if (!(faction.getOpen() || faction.isInvited(fplayer) || fme.isAdminBypassing() || Permission.JOIN_ANY.has(sender, false))) { + msg(TL.COMMAND_JOIN_REQUIRESINVITATION); + if (samePlayer) { + faction.msg(TL.COMMAND_JOIN_ATTEMPTEDJOIN, fplayer.describeTo(faction, true)); + } + return; + } + + // if economy is enabled, they're not on the bypass list, and this command has a cost set, make sure they can pay + if (samePlayer && !canAffordCommand(Conf.econCostJoin, TL.COMMAND_JOIN_TOJOIN.toString())) { + return; + } + + // trigger the join event (cancellable) + FPlayerJoinEvent joinEvent = new FPlayerJoinEvent(FPlayers.getInstance().getByPlayer(me), faction, FPlayerJoinEvent.PlayerJoinReason.COMMAND); + Bukkit.getServer().getPluginManager().callEvent(joinEvent); + if (joinEvent.isCancelled()) { + return; + } + + // then make 'em pay (if applicable) + if (samePlayer && !payForCommand(Conf.econCostJoin, TL.COMMAND_JOIN_TOJOIN.toString(), TL.COMMAND_JOIN_FORJOIN.toString())) { + return; + } + + fme.msg(TL.COMMAND_JOIN_SUCCESS, fplayer.describeTo(fme, true), faction.getTag(fme)); + + if (!samePlayer) { + fplayer.msg(TL.COMMAND_JOIN_MOVED, fme.describeTo(fplayer, true), faction.getTag(fplayer)); + } + faction.msg(TL.COMMAND_JOIN_JOINED, fplayer.describeTo(faction, true)); + + fplayer.resetFactionData(); + fplayer.setFaction(faction); + faction.deinvite(fplayer); + + if (Conf.logFactionJoin) { + if (samePlayer) { + P.p.log(TL.COMMAND_JOIN_JOINEDLOG.toString(), fplayer.getName(), faction.getTag()); + } else { + P.p.log(TL.COMMAND_JOIN_MOVEDLOG.toString(), fme.getName(), fplayer.getName(), faction.getTag()); + } + } + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_JOIN_DESCRIPTION; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdKick.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdKick.java new file mode 100644 index 0000000..974e688 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdKick.java @@ -0,0 +1,125 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.P; +import com.massivecraft.factions.event.FPlayerLeaveEvent; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.struct.Role; +import com.massivecraft.factions.zcore.util.TL; +import mkremins.fanciful.FancyMessage; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; + +public class CmdKick extends FCommand { + + public CmdKick() { + super(); + this.aliases.add("kick"); + + this.optionalArgs.put("player name", "player name"); + //this.optionalArgs.put("", ""); + + this.permission = Permission.KICK.node; + this.disableOnLock = false; + + senderMustBePlayer = true; + senderMustBeMember = false; + senderMustBeModerator = true; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + FPlayer toKick = this.argIsSet(0) ? this.argAsBestFPlayerMatch(0) : null; + if (toKick == null) { + FancyMessage msg = new FancyMessage(TL.COMMAND_KICK_CANDIDATES.toString()).color(ChatColor.GOLD); + for (FPlayer player : myFaction.getFPlayersWhereRole(Role.NORMAL)) { + String s = player.getName(); + msg.then(s + " ").color(ChatColor.WHITE).tooltip(TL.COMMAND_KICK_CLICKTOKICK.toString() + s).command("/" + Conf.baseCommandAliases.get(0) + " kick " + s); + } + if (fme.getRole() == Role.ADMIN) { + for (FPlayer player : myFaction.getFPlayersWhereRole(Role.MODERATOR)) { + String s = player.getName(); + msg.then(s + " ").color(ChatColor.GRAY).tooltip(TL.COMMAND_KICK_CLICKTOKICK.toString() + s).command("/" + Conf.baseCommandAliases.get(0) + " kick " + s); + } + } + + sendFancyMessage(msg); + return; + } + + if (fme == toKick) { + msg(TL.COMMAND_KICK_SELF); + msg(TL.GENERIC_YOUMAYWANT.toString() + p.cmdBase.cmdLeave.getUseageTemplate(false)); + return; + } + + Faction toKickFaction = toKick.getFaction(); + + if (toKickFaction.isWilderness()) { + sender.sendMessage(TL.COMMAND_KICK_NONE.toString()); + return; + } + + // players with admin-level "disband" permission can bypass these requirements + if (!Permission.KICK_ANY.has(sender)) { + if (toKickFaction != myFaction) { + msg(TL.COMMAND_KICK_NOTMEMBER, toKick.describeTo(fme, true), myFaction.describeTo(fme)); + return; + } + + if (toKick.getRole().value >= fme.getRole().value) { + msg(TL.COMMAND_KICK_INSUFFICIENTRANK); + return; + } + + if (!Conf.canLeaveWithNegativePower && toKick.getPower() < 0) { + msg(TL.COMMAND_KICK_NEGATIVEPOWER); + return; + } + } + + // if economy is enabled, they're not on the bypass list, and this command has a cost set, make sure they can pay + if (!canAffordCommand(Conf.econCostKick, TL.COMMAND_KICK_TOKICK.toString())) { + return; + } + + // trigger the leave event (cancellable) [reason:kicked] + FPlayerLeaveEvent event = new FPlayerLeaveEvent(toKick, toKick.getFaction(), FPlayerLeaveEvent.PlayerLeaveReason.KICKED); + Bukkit.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + return; + } + + // then make 'em pay (if applicable) + if (!payForCommand(Conf.econCostKick, TL.COMMAND_KICK_TOKICK.toString(), TL.COMMAND_KICK_FORKICK.toString())) { + return; + } + + toKickFaction.msg(TL.COMMAND_KICK_FACTION, fme.describeTo(toKickFaction, true), toKick.describeTo(toKickFaction, true)); + toKick.msg(TL.COMMAND_KICK_KICKED, fme.describeTo(toKick, true), toKickFaction.describeTo(toKick)); + if (toKickFaction != myFaction) { + fme.msg(TL.COMMAND_KICK_KICKS, toKick.describeTo(fme), toKickFaction.describeTo(fme)); + } + + if (Conf.logFactionKick) { + //TODO:TL + P.p.log((senderIsConsole ? "A console command" : fme.getName()) + " kicked " + toKick.getName() + " from the cartel: " + toKickFaction.getTag()); + } + + if (toKick.getRole() == Role.ADMIN) { + toKickFaction.promoteNewLeader(); + } + + toKickFaction.deinvite(toKick); + toKick.resetFactionData(); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_KICK_DESCRIPTION; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdLeave.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdLeave.java new file mode 100644 index 0000000..635b1da --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdLeave.java @@ -0,0 +1,34 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; + +public class CmdLeave extends FCommand { + + public CmdLeave() { + super(); + this.aliases.add("leave"); + + //this.requiredArgs.add(""); + //this.optionalArgs.put("", ""); + + this.permission = Permission.LEAVE.node; + this.disableOnLock = true; + + senderMustBePlayer = true; + senderMustBeMember = true; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + fme.leave(true); + } + + @Override + public TL getUsageTranslation() { + return TL.LEAVE_DESCRIPTION; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdList.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdList.java new file mode 100644 index 0000000..319b62e --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdList.java @@ -0,0 +1,131 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.Factions; +import com.massivecraft.factions.P; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; +import com.massivecraft.factions.zcore.util.TagUtil; + +import java.util.*; + + +public class CmdList extends FCommand { + + private String[] defaults = new String[3]; + + public CmdList() { + super(); + this.aliases.add("list"); + this.aliases.add("ls"); + + // default values in case user has old config + defaults[0] = "&e&m----------&r&e[ &2Cartel List &9{pagenumber}&e/&9{pagecount} &e]&m----------"; + defaults[1] = "Cartelless {factionless} online"; + defaults[2] = "{faction} {online} / {members} online, Land / Power / Maxpower: {chunks}/{power}/{maxPower}"; + + //this.requiredArgs.add(""); + this.optionalArgs.put("page", "1"); + + this.permission = Permission.LIST.node; + this.disableOnLock = false; + + senderMustBePlayer = false; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + // if economy is enabled, they're not on the bypass list, and this command has a cost set, make 'em pay + if (!payForCommand(Conf.econCostList, "to list the cartels", "for listing the cartels")) { + return; + } + + ArrayList factionList = Factions.getInstance().getAllFactions(); + factionList.remove(Factions.getInstance().getNone()); + factionList.remove(Factions.getInstance().getSafeZone()); + factionList.remove(Factions.getInstance().getWarZone()); + + // remove exempt factions + if (!fme.getPlayer().hasPermission("factions.show.bypassexempt")) { + List exemptFactions = P.p.getConfig().getStringList("show-exempt"); + Iterator factionIterator = factionList.iterator(); + while (factionIterator.hasNext()) { + Faction next = factionIterator.next(); + if (exemptFactions.contains(next.getTag())) { + factionIterator.remove(); + } + } + } + + // Sort by total followers first + Collections.sort(factionList, new Comparator() { + @Override + public int compare(Faction f1, Faction f2) { + int f1Size = f1.getFPlayers().size(); + int f2Size = f2.getFPlayers().size(); + if (f1Size < f2Size) { + return 1; + } else if (f1Size > f2Size) { + return -1; + } + return 0; + } + }); + + // Then sort by how many members are online now + Collections.sort(factionList, new Comparator() { + @Override + public int compare(Faction f1, Faction f2) { + int f1Size = f1.getFPlayersWhereOnline(true).size(); + int f2Size = f2.getFPlayersWhereOnline(true).size(); + if (f1Size < f2Size) { + return 1; + } else if (f1Size > f2Size) { + return -1; + } + return 0; + } + }); + + ArrayList lines = new ArrayList(); + + factionList.add(0, Factions.getInstance().getNone()); + + final int pageheight = 9; + int pagenumber = this.argAsInt(0, 1); + int pagecount = (factionList.size() / pageheight) + 1; + if (pagenumber > pagecount) { + pagenumber = pagecount; + } else if (pagenumber < 1) { + pagenumber = 1; + } + int start = (pagenumber - 1) * pageheight; + int end = start + pageheight; + if (end > factionList.size()) { + end = factionList.size(); + } + + + String header = p.getConfig().getString("list.header", defaults[0]); + header = header.replace("{pagenumber}", String.valueOf(pagenumber)).replace("{pagecount}", String.valueOf(pagecount)); + lines.add(p.txt.parse(header)); + + for (Faction faction : factionList.subList(start, end)) { + if (faction.isWilderness()) { + lines.add(p.txt.parse(TagUtil.parsePlain(faction, p.getConfig().getString("list.factionless", defaults[1])))); + continue; + } + lines.add(p.txt.parse(TagUtil.parsePlain(faction, fme, p.getConfig().getString("list.entry", defaults[2])))); + } + sendMessage(lines); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_LIST_DESCRIPTION; + } +} \ No newline at end of file diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdLock.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdLock.java new file mode 100644 index 0000000..a3c88af --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdLock.java @@ -0,0 +1,42 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; + +public class CmdLock extends FCommand { + + // TODO: This solution needs refactoring. + /* + factions.lock: + description: use the /f lock [on/off] command to temporarily lock the data files from being overwritten + default: op + */ + + public CmdLock() { + super(); + this.aliases.add("lock"); + + //this.requiredArgs.add(""); + this.optionalArgs.put("on/off", "flip"); + + this.permission = Permission.LOCK.node; + this.disableOnLock = false; + + senderMustBePlayer = false; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + p.setLocked(this.argAsBool(0, !p.getLocked())); + msg(p.getLocked() ? TL.COMMAND_LOCK_LOCKED : TL.COMMAND_LOCK_UNLOCKED); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_LOCK_DESCRIPTION; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdLogins.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdLogins.java new file mode 100644 index 0000000..08900c4 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdLogins.java @@ -0,0 +1,30 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; + +public class CmdLogins extends FCommand { + + public CmdLogins() { + super(); + this.aliases.add("login"); + this.aliases.add("logins"); + this.aliases.add("logout"); + this.aliases.add("logouts"); + this.senderMustBePlayer = true; + this.senderMustBeMember = true; + this.permission = Permission.MONITOR_LOGINS.node; + } + + @Override + public void perform() { + boolean monitor = fme.isMonitoringJoins(); + fme.msg(TL.COMMAND_LOGINS_TOGGLE, String.valueOf(!monitor)); + fme.setMonitorJoins(!monitor); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_LOGINS_DESCRIPTION; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdMap.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdMap.java new file mode 100644 index 0000000..9724cda --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdMap.java @@ -0,0 +1,68 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Board; +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.FLocation; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; + + +public class CmdMap extends FCommand { + + public CmdMap() { + super(); + this.aliases.add("map"); + + //this.requiredArgs.add(""); + this.optionalArgs.put("on/off", "once"); + + this.permission = Permission.MAP.node; + this.disableOnLock = false; + + senderMustBePlayer = true; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + if (this.argIsSet(0)) { + if (this.argAsBool(0, !fme.isMapAutoUpdating())) { + // Turn on + + // if economy is enabled, they're not on the bypass list, and this command has a cost set, make 'em pay + if (!payForCommand(Conf.econCostMap, "to show the map", "for showing the map")) { + return; + } + + fme.setMapAutoUpdating(true); + msg(TL.COMMAND_MAP_UPDATE_ENABLED); + + // And show the map once + showMap(); + } else { + // Turn off + fme.setMapAutoUpdating(false); + msg(TL.COMMAND_MAP_UPDATE_DISABLED); + } + } else { + // if economy is enabled, they're not on the bypass list, and this command has a cost set, make 'em pay + if (!payForCommand(Conf.econCostMap, TL.COMMAND_MAP_TOSHOW, TL.COMMAND_MAP_FORSHOW)) { + return; + } + + showMap(); + } + } + + public void showMap() { + sendMessage(Board.getInstance().getMap(myFaction, new FLocation(fme), fme.getPlayer().getLocation().getYaw())); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_MAP_DESCRIPTION; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdMod.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdMod.java new file mode 100644 index 0000000..2949224 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdMod.java @@ -0,0 +1,92 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.struct.Role; +import com.massivecraft.factions.zcore.util.TL; +import mkremins.fanciful.FancyMessage; +import org.bukkit.ChatColor; + +public class CmdMod extends FCommand { + + public CmdMod() { + super(); + this.aliases.add("underboss"); + this.aliases.add("setunderboss"); + this.aliases.add("ub"); + this.aliases.add("setub"); + this.aliases.add("mod"); + this.aliases.add("setmod"); + this.aliases.add("officer"); + this.aliases.add("setofficer"); + + this.optionalArgs.put("player name", "name"); + //this.optionalArgs.put("", ""); + + this.permission = Permission.MOD.node; + this.disableOnLock = true; + + senderMustBePlayer = false; + senderMustBeMember = true; + senderMustBeModerator = false; + senderMustBeAdmin = true; + } + + @Override + public void perform() { + FPlayer you = this.argAsBestFPlayerMatch(0); + if (you == null) { + FancyMessage msg = new FancyMessage(TL.COMMAND_MOD_CANDIDATES.toString()).color(ChatColor.GOLD); + for (FPlayer player : myFaction.getFPlayersWhereRole(Role.NORMAL)) { + String s = player.getName(); + msg.then(s + " ").color(ChatColor.WHITE).tooltip(TL.COMMAND_MOD_CLICKTOPROMOTE.toString() + s).command("/" + Conf.baseCommandAliases.get(0) + " underboss " + s); + } + + sendFancyMessage(msg); + return; + } + + boolean permAny = Permission.MOD_ANY.has(sender, false); + Faction targetFaction = you.getFaction(); + + if (targetFaction != myFaction && !permAny) { + msg(TL.COMMAND_MOD_NOTMEMBER, you.describeTo(fme, true)); + return; + } + + if (fme != null && fme.getRole() != Role.ADMIN && !permAny) { + msg(TL.COMMAND_MOD_NOTADMIN); + return; + } + + if (you == fme && !permAny) { + msg(TL.COMMAND_MOD_SELF); + return; + } + + if (you.getRole() == Role.ADMIN) { + msg(TL.COMMAND_MOD_TARGETISADMIN); + return; + } + + if (you.getRole() == Role.MODERATOR) { + // Revoke + you.setRole(Role.NORMAL); + targetFaction.msg(TL.COMMAND_MOD_REVOKED, you.describeTo(targetFaction, true)); + msg(TL.COMMAND_MOD_REVOKES, you.describeTo(fme, true)); + } else { + // Give + you.setRole(Role.MODERATOR); + targetFaction.msg(TL.COMMAND_MOD_PROMOTED, you.describeTo(targetFaction, true)); + msg(TL.COMMAND_MOD_PROMOTES, you.describeTo(fme, true)); + } + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_MOD_DESCRIPTION; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdModifyPower.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdModifyPower.java new file mode 100644 index 0000000..7c5f75d --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdModifyPower.java @@ -0,0 +1,49 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; + +public class CmdModifyPower extends FCommand { + + public CmdModifyPower() { + super(); + + this.aliases.add("pm"); + this.aliases.add("mp"); + this.aliases.add("modifypower"); + this.aliases.add("modpower"); + + this.requiredArgs.add("name"); + this.requiredArgs.add("power"); + + this.permission = Permission.MODIFY_POWER.node; // admin only perm. + + // Let's not require anything and let console modify this as well. + this.senderMustBeAdmin = false; + this.senderMustBePlayer = false; + this.senderMustBeMember = false; + this.senderMustBeModerator = false; + } + + @Override + public void perform() { + // /f modify # + FPlayer player = argAsBestFPlayerMatch(0); + Double number = argAsDouble(1); // returns null if not a Double. + + if (player == null || number == null) { + sender.sendMessage(getHelpShort()); + return; + } + + player.alterPower(number); + int newPower = player.getPowerRounded(); // int so we don't have super long doubles. + msg(TL.COMMAND_MODIFYPOWER_ADDED, number, player.getName(), newPower); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_MODIFYPOWER_DESCRIPTION; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdMoney.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdMoney.java new file mode 100644 index 0000000..738540d --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdMoney.java @@ -0,0 +1,53 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.P; +import com.massivecraft.factions.zcore.util.TL; + +public class CmdMoney extends FCommand { + + public CmdMoneyBalance cmdMoneyBalance = new CmdMoneyBalance(); + public CmdMoneyDeposit cmdMoneyDeposit = new CmdMoneyDeposit(); + public CmdMoneyWithdraw cmdMoneyWithdraw = new CmdMoneyWithdraw(); + public CmdMoneyTransferFf cmdMoneyTransferFf = new CmdMoneyTransferFf(); + public CmdMoneyTransferFp cmdMoneyTransferFp = new CmdMoneyTransferFp(); + public CmdMoneyTransferPf cmdMoneyTransferPf = new CmdMoneyTransferPf(); + + public CmdMoney() { + super(); + this.aliases.add("money"); + this.aliases.add("stash"); + this.aliases.add("bal"); + this.aliases.add("balance"); + + //this.requiredArgs.add(""); + //this.optionalArgs.put("","") + + this.isMoneyCommand = true; + + senderMustBePlayer = false; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + + this.helpLong.add(p.txt.parseTags(TL.COMMAND_MONEY_LONG.toString())); + + this.addSubCommand(this.cmdMoneyBalance); + this.addSubCommand(this.cmdMoneyDeposit); + this.addSubCommand(this.cmdMoneyWithdraw); +// this.addSubCommand(this.cmdMoneyTransferFf); +// this.addSubCommand(this.cmdMoneyTransferFp); +// this.addSubCommand(this.cmdMoneyTransferPf); + } + + @Override + public void perform() { + this.commandChain.add(this); + P.p.cmdAutoHelp.execute(this.sender, this.args, this.commandChain); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_MONEY_DESCRIPTION; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdMoneyBalance.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdMoneyBalance.java new file mode 100644 index 0000000..d843411 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdMoneyBalance.java @@ -0,0 +1,55 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.integration.Econ; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.util.MiscUtil; +import com.massivecraft.factions.zcore.util.TL; +import net.grandtheftmc.core.util.C; + +import java.text.NumberFormat; +import java.util.Locale; + +public class CmdMoneyBalance extends FCommand { + + private final Locale locale = Locale.US; + private final NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance(locale); + + public CmdMoneyBalance() { + super(); + this.aliases.add("b"); + this.aliases.add("bal"); + this.aliases.add("balance"); + + //this.requiredArgs.add(""); + this.optionalArgs.put("cartel", "yours"); + + this.permission = Permission.MONEY_BALANCE.node; + this.setHelpShort(TL.COMMAND_MONEYBALANCE_SHORT.toString()); + + senderMustBePlayer = false; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + Faction faction = myFaction; + if (this.argIsSet(0)) { + faction = this.argAsFaction(0); + } + + if (faction == null || !myFaction.isNormal()) return; + if (faction != myFaction && !Permission.MONEY_BALANCE_ANY.has(sender, true)) return; + +// Econ.sendBalanceInfo(fme, faction); + msg(C.GREEN + "%s's balance is %s.", faction.describeTo(fme, true), currencyFormatter.format(faction.getStash())); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_MONEYBALANCE_DESCRIPTION; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdMoneyDeposit.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdMoneyDeposit.java new file mode 100644 index 0000000..f1438a4 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdMoneyDeposit.java @@ -0,0 +1,68 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.P; +import com.massivecraft.factions.eco.EcoResult; +import com.massivecraft.factions.iface.EconomyParticipator; +import com.massivecraft.factions.integration.Econ; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.ViceUser; +import net.grandtheftmc.vice.users.ViceUserManager; +import org.bukkit.ChatColor; + +import java.text.NumberFormat; +import java.util.Locale; + + +public class CmdMoneyDeposit extends FCommand { + + private final Locale locale = Locale.US; + private final NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance(locale); + + public CmdMoneyDeposit() { + super(); + this.aliases.add("d"); + this.aliases.add("deposit"); + + this.requiredArgs.add("amount"); + this.optionalArgs.put("cartel", "yours"); + + this.permission = Permission.MONEY_DEPOSIT.node; + + senderMustBePlayer = true; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + double amount = this.argAsDouble(0, 0d); + Faction faction = this.argAsFaction(1, myFaction); + if (faction == null || !faction.isNormal()) return; + + ViceUser user = Vice.getUserManager().getLoadedUser(fme.getPlayer().getUniqueId()); + if(!user.hasMoney(amount)) { + sender.sendMessage(Utils.f("&cInsufficient funds.")); + return; + } + + EcoResult result = myFaction.addToStash(amount); + if(result != EcoResult.SUCCESS) return; + user.takeMoney(amount); + +// P.p.log(ChatColor.stripColor(P.p.txt.parse(TL.COMMAND_MONEYDEPOSIT_DEPOSITED.toString(), fme.getName(), currencyFormatter.format(amount), faction.describeTo(null)))); + faction.msg(C.GREEN + TL.COMMAND_MONEYDEPOSIT_DEPOSITED.toString(), fme.getName(), currencyFormatter.format(amount), faction.describeTo(null)); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_MONEYDEPOSIT_DESCRIPTION; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdMoneyTransferFf.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdMoneyTransferFf.java new file mode 100644 index 0000000..5f389ef --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdMoneyTransferFf.java @@ -0,0 +1,69 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.P; +import com.massivecraft.factions.eco.EcoResult; +import com.massivecraft.factions.iface.EconomyParticipator; +import com.massivecraft.factions.integration.Econ; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; +import net.grandtheftmc.core.util.Utils; +import org.bukkit.ChatColor; + +import java.text.NumberFormat; +import java.util.Locale; + + +public class CmdMoneyTransferFf extends FCommand { + + private final Locale locale = Locale.US; + private final NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance(locale); + + public CmdMoneyTransferFf() { + this.aliases.add("ff"); + + this.requiredArgs.add("amount"); + this.requiredArgs.add("cartel"); + this.requiredArgs.add("cartel"); + + //this.optionalArgs.put("", ""); + + this.permission = Permission.MONEY_F2F.node; + + senderMustBePlayer = false; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + double amount = this.argAsDouble(0, 0d); + Faction from = this.argAsFaction(1); + if (from == null || !from.isNormal()) return; + if (!from.getFPlayerAdmin().getName().equalsIgnoreCase(fme.getName())) { + sender.sendMessage(Utils.f("&cOnly Cartel Admin(s) can send money!")); + return; + } + + Faction to = this.argAsFaction(2); + if (to == null || !to.isNormal()) return; + if(amount <= 0) return; + + EcoResult result = from.takeFromStash(amount); + if(result != EcoResult.SUCCESS) return; + + result = to.addToStash(amount); + if(result != EcoResult.SUCCESS) return; + +// P.p.log(ChatColor.stripColor(P.p.txt.parse(TL.COMMAND_MONEYTRANSFERFF_TRANSFER.toString(), fme.getName(), currencyFormatter.format(amount), from.describeTo(null), to.describeTo(null)))); + from.msg(TL.COMMAND_MONEYTRANSFERFF_TRANSFER.toString(), fme.getName(), currencyFormatter.format(amount), from.describeTo(null), to.describeTo(null)); + to.msg(TL.COMMAND_MONEYTRANSFERFF_TRANSFER.toString(), fme.getName(), currencyFormatter.format(amount), from.describeTo(null), to.describeTo(null)); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_MONEYTRANSFERFF_DESCRIPTION; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdMoneyTransferFp.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdMoneyTransferFp.java new file mode 100644 index 0000000..4788d2e --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdMoneyTransferFp.java @@ -0,0 +1,69 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.P; +import com.massivecraft.factions.eco.EcoResult; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.ViceUser; +import org.bukkit.ChatColor; + +import java.text.NumberFormat; +import java.util.Locale; + + +public class CmdMoneyTransferFp extends FCommand { + + private final Locale locale = Locale.US; + private final NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance(locale); + + public CmdMoneyTransferFp() { + this.aliases.add("fp"); + + this.requiredArgs.add("amount"); + this.requiredArgs.add("cartel"); + this.requiredArgs.add("player"); + + //this.optionalArgs.put("", ""); + + this.permission = Permission.MONEY_F2P.node; + + senderMustBePlayer = false; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + double amount = this.argAsDouble(0, 0d); + Faction from = this.argAsFaction(1); + if (from == null) return; + if (!from.getFPlayerAdmin().getName().equalsIgnoreCase(fme.getName())) { + sender.sendMessage(Utils.f("&cOnly Cartel Admin(s) can send money!")); + return; + } + + FPlayer to = this.argAsBestFPlayerMatch(2); + if (to == null) return; + if(to.getPlayer() == null) return; + + EcoResult result = from.takeFromStash(amount); + if(result != EcoResult.SUCCESS) return; + + ViceUser user = Vice.getUserManager().getLoadedUser(to.getPlayer().getUniqueId()); + if(user == null) return; + user.addMoney(amount); + +// P.p.log(ChatColor.stripColor(P.p.txt.parse(TL.COMMAND_MONEYTRANSFERFP_TRANSFER.toString(), fme.getName(), currencyFormatter.format(amount), from.describeTo(null), to.describeTo(null)))); + msg(TL.COMMAND_MONEYTRANSFERFP_TRANSFER.toString(), fme.getName(), currencyFormatter.format(amount), from.describeTo(null), to.describeTo(null)); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_MONEYTRANSFERFP_DESCRIPTION; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdMoneyTransferPf.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdMoneyTransferPf.java new file mode 100644 index 0000000..aecd484 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdMoneyTransferPf.java @@ -0,0 +1,72 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.P; +import com.massivecraft.factions.eco.EcoResult; +import com.massivecraft.factions.iface.EconomyParticipator; +import com.massivecraft.factions.integration.Econ; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.ViceUser; +import org.bukkit.ChatColor; + +import java.text.NumberFormat; +import java.util.Locale; + + +public class CmdMoneyTransferPf extends FCommand { + + private final Locale locale = Locale.US; + private final NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance(locale); + + public CmdMoneyTransferPf() { + this.aliases.add("pf"); + + this.requiredArgs.add("amount"); + this.requiredArgs.add("player"); + this.requiredArgs.add("cartel"); + + //this.optionalArgs.put("", ""); + + this.permission = Permission.MONEY_P2F.node; + + senderMustBePlayer = false; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + double amount = this.argAsDouble(0, 0d); + FPlayer from = this.argAsBestFPlayerMatch(1); + if (from == null) return; + if(from.getPlayer() == null) return; + + Faction to = this.argAsFaction(2); + if (to == null) return; + + ViceUser user = Vice.getUserManager().getLoadedUser(from.getPlayer().getUniqueId()); + if(user == null) return; + if(!user.hasMoney(amount)) { + sender.sendMessage(Utils.f("&cInsufficient funds.")); + return; + } + + if(to.addToStash(amount) != EcoResult.SUCCESS) return; + user.takeMoney(amount); + + P.p.log(ChatColor.stripColor(P.p.txt.parse(TL.COMMAND_MONEYTRANSFERPF_TRANSFER.toString(), fme.getName(), currencyFormatter.format(amount), from.describeTo(null), to.describeTo(null)))); + msg(TL.COMMAND_MONEYTRANSFERPF_TRANSFER.toString(), fme.getName(), currencyFormatter.format(amount), from.describeTo(null), to.describeTo(null)); + + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_MONEYTRANSFERPF_DESCRIPTION; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdMoneyWithdraw.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdMoneyWithdraw.java new file mode 100644 index 0000000..dcfa070 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdMoneyWithdraw.java @@ -0,0 +1,66 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.P; +import com.massivecraft.factions.eco.EcoResult; +import com.massivecraft.factions.iface.EconomyParticipator; +import com.massivecraft.factions.integration.Econ; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.ViceUser; +import org.bukkit.ChatColor; + +import java.text.NumberFormat; +import java.util.Locale; + + +public class CmdMoneyWithdraw extends FCommand { + + private final Locale locale = Locale.US; + private final NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance(locale); + + public CmdMoneyWithdraw() { + this.aliases.add("w"); + this.aliases.add("wdraw"); + this.aliases.add("withdraw"); + + this.requiredArgs.add("amount"); + this.optionalArgs.put("cartel", "yours"); + + this.permission = Permission.MONEY_WITHDRAW.node; + + senderMustBePlayer = true; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + double amount = this.argAsDouble(0, 0d); + Faction faction = this.argAsFaction(1, myFaction); + if (faction == null || !faction.isNormal()) return; + if (!myFaction.getFPlayerAdmin().getName().equals(sender.getName())) { + sender.sendMessage(Utils.f("&cOnly Cartel Admin(s) can withdraw!")); + return; + } + + EcoResult result = myFaction.takeFromStash(amount); + if(result != EcoResult.SUCCESS) return; + + ViceUser user = Vice.getUserManager().getLoadedUser(fme.getPlayer().getUniqueId()); + user.addMoney(amount); + +// P.p.log(ChatColor.stripColor(P.p.txt.parse(TL.COMMAND_MONEYWITHDRAW_WITHDRAW.toString(), fme.getName(), currencyFormatter.format(amount), faction.describeTo(null)))); + myFaction.msg(C.GREEN + TL.COMMAND_MONEYWITHDRAW_WITHDRAW.toString(), fme.getName(), currencyFormatter.format(amount), faction.describeTo(null)); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_MONEYWITHDRAW_DESCRIPTION; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdOpen.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdOpen.java new file mode 100644 index 0000000..5f6239a --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdOpen.java @@ -0,0 +1,53 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.FPlayers; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; + +public class CmdOpen extends FCommand { + + public CmdOpen() { + super(); + this.aliases.add("open"); + + //this.requiredArgs.add(""); + this.optionalArgs.put("yes/no", "flip"); + + this.permission = Permission.OPEN.node; + this.disableOnLock = false; + + senderMustBePlayer = true; + senderMustBeMember = false; + senderMustBeModerator = true; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + // if economy is enabled, they're not on the bypass list, and this command has a cost set, make 'em pay + if (!payForCommand(Conf.econCostOpen, TL.COMMAND_OPEN_TOOPEN, TL.COMMAND_OPEN_FOROPEN)) { + return; + } + + myFaction.setOpen(this.argAsBool(0, !myFaction.getOpen())); + + String open = myFaction.getOpen() ? TL.COMMAND_OPEN_OPEN.toString() : TL.COMMAND_OPEN_CLOSED.toString(); + + // Inform + for (FPlayer fplayer : FPlayers.getInstance().getOnlinePlayers()) { + if (fplayer.getFactionId().equals(myFaction.getId())) { + fplayer.msg(TL.COMMAND_OPEN_CHANGES, fme.getName(), open); + continue; + } + fplayer.msg(TL.COMMAND_OPEN_CHANGED, myFaction.getTag(fplayer.getFaction()), open); + } + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_OPEN_DESCRIPTION; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdOwner.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdOwner.java new file mode 100644 index 0000000..f4710c1 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdOwner.java @@ -0,0 +1,106 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.*; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.struct.Role; +import com.massivecraft.factions.zcore.util.TL; + + +public class CmdOwner extends FCommand { + + public CmdOwner() { + super(); + this.aliases.add("owner"); + + //this.requiredArgs.add(""); + this.optionalArgs.put("player name", "you"); + + this.permission = Permission.OWNER.node; + this.disableOnLock = true; + + senderMustBePlayer = true; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + // TODO: Fix colors! + + @Override + public void perform() { + boolean hasBypass = fme.isAdminBypassing(); + + if (!hasBypass && !assertHasFaction()) { + return; + } + + if (!Conf.ownedAreasEnabled) { + fme.msg(TL.COMMAND_OWNER_DISABLED); + return; + } + + if (!hasBypass && Conf.ownedAreasLimitPerFaction > 0 && myFaction.getCountOfClaimsWithOwners() >= Conf.ownedAreasLimitPerFaction) { + fme.msg(TL.COMMAND_OWNER_LIMIT, Conf.ownedAreasLimitPerFaction); + return; + } + + if (!hasBypass && !assertMinRole(Conf.ownedAreasModeratorsCanSet ? Role.MODERATOR : Role.ADMIN)) { + return; + } + + FLocation flocation = new FLocation(fme); + + Faction factionHere = Board.getInstance().getFactionAt(flocation); + if (factionHere != myFaction) { + if (!factionHere.isNormal()) { + fme.msg(TL.COMMAND_OWNER_NOTCLAIMED); + return; + } + + if (!hasBypass) { + fme.msg(TL.COMMAND_OWNER_WRONGFACTION); + return; + } + + } + + FPlayer target = this.argAsBestFPlayerMatch(0, fme); + if (target == null) { + return; + } + + String playerName = target.getName(); + + if (target.getFaction() != myFaction) { + fme.msg(TL.COMMAND_OWNER_NOTMEMBER, playerName); + return; + } + + // if no player name was passed, and this claim does already have owners set, clear them + if (args.isEmpty() && myFaction.doesLocationHaveOwnersSet(flocation)) { + myFaction.clearClaimOwnership(flocation); + fme.msg(TL.COMMAND_OWNER_CLEARED); + return; + } + + if (myFaction.isPlayerInOwnerList(target, flocation)) { + myFaction.removePlayerAsOwner(target, flocation); + fme.msg(TL.COMMAND_OWNER_REMOVED, playerName); + return; + } + + // if economy is enabled, they're not on the bypass list, and this command has a cost set, make 'em pay + if (!payForCommand(Conf.econCostOwner, TL.COMMAND_OWNER_TOSET, TL.COMMAND_OWNER_FORSET)) { + return; + } + + myFaction.setPlayerAsOwner(target, flocation); + + fme.msg(TL.COMMAND_OWNER_ADDED, playerName); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_OWNER_DESCRIPTION; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdOwnerList.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdOwnerList.java new file mode 100644 index 0000000..ccf737f --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdOwnerList.java @@ -0,0 +1,70 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Board; +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.FLocation; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; + + +public class CmdOwnerList extends FCommand { + + public CmdOwnerList() { + super(); + this.aliases.add("ownerlist"); + + //this.requiredArgs.add(""); + //this.optionalArgs.put("", ""); + + this.permission = Permission.OWNERLIST.node; + this.disableOnLock = false; + + senderMustBePlayer = true; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + boolean hasBypass = fme.isAdminBypassing(); + + if (!hasBypass && !assertHasFaction()) { + return; + } + + if (!Conf.ownedAreasEnabled) { + fme.msg(TL.COMMAND_OWNERLIST_DISABLED); + return; + } + + FLocation flocation = new FLocation(fme); + + if (Board.getInstance().getFactionAt(flocation) != myFaction) { + if (!hasBypass) { + fme.msg(TL.COMMAND_OWNERLIST_WRONGFACTION); + return; + } + //TODO: This code won't ever be called. + myFaction = Board.getInstance().getFactionAt(flocation); + if (!myFaction.isNormal()) { + fme.msg(TL.COMMAND_OWNERLIST_NOTCLAIMED); + return; + } + } + + String owners = myFaction.getOwnerListString(flocation); + + if (owners == null || owners.isEmpty()) { + fme.msg(TL.COMMAND_OWNERLIST_NONE); + return; + } + + fme.msg(TL.COMMAND_OWNERLIST_OWNERS, owners); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_OWNERLIST_DESCRIPTION; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdPeaceful.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdPeaceful.java new file mode 100644 index 0000000..9830fcb --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdPeaceful.java @@ -0,0 +1,60 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.FPlayers; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; + +public class CmdPeaceful extends FCommand { + + public CmdPeaceful() { + super(); + this.aliases.add("peaceful"); + + this.requiredArgs.add("cartel tag"); + //this.optionalArgs.put("", ""); + + this.permission = Permission.SET_PEACEFUL.node; + this.disableOnLock = true; + + senderMustBePlayer = false; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + Faction faction = this.argAsFaction(0); + if (faction == null) { + return; + } + + String change; + if (faction.isPeaceful()) { + change = TL.COMMAND_PEACEFUL_REVOKE.toString(); + faction.setPeaceful(false); + } else { + change = TL.COMMAND_PEACEFUL_GRANT.toString(); + faction.setPeaceful(true); + } + + // Inform all players + for (FPlayer fplayer : FPlayers.getInstance().getOnlinePlayers()) { + String blame = (fme == null ? TL.GENERIC_SERVERADMIN.toString() : fme.describeTo(fplayer, true)); + if (fplayer.getFaction() == faction) { + fplayer.msg(TL.COMMAND_PEACEFUL_YOURS, blame, change); + } else { + fplayer.msg(TL.COMMAND_PEACEFUL_OTHER, blame, change, faction.getTag(fplayer)); + } + } + + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_PEACEFUL_DESCRIPTION; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdPermanent.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdPermanent.java new file mode 100644 index 0000000..dbc89da --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdPermanent.java @@ -0,0 +1,62 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.FPlayers; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.P; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; + + +public class CmdPermanent extends FCommand { + + public CmdPermanent() { + super(); + this.aliases.add("permanent"); + + this.requiredArgs.add("cartel tag"); + //this.optionalArgs.put("", ""); + + this.permission = Permission.SET_PERMANENT.node; + this.disableOnLock = true; + + senderMustBePlayer = false; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + Faction faction = this.argAsFaction(0); + if (faction == null) { + return; + } + + String change; + if (faction.isPermanent()) { + change = TL.COMMAND_PERMANENT_REVOKE.toString(); + faction.setPermanent(false); + } else { + change = TL.COMMAND_PERMANENT_GRANT.toString(); + faction.setPermanent(true); + } + + P.p.log((fme == null ? "A server admin" : fme.getName()) + " " + change + " the cartel \"" + faction.getTag() + "\"."); + + // Inform all players + for (FPlayer fplayer : FPlayers.getInstance().getOnlinePlayers()) { + String blame = (fme == null ? TL.GENERIC_SERVERADMIN.toString() : fme.describeTo(fplayer, true)); + if (fplayer.getFaction() == faction) { + fplayer.msg(TL.COMMAND_PERMANENT_YOURS, blame, change); + } else { + fplayer.msg(TL.COMMAND_PERMANENT_OTHER, blame, change, faction.getTag(fplayer)); + } + } + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_PERMANENT_DESCRIPTION; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdPermanentPower.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdPermanentPower.java new file mode 100644 index 0000000..8038826 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdPermanentPower.java @@ -0,0 +1,58 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; + +public class CmdPermanentPower extends FCommand { + public CmdPermanentPower() { + super(); + this.aliases.add("permanentpower"); + + this.requiredArgs.add("cartel"); + this.optionalArgs.put("power", "reset"); + + this.permission = Permission.SET_PERMANENTPOWER.node; + this.disableOnLock = true; + + senderMustBePlayer = false; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + Faction targetFaction = this.argAsFaction(0); + if (targetFaction == null) { + return; + } + + Integer targetPower = this.argAsInt(1); + + targetFaction.setPermanentPower(targetPower); + + String change = TL.COMMAND_PERMANENTPOWER_REVOKE.toString(); + if (targetFaction.hasPermanentPower()) { + change = TL.COMMAND_PERMANENTPOWER_GRANT.toString(); + } + + // Inform sender + msg(TL.COMMAND_PERMANENTPOWER_SUCCESS, change, targetFaction.describeTo(fme)); + + // Inform all other players + for (FPlayer fplayer : targetFaction.getFPlayersWhereOnline(true)) { + if (fplayer == fme) { + continue; + } + String blame = (fme == null ? TL.GENERIC_SERVERADMIN.toString() : fme.describeTo(fplayer, true)); + fplayer.msg(TL.COMMAND_PERMANENTPOWER_FACTION, blame, change); + } + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_PERMANENTPOWER_DESCRIPTION; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdPower.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdPower.java new file mode 100644 index 0000000..f8061d6 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdPower.java @@ -0,0 +1,53 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; + +public class CmdPower extends FCommand { + + public CmdPower() { + super(); + this.aliases.add("power"); + this.aliases.add("pow"); + + //this.requiredArgs.add("faction tag"); + this.optionalArgs.put("player name", "you"); + + this.permission = Permission.POWER.node; + this.disableOnLock = false; + + senderMustBePlayer = false; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + FPlayer target = this.argAsBestFPlayerMatch(0, fme); + if (target == null) { + return; + } + + if (target != fme && !Permission.POWER_ANY.has(sender, true)) { + return; + } + + // if economy is enabled, they're not on the bypass list, and this command has a cost set, make 'em pay + if (!payForCommand(Conf.econCostPower, TL.COMMAND_POWER_TOSHOW, TL.COMMAND_POWER_FORSHOW)) { + return; + } + + double powerBoost = target.getPowerBoost(); + String boost = (powerBoost == 0.0) ? "" : (powerBoost > 0.0 ? TL.COMMAND_POWER_BONUS.toString() : TL.COMMAND_POWER_PENALTY.toString()) + powerBoost + ")"; + msg(TL.COMMAND_POWER_POWER, target.describeTo(fme, true), target.getPowerRounded(), target.getPowerMaxRounded(), boost); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_POWER_DESCRIPTION; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdPowerBoost.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdPowerBoost.java new file mode 100644 index 0000000..8638eba --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdPowerBoost.java @@ -0,0 +1,87 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.P; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; + +public class CmdPowerBoost extends FCommand { + + public CmdPowerBoost() { + super(); + this.aliases.add("powerboost"); + + this.requiredArgs.add("p|c|player|cartel"); + this.requiredArgs.add("name"); + this.requiredArgs.add("# or reset"); + + this.permission = Permission.POWERBOOST.node; + this.disableOnLock = true; + + senderMustBePlayer = false; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + String type = this.argAsString(0).toLowerCase(); + boolean doPlayer = true; + if (type.equals("c") || type.equals("cartel")) { + doPlayer = false; + } else if (!type.equals("p") && !type.equals("player")) { + msg(TL.COMMAND_POWERBOOST_HELP_1); + msg(TL.COMMAND_POWERBOOST_HELP_2); + return; + } + + Double targetPower = this.argAsDouble(2); + if (targetPower == null) { + if (this.argAsString(2).equalsIgnoreCase("reset")) { + targetPower = 0D; + } else { + msg(TL.COMMAND_POWERBOOST_INVALIDNUM); + return; + } + } + + String target; + + if (doPlayer) { + FPlayer targetPlayer = this.argAsBestFPlayerMatch(1); + if (targetPlayer == null) { + return; + } + + if (targetPower != 0) { + targetPower += targetPlayer.getPowerBoost(); + } + targetPlayer.setPowerBoost(targetPower); + target = TL.COMMAND_POWERBOOST_PLAYER.format(targetPlayer.getName()); + } else { + Faction targetFaction = this.argAsFaction(1); + if (targetFaction == null) { + return; + } + + if (targetPower != 0) { + targetPower += targetFaction.getPowerBoost(); + } + targetFaction.setPowerBoost(targetPower); + target = TL.COMMAND_POWERBOOST_FACTION.format(targetFaction.getTag()); + } + + int roundedPower = (int) Math.round(targetPower); + msg(TL.COMMAND_POWERBOOST_BOOST, target, roundedPower); + if (!senderIsConsole) { + P.p.log(TL.COMMAND_POWERBOOST_BOOSTLOG.toString(), fme.getName(), target, roundedPower); + } + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_POWERBOOST_DESCRIPTION; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdRelationAlly.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdRelationAlly.java new file mode 100644 index 0000000..2520994 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdRelationAlly.java @@ -0,0 +1,11 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.struct.Relation; + +public class CmdRelationAlly extends FRelationCommand { + + public CmdRelationAlly() { + aliases.add("ally"); + targetRelation = Relation.ALLY; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdRelationEnemy.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdRelationEnemy.java new file mode 100644 index 0000000..720f0ef --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdRelationEnemy.java @@ -0,0 +1,11 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.struct.Relation; + +public class CmdRelationEnemy extends FRelationCommand { + + public CmdRelationEnemy() { + aliases.add("enemy"); + targetRelation = Relation.ENEMY; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdRelationNeutral.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdRelationNeutral.java new file mode 100644 index 0000000..4dba5c0 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdRelationNeutral.java @@ -0,0 +1,11 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.struct.Relation; + +public class CmdRelationNeutral extends FRelationCommand { + + public CmdRelationNeutral() { + aliases.add("neutral"); + targetRelation = Relation.NEUTRAL; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdReload.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdReload.java new file mode 100644 index 0000000..9a5198d --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdReload.java @@ -0,0 +1,41 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.P; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; + +public class CmdReload extends FCommand { + + public CmdReload() { + super(); + this.aliases.add("reload"); + + //this.requiredArgs.add(""); + this.optionalArgs.put("file", "all"); + + this.permission = Permission.RELOAD.node; + this.disableOnLock = false; + + senderMustBePlayer = false; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + long timeInitStart = System.currentTimeMillis(); + Conf.load(); + P.p.reloadConfig(); + P.p.loadLang(); + long timeReload = (System.currentTimeMillis() - timeInitStart); + + msg(TL.COMMAND_RELOAD_TIME, timeReload); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_RELOAD_DESCRIPTION; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdSB.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdSB.java new file mode 100644 index 0000000..e0f18a3 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdSB.java @@ -0,0 +1,33 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.scoreboards.FScoreboard; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; + +public class CmdSB extends FCommand { + + public CmdSB() { + this.aliases.add("sb"); + this.aliases.add("scoreboard"); + this.permission = Permission.SCOREBOARD.node; + this.senderMustBePlayer = true; + } + + @Override + public void perform() { + boolean toggleTo = !fme.showScoreboard(); + FScoreboard board = FScoreboard.get(fme); + if (board == null) { + me.sendMessage(TL.COMMAND_TOGGLESB_DISABLED.toString()); + } else { + me.sendMessage(TL.TOGGLE_SB.toString().replace("{value}", String.valueOf(toggleTo))); + board.setSidebarVisibility(toggleTo); + } + fme.setShowScoreboard(toggleTo); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_SCOREBOARD_DESCRIPTION; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdSafeunclaimall.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdSafeunclaimall.java new file mode 100644 index 0000000..21bf11f --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdSafeunclaimall.java @@ -0,0 +1,44 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Board; +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.Factions; +import com.massivecraft.factions.P; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; + +public class CmdSafeunclaimall extends FCommand { + + public CmdSafeunclaimall() { + this.aliases.add("safeunclaimall"); + this.aliases.add("safedeclaimall"); + + //this.requiredArgs.add(""); + //this.optionalArgs.put("radius", "0"); + + this.permission = Permission.MANAGE_SAFE_ZONE.node; + this.disableOnLock = true; + + senderMustBePlayer = false; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + + } + + @Override + public void perform() { + Board.getInstance().unclaimAll(Factions.getInstance().getSafeZone().getId()); + msg(TL.COMMAND_SAFEUNCLAIMALL_UNCLAIMED); + + if (Conf.logLandUnclaims) { + P.p.log(TL.COMMAND_SAFEUNCLAIMALL_UNCLAIMEDLOG.format(sender.getName())); + } + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_SAFEUNCLAIMALL_DESCRIPTION; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdSaveAll.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdSaveAll.java new file mode 100644 index 0000000..2a5f568 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdSaveAll.java @@ -0,0 +1,43 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Board; +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.FPlayers; +import com.massivecraft.factions.Factions; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; + +public class CmdSaveAll extends FCommand { + + public CmdSaveAll() { + super(); + this.aliases.add("saveall"); + this.aliases.add("save"); + + //this.requiredArgs.add(""); + //this.optionalArgs.put("", ""); + + this.permission = Permission.SAVE.node; + this.disableOnLock = false; + + senderMustBePlayer = false; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + FPlayers.getInstance().forceSave(false); + Factions.getInstance().forceSave(false); + Board.getInstance().forceSave(false); + Conf.save(); + msg(TL.COMMAND_SAVEALL_SUCCESS); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_SAVEALL_DESCRIPTION; + } + +} \ No newline at end of file diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdSeeChunk.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdSeeChunk.java new file mode 100644 index 0000000..d9284c7 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdSeeChunk.java @@ -0,0 +1,71 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.FLocation; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.util.VisualizeUtil; +import com.massivecraft.factions.zcore.util.TL; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.entity.Player; + +public class CmdSeeChunk extends FCommand { + + public CmdSeeChunk() { + super(); + aliases.add("seechunk"); + aliases.add("sc"); + + permission = Permission.SEECHUNK.node; + + senderMustBePlayer = true; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + World world = me.getWorld(); + FLocation flocation = new FLocation(me); + int chunkX = (int) flocation.getX(); + int chunkZ = (int) flocation.getZ(); + + int blockX; + int blockZ; + + blockX = chunkX * 16; + blockZ = chunkZ * 16; + showPillar(me, world, blockX, blockZ); + + blockX = chunkX * 16 + 15; + blockZ = chunkZ * 16; + showPillar(me, world, blockX, blockZ); + + blockX = chunkX * 16; + blockZ = chunkZ * 16 + 15; + showPillar(me, world, blockX, blockZ); + + blockX = chunkX * 16 + 15; + blockZ = chunkZ * 16 + 15; + showPillar(me, world, blockX, blockZ); + } + + @SuppressWarnings("deprecation") + public static void showPillar(Player player, World world, int blockX, int blockZ) { + for (int blockY = 0; blockY < player.getLocation().getBlockY() + 30; blockY++) { + Location loc = new Location(world, blockX, blockY, blockZ); + if (loc.getBlock().getType() != Material.AIR) { + continue; + } + int typeId = blockY % 5 == 0 ? Material.REDSTONE_LAMP_ON.getId() : Material.STAINED_GLASS.getId(); + VisualizeUtil.addLocation(player, loc, typeId); + } + } + + @Override + public TL getUsageTranslation() { + return TL.GENERIC_PLACEHOLDER; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdSetFWarp.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdSetFWarp.java new file mode 100644 index 0000000..630540c --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdSetFWarp.java @@ -0,0 +1,54 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.P; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.struct.Relation; +import com.massivecraft.factions.util.LazyLocation; +import com.massivecraft.factions.zcore.util.TL; + +public class CmdSetFWarp extends FCommand { + + public CmdSetFWarp() { + super(); + this.aliases.add("setwarp"); + this.aliases.add("sw"); + this.requiredArgs.add("warp name"); + this.senderMustBeMember = true; + this.senderMustBeModerator = true; + this.senderMustBePlayer = true; + this.permission = Permission.SETWARP.node; + } + + @Override + public void perform() { + if (!(fme.getRelationToLocation() == Relation.MEMBER)) { + fme.msg(TL.COMMAND_SETFWARP_NOTCLAIMED); + return; + } + + int maxWarps = P.p.getConfig().getInt("max-warps", 5); + if (maxWarps <= myFaction.getWarps().size()) { + fme.msg(TL.COMMAND_SETFWARP_LIMIT, maxWarps); + return; + } + + if (!transact(fme)) { + return; + } + + String warp = argAsString(0); + LazyLocation loc = new LazyLocation(fme.getPlayer().getLocation()); + myFaction.setWarp(warp, loc); + fme.msg(TL.COMMAND_SETFWARP_SET, warp); + } + + private boolean transact(FPlayer player) { + return !P.p.getConfig().getBoolean("warp-cost.enabled", false) || player.isAdminBypassing() || payForCommand(P.p.getConfig().getDouble("warp-cost.setwarp", 5), TL.COMMAND_SETFWARP_TOSET.toString(), TL.COMMAND_SETFWARP_FORSET.toString()); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_SETFWARP_DESCRIPTION; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdSethome.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdSethome.java new file mode 100644 index 0000000..365fe5f --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdSethome.java @@ -0,0 +1,96 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Board; +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.FLocation; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.eco.EcoResult; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.struct.Role; +import com.massivecraft.factions.zcore.util.TL; +import net.grandtheftmc.core.util.NumeralUtil; + +import java.util.Locale; + +public class CmdSethome extends FCommand { + + public CmdSethome() { + this.aliases.add("sethome"); + + //this.requiredArgs.add(""); + this.optionalArgs.put("cartel tag", "mine"); + + this.permission = Permission.SETHOME.node; + this.disableOnLock = true; + + senderMustBePlayer = true; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + if (!Conf.homesEnabled) { + fme.msg(TL.COMMAND_SETHOME_DISABLED); + return; + } + + Faction faction = this.argAsFaction(0, myFaction); + if (faction == null) { + return; + } + + if (me.getWorld().getName().equals("spawn")) { + return; + } + + // Can the player set the home for this faction? + if (faction == myFaction) { + if (!Permission.SETHOME_ANY.has(sender) && !assertMinRole(Role.MODERATOR)) { + return; + } + } else { + if (!Permission.SETHOME_ANY.has(sender, true)) { + return; + } + } + + // Can the player set the faction home HERE? + if (!Permission.BYPASS.has(me) && + Conf.homesMustBeInClaimedTerritory && + Board.getInstance().getFactionAt(new FLocation(me)) != faction) { + fme.msg(TL.COMMAND_SETHOME_NOTCLAIMED); + return; + } + + // if economy is enabled, they're not on the bypass list, and this command has a cost set, make 'em pay +// if (!payForCommand(Conf.econCostSethome, TL.COMMAND_SETHOME_TOSET, TL.COMMAND_SETHOME_FORSET)) { +// return;//msg("%s can't afford %s %s.", You, moneyString(-delta), toDoThis) +// } + + if(Conf.econCostSethome > 0) { + EcoResult result = faction.takeFromStash(Conf.econCostSethome); + if(result == EcoResult.LOW_FUNDS) { + fme.msg("%s can't afford %s %s.", faction.describeTo(faction, true), NumeralUtil.toCurrency(Conf.econCostSethome, Locale.US), TL.COMMAND_SETHOME_TOSET); + return; + } + + if(result != EcoResult.SUCCESS) return; + } + + faction.setHome(me.getLocation()); + + faction.msg(TL.COMMAND_SETHOME_SET, fme.describeTo(myFaction, true)); + faction.sendMessage(p.cmdBase.cmdHome.getUseageTemplate()); + if (faction != myFaction) { + fme.msg(TL.COMMAND_SETHOME_SETOTHER, faction.getTag(fme)); + } + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_SETHOME_DESCRIPTION; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdShow.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdShow.java new file mode 100644 index 0000000..963bf4f --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdShow.java @@ -0,0 +1,115 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.P; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; +import com.massivecraft.factions.zcore.util.TagReplacer; +import com.massivecraft.factions.zcore.util.TagUtil; +import mkremins.fanciful.FancyMessage; + +import java.util.ArrayList; +import java.util.List; + +public class CmdShow extends FCommand { + + List defaults = new ArrayList(); + + public CmdShow() { + this.aliases.add("show"); + this.aliases.add("who"); + + // add defaults to /f show in case config doesnt have it + defaults.add("{header}"); + defaults.add("Description: {description}"); + defaults.add("Joining: {joining} {peaceful}"); + defaults.add("Land / Power / Maxpower: {chunks} / {power} / {maxPower}"); + defaults.add("Founded: {create-date}"); + defaults.add("This cartel is permanent, remaining even with no members."); + defaults.add("Land value: {land-value} {land-refund}"); + defaults.add("Stash: {stash}"); + defaults.add("Allies({allies}/{max-allies}): {allies-list}"); + defaults.add("Online: ({online}/{members}): {online-list}"); + defaults.add("Offline: ({offline}/{members}): {offline-list}"); + + // this.requiredArgs.add(""); + this.optionalArgs.put("cartel tag", "yours"); + + this.permission = Permission.SHOW.node; + this.disableOnLock = false; + + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + Faction faction = myFaction; + if (this.argIsSet(0)) { + faction = this.argAsFaction(0); + } + if (faction == null) { + return; + } + + if (!fme.getPlayer().hasPermission("factions.show.bypassexempt") + && P.p.getConfig().getStringList("show-exempt").contains(faction.getTag())) { + msg(TL.COMMAND_SHOW_EXEMPT); + return; + } + + // if economy is enabled, they're not on the bypass list, and this command has a cost set, make 'em pay + if (!payForCommand(Conf.econCostShow, TL.COMMAND_SHOW_TOSHOW, TL.COMMAND_SHOW_FORSHOW)) { + return; + } + + List show = defaults; +// if (show == null || show.isEmpty()) { +// show = defaults; +// } + + if (!faction.isNormal()) { + String tag = faction.getTag(fme); + // send header and that's all + String header = show.get(0); + if (TagReplacer.HEADER.contains(header)) { + msg(p.txt.titleize(tag)); + } else { + msg(p.txt.parse(TagReplacer.FACTION.replace(header, tag))); + } + return; // we only show header for non-normal factions + } + + for (String raw : show) { + String parsed = TagUtil.parsePlain(faction, fme, raw); // use relations + if (parsed == null) { + continue; // Due to minimal f show. + } + if (TagUtil.hasFancy(parsed)) { + List fancy = TagUtil.parseFancy(faction, fme, parsed); + if (fancy != null) { + sendFancyMessage(fancy); + } + continue; + } + if (!parsed.contains("{notFrozen}") && !parsed.contains("{notPermanent}")) { + if (parsed.contains("{ig}")) { + // replaces all variables with no home TL + parsed = parsed.substring(0, parsed.indexOf("{ig}")) + TL.COMMAND_SHOW_NOHOME.toString(); + } + if (parsed.contains("%")) { + parsed = parsed.replaceAll("%", ""); // Just in case it got in there before we disallowed it. + } + msg(p.txt.parse(parsed)); + } + } + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_SHOW_COMMANDDESCRIPTION; + } + +} \ No newline at end of file diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdShowInvites.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdShowInvites.java new file mode 100644 index 0000000..3f8ab4e --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdShowInvites.java @@ -0,0 +1,40 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.FPlayers; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; +import mkremins.fanciful.FancyMessage; +import org.bukkit.ChatColor; + +public class CmdShowInvites extends FCommand { + + public CmdShowInvites() { + super(); + aliases.add("showinvites"); + permission = Permission.SHOW_INVITES.node; + + senderMustBePlayer = true; + senderMustBeMember = true; + } + + @Override + public void perform() { + FancyMessage msg = new FancyMessage(TL.COMMAND_SHOWINVITES_PENDING.toString()).color(ChatColor.GOLD); + for (String id : myFaction.getInvites()) { + FPlayer fp = FPlayers.getInstance().getById(id); + String name = fp != null ? fp.getName() : id; + msg.then(name + " ").color(ChatColor.WHITE).tooltip(TL.COMMAND_SHOWINVITES_CLICKTOREVOKE.format(name)).command("/" + Conf.baseCommandAliases.get(0) + " deinvite " + name); + } + + sendFancyMessage(msg); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_SHOWINVITES_DESCRIPTION; + } + + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdStatus.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdStatus.java new file mode 100644 index 0000000..7caea96 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdStatus.java @@ -0,0 +1,43 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; +import org.apache.commons.lang.time.DurationFormatUtils; +import org.bukkit.ChatColor; + +import java.util.ArrayList; + +public class CmdStatus extends FCommand { + + public CmdStatus() { + super(); + this.aliases.add("status"); + this.aliases.add("s"); + + this.permission = Permission.STATUS.node; + + senderMustBePlayer = true; + senderMustBeMember = true; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + ArrayList ret = new ArrayList(); + for (FPlayer fp : myFaction.getFPlayers()) { + String humanized = DurationFormatUtils.formatDurationWords(System.currentTimeMillis() - fp.getLastLoginTime(), true, true) + TL.COMMAND_STATUS_AGOSUFFIX; + String last = fp.isOnline() ? ChatColor.GREEN + TL.COMMAND_STATUS_ONLINE.toString() : (System.currentTimeMillis() - fp.getLastLoginTime() < 432000000 ? ChatColor.YELLOW + humanized : ChatColor.RED + humanized); + String power = ChatColor.YELLOW + String.valueOf(fp.getPowerRounded()) + " / " + String.valueOf(fp.getPowerMaxRounded()) + ChatColor.RESET; + ret.add(String.format(TL.COMMAND_STATUS_FORMAT.toString(), ChatColor.GOLD + fp.getRole().getPrefix() + fp.getName() + ChatColor.RESET, power, last).trim()); + } + fme.sendMessage(ret); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_STATUS_DESCRIPTION; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdStuck.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdStuck.java new file mode 100644 index 0000000..2dd4a9f --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdStuck.java @@ -0,0 +1,109 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.*; +import com.massivecraft.factions.integration.Essentials; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.util.SpiralTask; +import com.massivecraft.factions.zcore.util.TL; +import org.apache.commons.lang.time.DurationFormatUtils; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +public class CmdStuck extends FCommand { + + public CmdStuck() { + super(); + + this.aliases.add("stuck"); + this.aliases.add("halp!"); // halp! c: + + this.permission = Permission.STUCK.node; + this.disableOnLock = true; + + senderMustBePlayer = false; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + final Player player = fme.getPlayer(); + final Location sentAt = player.getLocation(); + final FLocation chunk = fme.getLastStoodAt(); + final long delay = P.p.getConfig().getLong("hcf.stuck.delay", 30); + final int radius = P.p.getConfig().getInt("hcf.stuck.radius", 10); + + if (P.p.getStuckMap().containsKey(player.getUniqueId())) { + long wait = P.p.getTimers().get(player.getUniqueId()) - System.currentTimeMillis(); + String time = DurationFormatUtils.formatDuration(wait, TL.COMMAND_STUCK_TIMEFORMAT.toString(), true); + msg(TL.COMMAND_STUCK_EXISTS, time); + } else { + + // if economy is enabled, they're not on the bypass list, and this command has a cost set, make 'em pay + if (!payForCommand(Conf.econCostStuck, TL.COMMAND_STUCK_TOSTUCK.format(fme.getName()), TL.COMMAND_STUCK_FORSTUCK.format(fme.getName()))) { + return; + } + + final int id = Bukkit.getScheduler().runTaskLater(P.p, new BukkitRunnable() { + + @Override + public void run() { + if (!P.p.getStuckMap().containsKey(player.getUniqueId())) { + return; + } + + // check for world difference or radius exceeding + final World world = chunk.getWorld(); + if (world.getUID() != player.getWorld().getUID() || sentAt.distance(player.getLocation()) > radius) { + msg(TL.COMMAND_STUCK_OUTSIDE.format(radius)); + P.p.getTimers().remove(player.getUniqueId()); + P.p.getStuckMap().remove(player.getUniqueId()); + return; + } + + final Board board = Board.getInstance(); + // spiral task to find nearest wilderness chunk + new SpiralTask(new FLocation(me), radius * 2) { + + @Override + public boolean work() { + FLocation chunk = currentFLocation(); + Faction faction = board.getFactionAt(chunk); + if (faction.isWilderness()) { + int cx = FLocation.chunkToBlock((int) chunk.getX()); + int cz = FLocation.chunkToBlock((int) chunk.getZ()); + int y = world.getHighestBlockYAt(cx, cz); + Location tp = new Location(world, cx, y, cz); + msg(TL.COMMAND_STUCK_TELEPORT, tp.getBlockX(), tp.getBlockY(), tp.getBlockZ()); + P.p.getTimers().remove(player.getUniqueId()); + P.p.getStuckMap().remove(player.getUniqueId()); + if (!Essentials.handleTeleport(player, tp)) { + player.teleport(tp); + P.p.debug("/c stuck used regular teleport, not essentials!"); + } + this.stop(); + return false; + } + return true; + } + }; + } + }, delay * 20).getTaskId(); + + P.p.getTimers().put(player.getUniqueId(), System.currentTimeMillis() + (delay * 1000)); + long wait = P.p.getTimers().get(player.getUniqueId()) - System.currentTimeMillis(); + String time = DurationFormatUtils.formatDuration(wait, TL.COMMAND_STUCK_TIMEFORMAT.toString(), true); + msg(TL.COMMAND_STUCK_START, time); + P.p.getStuckMap().put(player.getUniqueId(), id); + } + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_STUCK_DESCRIPTION; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdTag.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdTag.java new file mode 100644 index 0000000..eac25bb --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdTag.java @@ -0,0 +1,112 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.*; +import com.massivecraft.factions.eco.EcoResult; +import com.massivecraft.factions.event.FactionRenameEvent; +import com.massivecraft.factions.scoreboards.FTeamWrapper; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.util.MiscUtil; +import com.massivecraft.factions.zcore.util.TL; +import net.grandtheftmc.core.util.NumeralUtil; +import org.bukkit.Bukkit; + +import java.util.ArrayList; +import java.util.Locale; + +public class CmdTag extends FCommand { + + public CmdTag() { + this.aliases.add("tag"); + this.aliases.add("rename"); + + this.requiredArgs.add("cartel tag"); + //this.optionalArgs.put("", ""); + + this.permission = Permission.TAG.node; + this.disableOnLock = true; + + senderMustBePlayer = true; + senderMustBeMember = false; + senderMustBeModerator = true; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + String tag = this.argAsString(0); + + // TODO does not first test cover selfcase? + if (Factions.getInstance().isTagTaken(tag) && !MiscUtil.getComparisonString(tag).equals(myFaction.getComparisonTag())) { + msg(TL.COMMAND_TAG_TAKEN); + System.out.println("1"); + return; + } + + ArrayList errors = MiscUtil.validateTag(tag); + if (errors.size() > 0) { + sendMessage(errors); + System.out.println("2"); + return; + } + + // if economy is enabled, they're not on the bypass list, and this command has a cost set, make sure they can pay +// if (!canAffordCommand(Conf.econCostTag, TL.COMMAND_TAG_TOCHANGE.toString())) { +// return; +// } + + if(Conf.econCostTag > 0) { + EcoResult result = myFaction.takeFromStash(Conf.econCostTag); + if(result == EcoResult.LOW_FUNDS) { + fme.msg("%s can't afford %s %s.", myFaction.describeTo(myFaction, true), NumeralUtil.toCurrency(Conf.econCostTag, Locale.US), TL.COMMAND_TAG_TOCHANGE); + System.out.println("3"); + return; + } + + if(result != EcoResult.SUCCESS) { + System.out.println("4"); + return; + } + } + + // trigger the faction rename event (cancellable) + FactionRenameEvent renameEvent = new FactionRenameEvent(fme, tag); + Bukkit.getServer().getPluginManager().callEvent(renameEvent); + if (renameEvent.isCancelled()) { + System.out.println("5"); + return; + } + + // then make 'em pay (if applicable) + if (!payForCommand(Conf.econCostTag, TL.COMMAND_TAG_TOCHANGE, TL.COMMAND_TAG_FORCHANGE)) { + System.out.println("6"); + return; + } + + String oldtag = myFaction.getTag(); + myFaction.setTag(tag); + System.out.println("7"); + + // Inform + for (FPlayer fplayer : FPlayers.getInstance().getOnlinePlayers()) { + if (fplayer.getFactionId().equals(myFaction.getId())) { + fplayer.msg(TL.COMMAND_TAG_FACTION, fme.describeTo(myFaction, true), myFaction.getTag(myFaction)); + continue; + } + + // Broadcast the tag change (if applicable) + if (Conf.broadcastTagChanges) { + Faction faction = fplayer.getFaction(); + fplayer.msg(TL.COMMAND_TAG_CHANGED, fme.getColorTo(faction) + oldtag, myFaction.getTag(faction)); + } + } + + FTeamWrapper.updatePrefixes(myFaction); + System.out.println("8"); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_TAG_DESCRIPTION; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdTitle.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdTitle.java new file mode 100644 index 0000000..02b8da6 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdTitle.java @@ -0,0 +1,56 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; +import com.massivecraft.factions.zcore.util.TextUtil; + +public class CmdTitle extends FCommand { + + public CmdTitle() { + this.aliases.add("title"); + + this.requiredArgs.add("player name"); + this.optionalArgs.put("title", ""); + + this.permission = Permission.TITLE.node; + this.disableOnLock = true; + + senderMustBePlayer = true; + senderMustBeMember = false; + senderMustBeModerator = true; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + FPlayer you = this.argAsBestFPlayerMatch(0); + if (you == null) { + return; + } + + args.remove(0); + String title = TextUtil.implode(args, " "); + + if (!canIAdministerYou(fme, you)) { + return; + } + + // if economy is enabled, they're not on the bypass list, and this command has a cost set, make 'em pay + if (!payForCommand(Conf.econCostTitle, TL.COMMAND_TITLE_TOCHANGE, TL.COMMAND_TITLE_FORCHANGE)) { + return; + } + + you.setTitle(title); + + // Inform + myFaction.msg(TL.COMMAND_TITLE_CHANGED, fme.describeTo(myFaction, true), you.describeTo(myFaction, true)); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_TITLE_DESCRIPTION; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdToggleAllianceChat.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdToggleAllianceChat.java new file mode 100644 index 0000000..5bea5ac --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdToggleAllianceChat.java @@ -0,0 +1,43 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; + +public class CmdToggleAllianceChat extends FCommand { + + public CmdToggleAllianceChat() { + super(); + this.aliases.add("tac"); + this.aliases.add("togglealliancechat"); + this.aliases.add("ac"); + + this.disableOnLock = false; + + this.permission = Permission.TOGGLE_ALLIANCE_CHAT.node; + this.disableOnLock = false; + + senderMustBePlayer = true; + senderMustBeMember = true; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_TOGGLEALLIANCECHAT_DESCRIPTION; + } + + @Override + public void perform() { + if (!Conf.factionOnlyChat) { + msg(TL.COMMAND_CHAT_DISABLED.toString()); + return; + } + + boolean ignoring = fme.isIgnoreAllianceChat(); + + msg(ignoring ? TL.COMMAND_TOGGLEALLIANCECHAT_UNIGNORE : TL.COMMAND_TOGGLEALLIANCECHAT_IGNORE); + fme.setIgnoreAllianceChat(!ignoring); + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdTop.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdTop.java new file mode 100644 index 0000000..972648d --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdTop.java @@ -0,0 +1,49 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.*; +import com.massivecraft.factions.integration.Econ; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.MPlugin; +import com.massivecraft.factions.zcore.util.TL; +import net.grandtheftmc.core.menus.MenuManager; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.LinkedList; + +public class CmdTop extends FCommand { + + public CmdTop() { + super(); + this.aliases.add("top"); + this.aliases.add("t"); + + this.permission = Permission.TOP.node; + this.disableOnLock = false; + + senderMustBePlayer = true; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + MenuManager.openMenu(fme.getPlayer(), "carteltop"); + } + + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_TOP_DESCRIPTION; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdUnclaim.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdUnclaim.java new file mode 100644 index 0000000..dd68471 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdUnclaim.java @@ -0,0 +1,169 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.*; +import com.massivecraft.factions.event.LandUnclaimEvent; +import com.massivecraft.factions.integration.Econ; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.struct.Role; +import com.massivecraft.factions.util.SpiralTask; +import com.massivecraft.factions.zcore.util.TL; +import org.bukkit.Bukkit; + +public class CmdUnclaim extends FCommand { + + public CmdUnclaim() { + this.aliases.add("unclaim"); + this.aliases.add("declaim"); + + this.optionalArgs.put("radius", "1"); + this.optionalArgs.put("cartel", "your"); + + this.permission = Permission.UNCLAIM.node; + this.disableOnLock = true; + + senderMustBePlayer = true; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + // Read and validate input + int radius = this.argAsInt(0, 1); // Default to 1 + final Faction forFaction = this.argAsFaction(1, myFaction); // Default to own + + if (radius < 1) { + msg(TL.COMMAND_CLAIM_INVALIDRADIUS); + return; + } + + if (radius < 2) { + // single chunk + unClaim(new FLocation(me)); + } else { + // radius claim + if (!Permission.CLAIM_RADIUS.has(sender, false)) { + msg(TL.COMMAND_CLAIM_DENIED); + return; + } + + new SpiralTask(new FLocation(me), radius) { + private int failCount = 0; + private final int limit = Conf.radiusClaimFailureLimit - 1; + + @Override + public boolean work() { + boolean success = unClaim(this.currentFLocation()); + if (success) { + failCount = 0; + } else if (failCount++ >= limit) { + this.stop(); + return false; + } + + return true; + } + }; + } + } + + private boolean unClaim(FLocation target) { + Faction targetFaction = Board.getInstance().getFactionAt(target); + if (targetFaction.isSafeZone()) { + if (Permission.MANAGE_SAFE_ZONE.has(sender)) { + Board.getInstance().removeAt(target); + msg(TL.COMMAND_UNCLAIM_SAFEZONE_SUCCESS); + + if (Conf.logLandUnclaims) { + P.p.log(TL.COMMAND_UNCLAIM_LOG.format(fme.getName(), target.getCoordString(), targetFaction.getTag())); + } + return true; + } else { + msg(TL.COMMAND_UNCLAIM_SAFEZONE_NOPERM); + return false; + } + } else if (targetFaction.isWarZone()) { + if (Permission.MANAGE_WAR_ZONE.has(sender)) { + Board.getInstance().removeAt(target); + msg(TL.COMMAND_UNCLAIM_WARZONE_SUCCESS); + + if (Conf.logLandUnclaims) { + P.p.log(TL.COMMAND_UNCLAIM_LOG.format(fme.getName(), target.getCoordString(), targetFaction.getTag())); + } + return true; + } else { + msg(TL.COMMAND_UNCLAIM_WARZONE_NOPERM); + return false; + } + } + + if (fme.isAdminBypassing()) { + LandUnclaimEvent unclaimEvent = new LandUnclaimEvent(target, targetFaction, fme); + Bukkit.getServer().getPluginManager().callEvent(unclaimEvent); + if (unclaimEvent.isCancelled()) { + return false; + } + + Board.getInstance().removeAt(target); + + targetFaction.msg(TL.COMMAND_UNCLAIM_UNCLAIMED, fme.describeTo(targetFaction, true)); + msg(TL.COMMAND_UNCLAIM_UNCLAIMS); + + if (Conf.logLandUnclaims) { + P.p.log(TL.COMMAND_UNCLAIM_LOG.format(fme.getName(), target.getCoordString(), targetFaction.getTag())); + } + + return true; + } + + if (!assertHasFaction()) { + return false; + } + + if (!assertMinRole(Role.MODERATOR)) { + return false; + } + + + if (myFaction != targetFaction) { + msg(TL.COMMAND_UNCLAIM_WRONGFACTION); + return false; + } + + LandUnclaimEvent unclaimEvent = new LandUnclaimEvent(target, targetFaction, fme); + Bukkit.getServer().getPluginManager().callEvent(unclaimEvent); + if (unclaimEvent.isCancelled()) { + return false; + } + + if (Econ.shouldBeUsed()) { + double refund = Econ.calculateClaimRefund(myFaction.getLandRounded()); + + if (Conf.bankEnabled && Conf.bankFactionPaysLandCosts) { + if (!Econ.modifyMoney(myFaction, refund, TL.COMMAND_UNCLAIM_TOUNCLAIM.toString(), TL.COMMAND_UNCLAIM_FORUNCLAIM.toString())) { + return false; + } + } else { + if (!Econ.modifyMoney(fme, refund, TL.COMMAND_UNCLAIM_TOUNCLAIM.toString(), TL.COMMAND_UNCLAIM_FORUNCLAIM.toString())) { + return false; + } + } + } + + Board.getInstance().removeAt(target); + myFaction.msg(TL.COMMAND_UNCLAIM_FACTIONUNCLAIMED, fme.describeTo(myFaction, true)); + + if (Conf.logLandUnclaims) { + P.p.log(TL.COMMAND_UNCLAIM_LOG.format(fme.getName(), target.getCoordString(), targetFaction.getTag())); + } + + return true; + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_UNCLAIM_DESCRIPTION; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdUnclaimall.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdUnclaimall.java new file mode 100644 index 0000000..c8e2b68 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdUnclaimall.java @@ -0,0 +1,64 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Board; +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.P; +import com.massivecraft.factions.event.LandUnclaimAllEvent; +import com.massivecraft.factions.integration.Econ; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; +import org.bukkit.Bukkit; + +public class CmdUnclaimall extends FCommand { + + public CmdUnclaimall() { + this.aliases.add("unclaimall"); + this.aliases.add("declaimall"); + + //this.requiredArgs.add(""); + //this.optionalArgs.put("", ""); + + this.permission = Permission.UNCLAIM_ALL.node; + this.disableOnLock = true; + + senderMustBePlayer = true; + senderMustBeMember = false; + senderMustBeModerator = true; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + if (Econ.shouldBeUsed()) { + double refund = Econ.calculateTotalLandRefund(myFaction.getLandRounded()); + if (Conf.bankEnabled && Conf.bankFactionPaysLandCosts) { + if (!Econ.modifyMoney(myFaction, refund, TL.COMMAND_UNCLAIMALL_TOUNCLAIM.toString(), TL.COMMAND_UNCLAIMALL_FORUNCLAIM.toString())) { + return; + } + } else { + if (!Econ.modifyMoney(fme, refund, TL.COMMAND_UNCLAIMALL_TOUNCLAIM.toString(), TL.COMMAND_UNCLAIMALL_FORUNCLAIM.toString())) { + return; + } + } + } + + LandUnclaimAllEvent unclaimAllEvent = new LandUnclaimAllEvent(myFaction, fme); + Bukkit.getServer().getPluginManager().callEvent(unclaimAllEvent); + if (unclaimAllEvent.isCancelled()) { + return; + } + + Board.getInstance().unclaimAll(myFaction.getId()); + myFaction.msg(TL.COMMAND_UNCLAIMALL_UNCLAIMED, fme.describeTo(myFaction, true)); + + if (Conf.logLandUnclaims) { + P.p.log(TL.COMMAND_UNCLAIMALL_LOG.format(fme.getName(), myFaction.getTag())); + } + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_UNCLAIMALL_DESCRIPTION; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdVersion.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdVersion.java new file mode 100644 index 0000000..84b2362 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdVersion.java @@ -0,0 +1,35 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.P; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; + + +public class CmdVersion extends FCommand { + + public CmdVersion() { + this.aliases.add("version"); + this.aliases.add("ver"); + + //this.requiredArgs.add(""); + //this.optionalArgs.put("", ""); + + this.permission = Permission.VERSION.node; + this.disableOnLock = false; + + senderMustBePlayer = false; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + msg(TL.COMMAND_VERSION_VERSION, P.p.getDescription().getFullName()); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_VERSION_DESCRIPTION; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdWarunclaimall.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdWarunclaimall.java new file mode 100644 index 0000000..f85c84f --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/CmdWarunclaimall.java @@ -0,0 +1,43 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Board; +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.Factions; +import com.massivecraft.factions.P; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; + +public class CmdWarunclaimall extends FCommand { + + public CmdWarunclaimall() { + this.aliases.add("warunclaimall"); + this.aliases.add("wardeclaimall"); + + //this.requiredArgs.add(""); + //this.optionalArgs.put("", ""); + + this.permission = Permission.MANAGE_WAR_ZONE.node; + this.disableOnLock = true; + + senderMustBePlayer = false; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + Board.getInstance().unclaimAll(Factions.getInstance().getWarZone().getId()); + msg(TL.COMMAND_WARUNCLAIMALL_SUCCESS); + + if (Conf.logLandUnclaims) { + P.p.log(TL.COMMAND_WARUNCLAIMALL_LOG.format(fme.getName())); + } + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_WARUNCLAIMALL_DESCRIPTION; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/FCmdRoot.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/FCmdRoot.java new file mode 100644 index 0000000..53f43e8 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/FCmdRoot.java @@ -0,0 +1,167 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.zcore.util.TL; + +import java.util.Collections; + +public class FCmdRoot extends FCommand { + + public CmdAdmin cmdAdmin = new CmdAdmin(); + public CmdAutoClaim cmdAutoClaim = new CmdAutoClaim(); + public CmdBoom cmdBoom = new CmdBoom(); + public CmdBypass cmdBypass = new CmdBypass(); + public CmdChat cmdChat = new CmdChat(); + public CmdChatSpy cmdChatSpy = new CmdChatSpy(); + public CmdClaim cmdClaim = new CmdClaim(); + public CmdConfig cmdConfig = new CmdConfig(); + public CmdCreate cmdCreate = new CmdCreate(); + public CmdDeinvite cmdDeinvite = new CmdDeinvite(); + public CmdDescription cmdDescription = new CmdDescription(); + public CmdDisband cmdDisband = new CmdDisband(); + public CmdHelp cmdHelp = new CmdHelp(); + public CmdHome cmdHome = new CmdHome(); + public CmdInvite cmdInvite = new CmdInvite(); + public CmdJoin cmdJoin = new CmdJoin(); + public CmdKick cmdKick = new CmdKick(); + public CmdLeave cmdLeave = new CmdLeave(); + public CmdList cmdList = new CmdList(); + public CmdLock cmdLock = new CmdLock(); + public CmdMap cmdMap = new CmdMap(); + public CmdMod cmdMod = new CmdMod(); + public CmdMoney cmdMoney = new CmdMoney(); + public CmdOpen cmdOpen = new CmdOpen(); + public CmdOwner cmdOwner = new CmdOwner(); + public CmdOwnerList cmdOwnerList = new CmdOwnerList(); + public CmdPeaceful cmdPeaceful = new CmdPeaceful(); + public CmdPermanent cmdPermanent = new CmdPermanent(); + public CmdPermanentPower cmdPermanentPower = new CmdPermanentPower(); + public CmdPowerBoost cmdPowerBoost = new CmdPowerBoost(); + public CmdPower cmdPower = new CmdPower(); + public CmdRelationAlly cmdRelationAlly = new CmdRelationAlly(); + public CmdRelationEnemy cmdRelationEnemy = new CmdRelationEnemy(); + public CmdRelationNeutral cmdRelationNeutral = new CmdRelationNeutral(); + public CmdReload cmdReload = new CmdReload(); + public CmdSafeunclaimall cmdSafeunclaimall = new CmdSafeunclaimall(); + public CmdSaveAll cmdSaveAll = new CmdSaveAll(); + public CmdSethome cmdSethome = new CmdSethome(); + public CmdShow cmdShow = new CmdShow(); + public CmdStatus cmdStatus = new CmdStatus(); + public CmdStuck cmdStuck = new CmdStuck(); + public CmdTag cmdTag = new CmdTag(); + public CmdTitle cmdTitle = new CmdTitle(); + public CmdToggleAllianceChat cmdToggleAllianceChat = new CmdToggleAllianceChat(); + public CmdUnclaim cmdUnclaim = new CmdUnclaim(); + public CmdUnclaimall cmdUnclaimall = new CmdUnclaimall(); + public CmdVersion cmdVersion = new CmdVersion(); + public CmdWarunclaimall cmdWarunclaimall = new CmdWarunclaimall(); + public CmdSB cmdSB = new CmdSB(); + public CmdShowInvites cmdShowInvites = new CmdShowInvites(); + public CmdAnnounce cmdAnnounce = new CmdAnnounce(); + public CmdSeeChunk cmdSeeChunk = new CmdSeeChunk(); + public CmdConvert cmdConvert = new CmdConvert(); + public CmdFWarp cmdFWarp = new CmdFWarp(); + public CmdSetFWarp cmdSetFWarp = new CmdSetFWarp(); + public CmdDelFWarp cmdDelFWarp = new CmdDelFWarp(); + public CmdModifyPower cmdModifyPower = new CmdModifyPower(); + public CmdLogins cmdLogins = new CmdLogins(); + public CmdClaimLine cmdClaimLine = new CmdClaimLine(); + public CmdTop cmdTop = new CmdTop(); + public CmdAHome cmdAHome = new CmdAHome(); + + public FCmdRoot() { + super(); + this.aliases.addAll(Conf.baseCommandAliases); + this.aliases.removeAll(Collections.singletonList(null)); // remove any nulls from extra commas + this.allowNoSlashAccess = Conf.allowNoSlashCommand; + + //this.requiredArgs.add(""); + //this.optionalArgs.put("","") + + senderMustBePlayer = false; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + + this.disableOnLock = false; + + this.setHelpShort("The cartel base command"); + this.helpLong.add(p.txt.parseTags("This command contains all cartel stuff.")); + +// this.subCommands.add(p.cmdHelp); + + this.addSubCommand(this.cmdAdmin); + this.addSubCommand(this.cmdAutoClaim); + this.addSubCommand(this.cmdBoom); + this.addSubCommand(this.cmdBypass); + this.addSubCommand(this.cmdChat); + this.addSubCommand(this.cmdToggleAllianceChat); + this.addSubCommand(this.cmdChatSpy); + this.addSubCommand(this.cmdClaim); + this.addSubCommand(this.cmdConfig); + this.addSubCommand(this.cmdCreate); + this.addSubCommand(this.cmdDeinvite); + this.addSubCommand(this.cmdDescription); + this.addSubCommand(this.cmdDisband); + this.addSubCommand(this.cmdHelp); + this.addSubCommand(this.cmdHome); + this.addSubCommand(this.cmdInvite); + this.addSubCommand(this.cmdJoin); + this.addSubCommand(this.cmdKick); + this.addSubCommand(this.cmdLeave); + this.addSubCommand(this.cmdList); + this.addSubCommand(this.cmdLock); + this.addSubCommand(this.cmdMap); + this.addSubCommand(this.cmdMod); + this.addSubCommand(this.cmdMoney); + this.addSubCommand(this.cmdOpen); + this.addSubCommand(this.cmdOwner); + this.addSubCommand(this.cmdOwnerList); + this.addSubCommand(this.cmdPeaceful); + this.addSubCommand(this.cmdPermanent); + this.addSubCommand(this.cmdPermanentPower); + this.addSubCommand(this.cmdPower); + this.addSubCommand(this.cmdPowerBoost); + this.addSubCommand(this.cmdRelationAlly); + this.addSubCommand(this.cmdRelationEnemy); + this.addSubCommand(this.cmdRelationNeutral); + this.addSubCommand(this.cmdReload); + this.addSubCommand(this.cmdSafeunclaimall); + this.addSubCommand(this.cmdSaveAll); + this.addSubCommand(this.cmdSethome); + this.addSubCommand(this.cmdShow); + this.addSubCommand(this.cmdStatus); + this.addSubCommand(this.cmdStuck); + this.addSubCommand(this.cmdTag); + this.addSubCommand(this.cmdTitle); + this.addSubCommand(this.cmdUnclaim); + this.addSubCommand(this.cmdUnclaimall); + this.addSubCommand(this.cmdVersion); + this.addSubCommand(this.cmdWarunclaimall); + this.addSubCommand(this.cmdSB); + this.addSubCommand(this.cmdShowInvites); + this.addSubCommand(this.cmdAnnounce); + this.addSubCommand(this.cmdSeeChunk); + this.addSubCommand(this.cmdConvert); + this.addSubCommand(this.cmdFWarp); + this.addSubCommand(this.cmdSetFWarp); + this.addSubCommand(this.cmdDelFWarp); + this.addSubCommand(this.cmdModifyPower); + this.addSubCommand(this.cmdLogins); + this.addSubCommand(this.cmdClaimLine); + this.addSubCommand(this.cmdTop); + this.addSubCommand(this.cmdAHome); + } + + @Override + public void perform() { + this.commandChain.add(this); + this.cmdHelp.execute(this.sender, this.args, this.commandChain); + } + + @Override + public TL getUsageTranslation() { + return TL.GENERIC_PLACEHOLDER; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/FCommand.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/FCommand.java new file mode 100644 index 0000000..1715585 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/FCommand.java @@ -0,0 +1,312 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.*; +import com.massivecraft.factions.integration.Econ; +import com.massivecraft.factions.struct.Role; +import com.massivecraft.factions.util.WarmUpUtil; +import com.massivecraft.factions.zcore.MCommand; +import com.massivecraft.factions.zcore.util.TL; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.text.SimpleDateFormat; +import java.util.List; + + +public abstract class FCommand extends MCommand

{ + + public SimpleDateFormat sdf = new SimpleDateFormat(TL.DATE_FORMAT.toString()); + + public boolean disableOnLock; + + public FPlayer fme; + public Faction myFaction; + public boolean senderMustBeMember; + public boolean senderMustBeModerator; + public boolean senderMustBeAdmin; + + public boolean isMoneyCommand; + + public FCommand() { + super(P.p); + + // Due to safety reasons it defaults to disable on lock. + disableOnLock = true; + + // The money commands must be disabled if money should not be used. + isMoneyCommand = false; + + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void execute(CommandSender sender, List args, List> commandChain) { + if (sender instanceof Player) { + this.fme = FPlayers.getInstance().getByPlayer((Player) sender); + this.myFaction = this.fme.getFaction(); + } else { + this.fme = null; + this.myFaction = null; + } + super.execute(sender, args, commandChain); + } + + @Override + public boolean isEnabled() { + if (p.getLocked() && this.disableOnLock) { + msg("Cartels was locked by an admin. Please try again later."); + return false; + } + + if (this.isMoneyCommand && !Conf.econEnabled) { + msg("Cartels economy features are disabled on this server."); + return false; + } + + if (this.isMoneyCommand && !Conf.bankEnabled) { + msg("The cartel bank system is disabled on this server."); + return false; + } + + return true; + } + + @Override + public boolean validSenderType(CommandSender sender, boolean informSenderIfNot) { + boolean superValid = super.validSenderType(sender, informSenderIfNot); + if (!superValid) { + return false; + } + + if (!(this.senderMustBeMember || this.senderMustBeModerator || this.senderMustBeAdmin)) { + return true; + } + + if (!(sender instanceof Player)) { + return false; + } + + if (!fme.hasFaction()) { + sender.sendMessage(p.txt.parse("You are not member of any cartel.")); + return false; + } + + if (this.senderMustBeModerator && !fme.getRole().isAtLeast(Role.MODERATOR)) { + sender.sendMessage(p.txt.parse("Only cartel underbosses can %s.", this.getHelpShort())); + return false; + } + + if (this.senderMustBeAdmin && !fme.getRole().isAtLeast(Role.ADMIN)) { + sender.sendMessage(p.txt.parse("Only cartel bosses can %s.", this.getHelpShort())); + return false; + } + + return true; + } + + // -------------------------------------------- // + // Assertions + // -------------------------------------------- // + + public boolean assertHasFaction() { + if (me == null) { + return true; + } + + if (!fme.hasFaction()) { + sendMessage("You are not member of any cartel."); + return false; + } + return true; + } + + public boolean assertMinRole(Role role) { + if (me == null) { + return true; + } + + if (fme.getRole().value < role.value) { + msg("You must be " + role + " to " + this.getHelpShort() + "."); + return false; + } + return true; + } + + // -------------------------------------------- // + // Argument Readers + // -------------------------------------------- // + + // FPLAYER ====================== + public FPlayer strAsFPlayer(String name, FPlayer def, boolean msg) { + FPlayer ret = def; + + if (name != null) { + for (FPlayer fplayer : FPlayers.getInstance().getAllFPlayers()) { + if (fplayer.getName().equalsIgnoreCase(name)) { + ret = fplayer; + break; + } + } + } + + if (msg && ret == null) { + this.msg("No player \"

%s\" could be found.", name); + } + + return ret; + } + + public FPlayer argAsFPlayer(int idx, FPlayer def, boolean msg) { + return this.strAsFPlayer(this.argAsString(idx), def, msg); + } + + public FPlayer argAsFPlayer(int idx, FPlayer def) { + return this.argAsFPlayer(idx, def, true); + } + + public FPlayer argAsFPlayer(int idx) { + return this.argAsFPlayer(idx, null); + } + + // BEST FPLAYER MATCH ====================== + public FPlayer strAsBestFPlayerMatch(String name, FPlayer def, boolean msg) { + return strAsFPlayer(name, def, msg); + } + + public FPlayer argAsBestFPlayerMatch(int idx, FPlayer def, boolean msg) { + return this.strAsBestFPlayerMatch(this.argAsString(idx), def, msg); + } + + public FPlayer argAsBestFPlayerMatch(int idx, FPlayer def) { + return this.argAsBestFPlayerMatch(idx, def, true); + } + + public FPlayer argAsBestFPlayerMatch(int idx) { + return this.argAsBestFPlayerMatch(idx, null); + } + + // FACTION ====================== + public Faction strAsFaction(String name, Faction def, boolean msg) { + Faction ret = def; + + if (name != null) { + // First we try an exact match + Faction faction = Factions.getInstance().getByTag(name); // Checks for faction name match. + + // Now lets try for warzone / safezone. Helpful for custom warzone / safezone names. + // Do this after we check for an exact match in case they rename the warzone / safezone + // and a player created faction took one of the names. + if (faction == null) { + if (name.equalsIgnoreCase("warzone")) { + faction = Factions.getInstance().getWarZone(); + } else if (name.equalsIgnoreCase("safezone")) { + faction = Factions.getInstance().getSafeZone(); + } + } + + // Next we match faction tags + if (faction == null) { + faction = Factions.getInstance().getBestTagMatch(name); + } + + // Next we match player names + if (faction == null) { + FPlayer fplayer = strAsFPlayer(name, null, false); + if (fplayer != null) { + faction = fplayer.getFaction(); + } + } + + if (faction != null) { + ret = faction; + } + } + + if (msg && ret == null) { + this.msg("The cartel or player \"

%s\" could not be found.", name); + } + + return ret; + } + + public Faction argAsFaction(int idx, Faction def, boolean msg) { + return this.strAsFaction(this.argAsString(idx), def, msg); + } + + public Faction argAsFaction(int idx, Faction def) { + return this.argAsFaction(idx, def, true); + } + + public Faction argAsFaction(int idx) { + return this.argAsFaction(idx, null); + } + + // -------------------------------------------- // + // Commonly used logic + // -------------------------------------------- // + + public boolean canIAdministerYou(FPlayer i, FPlayer you) { + if (!i.getFaction().equals(you.getFaction())) { + i.sendMessage(p.txt.parse("%s is not in the same cartel as you.", you.describeTo(i, true))); + return false; + } + + if (i.getRole().value > you.getRole().value || i.getRole().equals(Role.ADMIN)) { + return true; + } + + if (you.getRole().equals(Role.ADMIN)) { + i.sendMessage(p.txt.parse("Only the cartel admin can do that.")); + } else if (i.getRole().equals(Role.MODERATOR)) { + if (i == you) { + return true; //Moderators can control themselves + } else { + i.sendMessage(p.txt.parse("Underbosses can't control each other...")); + } + } else { + i.sendMessage(p.txt.parse("You must be a cartel underboss to do that.")); + } + + return false; + } + + // if economy is enabled and they're not on the bypass list, make 'em pay; returns true unless person can't afford the cost + public boolean payForCommand(double cost, String toDoThis, String forDoingThis) { + if (!Econ.shouldBeUsed() || this.fme == null || cost == 0.0 || fme.isAdminBypassing()) { + return true; + } + + if (Conf.bankEnabled && Conf.bankFactionPaysCosts && fme.hasFaction()) { + return Econ.modifyMoney(myFaction, -cost, toDoThis, forDoingThis); + } else { + return Econ.modifyMoney(fme, -cost, toDoThis, forDoingThis); + } + } + + public boolean payForCommand(double cost, TL toDoThis, TL forDoingThis) { + return payForCommand(cost, toDoThis.toString(), forDoingThis.toString()); + } + + // like above, but just make sure they can pay; returns true unless person can't afford the cost + public boolean canAffordCommand(double cost, String toDoThis) { + if (!Econ.shouldBeUsed() || this.fme == null || cost == 0.0 || fme.isAdminBypassing()) { + return true; + } + + if (Conf.bankEnabled && Conf.bankFactionPaysCosts && fme.hasFaction()) { + return Econ.hasAtLeast(myFaction, cost, toDoThis); + } else { + return Econ.hasAtLeast(fme, cost, toDoThis); + } + } + + public void doWarmUp(WarmUpUtil.Warmup warmup, TL translationKey, String action, Runnable runnable, long delay) { + this.doWarmUp(this.fme, warmup, translationKey, action, runnable, delay); + } + + public void doWarmUp(FPlayer player, WarmUpUtil.Warmup warmup, TL translationKey, String action, Runnable runnable, long delay) { + WarmUpUtil.process(player, warmup, translationKey, action, runnable, delay); + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/FRelationCommand.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/FRelationCommand.java new file mode 100644 index 0000000..cb497d6 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/cmd/FRelationCommand.java @@ -0,0 +1,126 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.P; +import com.massivecraft.factions.event.FactionRelationEvent; +import com.massivecraft.factions.event.FactionRelationWishEvent; +import com.massivecraft.factions.scoreboards.FTeamWrapper; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.struct.Relation; +import com.massivecraft.factions.zcore.util.TL; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; + +public abstract class FRelationCommand extends FCommand { + + public Relation targetRelation; + + public FRelationCommand() { + super(); + this.requiredArgs.add("faction tag"); + //this.optionalArgs.put("player name", "you"); + + this.permission = Permission.RELATION.node; + this.disableOnLock = true; + + senderMustBePlayer = true; + senderMustBeMember = false; + senderMustBeModerator = true; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + Faction them = this.argAsFaction(0); + if (them == null) { + return; + } + + if (!them.isNormal()) { + msg(TL.COMMAND_RELATIONS_ALLTHENOPE); + return; + } + + if (them == myFaction) { + msg(TL.COMMAND_RELATIONS_MORENOPE); + return; + } + + if (myFaction.getRelationWish(them) == targetRelation) { + msg(TL.COMMAND_RELATIONS_ALREADYINRELATIONSHIP, them.getTag()); + return; + } + + if (hasMaxRelations(them, targetRelation)) { + // We message them down there with the count. + return; + } + Relation oldRelation = myFaction.getRelationTo(them, true); + FactionRelationWishEvent wishEvent = new FactionRelationWishEvent(fme, myFaction, them, oldRelation, targetRelation); + Bukkit.getPluginManager().callEvent(wishEvent); + if (wishEvent.isCancelled()) { + return; + } + + // if economy is enabled, they're not on the bypass list, and this command has a cost set, make 'em pay + if (!payForCommand(targetRelation.getRelationCost(), TL.COMMAND_RELATIONS_TOMARRY, TL.COMMAND_RELATIONS_FORMARRY)) { + return; + } + + // try to set the new relation + myFaction.setRelationWish(them, targetRelation); + Relation currentRelation = myFaction.getRelationTo(them, true); + ChatColor currentRelationColor = currentRelation.getColor(); + + // if the relation change was successful + if (targetRelation.value == currentRelation.value) { + // trigger the faction relation event + FactionRelationEvent relationEvent = new FactionRelationEvent(myFaction, them, oldRelation, currentRelation); + Bukkit.getServer().getPluginManager().callEvent(relationEvent); + + them.msg(TL.COMMAND_RELATIONS_MUTUAL, currentRelationColor + targetRelation.getTranslation(), currentRelationColor + myFaction.getTag()); + myFaction.msg(TL.COMMAND_RELATIONS_MUTUAL, currentRelationColor + targetRelation.getTranslation(), currentRelationColor + them.getTag()); + } else { + // inform the other faction of your request + them.msg(TL.COMMAND_RELATIONS_PROPOSAL_1, currentRelationColor + myFaction.getTag(), targetRelation.getColor() + targetRelation.getTranslation()); + them.msg(TL.COMMAND_RELATIONS_PROPOSAL_2, Conf.baseCommandAliases.get(0), targetRelation, myFaction.getTag()); + myFaction.msg(TL.COMMAND_RELATIONS_PROPOSAL_SENT, currentRelationColor + them.getTag(), "" + targetRelation.getColor() + targetRelation); + } + + if (!targetRelation.isNeutral() && them.isPeaceful()) { + them.msg(TL.COMMAND_RELATIONS_PEACEFUL); + myFaction.msg(TL.COMMAND_RELATIONS_PEACEFULOTHER); + } + + if (!targetRelation.isNeutral() && myFaction.isPeaceful()) { + them.msg(TL.COMMAND_RELATIONS_PEACEFULOTHER); + myFaction.msg(TL.COMMAND_RELATIONS_PEACEFUL); + } + + FTeamWrapper.updatePrefixes(myFaction); + FTeamWrapper.updatePrefixes(them); + } + + private boolean hasMaxRelations(Faction them, Relation targetRelation) { + int max = P.p.getConfig().getInt("max-relations." + targetRelation.toString(), -1); + if (P.p.getConfig().getBoolean("max-relations.enabled", false)) { + if (max != -1) { + if (myFaction.getRelationCount(targetRelation) >= max) { + msg(TL.COMMAND_RELATIONS_EXCEEDS_ME, max, targetRelation.getPluralTranslation()); + return true; + } + if (them.getRelationCount(targetRelation) > max) { + msg(TL.COMMAND_RELATIONS_EXCEEDS_THEY, max, targetRelation.getPluralTranslation()); + return true; + } + } + } + return false; + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_RELATIONS_DESCRIPTION; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/eco/EcoResult.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/eco/EcoResult.java new file mode 100644 index 0000000..845e6ce --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/eco/EcoResult.java @@ -0,0 +1,30 @@ +package com.massivecraft.factions.eco; + +/** + * Created by Luke Bingham on 31/07/2017. + */ +public enum EcoResult { + + /** + * If the transaction goes well, + * This shall be returned. + */ + SUCCESS(), + + /** + * If the balance is hitting the maximum capacity, + * This shall be returned. + */ + OVERWEIGHT(), + + /** + * If the transaction cannot be made due to lack of funds, + * This shall be returned. + */ + LOW_FUNDS(), + + /** + * This shall be returned when a Unknown issue occurs. + */ + UNKNOWN(), +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/FPlayerJoinEvent.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/FPlayerJoinEvent.java new file mode 100644 index 0000000..ce3148a --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/FPlayerJoinEvent.java @@ -0,0 +1,42 @@ +package com.massivecraft.factions.event; + +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.Faction; +import org.bukkit.event.Cancellable; + +/** + * Event called when an FPlayer joins a Faction. + */ +public class FPlayerJoinEvent extends FactionPlayerEvent implements Cancellable { + + PlayerJoinReason reason; + boolean cancelled = false; + + public enum PlayerJoinReason { + CREATE, LEADER, COMMAND + } + + public FPlayerJoinEvent(FPlayer fp, Faction f, PlayerJoinReason r) { + super(f, fp); + reason = r; + } + + /** + * Get the reason the player joined the faction. + * + * @return reason player joined the faction. + */ + public PlayerJoinReason getReason() { + return reason; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean c) { + cancelled = c; + } +} \ No newline at end of file diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/FPlayerLeaveEvent.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/FPlayerLeaveEvent.java new file mode 100644 index 0000000..73afb5e --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/FPlayerLeaveEvent.java @@ -0,0 +1,43 @@ +package com.massivecraft.factions.event; + +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.Faction; +import org.bukkit.event.Cancellable; + +public class FPlayerLeaveEvent extends FactionPlayerEvent implements Cancellable { + + private PlayerLeaveReason reason; + boolean cancelled = false; + + public enum PlayerLeaveReason { + KICKED, DISBAND, RESET, JOINOTHER, LEAVE + } + + public FPlayerLeaveEvent(FPlayer p, Faction f, PlayerLeaveReason r) { + super(f, p); + reason = r; + } + + /** + * Get the reason the player left the faction. + * + * @return reason player left the faction. + */ + public PlayerLeaveReason getReason() { + return reason; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean c) { + if (reason == PlayerLeaveReason.DISBAND || reason == PlayerLeaveReason.RESET) { + cancelled = false; // Don't let them cancel factions disbanding. + } else { + cancelled = c; + } + } +} \ No newline at end of file diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/FactionCreateEvent.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/FactionCreateEvent.java new file mode 100644 index 0000000..0afc612 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/FactionCreateEvent.java @@ -0,0 +1,52 @@ +package com.massivecraft.factions.event; + +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.FPlayers; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * Event called when a Faction is created. + */ +public class FactionCreateEvent extends Event implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + + private String factionTag; + private Player sender; + private boolean cancelled; + + public FactionCreateEvent(Player sender, String tag) { + this.factionTag = tag; + this.sender = sender; + this.cancelled = false; + } + + public FPlayer getFPlayer() { + return FPlayers.getInstance().getByPlayer(sender); + } + + public String getFactionTag() { + return factionTag; + } + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean c) { + this.cancelled = c; + } +} \ No newline at end of file diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/FactionDisbandEvent.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/FactionDisbandEvent.java new file mode 100644 index 0000000..5504b87 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/FactionDisbandEvent.java @@ -0,0 +1,39 @@ +package com.massivecraft.factions.event; + +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.FPlayers; +import com.massivecraft.factions.Factions; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; + +/** + * Event called when a faction is disbanded. + */ +public class FactionDisbandEvent extends FactionEvent implements Cancellable { + + private boolean cancelled = false; + private Player sender; + + public FactionDisbandEvent(Player sender, String factionId) { + super(Factions.getInstance().getFactionById(factionId)); + this.sender = sender; + } + + public FPlayer getFPlayer() { + return FPlayers.getInstance().getByPlayer(sender); + } + + public Player getPlayer() { + return sender; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean c) { + cancelled = c; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/FactionEvent.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/FactionEvent.java new file mode 100644 index 0000000..53c87fd --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/FactionEvent.java @@ -0,0 +1,36 @@ +package com.massivecraft.factions.event; + +import com.massivecraft.factions.Faction; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * Represents an event involving a Faction. + */ +public class FactionEvent extends Event { + + private static final HandlerList handlers = new HandlerList(); + private final Faction faction; + + public FactionEvent(Faction faction) { + this.faction = faction; + } + + /** + * Get the Faction involved in the event. + * + * @return faction involved in the event. + */ + public Faction getFaction() { + return this.faction; + } + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/FactionPlayerEvent.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/FactionPlayerEvent.java new file mode 100644 index 0000000..8a2552d --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/FactionPlayerEvent.java @@ -0,0 +1,21 @@ +package com.massivecraft.factions.event; + +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.Faction; + +/** + * Represents an event involving a Faction and a FPlayer. + */ +public class FactionPlayerEvent extends FactionEvent { + + private final FPlayer fPlayer; + + public FactionPlayerEvent(Faction faction, FPlayer fPlayer) { + super(faction); + this.fPlayer = fPlayer; + } + + public FPlayer getfPlayer() { + return this.fPlayer; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/FactionRelationEvent.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/FactionRelationEvent.java new file mode 100644 index 0000000..a9b6a2f --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/FactionRelationEvent.java @@ -0,0 +1,50 @@ +package com.massivecraft.factions.event; + +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.struct.Relation; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * Event called when a Faction relation is called. + */ +public class FactionRelationEvent extends Event { + + private static final HandlerList handlers = new HandlerList(); + + private Faction fsender; + private Faction ftarget; + private Relation foldrel; + private Relation frel; + + public FactionRelationEvent(Faction sender, Faction target, Relation oldrel, Relation rel) { + fsender = sender; + ftarget = target; + foldrel = oldrel; + frel = rel; + } + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + public Relation getOldRelation() { + return foldrel; + } + + public Relation getRelation() { + return frel; + } + + public Faction getFaction() { + return fsender; + } + + public Faction getTargetFaction() { + return ftarget; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/FactionRelationWishEvent.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/FactionRelationWishEvent.java new file mode 100644 index 0000000..8590f7b --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/FactionRelationWishEvent.java @@ -0,0 +1,44 @@ +package com.massivecraft.factions.event; + +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.struct.Relation; +import org.bukkit.event.Cancellable; + +public class FactionRelationWishEvent extends FactionPlayerEvent implements Cancellable { + private final Faction targetFaction; + private final Relation currentRelation; + private final Relation targetRelation; + + private boolean cancelled; + + public FactionRelationWishEvent(FPlayer caller, Faction sender, Faction targetFaction, Relation currentRelation, Relation targetRelation) { + super(sender, caller); + + this.targetFaction = targetFaction; + this.currentRelation = currentRelation; + this.targetRelation = targetRelation; + } + + public Faction getTargetFaction() { + return targetFaction; + } + + public Relation getCurrentRelation() { + return currentRelation; + } + + public Relation getTargetRelation() { + return targetRelation; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/FactionRenameEvent.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/FactionRenameEvent.java new file mode 100644 index 0000000..702f9b0 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/FactionRenameEvent.java @@ -0,0 +1,59 @@ +package com.massivecraft.factions.event; + +import com.massivecraft.factions.FPlayer; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; + +public class FactionRenameEvent extends FactionPlayerEvent implements Cancellable { + + private boolean cancelled = false; + private String tag; + + public FactionRenameEvent(FPlayer sender, String newTag) { + super(sender.getFaction(), sender); + tag = newTag; + } + + /** + * Get the player involved in the event. + * + * @return Player involved in the event. + * + * @deprecated use getfPlayer().getPlayer() instead. + */ + @Deprecated + public Player getPlayer() { + return getfPlayer().getPlayer(); + } + + /** + * Get the faction tag before it was renamed. + * + * @return old faction tag. + * + * @deprecated use getFaction().getTag() instead. + */ + @Deprecated + public String getOldFactionTag() { + return getFaction().getTag(); + } + + /** + * Get the new faction tag. + * + * @return new faction tag as String. + */ + public String getFactionTag() { + return tag; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean c) { + this.cancelled = c; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/LandClaimEvent.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/LandClaimEvent.java new file mode 100644 index 0000000..a41a5eb --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/LandClaimEvent.java @@ -0,0 +1,77 @@ +package com.massivecraft.factions.event; + +import com.massivecraft.factions.FLocation; +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.Faction; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; + +/** + * Event called when an FPlayer claims land for a Faction. + */ +public class LandClaimEvent extends FactionPlayerEvent implements Cancellable { + + private boolean cancelled; + private FLocation location; + + public LandClaimEvent(FLocation loc, Faction f, FPlayer p) { + super(f, p); + cancelled = false; + location = loc; + } + + /** + * Get the FLocation involved in this event. + * + * @return the FLocation (also a chunk) involved in this event. + */ + public FLocation getLocation() { + return this.location; + } + + /** + * Get the id of the faction. + * + * @return id of faction as String + * + * @deprecated use getFaction().getId() instead. + */ + @Deprecated + public String getFactionId() { + return getFaction().getId(); + } + + /** + * Get the tag of the faction. + * + * @return tag of faction as String + * + * @deprecated use getFaction().getTag() instead. + */ + @Deprecated + public String getFactionTag() { + return getFaction().getTag(); + } + + /** + * Get the Player involved in this event. + * + * @return player from FPlayer. + * + * @deprecated use getfPlayer().getPlayer() instead. + */ + @Deprecated + public Player getPlayer() { + return getfPlayer().getPlayer(); + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean c) { + this.cancelled = c; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/LandUnclaimAllEvent.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/LandUnclaimAllEvent.java new file mode 100644 index 0000000..6c52b93 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/LandUnclaimAllEvent.java @@ -0,0 +1,60 @@ +package com.massivecraft.factions.event; + +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.Faction; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; + +public class LandUnclaimAllEvent extends FactionPlayerEvent implements Cancellable { + private boolean cancelled; + + public LandUnclaimAllEvent(Faction f, FPlayer p) { + super(f, p); + } + + /** + * Get the id of the faction. + * + * @return id of faction as String + * + * @deprecated use getFaction().getId() instead. + */ + @Deprecated + public String getFactionId() { + return getFaction().getId(); + } + + /** + * Get the tag of the faction. + * + * @return tag of faction as String + * + * @deprecated use getFaction().getTag() instead. + */ + @Deprecated + public String getFactionTag() { + return getFaction().getTag(); + } + + /** + * Get the Player involved in the event. + * + * @return Player from FPlayer. + * + * @deprecated use getfPlayer().getPlayer() instead. + */ + @Deprecated + public Player getPlayer() { + return getfPlayer().getPlayer(); + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/LandUnclaimEvent.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/LandUnclaimEvent.java new file mode 100644 index 0000000..c7321eb --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/LandUnclaimEvent.java @@ -0,0 +1,72 @@ +package com.massivecraft.factions.event; + +import com.massivecraft.factions.FLocation; +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.Faction; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; + +/** + * Event called when an FPlayer unclaims land for a Faction. + */ +public class LandUnclaimEvent extends FactionPlayerEvent implements Cancellable { + + private boolean cancelled; + private FLocation location; + + public LandUnclaimEvent(FLocation loc, Faction f, FPlayer p) { + super(f, p); + cancelled = false; + location = loc; + } + + public FLocation getLocation() { + return this.location; + } + + /** + * Get the id of the faction. + * + * @return id of faction as String + * + * @deprecated use getFaction().getId() instead. + */ + @Deprecated + public String getFactionId() { + return getFaction().getId(); + } + + /** + * Get the tag of the faction. + * + * @return tag of faction as String + * + * @deprecated use getFaction().getTag() instead. + */ + @Deprecated + public String getFactionTag() { + return getFaction().getTag(); + } + + /** + * Get the Player involved in the event. + * + * @return Player from FPlayer. + * + * @deprecated use getfPlayer().getPlayer() instead. + */ + @Deprecated + public Player getPlayer() { + return getfPlayer().getPlayer(); + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean c) { + cancelled = c; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/PowerLossEvent.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/PowerLossEvent.java new file mode 100644 index 0000000..681ba61 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/event/PowerLossEvent.java @@ -0,0 +1,84 @@ +package com.massivecraft.factions.event; + +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.Faction; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; + +/** + * Event called when a player loses power. + */ +public class PowerLossEvent extends FactionPlayerEvent implements Cancellable { + + private boolean cancelled = false; + private String message; + + public PowerLossEvent(Faction f, FPlayer p) { + super(f, p); + } + + /** + * Get the id of the faction. + * + * @return id of faction as String + * + * @deprecated use getFaction().getId() instead. + */ + @Deprecated + public String getFactionId() { + return getFaction().getId(); + } + + /** + * Get the tag of the faction. + * + * @return tag of faction as String + * + * @deprecated use getFaction().getTag() instead. + */ + @Deprecated + public String getFactionTag() { + return getFaction().getTag(); + } + + /** + * Get the Player involved in the event. + * + * @return Player from FPlayer. + * + * @deprecated use getfPlayer().getPlayer() instead. + */ + @Deprecated + public Player getPlayer() { + return getfPlayer().getPlayer(); + } + + /** + * Get the power loss message. + * + * @return power loss message as String. + */ + public String getMessage() { + return message; + } + + /** + * Set the power loss message. + * + * @param message + */ + public void setMessage(String message) { + this.message = message; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean c) { + this.cancelled = c; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/iface/EconomyParticipator.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/iface/EconomyParticipator.java new file mode 100644 index 0000000..37fcb5c --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/iface/EconomyParticipator.java @@ -0,0 +1,12 @@ +package com.massivecraft.factions.iface; + +import com.massivecraft.factions.zcore.util.TL; + +public interface EconomyParticipator extends RelationParticipator { + + public String getAccountId(); + + public void msg(String str, Object... args); + + public void msg(TL translation, Object... args); +} \ No newline at end of file diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/iface/RelationParticipator.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/iface/RelationParticipator.java new file mode 100644 index 0000000..eb0bb55 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/iface/RelationParticipator.java @@ -0,0 +1,17 @@ +package com.massivecraft.factions.iface; + +import com.massivecraft.factions.struct.Relation; +import org.bukkit.ChatColor; + +public interface RelationParticipator { + + public String describeTo(RelationParticipator that); + + public String describeTo(RelationParticipator that, boolean ucfirst); + + public Relation getRelationTo(RelationParticipator that); + + public Relation getRelationTo(RelationParticipator that, boolean ignorePeaceful); + + public ChatColor getColorTo(RelationParticipator to); +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/integration/Econ.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/integration/Econ.java new file mode 100644 index 0000000..2213bab --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/integration/Econ.java @@ -0,0 +1,442 @@ +package com.massivecraft.factions.integration; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.P; +import com.massivecraft.factions.iface.EconomyParticipator; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.struct.Role; +import com.massivecraft.factions.util.RelationUtil; +import net.milkbowl.vault.economy.Economy; +import net.milkbowl.vault.economy.EconomyResponse; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.plugin.RegisteredServiceProvider; + +import java.text.DecimalFormat; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import java.util.logging.Level; + +public class Econ { + + private static Economy econ = null; + + public static void setup() { + if (isSetup()) { + return; + } + + String integrationFail = "Economy integration is " + (Conf.econEnabled ? "enabled, but" : "disabled, and") + " the plugin \"Vault\" "; + + if (Bukkit.getServer().getPluginManager().getPlugin("Vault") == null) { + P.p.log(integrationFail + "is not installed."); + return; + } + + RegisteredServiceProvider rsp = Bukkit.getServer().getServicesManager().getRegistration(Economy.class); + if (rsp == null) { + P.p.log(integrationFail + "is not hooked into an economy plugin."); + return; + } + econ = rsp.getProvider(); + + P.p.log("Economy integration through Vault plugin successful."); + + if (!Conf.econEnabled) { + P.p.log("NOTE: Economy is disabled. You can enable it with the command: c config econEnabled true"); + } + + P.p.cmdBase.cmdHelp.updateHelp(); + } + + public static boolean shouldBeUsed() { + return Conf.econEnabled && econ != null && econ.isEnabled(); + } + + public static boolean isSetup() { + return econ != null; + } + + + public static void modifyUniverseMoney(double delta) { + if (!shouldBeUsed()) { + return; + } + + if (Conf.econUniverseAccount == null) { + return; + } + if (Conf.econUniverseAccount.length() == 0) { + return; + } + if (!econ.hasAccount(Conf.econUniverseAccount)) { + return; + } + + modifyBalance(Conf.econUniverseAccount, delta); + } + + public static void sendBalanceInfo(FPlayer to, EconomyParticipator about) { + if (!shouldBeUsed()) { + P.p.log(Level.WARNING, "Vault does not appear to be hooked into an economy plugin."); + return; + } + to.msg("%s's balance is %s.", about.describeTo(to, true), Econ.moneyString(econ.getBalance(about.getAccountId()))); + } + + public static boolean canIControllYou(EconomyParticipator i, EconomyParticipator you) { + Faction fI = RelationUtil.getFaction(i); + Faction fYou = RelationUtil.getFaction(you); + + // This is a system invoker. Accept it. + if (fI == null) { + return true; + } + + // Bypassing players can do any kind of transaction + if (i instanceof FPlayer && ((FPlayer) i).isAdminBypassing()) { + return true; + } + + // Players with the any withdraw can do. + if (i instanceof FPlayer && Permission.MONEY_WITHDRAW_ANY.has(((FPlayer) i).getPlayer())) { + return true; + } + + // You can deposit to anywhere you feel like. It's your loss if you can't withdraw it again. + if (i == you) { + return true; + } + + // A faction can always transfer away the money of it's members and its own money... + // This will however probably never happen as a faction does not have free will. + // Ohh by the way... Yes it could. For daily rent to the faction. + if (i == fI && fI == fYou) { + return true; + } + + // Factions can be controlled by members that are moderators... or any member if any member can withdraw. + if (you instanceof Faction && fI == fYou && (Conf.bankMembersCanWithdraw || ((FPlayer) i).getRole().value >= Role.MODERATOR.value)) { + return true; + } + + // Otherwise you may not! ;,,; + i.msg("%s lacks permission to control %s's money.", i.describeTo(i, true), you.describeTo(i)); + return false; + } + + public static boolean transferMoney(EconomyParticipator invoker, EconomyParticipator from, EconomyParticipator to, double amount) { + return transferMoney(invoker, from, to, amount, true); + } + + public static boolean transferMoney(EconomyParticipator invoker, EconomyParticipator from, EconomyParticipator to, double amount, boolean notify) { + if (!shouldBeUsed()) { + return false; + } + + // The amount must be positive. + // If the amount is negative we must flip and multiply amount with -1. + if (amount < 0) { + amount *= -1; + EconomyParticipator temp = from; + from = to; + to = temp; + } + + // Check the rights + if (!canIControllYou(invoker, from)) { + return false; + } + + OfflinePlayer fromAcc; + OfflinePlayer toAcc; + + if (isUUID(from.getAccountId())) { + fromAcc = Bukkit.getOfflinePlayer(UUID.fromString(from.getAccountId())); + if (fromAcc.getName() == null) { + return false; + } + } else { + fromAcc = Bukkit.getOfflinePlayer(from.getAccountId()); + } + + if (isUUID(to.getAccountId())) { + toAcc = Bukkit.getOfflinePlayer(UUID.fromString(to.getAccountId())); + if (toAcc.getName() == null) { + return false; + } + } else { + toAcc = Bukkit.getOfflinePlayer(to.getAccountId()); + } + + // Is there enough money for the transaction to happen? + if (!econ.has(fromAcc, amount)) { + // There was not enough money to pay + if (invoker != null && notify) { + invoker.msg("%s can't afford to transfer %s to %s.", from.describeTo(invoker, true), moneyString(amount), to.describeTo(invoker)); + } + + return false; + } + + // Transfer money + EconomyResponse erw = econ.withdrawPlayer(fromAcc, amount); + + if (erw.transactionSuccess()) { + EconomyResponse erd = econ.depositPlayer(toAcc, amount); + if (erd.transactionSuccess()) { + if (notify) { + sendTransferInfo(invoker, from, to, amount); + } + return true; + } else { + // transaction failed, refund account + econ.depositPlayer(fromAcc, amount); + } + } + + // if we get here something with the transaction failed + if (notify) { + invoker.msg("Unable to transfer %s to %s from %s.", moneyString(amount), to.describeTo(invoker), from.describeTo(invoker, true)); + } + + return false; + } + + public static Set getFplayers(EconomyParticipator ep) { + Set fplayers = new HashSet(); + + if (ep != null) { + if (ep instanceof FPlayer) { + fplayers.add((FPlayer) ep); + } else if (ep instanceof Faction) { + fplayers.addAll(((Faction) ep).getFPlayers()); + } + } + + return fplayers; + } + + public static void sendTransferInfo(EconomyParticipator invoker, EconomyParticipator from, EconomyParticipator to, double amount) { + Set recipients = new HashSet(); + recipients.addAll(getFplayers(invoker)); + recipients.addAll(getFplayers(from)); + recipients.addAll(getFplayers(to)); + + if (invoker == null) { + for (FPlayer recipient : recipients) { + recipient.msg("%s was transferred from %s to %s.", moneyString(amount), from.describeTo(recipient), to.describeTo(recipient)); + } + } else if (invoker == from) { + for (FPlayer recipient : recipients) { + recipient.msg("%s gave %s to %s.", from.describeTo(recipient, true), moneyString(amount), to.describeTo(recipient)); + } + } else if (invoker == to) { + for (FPlayer recipient : recipients) { + recipient.msg("%s took %s from %s.", to.describeTo(recipient, true), moneyString(amount), from.describeTo(recipient)); + } + } else { + for (FPlayer recipient : recipients) { + recipient.msg("%s transferred %s from %s to %s.", invoker.describeTo(recipient, true), moneyString(amount), from.describeTo(recipient), to.describeTo(recipient)); + } + } + } + + public static boolean hasAtLeast(EconomyParticipator ep, double delta, String toDoThis) { + if (!shouldBeUsed()) { + return true; + } + + // going the hard way round as econ.has refuses to work. + boolean affordable = false; + double currentBalance; + + if (isUUID(ep.getAccountId())) { + OfflinePlayer offline = Bukkit.getOfflinePlayer(UUID.fromString(ep.getAccountId())); + if (offline.getName() != null) { + currentBalance = econ.getBalance(Bukkit.getOfflinePlayer(UUID.fromString(ep.getAccountId()))); + } else { + currentBalance = 0; + } + } else { + currentBalance = econ.getBalance(ep.getAccountId()); + } + + if (currentBalance >= delta) { + affordable = true; + } + + if (!affordable) { + if (toDoThis != null && !toDoThis.isEmpty()) { + ep.msg("%s can't afford %s %s.", ep.describeTo(ep, true), moneyString(delta), toDoThis); + } + return false; + } + return true; + } + + public static boolean modifyMoney(EconomyParticipator ep, double delta, String toDoThis, String forDoingThis) { + if (!shouldBeUsed()) { + return false; + } + + OfflinePlayer acc; + + if (isUUID(ep.getAccountId())) { + acc = Bukkit.getOfflinePlayer(UUID.fromString(ep.getAccountId())); + if (acc.getName() == null) { + return false; + } + } else { + acc = Bukkit.getOfflinePlayer(ep.getAccountId()); + } + + String You = ep.describeTo(ep, true); + + if (delta == 0) { + // no money actually transferred? +// ep.msg("%s didn't have to pay anything %s.", You, forDoingThis); // might be for gains, might be for losses + return true; + } + + if (delta > 0) { + // The player should gain money + // The account might not have enough space + EconomyResponse er = econ.depositPlayer(acc, delta); + if (er.transactionSuccess()) { + modifyUniverseMoney(-delta); + if (forDoingThis != null && !forDoingThis.isEmpty()) { + ep.msg("%s gained %s %s.", You, moneyString(delta), forDoingThis); + } + return true; + } else { + // transfer to account failed + if (forDoingThis != null && !forDoingThis.isEmpty()) { + ep.msg("%s would have gained %s %s, but the deposit failed.", You, moneyString(delta), forDoingThis); + } + return false; + } + } else { + // The player should loose money + // The player might not have enough. + + if (econ.has(acc, -delta) && econ.withdrawPlayer(acc, -delta).transactionSuccess()) { + // There is enough money to pay + modifyUniverseMoney(-delta); + if (forDoingThis != null && !forDoingThis.isEmpty()) { + ep.msg("%s lost %s %s.", You, moneyString(-delta), forDoingThis); + } + return true; + } else { + // There was not enough money to pay + if (toDoThis != null && !toDoThis.isEmpty()) { + ep.msg("%s can't afford %s %s.", You, moneyString(-delta), toDoThis); + } + return false; + } + } + } + + // format money string based on server's set currency type, like "24 gold" or "$24.50" + public static String moneyString(double amount) { + return econ.format(amount); + } + + // calculate the cost for claiming land + public static double calculateClaimCost(int ownedLand, boolean takingFromAnotherFaction) { +// if (!shouldBeUsed()) { +// return 0d; +// } + + // basic claim cost, plus land inflation cost, minus the potential bonus given for claiming from another faction + return Conf.econCostClaimWilderness + (Conf.econCostClaimWilderness * Conf.econClaimAdditionalMultiplier * ownedLand) - (takingFromAnotherFaction ? Conf.econCostClaimFromFactionBonus : 0); + } + + // calculate refund amount for unclaiming land + public static double calculateClaimRefund(int ownedLand) { + return calculateClaimCost(ownedLand - 1, false) * Conf.econClaimRefundMultiplier; + } + + // calculate value of all owned land + public static double calculateTotalLandValue(int ownedLand) { + double amount = 0; + for (int x = 0; x < ownedLand; x++) { + amount += calculateClaimCost(x, false); + } + return amount; + } + + // calculate refund amount for all owned land + public static double calculateTotalLandRefund(int ownedLand) { + return calculateTotalLandValue(ownedLand) * Conf.econClaimRefundMultiplier; + } + + + // -------------------------------------------- // + // Standard account management methods + // -------------------------------------------- // + + public static boolean hasAccount(String name) { + return econ.hasAccount(name); + } + + public static double getBalance(String account) { + return econ.getBalance(account); + } + + private static final DecimalFormat format = new DecimalFormat("#,###"); + + public static String getFriendlyBalance(UUID uuid) { + OfflinePlayer offline = Bukkit.getOfflinePlayer(uuid); + if (offline.getName() == null) { + return "0"; + } + return format.format(econ.getBalance(offline)); + } + + public static String getFriendlyBalance(FPlayer player) { + return getFriendlyBalance(UUID.fromString(player.getId())); + } + + public static boolean setBalance(String account, double amount) { + double current = econ.getBalance(account); + if (current > amount) { + return econ.withdrawPlayer(account, current - amount).transactionSuccess(); + } else { + return econ.depositPlayer(account, amount - current).transactionSuccess(); + } + } + + public static boolean modifyBalance(String account, double amount) { + if (amount < 0) { + return econ.withdrawPlayer(account, -amount).transactionSuccess(); + } else { + return econ.depositPlayer(account, amount).transactionSuccess(); + } + } + + public static boolean deposit(String account, double amount) { + return econ.depositPlayer(account, amount).transactionSuccess(); + } + + public static boolean withdraw(String account, double amount) { + return econ.withdrawPlayer(account, amount).transactionSuccess(); + } + + // --------------------------------------- + // Helpful Utilities + // --------------------------------------- + + public static boolean isUUID(String uuid) { + try { + UUID.fromString(uuid); + } catch (IllegalArgumentException ex) { + return false; + } + + return true; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/integration/Essentials.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/integration/Essentials.java new file mode 100644 index 0000000..7b67d56 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/integration/Essentials.java @@ -0,0 +1,46 @@ +package com.massivecraft.factions.integration; + +import com.earth2me.essentials.IEssentials; +import com.earth2me.essentials.Teleport; +import com.earth2me.essentials.Trade; +import com.massivecraft.factions.Conf; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +public class Essentials { + + private static IEssentials essentials; + + public static void setup() { + Plugin ess = Bukkit.getPluginManager().getPlugin("Essentials"); + if (ess != null) { + essentials = (IEssentials) ess; + } + } + + // return false if feature is disabled or Essentials isn't available + public static boolean handleTeleport(Player player, Location loc) { + if (!Conf.homesTeleportCommandEssentialsIntegration || essentials == null) { + return false; + } + + Teleport teleport = essentials.getUser(player).getTeleport(); + Trade trade = new Trade(Conf.econCostHome, essentials); + try { + teleport.teleport(loc, trade); + } catch (Exception e) { + player.sendMessage(ChatColor.RED.toString() + e.getMessage()); + } + return true; + } + + public static boolean isVanished(Player player) { + if (essentials == null) { + return false; + } + return essentials.getUser(player).isVanished(); + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/integration/Worldguard.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/integration/Worldguard.java new file mode 100644 index 0000000..4bd0f65 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/integration/Worldguard.java @@ -0,0 +1,132 @@ +package com.massivecraft.factions.integration; + +import com.massivecraft.factions.P; +import com.sk89q.worldedit.BlockVector; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldguard.bukkit.WorldGuardPlugin; +import com.sk89q.worldguard.protection.ApplicableRegionSet; +import com.sk89q.worldguard.protection.flags.DefaultFlag; +import com.sk89q.worldguard.protection.managers.RegionManager; +import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion; +import com.sk89q.worldguard.protection.regions.ProtectedRegion; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector; + +/* + * Worldguard Region Checking + * Author: Spathizilla + */ + +public class Worldguard { + + private static WorldGuardPlugin wg; + private static boolean enabled = false; + + public static void init(Plugin plugin) { + Plugin wgplug = plugin.getServer().getPluginManager().getPlugin("WorldGuard"); + if (wgplug == null || !(wgplug instanceof WorldGuardPlugin)) { + enabled = false; + wg = null; + P.p.log("Could not hook to WorldGuard. WorldGuard checks are disabled."); + } else { + wg = (WorldGuardPlugin) wgplug; + enabled = true; + P.p.log("Successfully hooked to WorldGuard."); + } + } + + public static boolean isEnabled() { + return enabled; + } + + // PVP Flag check + // Returns: + // True: PVP is allowed + // False: PVP is disallowed + public static boolean isPVP(Player player) { + if (!enabled) { + // No WG hooks so we'll always bypass this check. + return true; + } + + Location loc = player.getLocation(); + World world = loc.getWorld(); + Vector pt = toVector(loc); + + RegionManager regionManager = wg.getRegionManager(world); + ApplicableRegionSet set = regionManager.getApplicableRegions(pt); + return set.allows(DefaultFlag.PVP); + } + + // Check if player can build at location by worldguards rules. + // Returns: + // True: Player can build in the region. + // False: Player can not build in the region. + public static boolean playerCanBuild(Player player, Location loc) { + if (!enabled) { + // No WG hooks so we'll always bypass this check. + return false; + } + + World world = loc.getWorld(); + Vector pt = toVector(loc); + + if (wg.getRegionManager(world).getApplicableRegions(pt).size() > 0) { + return wg.canBuild(player, loc); + } + return false; + } + + // Check for Regions in chunk the chunk + // Returns: + // True: Regions found within chunk + // False: No regions found within chunk + public static boolean checkForRegionsInChunk(Location loc) { + if (!enabled) { + // No WG hooks so we'll always bypass this check. + return false; + } + + World world = loc.getWorld(); + Chunk chunk = world.getChunkAt(loc); + int minChunkX = chunk.getX() << 4; + int minChunkZ = chunk.getZ() << 4; + int maxChunkX = minChunkX + 15; + int maxChunkZ = minChunkZ + 15; + + int worldHeight = world.getMaxHeight(); // Allow for heights other than default + + BlockVector minChunk = new BlockVector(minChunkX, 0, minChunkZ); + BlockVector maxChunk = new BlockVector(maxChunkX, worldHeight, maxChunkZ); + + RegionManager regionManager = wg.getRegionManager(world); + ProtectedCuboidRegion region = new ProtectedCuboidRegion("wgfactionoverlapcheck", minChunk, maxChunk); + Map allregions = regionManager.getRegions(); + Collection allregionslist = new ArrayList(allregions.values()); + List overlaps; + boolean foundregions = false; + + try { + overlaps = region.getIntersectingRegions(allregionslist); + if (overlaps == null || overlaps.isEmpty()) { + foundregions = false; + } else { + foundregions = true; + } + } catch (Exception e) { + e.printStackTrace(); + } + + return foundregions; + } +} \ No newline at end of file diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/integration/dynmap/DynmapStyle.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/integration/dynmap/DynmapStyle.java new file mode 100644 index 0000000..e34d78c --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/integration/dynmap/DynmapStyle.java @@ -0,0 +1,113 @@ +package com.massivecraft.factions.integration.dynmap; + +import com.massivecraft.factions.Conf; + +public class DynmapStyle { + // -------------------------------------------- // + // FIELDS + // -------------------------------------------- // + + public String lineColor = null; + + public int getLineColor() { + return getColor(coalesce(this.lineColor, Conf.dynmapDefaultStyle.lineColor, Conf.DYNMAP_STYLE_LINE_COLOR)); + } + + public DynmapStyle setStrokeColor(String strokeColor) { + this.lineColor = strokeColor; + return this; + } + + public Double lineOpacity = null; + + public double getLineOpacity() { + return coalesce(this.lineOpacity, Conf.dynmapDefaultStyle.lineOpacity, Conf.DYNMAP_STYLE_LINE_OPACITY); + } + + public DynmapStyle setLineOpacity(Double strokeOpacity) { + this.lineOpacity = strokeOpacity; + return this; + } + + public Integer lineWeight = null; + + public int getLineWeight() { + return coalesce(this.lineWeight, Conf.dynmapDefaultStyle.lineWeight, Conf.DYNMAP_STYLE_LINE_WEIGHT); + } + + public DynmapStyle setLineWeight(Integer strokeWeight) { + this.lineWeight = strokeWeight; + return this; + } + + public String fillColor = null; + + public int getFillColor() { + return getColor(coalesce(this.fillColor, Conf.dynmapDefaultStyle.fillColor, Conf.DYNMAP_STYLE_FILL_COLOR)); + } + + public DynmapStyle setFillColor(String fillColor) { + this.fillColor = fillColor; + return this; + } + + public Double fillOpacity = null; + + public double getFillOpacity() { + return coalesce(this.fillOpacity, Conf.dynmapDefaultStyle.fillOpacity, Conf.DYNMAP_STYLE_FILL_OPACITY); + } + + public DynmapStyle setFillOpacity(Double fillOpacity) { + this.fillOpacity = fillOpacity; + return this; + } + + // NOTE: We just return the string here. We do not return the resolved Dynmap MarkerIcon object. + // The reason is we use this class in the MConf. For serialization to work Dynmap would have to be loaded and we can't require that. + // Using dynmap is optional. + public String homeMarker = null; + + public String getHomeMarker() { + return coalesce(this.homeMarker, Conf.dynmapDefaultStyle.homeMarker, Conf.DYNMAP_STYLE_HOME_MARKER); + } + + public DynmapStyle setHomeMarker(String homeMarker) { + this.homeMarker = homeMarker; + return this; + } + + public Boolean boost = null; + + public boolean getBoost() { + return coalesce(this.boost, Conf.dynmapDefaultStyle.boost, Conf.DYNMAP_STYLE_BOOST); + } + + public DynmapStyle setBoost(Boolean boost) { + this.boost = boost; + return this; + } + + // -------------------------------------------- // + // UTIL + // -------------------------------------------- // + + @SafeVarargs + public static T coalesce(T... items) { + for (T item : items) { + if (item != null) { + return item; + } + } + return null; + } + + public static int getColor(String string) { + int ret = 0x00FF00; + try { + ret = Integer.parseInt(string.substring(1), 16); + } catch (NumberFormatException ignored) { + } + return ret; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/integration/dynmap/EngineDynmap.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/integration/dynmap/EngineDynmap.java new file mode 100644 index 0000000..40faace --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/integration/dynmap/EngineDynmap.java @@ -0,0 +1,780 @@ +package com.massivecraft.factions.integration.dynmap; + +import com.massivecraft.factions.*; +import com.massivecraft.factions.integration.Econ; +import com.massivecraft.factions.struct.Role; +import com.massivecraft.factions.zcore.persist.MemoryBoard; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.plugin.Plugin; +import org.dynmap.DynmapAPI; +import org.dynmap.markers.*; +import org.dynmap.utils.TileFlags; + +import java.util.*; +import java.util.Map.Entry; + +// This source code is a heavily modified version of mikeprimms plugin Dynmap-Factions. +public class EngineDynmap { + // -------------------------------------------- // + // CONSTANTS + // -------------------------------------------- // + + public final static int BLOCKS_PER_CHUNK = 16; + + public final static String DYNMAP_INTEGRATION = "\u00A7dDynmap Integration: \u00A7e"; + + public final static String FACTIONS = "factions"; + public final static String FACTIONS_ = FACTIONS + "_"; + + public final static String FACTIONS_MARKERSET = FACTIONS_ + "markerset"; + + public final static String FACTIONS_HOME = FACTIONS_ + "home"; + public final static String FACTIONS_HOME_ = FACTIONS_HOME + "_"; + + public final static String FACTIONS_PLAYERSET = FACTIONS_ + "playerset"; + public final static String FACTIONS_PLAYERSET_ = FACTIONS_PLAYERSET + "_"; + + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static EngineDynmap i = new EngineDynmap(); + + public static EngineDynmap getInstance() { + return i; + } + + private EngineDynmap() { + } + + public DynmapAPI dynmapApi; + public MarkerAPI markerApi; + public MarkerSet markerset; + + public void init() { + Plugin dynmap = Bukkit.getServer().getPluginManager().getPlugin("dynmap"); + + if (dynmap == null || !dynmap.isEnabled()) { + return; + } + + // Should we even use dynmap? + if (!Conf.dynmapUse) { + if (this.markerset != null) { + this.markerset.deleteMarkerSet(); + this.markerset = null; + } + return; + } + + // Shedule non thread safe sync at the end! + Bukkit.getScheduler().scheduleSyncRepeatingTask(P.p, new Runnable() { + @Override + public void run() { + + final Map homes = createHomes(); + final Map areas = createAreas(); + final Map> playerSets = createPlayersets(); + + if (!updateCore()) { + return; + } + + // createLayer() is thread safe but it makes use of fields set in updateCore() so we must have it after. + if (!updateLayer(createLayer())) { + return; + } + + updateHomes(homes); + updateAreas(areas); + updatePlayersets(playerSets); + } + }, 100L, 100L); + } + + // Thread Safe / Asynchronous: No + public boolean updateCore() { + // Get DynmapAPI + this.dynmapApi = (DynmapAPI) Bukkit.getPluginManager().getPlugin("dynmap"); + if (this.dynmapApi == null) { + severe("Could not retrieve the DynmapAPI."); + return false; + } + + // Get MarkerAPI + this.markerApi = this.dynmapApi.getMarkerAPI(); + if (this.markerApi == null) { + severe("Could not retrieve the MarkerAPI."); + return false; + } + + return true; + } + + // Thread Safe / Asynchronous: Yes + public TempMarkerSet createLayer() { + TempMarkerSet ret = new TempMarkerSet(); + ret.label = Conf.dynmapLayerName; + ret.minimumZoom = Conf.dynmapLayerMinimumZoom; + ret.priority = Conf.dynmapLayerPriority; + ret.hideByDefault = !Conf.dynmapLayerVisible; + return ret; + } + + // Thread Safe / Asynchronous: No + public boolean updateLayer(TempMarkerSet temp) { + this.markerset = this.markerApi.getMarkerSet(FACTIONS_MARKERSET); + if (this.markerset == null) { + this.markerset = temp.create(this.markerApi, FACTIONS_MARKERSET); + if (this.markerset == null) { + severe("Could not create the Faction Markerset/Layer"); + return false; + } + } else { + temp.update(this.markerset); + } + return true; + } + + // -------------------------------------------- // + // UPDATE: HOMES + // -------------------------------------------- // + + // Thread Safe / Asynchronous: Yes + public Map createHomes() { + Map ret = new HashMap(); + + // Loop current factions + for (Faction faction : Factions.getInstance().getAllFactions()) { + Location ps = faction.getHome(); + if (ps == null) { + continue; + } + + DynmapStyle style = getStyle(faction); + + String markerId = FACTIONS_HOME_ + faction.getId(); + + TempMarker temp = new TempMarker(); + temp.label = ChatColor.stripColor(faction.getTag()); + temp.world = ps.getWorld().toString(); + temp.x = ps.getX(); + temp.y = ps.getY(); + temp.z = ps.getZ(); + temp.iconName = style.getHomeMarker(); + temp.description = getDescription(faction); + + ret.put(markerId, temp); + } + + return ret; + } + + // Thread Safe / Asynchronous: No + // This method places out the faction home markers into the factions markerset. + public void updateHomes(Map homes) { + // Put all current faction markers in a map + Map markers = new HashMap(); + for (Marker marker : this.markerset.getMarkers()) { + markers.put(marker.getMarkerID(), marker); + } + + // Loop homes + for (Entry entry : homes.entrySet()) { + String markerId = entry.getKey(); + TempMarker temp = entry.getValue(); + + // Get Creative + // NOTE: I remove from the map created just in the beginning of this method. + // NOTE: That way what is left at the end will be outdated markers to remove. + Marker marker = markers.remove(markerId); + if (marker == null) { + marker = temp.create(this.markerApi, this.markerset, markerId); + if (marker == null) { + EngineDynmap.severe("Could not get/create the home marker " + markerId); + } + } else { + temp.update(this.markerApi, marker); + } + } + + // Delete Deprecated Markers + // Only old markers should now be left + for (Marker marker : markers.values()) { + marker.deleteMarker(); + } + } + + // -------------------------------------------- // + // UPDATE: AREAS + // -------------------------------------------- // + + // Thread Safe: YES + public Map createAreas() { + Map>> worldFactionChunks = createWorldFactionChunks(); + return createAreas(worldFactionChunks); + } + + // Thread Safe: YES + public Map>> createWorldFactionChunks() { + // Create map "world name --> faction --> set of chunk coords" + Map>> worldFactionChunks = new HashMap>>(); + + // Note: The board is the world. The board id is the world name. + MemoryBoard board = (MemoryBoard) Board.getInstance(); + + for (Entry entry : board.flocationIds.entrySet()) { + String world = entry.getKey().getWorldName(); + Faction chunkOwner = Factions.getInstance().getFactionById(entry.getValue()); + + Map> factionChunks = worldFactionChunks.get(world); + if (factionChunks == null) { + factionChunks = new HashMap>(); + worldFactionChunks.put(world, factionChunks); + } + + Set factionTerritory = factionChunks.get(chunkOwner); + if (factionTerritory == null) { + factionTerritory = new HashSet(); + factionChunks.put(chunkOwner, factionTerritory); + } + + factionTerritory.add(entry.getKey()); + } + + return worldFactionChunks; + } + + // Thread Safe: YES + public Map createAreas(Map>> worldFactionChunks) { + Map ret = new HashMap(); + + // For each world + for (Entry>> entry : worldFactionChunks.entrySet()) { + String world = entry.getKey(); + Map> factionChunks = entry.getValue(); + + // For each faction and its chunks in that world + for (Entry> entry1 : factionChunks.entrySet()) { + Faction faction = entry1.getKey(); + Set chunks = entry1.getValue(); + Map worldFactionMarkers = createAreas(world, faction, chunks); + ret.putAll(worldFactionMarkers); + } + } + + return ret; + } + + // Thread Safe: YES + // Handle specific faction on specific world + // "handle faction on world" + public Map createAreas(String world, Faction faction, Set chunks) { + Map ret = new HashMap(); + + // If the faction is visible ... + if (!isVisible(faction, world)) { + return ret; + } + + // ... and has any chunks ... + if (chunks.isEmpty()) { + return ret; + } + + // Index of polygon for given faction + int markerIndex = 0; + + // Create the info window + String description = getDescription(faction); + + // Fetch Style + DynmapStyle style = this.getStyle(faction); + + // Loop through chunks: set flags on chunk map + TileFlags allChunkFlags = new TileFlags(); + LinkedList allChunks = new LinkedList(); + for (FLocation chunk : chunks) { + allChunkFlags.setFlag((int) chunk.getX(), (int) chunk.getZ(), true); // Set flag for chunk + allChunks.addLast(chunk); + } + + // Loop through until we don't find more areas + while (allChunks != null) { + TileFlags ourChunkFlags = null; + LinkedList ourChunks = null; + LinkedList newChunks = null; + + int minimumX = Integer.MAX_VALUE; + int minimumZ = Integer.MAX_VALUE; + for (FLocation chunk : allChunks) { + int chunkX = (int) chunk.getX(); + int chunkZ = (int) chunk.getZ(); + + // If we need to start shape, and this block is not part of one yet + if (ourChunkFlags == null && allChunkFlags.getFlag(chunkX, chunkZ)) { + ourChunkFlags = new TileFlags(); // Create map for shape + ourChunks = new LinkedList(); + floodFillTarget(allChunkFlags, ourChunkFlags, chunkX, chunkZ); // Copy shape + ourChunks.add(chunk); // Add it to our chunk list + minimumX = chunkX; + minimumZ = chunkZ; + } + // If shape found, and we're in it, add to our node list + else if (ourChunkFlags != null && ourChunkFlags.getFlag(chunkX, chunkZ)) { + ourChunks.add(chunk); + if (chunkX < minimumX) { + minimumX = chunkX; + minimumZ = chunkZ; + } else if (chunkX == minimumX && chunkZ < minimumZ) { + minimumZ = chunkZ; + } + } + // Else, keep it in the list for the next polygon + else { + if (newChunks == null) { + newChunks = new LinkedList(); + } + newChunks.add(chunk); + } + } + + // Replace list (null if no more to process) + allChunks = newChunks; + + if (ourChunkFlags == null) { + continue; + } + + // Trace outline of blocks - start from minx, minz going to x+ + int initialX = minimumX; + int initialZ = minimumZ; + int currentX = minimumX; + int currentZ = minimumZ; + Direction direction = Direction.XPLUS; + ArrayList linelist = new ArrayList(); + linelist.add(new int[]{initialX, initialZ}); // Add start point + while ((currentX != initialX) || (currentZ != initialZ) || (direction != Direction.ZMINUS)) { + switch (direction) { + case XPLUS: // Segment in X+ direction + if (!ourChunkFlags.getFlag(currentX + 1, currentZ)) { // Right turn? + linelist.add(new int[]{currentX + 1, currentZ}); // Finish line + direction = Direction.ZPLUS; // Change direction + } else if (!ourChunkFlags.getFlag(currentX + 1, currentZ - 1)) { // Straight? + currentX++; + } else { // Left turn + linelist.add(new int[]{currentX + 1, currentZ}); // Finish line + direction = Direction.ZMINUS; + currentX++; + currentZ--; + } + break; + case ZPLUS: // Segment in Z+ direction + if (!ourChunkFlags.getFlag(currentX, currentZ + 1)) { // Right turn? + linelist.add(new int[]{currentX + 1, currentZ + 1}); // Finish line + direction = Direction.XMINUS; // Change direction + } else if (!ourChunkFlags.getFlag(currentX + 1, currentZ + 1)) { // Straight? + currentZ++; + } else { // Left turn + linelist.add(new int[]{currentX + 1, currentZ + 1}); // Finish line + direction = Direction.XPLUS; + currentX++; + currentZ++; + } + break; + case XMINUS: // Segment in X- direction + if (!ourChunkFlags.getFlag(currentX - 1, currentZ)) { // Right turn? + linelist.add(new int[]{currentX, currentZ + 1}); // Finish line + direction = Direction.ZMINUS; // Change direction + } else if (!ourChunkFlags.getFlag(currentX - 1, currentZ + 1)) { // Straight? + currentX--; + } else { // Left turn + linelist.add(new int[]{currentX, currentZ + 1}); // Finish line + direction = Direction.ZPLUS; + currentX--; + currentZ++; + } + break; + case ZMINUS: // Segment in Z- direction + if (!ourChunkFlags.getFlag(currentX, currentZ - 1)) { // Right turn? + linelist.add(new int[]{currentX, currentZ}); // Finish line + direction = Direction.XPLUS; // Change direction + } else if (!ourChunkFlags.getFlag(currentX - 1, currentZ - 1)) { // Straight? + currentZ--; + } else { // Left turn + linelist.add(new int[]{currentX, currentZ}); // Finish line + direction = Direction.XMINUS; + currentX--; + currentZ--; + } + break; + } + } + + int sz = linelist.size(); + double[] x = new double[sz]; + double[] z = new double[sz]; + for (int i = 0; i < sz; i++) { + int[] line = linelist.get(i); + x[i] = (double) line[0] * (double) BLOCKS_PER_CHUNK; + z[i] = (double) line[1] * (double) BLOCKS_PER_CHUNK; + } + + // Build information for specific area + String markerId = FACTIONS_ + world + "__" + faction.getId() + "__" + markerIndex; + + TempAreaMarker temp = new TempAreaMarker(); + temp.label = faction.getTag(); + temp.world = world; + temp.x = x; + temp.z = z; + temp.description = description; + + temp.lineColor = style.getLineColor(); + temp.lineOpacity = style.getLineOpacity(); + temp.lineWeight = style.getLineWeight(); + + temp.fillColor = style.getFillColor(); + temp.fillOpacity = style.getFillOpacity(); + + temp.boost = style.getBoost(); + + ret.put(markerId, temp); + + markerIndex++; + } + + return ret; + } + + // Thread Safe: NO + public void updateAreas(Map areas) { + // Map Current + Map markers = new HashMap(); + for (AreaMarker marker : this.markerset.getAreaMarkers()) { + markers.put(marker.getMarkerID(), marker); + } + + // Loop New + for (Entry entry : areas.entrySet()) { + String markerId = entry.getKey(); + TempAreaMarker temp = entry.getValue(); + + // Get Creative + // NOTE: I remove from the map created just in the beginning of this method. + // NOTE: That way what is left at the end will be outdated markers to remove. + AreaMarker marker = markers.remove(markerId); + if (marker == null) { + marker = temp.create(this.markerset, markerId); + if (marker == null) { + severe("Could not get/create the area marker " + markerId); + } + } else { + temp.update(marker); + } + } + + // Only old/outdated should now be left. Delete them. + for (AreaMarker marker : markers.values()) { + marker.deleteMarker(); + } + } + + // -------------------------------------------- // + // UPDATE: PLAYERSET + // -------------------------------------------- // + + // Thread Safe / Asynchronous: Yes + public String createPlayersetId(Faction faction) { + if (faction == null) { + return null; + } + if (faction.isWilderness()) { + return null; + } + String factionId = faction.getId(); + if (factionId == null) { + return null; + } + return FACTIONS_PLAYERSET_ + factionId; + } + + // Thread Safe / Asynchronous: Yes + public Set createPlayerset(Faction faction) { + if (faction == null) { + return null; + } + if (faction.isWilderness()) { + return null; + } + + Set ret = new HashSet(); + + for (FPlayer fplayer : faction.getFPlayers()) { + // NOTE: We add both UUID and name. This might be a good idea for future proofing. + ret.add(fplayer.getId()); + ret.add(fplayer.getName()); + } + + return ret; + } + + // Thread Safe / Asynchronous: Yes + public Map> createPlayersets() { + if (!Conf.dynmapVisibilityByFaction) { + return null; + } + + Map> ret = new HashMap>(); + + for (Faction faction : Factions.getInstance().getAllFactions()) { + String playersetId = createPlayersetId(faction); + if (playersetId == null) { + continue; + } + Set playerIds = createPlayerset(faction); + if (playerIds == null) { + continue; + } + ret.put(playersetId, playerIds); + } + + return ret; + } + + // Thread Safe / Asynchronous: No + public void updatePlayersets(Map> playersets) { + if (playersets == null) { + return; + } + + // Remove + for (PlayerSet set : this.markerApi.getPlayerSets()) { + if (!set.getSetID().startsWith(FACTIONS_PLAYERSET_)) { + continue; + } + + // (Null means remove all) + if (playersets.containsKey(set.getSetID())) { + continue; + } + + set.deleteSet(); + } + + // Add / Update + for (Entry> entry : playersets.entrySet()) { + // Extract from Entry + String setId = entry.getKey(); + Set playerIds = entry.getValue(); + + // Get Creatively + PlayerSet set = this.markerApi.getPlayerSet(setId); + if (set == null) { + set = this.markerApi.createPlayerSet(setId, // id + true, // symmetric + playerIds, // players + false // persistent + ); + } + if (set == null) { + severe("Could not get/create the player set " + setId); + continue; + } + + // Set Content + set.setPlayers(playerIds); + } + } + + // -------------------------------------------- // + // UTIL & SHARED + // -------------------------------------------- // + + // Thread Safe / Asynchronous: Yes + private String getDescription(Faction faction) { + String ret = "

"; + + // Name + String name = faction.getTag(); + name = ChatColor.stripColor(name); + name = escapeHtml(name); + ret = ret.replace("%name%", name); + + // Description + String description = faction.getDescription(); + description = ChatColor.stripColor(description); + description = escapeHtml(description); + ret = ret.replace("%description%", description); + + // Money + + String money = "unavailable"; + if (Conf.bankEnabled && Conf.dynmapDescriptionMoney) { + money = String.format("%.2f", Econ.getBalance(faction.getAccountId())); + } + ret = ret.replace("%money%", money); + + + // Players + Set playersList = faction.getFPlayers(); + String playersCount = String.valueOf(playersList.size()); + String players = getHtmlPlayerString(playersList); + + FPlayer playersLeaderObject = faction.getFPlayerAdmin(); + String playersLeader = getHtmlPlayerName(playersLeaderObject); + + ArrayList playersAdminsList = faction.getFPlayersWhereRole(Role.ADMIN); + String playersAdminsCount = String.valueOf(playersAdminsList.size()); + String playersAdmins = getHtmlPlayerString(playersAdminsList); + + ArrayList playersModeratorsList = faction.getFPlayersWhereRole(Role.MODERATOR); + String playersModeratorsCount = String.valueOf(playersModeratorsList.size()); + String playersModerators = getHtmlPlayerString(playersModeratorsList); + + + ArrayList playersNormalsList = faction.getFPlayersWhereRole(Role.NORMAL); + String playersNormalsCount = String.valueOf(playersNormalsList.size()); + String playersNormals = getHtmlPlayerString(playersNormalsList); + + + ret = ret.replace("%players%", players); + ret = ret.replace("%players.count%", playersCount); + ret = ret.replace("%players.leader%", playersLeader); + ret = ret.replace("%players.admins%", playersAdmins); + ret = ret.replace("%players.admins.count%", playersAdminsCount); + ret = ret.replace("%players.moderators%", playersModerators); + ret = ret.replace("%players.moderators.count%", playersModeratorsCount); + ret = ret.replace("%players.normals%", playersNormals); + ret = ret.replace("%players.normals.count%", playersNormalsCount); + + return ret; + } + + public static String getHtmlPlayerString(Collection playersOfficersList) { + String ret = ""; + for (FPlayer fplayer : playersOfficersList) { + if (ret.length() > 0) { + ret += ", "; + } + ret += getHtmlPlayerName(fplayer); + } + return ret; + } + + public static String getHtmlPlayerName(FPlayer fplayer) { + if (fplayer == null) { + return "none"; + } + return escapeHtml(fplayer.getName()); + } + + public static String escapeHtml(String string) { + StringBuilder out = new StringBuilder(Math.max(16, string.length())); + for (int i = 0; i < string.length(); i++) { + char c = string.charAt(i); + if (c > 127 || c == '"' || c == '<' || c == '>' || c == '&') { + out.append("&#"); + out.append((int) c); + out.append(';'); + } else { + out.append(c); + } + } + return out.toString(); + } + + // Thread Safe / Asynchronous: Yes + private boolean isVisible(Faction faction, String world) { + if (faction == null) { + return false; + } + final String factionId = faction.getId(); + if (factionId == null) { + return false; + } + final String factionName = faction.getTag(); + if (factionName == null) { + return false; + } + + Set visible = Conf.dynmapVisibleFactions; + Set hidden = Conf.dynmapHiddenFactions; + + if (!visible.isEmpty() && !visible.contains(factionId) && !visible.contains(factionName) && !visible.contains("world:" + world)) { + return false; + } + + if (hidden.contains(factionId) || hidden.contains(factionName) || hidden.contains("world:" + world)) { + return false; + } + + return true; + } + + // Thread Safe / Asynchronous: Yes + public DynmapStyle getStyle(Faction faction) { + DynmapStyle ret; + + ret = Conf.dynmapFactionStyles.get(faction.getId()); + if (ret != null) { + return ret; + } + + ret = Conf.dynmapFactionStyles.get(faction.getTag()); + if (ret != null) { + return ret; + } + + return Conf.dynmapDefaultStyle; + } + + // Thread Safe / Asynchronous: Yes + public static void info(String msg) { + String message = DYNMAP_INTEGRATION + msg; + System.out.println(message); + } + + // Thread Safe / Asynchronous: Yes + public static void severe(String msg) { + String message = DYNMAP_INTEGRATION + ChatColor.RED.toString() + msg; + System.out.println(message); + } + + enum Direction { + XPLUS, ZPLUS, XMINUS, ZMINUS + } + + // Find all contiguous blocks, set in target and clear in source + private int floodFillTarget(TileFlags source, TileFlags destination, int x, int y) { + int cnt = 0; + ArrayDeque stack = new ArrayDeque(); + stack.push(new int[]{x, y}); + + while (!stack.isEmpty()) { + int[] nxt = stack.pop(); + x = nxt[0]; + y = nxt[1]; + if (source.getFlag(x, y)) { // Set in src + source.setFlag(x, y, false); // Clear source + destination.setFlag(x, y, true); // Set in destination + cnt++; + if (source.getFlag(x + 1, y)) { + stack.push(new int[]{x + 1, y}); + } + if (source.getFlag(x - 1, y)) { + stack.push(new int[]{x - 1, y}); + } + if (source.getFlag(x, y + 1)) { + stack.push(new int[]{x, y + 1}); + } + if (source.getFlag(x, y - 1)) { + stack.push(new int[]{x, y - 1}); + } + } + } + return cnt; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/integration/dynmap/TempAreaMarker.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/integration/dynmap/TempAreaMarker.java new file mode 100644 index 0000000..f03dff6 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/integration/dynmap/TempAreaMarker.java @@ -0,0 +1,116 @@ +package com.massivecraft.factions.integration.dynmap; + +import org.dynmap.markers.AreaMarker; +import org.dynmap.markers.MarkerSet; + +public class TempAreaMarker { + // -------------------------------------------- // + // FIELDS + // -------------------------------------------- // + + public String label; + public String world; + public double x[]; + public double z[]; + public String description; + + public int lineColor; + public double lineOpacity; + public int lineWeight; + + public int fillColor; + public double fillOpacity; + + public boolean boost; + + // -------------------------------------------- // + // CREATE + // -------------------------------------------- // + + public AreaMarker create(MarkerSet markerset, String markerId) { + AreaMarker ret = markerset.createAreaMarker(markerId, this.label, false, this.world, this.x, this.z, false // not persistent + ); + + if (ret == null) { + return null; + } + + // Description + ret.setDescription(this.description); + + // Line Style + ret.setLineStyle(this.lineWeight, this.lineOpacity, this.lineColor); + + // Fill Style + ret.setFillStyle(this.fillOpacity, this.fillColor); + + // Boost Flag + ret.setBoostFlag(this.boost); + + return ret; + } + + // -------------------------------------------- // + // UPDATE + // -------------------------------------------- // + + public void update(AreaMarker marker) { + // Corner Locations + if (!equals(marker, this.x, this.z)) { + marker.setCornerLocations(this.x, this.z); + } + + // Label + if (!marker.getLabel().equals(this.label)) { + marker.setLabel(this.label); + } + + // Description + if (!marker.getDescription().equals(this.description)) { + marker.setDescription(this.description); + } + + // Line Style + if (marker.getLineWeight() != this.lineWeight || + marker.getLineOpacity() != this.lineOpacity || + marker.getLineColor() != this.lineColor) { + marker.setLineStyle(this.lineWeight, this.lineOpacity, this.lineColor); + } + + // Fill Style + if ((marker.getFillOpacity() != this.fillOpacity) || (marker.getFillColor() != this.fillColor)) { + marker.setFillStyle(this.fillOpacity, this.fillColor); + } + // Boost Flag + if (marker.getBoostFlag() != this.boost) { + marker.setBoostFlag(this.boost); + } + } + + // -------------------------------------------- // + // UTIL + // -------------------------------------------- // + + public static boolean equals(AreaMarker marker, double x[], double z[]) { + int length = marker.getCornerCount(); + + if (x.length != length) { + return false; + } + if (z.length != length) { + return false; + } + + for (int i = 0; i < length; i++) { + if (marker.getCornerX(i) != x[i]) { + return false; + } + if (marker.getCornerZ(i) != z[i]) { + return false; + } + } + + return true; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/integration/dynmap/TempMarker.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/integration/dynmap/TempMarker.java new file mode 100644 index 0000000..ee3bbd5 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/integration/dynmap/TempMarker.java @@ -0,0 +1,74 @@ +package com.massivecraft.factions.integration.dynmap; + +import com.massivecraft.factions.Conf; +import org.dynmap.markers.Marker; +import org.dynmap.markers.MarkerAPI; +import org.dynmap.markers.MarkerIcon; +import org.dynmap.markers.MarkerSet; + +public class TempMarker { + // -------------------------------------------- // + // FIELDS + // -------------------------------------------- // + + public String label; + public String world; + public double x; + public double y; + public double z; + public String iconName; + public String description; + + // -------------------------------------------- // + // CREATE + // -------------------------------------------- // + + public Marker create(MarkerAPI markerApi, MarkerSet markerset, String markerId) { + Marker ret = markerset.createMarker(markerId, this.label, this.world, this.x, this.y, this.z, getMarkerIcon(markerApi, this.iconName), false // not persistent + ); + + if (ret == null) { + return null; + } + + ret.setDescription(this.description); + + return ret; + } + + // -------------------------------------------- // + // UPDATE + // -------------------------------------------- // + + public void update(MarkerAPI markerApi, Marker marker) { + if (!this.world.equals(marker.getWorld()) || this.x != marker.getX() || this.y != marker.getY() || this.z != marker.getZ()) { + marker.setLocation(this.world, this.x, this.y, this.z); + } + + if (!marker.getLabel().equals(this.label)) { + marker.setLabel(this.label); + } + + MarkerIcon icon = getMarkerIcon(markerApi, this.iconName); + if (marker.getMarkerIcon() == null || marker.getMarkerIcon().equals(icon)) { + marker.setMarkerIcon(icon); + } + + if (!marker.getDescription().equals(this.description)) { + marker.setDescription(this.description); + } + } + + // -------------------------------------------- // + // UTIL + // -------------------------------------------- // + + public static MarkerIcon getMarkerIcon(MarkerAPI markerApi, String name) { + MarkerIcon ret = markerApi.getMarkerIcon(name); + if (ret == null) { + ret = markerApi.getMarkerIcon(Conf.DYNMAP_STYLE_HOME_MARKER); + } + return ret; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/integration/dynmap/TempMarkerSet.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/integration/dynmap/TempMarkerSet.java new file mode 100644 index 0000000..553bbde --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/integration/dynmap/TempMarkerSet.java @@ -0,0 +1,55 @@ +package com.massivecraft.factions.integration.dynmap; + +import org.dynmap.markers.MarkerAPI; +import org.dynmap.markers.MarkerSet; + +public class TempMarkerSet { + + public String label; + public int minimumZoom; + public int priority; + public boolean hideByDefault; + + public MarkerSet create(MarkerAPI markerApi, String id) { + MarkerSet ret = markerApi.createMarkerSet(id, this.label, null, false); // ("null, false" at the end means "all icons allowed, not perisistent") + + if (ret == null) { + return null; + } + + // Minimum Zoom + if (this.minimumZoom > 0) { + ret.setMinZoom(this.minimumZoom); + } + + // Priority + ret.setLayerPriority(this.priority); + + // Hide by Default + ret.setHideByDefault(this.hideByDefault); + + return ret; + } + + public void update(MarkerSet markerset) { + // Name + if (!markerset.getMarkerSetLabel().equals(this.label)) { + markerset.setMarkerSetLabel(this.label); + } + + if (this.minimumZoom > 0) { + if (markerset.getMinZoom() != this.minimumZoom) { + markerset.setMinZoom(this.minimumZoom); + } + } + + if (markerset.getLayerPriority() != this.priority) { + markerset.setLayerPriority(this.priority); + } + + if (markerset.getHideByDefault() != this.hideByDefault) { + markerset.setHideByDefault(this.hideByDefault); + } + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/listeners/FactionsBlockListener.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/listeners/FactionsBlockListener.java new file mode 100644 index 0000000..061e34c --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/listeners/FactionsBlockListener.java @@ -0,0 +1,308 @@ +package com.massivecraft.factions.listeners; + +import com.massivecraft.factions.*; +import com.massivecraft.factions.event.LandClaimEvent; +import com.massivecraft.factions.integration.Worldguard; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.struct.Relation; +import net.grandtheftmc.core.util.Utils; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.*; + + +public class FactionsBlockListener implements Listener { + + public P p; + + public FactionsBlockListener(P p) { + this.p = p; + } + + @EventHandler + public void onLandClaim(LandClaimEvent event) { + FPlayer player = event.getfPlayer(); + if(player.getPlayer().getWorld().getName().equalsIgnoreCase("spawn") && !player.getPlayer().isOp()) { + event.setCancelled(true); + Utils.f("&c&l Cartels&8&l> &cYou cannot claim in spawn area!"); + } + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onBlockPlace(BlockPlaceEvent event) { + if (!event.canBuild()) { + return; + } + + // special case for flint&steel, which should only be prevented by DenyUsage list + if (event.getBlockPlaced().getType() == Material.FIRE) { + return; + } + + if (!playerCanBuildDestroyBlock(event.getPlayer(), event.getBlock().getLocation(), "build", false)) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onBlockFromTo(BlockFromToEvent event) { + if (!Conf.handleExploitLiquidFlow) { + return; + } + if (event.getBlock().isLiquid()) { + if (event.getToBlock().isEmpty()) { + Faction from = Board.getInstance().getFactionAt(new FLocation(event.getBlock())); + Faction to = Board.getInstance().getFactionAt(new FLocation(event.getToBlock())); + if (from == to) { + // not concerned with inter-faction events + return; + } + // from faction != to faction + if (to.isNormal()) { + if (from.isNormal() && from.getRelationTo(to).isAlly()) { + return; + } + event.setCancelled(true); + } + } + } + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onBlockBreak(BlockBreakEvent event) { + if (!playerCanBuildDestroyBlock(event.getPlayer(), event.getBlock().getLocation(), "destroy", false)) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onBlockDamage(BlockDamageEvent event) { + if (event.getInstaBreak() && !playerCanBuildDestroyBlock(event.getPlayer(), event.getBlock().getLocation(), "destroy", false)) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onBlockPistonExtend(BlockPistonExtendEvent event) { + if (!Conf.pistonProtectionThroughDenyBuild) { + return; + } + + Faction pistonFaction = Board.getInstance().getFactionAt(new FLocation(event.getBlock())); + + // target end-of-the-line empty (air) block which is being pushed into, including if piston itself would extend into air + Block targetBlock = event.getBlock().getRelative(event.getDirection(), event.getLength() + 1); + + // if potentially pushing into air/water/lava in another territory, we need to check it out + if ((targetBlock.isEmpty() || targetBlock.isLiquid()) && !canPistonMoveBlock(pistonFaction, targetBlock.getLocation())) { + event.setCancelled(true); + return; + } + + /* + * note that I originally was testing the territory of each affected block, but since I found that pistons can only push + * up to 12 blocks and the width of any territory is 16 blocks, it should be safe (and much more lightweight) to test + * only the final target block as done above + */ + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onBlockPistonRetract(BlockPistonRetractEvent event) { + // if not a sticky piston, retraction should be fine + if (!event.isSticky() || !Conf.pistonProtectionThroughDenyBuild) { + return; + } + + Location targetLoc = event.getRetractLocation(); + Faction otherFaction = Board.getInstance().getFactionAt(new FLocation(targetLoc)); + + // Check if the piston is moving in a faction's territory. This disables pistons entirely in faction territory. + if (otherFaction.isNormal() && P.p.getConfig().getBoolean("disable-pistons-in-territory", false)) { + event.setCancelled(true); + return; + } + + // if potentially retracted block is just air/water/lava, no worries + if (targetLoc.getBlock().isEmpty() || targetLoc.getBlock().isLiquid()) { + return; + } + + Faction pistonFaction = Board.getInstance().getFactionAt(new FLocation(event.getBlock())); + + if (!canPistonMoveBlock(pistonFaction, targetLoc)) { + event.setCancelled(true); + return; + } + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onFrostWalker(EntityBlockFormEvent event) { + if (event.getEntity() == null || event.getEntity().getType() != EntityType.PLAYER || event.getBlock() == null) { + return; + } + + Player player = (Player) event.getEntity(); + Location location = event.getBlock().getLocation(); + + // only notify every 10 seconds + FPlayer fPlayer = FPlayers.getInstance().getByPlayer(player); + boolean justCheck = fPlayer.getLastFrostwalkerMessage() + 10000 > System.currentTimeMillis(); + if (!justCheck) { + fPlayer.setLastFrostwalkerMessage(); + } + + // Check if they have build permissions here. If not, block this from happening. + if (!playerCanBuildDestroyBlock(player, location, "frost walk", justCheck)) { + event.setCancelled(true); + } + } + + private boolean canPistonMoveBlock(Faction pistonFaction, Location target) { + + Faction otherFaction = Board.getInstance().getFactionAt(new FLocation(target)); + + if (pistonFaction == otherFaction) { + return true; + } + + if (otherFaction.isWilderness()) { + if (!Conf.wildernessDenyBuild || Conf.worldsNoWildernessProtection.contains(target.getWorld().getName())) { + return true; + } + + return false; + } else if (otherFaction.isSafeZone()) { + if (!Conf.safeZoneDenyBuild) { + return true; + } + + return false; + } else if (otherFaction.isWarZone()) { + if (!Conf.warZoneDenyBuild) { + return true; + } + + return false; + } + + Relation rel = pistonFaction.getRelationTo(otherFaction); + + if (rel.confDenyBuild(otherFaction.hasPlayersOnline())) { + return false; + } + + return true; + } + + public static boolean playerCanBuildDestroyBlock(Player player, Location location, String action, boolean justCheck) { + String name = player.getName(); + if (Conf.playersWhoBypassAllProtection.contains(name)) { + return true; + } + + FPlayer me = FPlayers.getInstance().getById(player.getUniqueId().toString()); + if (me.isAdminBypassing()) { + return true; + } + + FLocation loc = new FLocation(location); + Faction otherFaction = Board.getInstance().getFactionAt(loc); + + if (otherFaction.isWilderness()) { + if (Conf.worldGuardBuildPriority && Worldguard.playerCanBuild(player, location)) { + return true; + } + + if (!Conf.wildernessDenyBuild || Conf.worldsNoWildernessProtection.contains(location.getWorld().getName())) { + return true; // This is not faction territory. Use whatever you like here. + } + + if (!justCheck) { + me.msg("You can't " + action + " in the wilderness."); + } + + return false; + } else if (otherFaction.isSafeZone()) { + if (Conf.worldGuardBuildPriority && Worldguard.playerCanBuild(player, location)) { + return true; + } + + if (!Conf.safeZoneDenyBuild || Permission.MANAGE_SAFE_ZONE.has(player)) { + return true; + } + + if (!justCheck) { + me.msg("You can't " + action + " in a safe zone."); + } + + return false; + } else if (otherFaction.isWarZone()) { + if (Conf.worldGuardBuildPriority && Worldguard.playerCanBuild(player, location)) { + return true; + } + + if (!Conf.warZoneDenyBuild || Permission.MANAGE_WAR_ZONE.has(player)) { + return true; + } + + if (!justCheck) { + me.msg("You can't " + action + " in a war zone."); + } + + return false; + } + if (P.p.getConfig().getBoolean("hcf.raidable", false) && otherFaction.getLandRounded() >= otherFaction.getPowerRounded()) { + return true; + } + + Faction myFaction = me.getFaction(); + Relation rel = myFaction.getRelationTo(otherFaction); + boolean online = otherFaction.hasPlayersOnline(); + boolean pain = !justCheck && rel.confPainBuild(online); + boolean deny = rel.confDenyBuild(online); + + // hurt the player for building/destroying in other territory? + if (pain) { + player.damage(Conf.actionDeniedPainAmount); + + if (!deny) { + me.msg("It is painful to try to " + action + " in the territory of " + otherFaction.getTag(myFaction)); + } + } + + // cancel building/destroying in other territory? + if (deny) { + if (!justCheck) { + me.msg("You can't " + action + " in the territory of " + otherFaction.getTag(myFaction)); + } + + return false; + } + + // Also cancel and/or cause pain if player doesn't have ownership rights for this claim + if (Conf.ownedAreasEnabled && (Conf.ownedAreaDenyBuild || Conf.ownedAreaPainBuild) && !otherFaction.playerHasOwnershipRights(me, loc)) { + if (!pain && Conf.ownedAreaPainBuild && !justCheck) { + player.damage(Conf.actionDeniedPainAmount); + + if (!Conf.ownedAreaDenyBuild) { + me.msg("It is painful to try to " + action + " in this territory, it is owned by: " + otherFaction.getOwnerListString(loc)); + } + } + if (Conf.ownedAreaDenyBuild) { + if (!justCheck) { + me.msg("You can't " + action + " in this territory, it is owned by: " + otherFaction.getOwnerListString(loc)); + } + + return false; + } + } + + return true; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/listeners/FactionsChatListener.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/listeners/FactionsChatListener.java new file mode 100644 index 0000000..00d2513 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/listeners/FactionsChatListener.java @@ -0,0 +1,164 @@ +package com.massivecraft.factions.listeners; + +import com.massivecraft.factions.*; +import com.massivecraft.factions.struct.ChatMode; +import com.massivecraft.factions.struct.Relation; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; + +import java.util.UnknownFormatConversionException; +import java.util.logging.Level; + + +public class FactionsChatListener implements Listener { + + public P p; + + public FactionsChatListener(P p) { + this.p = p; + } + + // this is for handling slashless command usage and faction/alliance chat, set at lowest priority so Factions gets to them first + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onPlayerEarlyChat(AsyncPlayerChatEvent event) { + Player talkingPlayer = event.getPlayer(); + String msg = event.getMessage(); + FPlayer me = FPlayers.getInstance().getByPlayer(talkingPlayer); + ChatMode chat = me.getChatMode(); + + // Is it a faction chat message? + if (chat == ChatMode.FACTION) { + Faction myFaction = me.getFaction(); + + String message = String.format(Conf.factionChatFormat, me.describeTo(myFaction), msg); + myFaction.sendMessage(message); + + Bukkit.getLogger().log(Level.INFO, ChatColor.stripColor("CartelChat " + myFaction.getTag() + ": " + message)); + + //Send to any players who are spying chat + for (FPlayer fplayer : FPlayers.getInstance().getOnlinePlayers()) { + if (fplayer.isSpyingChat() && fplayer.getFaction() != myFaction && me != fplayer) { + fplayer.sendMessage("[CCspy] " + myFaction.getTag() + ": " + message); + } + } + + event.setCancelled(true); + } else if (chat == ChatMode.ALLIANCE) { + Faction myFaction = me.getFaction(); + + String message = String.format(Conf.allianceChatFormat, ChatColor.stripColor(me.getNameAndTag()), msg); + + //Send message to our own faction + myFaction.sendMessage(message); + + //Send to all our allies + for (FPlayer fplayer : FPlayers.getInstance().getOnlinePlayers()) { + if (myFaction.getRelationTo(fplayer) == Relation.ALLY && !fplayer.isIgnoreAllianceChat()) { + fplayer.sendMessage(message); + } else if (fplayer.isSpyingChat() && me != fplayer) { + fplayer.sendMessage("[ACspy]: " + message); + } + } + + Bukkit.getLogger().log(Level.INFO, ChatColor.stripColor("AllianceChat: " + message)); + + event.setCancelled(true); + } else if (chat == ChatMode.TRUCE) { + Faction myFaction = me.getFaction(); + + String message = String.format(Conf.truceChatFormat, ChatColor.stripColor(me.getNameAndTag()), msg); + + //Send message to our own faction + myFaction.sendMessage(message); + + //Send to all our truces + for (FPlayer fplayer : FPlayers.getInstance().getOnlinePlayers()) { + if (myFaction.getRelationTo(fplayer) == Relation.TRUCE) { + fplayer.sendMessage(message); + } else if (fplayer.isSpyingChat() && fplayer != me) { + fplayer.sendMessage("[TCspy]: " + message); + } + } + + Bukkit.getLogger().log(Level.INFO, ChatColor.stripColor("TruceChat: " + message)); + event.setCancelled(true); + } + } + + // this is for handling insertion of the player's faction tag, set at highest priority to give other plugins a chance to modify chat first + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onPlayerChat(AsyncPlayerChatEvent event) { + // Are we to insert the Faction tag into the format? + // If we are not to insert it - we are done. + if (!Conf.chatTagEnabled || Conf.chatTagHandledByAnotherPlugin) { + return; + } + + Player talkingPlayer = event.getPlayer(); + String msg = event.getMessage(); + String eventFormat = event.getFormat(); + FPlayer me = FPlayers.getInstance().getByPlayer(talkingPlayer); + int InsertIndex; + + if (!Conf.chatTagReplaceString.isEmpty() && eventFormat.contains(Conf.chatTagReplaceString)) { + // we're using the "replace" method of inserting the faction tags + if (eventFormat.contains("[FACTION_TITLE]")) { + eventFormat = eventFormat.replace("[FACTION_TITLE]", me.getTitle()); + } + InsertIndex = eventFormat.indexOf(Conf.chatTagReplaceString); + eventFormat = eventFormat.replace(Conf.chatTagReplaceString, ""); + Conf.chatTagPadAfter = false; + Conf.chatTagPadBefore = false; + } else if (!Conf.chatTagInsertAfterString.isEmpty() && eventFormat.contains(Conf.chatTagInsertAfterString)) { + // we're using the "insert after string" method + InsertIndex = eventFormat.indexOf(Conf.chatTagInsertAfterString) + Conf.chatTagInsertAfterString.length(); + } else if (!Conf.chatTagInsertBeforeString.isEmpty() && eventFormat.contains(Conf.chatTagInsertBeforeString)) { + // we're using the "insert before string" method + InsertIndex = eventFormat.indexOf(Conf.chatTagInsertBeforeString); + } else { + // we'll fall back to using the index place method + InsertIndex = Conf.chatTagInsertIndex; + if (InsertIndex > eventFormat.length()) { + return; + } + } + + String formatStart = eventFormat.substring(0, InsertIndex) + ((Conf.chatTagPadBefore && !me.getChatTag().isEmpty()) ? " " : ""); + String formatEnd = ((Conf.chatTagPadAfter && !me.getChatTag().isEmpty()) ? " " : "") + eventFormat.substring(InsertIndex); + + String nonColoredMsgFormat = formatStart + me.getChatTag().trim() + formatEnd; + + // Relation Colored? + if (Conf.chatTagRelationColored) { + // We must choke the standard message and send out individual messages to all players + // Why? Because the relations will differ. + event.setCancelled(true); + + for (Player listeningPlayer : event.getRecipients()) { + FPlayer you = FPlayers.getInstance().getByPlayer(listeningPlayer); + String yourFormat = formatStart + me.getChatTag(you).trim() + formatEnd; + try { + listeningPlayer.sendMessage(String.format(yourFormat, talkingPlayer.getDisplayName(), msg)); + } catch (UnknownFormatConversionException ex) { + Conf.chatTagInsertIndex = 0; + P.p.log(Level.SEVERE, "Critical error in chat message formatting!"); + P.p.log(Level.SEVERE, "NOTE: This has been automatically fixed right now by setting chatTagInsertIndex to 0."); + P.p.log(Level.SEVERE, "For a more proper fix, please read this regarding chat configuration: http://massivecraft.com/plugins/factions/config#Chat_configuration"); + return; + } + } + + // Write to the log... We will write the non colored message. + String nonColoredMsg = ChatColor.stripColor(String.format(nonColoredMsgFormat, talkingPlayer.getDisplayName(), msg)); + Bukkit.getLogger().log(Level.INFO, nonColoredMsg); + } else { + // No relation color. + event.setFormat(nonColoredMsgFormat); + } + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/listeners/FactionsEntityListener.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/listeners/FactionsEntityListener.java new file mode 100644 index 0000000..4fa5d5b --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/listeners/FactionsEntityListener.java @@ -0,0 +1,586 @@ +package com.massivecraft.factions.listeners; + +import com.massivecraft.factions.*; +import com.massivecraft.factions.event.PowerLossEvent; +import com.massivecraft.factions.struct.Relation; +import com.massivecraft.factions.util.MiscUtil; +import com.massivecraft.factions.zcore.util.TL; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.TravelAgent; +import org.bukkit.block.Block; +import org.bukkit.entity.*; +import org.bukkit.entity.minecart.ExplosiveMinecart; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.*; +import org.bukkit.event.hanging.HangingBreakByEntityEvent; +import org.bukkit.event.hanging.HangingBreakEvent; +import org.bukkit.event.hanging.HangingBreakEvent.RemoveCause; +import org.bukkit.event.hanging.HangingPlaceEvent; +import org.bukkit.event.player.PlayerPortalEvent; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.projectiles.ProjectileSource; + +import java.util.*; + + +public class FactionsEntityListener implements Listener { + + public P p; + + public FactionsEntityListener(P p) { + this.p = p; + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onEntityDeath(EntityDeathEvent event) { + Entity entity = event.getEntity(); + if (!(entity instanceof Player)) { + return; + } + + Player player = (Player) entity; + FPlayer fplayer = FPlayers.getInstance().getByPlayer(player); + Faction faction = Board.getInstance().getFactionAt(new FLocation(player.getLocation())); + + PowerLossEvent powerLossEvent = new PowerLossEvent(faction, fplayer); + // Check for no power loss conditions + if (faction.isWarZone()) { + // war zones always override worldsNoPowerLoss either way, thus this layout + if (!Conf.warZonePowerLoss) { + powerLossEvent.setMessage(TL.PLAYER_POWER_NOLOSS_WARZONE.toString()); + powerLossEvent.setCancelled(true); + } + if (Conf.worldsNoPowerLoss.contains(player.getWorld().getName())) { + powerLossEvent.setMessage(TL.PLAYER_POWER_LOSS_WARZONE.toString()); + } + } else if (faction.isWilderness() && !Conf.wildernessPowerLoss && !Conf.worldsNoWildernessProtection.contains(player.getWorld().getName())) { + powerLossEvent.setMessage(TL.PLAYER_POWER_NOLOSS_WILDERNESS.toString()); + powerLossEvent.setCancelled(true); + } else if (Conf.worldsNoPowerLoss.contains(player.getWorld().getName())) { + powerLossEvent.setMessage(TL.PLAYER_POWER_NOLOSS_WORLD.toString()); + powerLossEvent.setCancelled(true); + } else if (Conf.peacefulMembersDisablePowerLoss && fplayer.hasFaction() && fplayer.getFaction().isPeaceful()) { + powerLossEvent.setMessage(TL.PLAYER_POWER_NOLOSS_PEACEFUL.toString()); + powerLossEvent.setCancelled(true); + } else { + powerLossEvent.setMessage(TL.PLAYER_POWER_NOW.toString()); + } + + // call Event + Bukkit.getPluginManager().callEvent(powerLossEvent); + + // Call player onDeath if the event is not cancelled + if (!powerLossEvent.isCancelled()) { + fplayer.onDeath(); + } + // Send the message from the powerLossEvent + final String msg = powerLossEvent.getMessage(); + if (msg != null && !msg.isEmpty()) { + fplayer.msg(msg, fplayer.getPowerRounded(), fplayer.getPowerMaxRounded()); + } + } + + /** + * Who can I hurt? I can never hurt members or allies. I can always hurt enemies. I can hurt neutrals as long as + * they are outside their own territory. + */ + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onEntityDamage(EntityDamageEvent event) { + if (event instanceof EntityDamageByEntityEvent) { + EntityDamageByEntityEvent sub = (EntityDamageByEntityEvent) event; + if (!this.canDamagerHurtDamagee(sub, true)) { + event.setCancelled(true); + } + // event is not cancelled by factions + + Entity damagee = sub.getEntity(); + Entity damager = sub.getDamager(); + + if (damagee != null && damagee instanceof Player) { + cancelFStuckTeleport((Player) damagee); + } + if (damager instanceof Player) { + cancelFStuckTeleport((Player) damager); + } + } else if (Conf.safeZonePreventAllDamageToPlayers && isPlayerInSafeZone(event.getEntity())) { + // Players can not take any damage in a Safe Zone + event.setCancelled(true); + } + + // entity took generic damage? + Entity entity = event.getEntity(); + if (entity instanceof Player) { + Player player = (Player) entity; + FPlayer me = FPlayers.getInstance().getByPlayer(player); + cancelFStuckTeleport(player); + if (me.isWarmingUp()) { + me.clearWarmup(); + me.msg(TL.WARMUPS_CANCELLED); + } + } + } + + public void cancelFStuckTeleport(Player player) { + if (player == null) { + return; + } + UUID uuid = player.getUniqueId(); + if (P.p.getStuckMap().containsKey(uuid)) { + FPlayers.getInstance().getByPlayer(player).msg(TL.COMMAND_STUCK_CANCELLED); + P.p.getStuckMap().remove(uuid); + } + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onEntityExplode(EntityExplodeEvent event) { + Location loc = event.getLocation(); + Entity boomer = event.getEntity(); + Faction faction = Board.getInstance().getFactionAt(new FLocation(loc)); + + if (faction.noExplosionsInTerritory() || (faction.isPeaceful() && Conf.peacefulTerritoryDisableBoom)) { + // faction is peaceful and has explosions set to disabled + event.setCancelled(true); + return; + } + + boolean online = faction.hasPlayersOnline(); + + //TODO: :( + if (boomer instanceof Creeper && ((faction.isWilderness() && Conf.wildernessBlockCreepers && !Conf.worldsNoWildernessProtection.contains(loc.getWorld().getName())) || + (faction.isNormal() && (online ? Conf.territoryBlockCreepers : Conf.territoryBlockCreepersWhenOffline)) || + (faction.isWarZone() && Conf.warZoneBlockCreepers) || + faction.isSafeZone())) { + // creeper which needs prevention + event.setCancelled(true); + } else if ( + // it's a bit crude just using fireball protection for Wither boss too, but I'd rather not add in a whole new set of xxxBlockWitherExplosion or whatever + (boomer instanceof Fireball || boomer instanceof WitherSkull || boomer instanceof Wither) && ((faction.isWilderness() && Conf.wildernessBlockFireballs && !Conf.worldsNoWildernessProtection.contains(loc.getWorld().getName())) || + (faction.isNormal() && (online ? Conf.territoryBlockFireballs : Conf.territoryBlockFireballsWhenOffline)) || + (faction.isWarZone() && Conf.warZoneBlockFireballs) || + faction.isSafeZone())) { + // ghast fireball which needs prevention + event.setCancelled(true); + } else if ((boomer instanceof TNTPrimed || boomer instanceof ExplosiveMinecart) && ((faction.isWilderness() && Conf.wildernessBlockTNT && !Conf.worldsNoWildernessProtection.contains(loc.getWorld().getName())) || + (faction.isNormal() && (online ? Conf.territoryBlockTNT : Conf.territoryBlockTNTWhenOffline)) || + (faction.isWarZone() && Conf.warZoneBlockTNT) || + (faction.isSafeZone() && Conf.safeZoneBlockTNT))) { + // TNT which needs prevention + event.setCancelled(true); + } else if ((boomer instanceof TNTPrimed || boomer instanceof ExplosiveMinecart) && Conf.handleExploitTNTWaterlog) { + // TNT in water/lava doesn't normally destroy any surrounding blocks, which is usually desired behavior, but... + // this change below provides workaround for waterwalling providing perfect protection, + // and makes cheap (non-obsidian) TNT cannons require minor maintenance between shots + Block center = loc.getBlock(); + if (center.isLiquid()) { + // a single surrounding block in all 6 directions is broken if the material is weak enough + List targets = new ArrayList(); + targets.add(center.getRelative(0, 0, 1)); + targets.add(center.getRelative(0, 0, -1)); + targets.add(center.getRelative(0, 1, 0)); + targets.add(center.getRelative(0, -1, 0)); + targets.add(center.getRelative(1, 0, 0)); + targets.add(center.getRelative(-1, 0, 0)); + for (Block target : targets) { + int id = target.getTypeId(); + // ignore air, bedrock, water, lava, obsidian, enchanting table, etc.... too bad we can't get a blast resistance value through Bukkit yet + if (id != 0 && (id < 7 || id > 11) && id != 49 && id != 90 && id != 116 && id != 119 && id != 120 && id != 130) { + target.breakNaturally(); + } + } + } + } + } + + // mainly for flaming arrows; don't want allies or people in safe zones to be ignited even after damage event is cancelled + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onEntityCombustByEntity(EntityCombustByEntityEvent event) { + EntityDamageByEntityEvent sub = new EntityDamageByEntityEvent(event.getCombuster(), event.getEntity(), EntityDamageEvent.DamageCause.FIRE, 0d); + if (!this.canDamagerHurtDamagee(sub, false)) { + event.setCancelled(true); + } + sub = null; + } + + private static final Set badPotionEffects = new LinkedHashSet(Arrays.asList(PotionEffectType.BLINDNESS, PotionEffectType.CONFUSION, PotionEffectType.HARM, PotionEffectType.HUNGER, PotionEffectType.POISON, PotionEffectType.SLOW, PotionEffectType.SLOW_DIGGING, PotionEffectType.WEAKNESS, PotionEffectType.WITHER)); + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onPotionSplashEvent(PotionSplashEvent event) { + // see if the potion has a harmful effect + boolean badjuju = false; + for (PotionEffect effect : event.getPotion().getEffects()) { + if (badPotionEffects.contains(effect.getType())) { + badjuju = true; + break; + } + } + if (!badjuju) { + return; + } + + ProjectileSource thrower = event.getPotion().getShooter(); + if (!(thrower instanceof Entity)) { + return; + } + + if (thrower instanceof Player) { + Player player = (Player) thrower; + FPlayer fPlayer = FPlayers.getInstance().getByPlayer(player); + if (badjuju && fPlayer.getFaction().isPeaceful()) { + event.setCancelled(true); + return; + } + } + + // scan through affected entities to make sure they're all valid targets + Iterator iter = event.getAffectedEntities().iterator(); + while (iter.hasNext()) { + LivingEntity target = iter.next(); + EntityDamageByEntityEvent sub = new EntityDamageByEntityEvent((Entity) thrower, target, EntityDamageEvent.DamageCause.CUSTOM, 0); + if (!this.canDamagerHurtDamagee(sub, true)) { + event.setIntensity(target, 0.0); // affected entity list doesn't accept modification (so no iter.remove()), but this works + } + sub = null; + } + } + + public boolean isPlayerInSafeZone(Entity damagee) { + if (!(damagee instanceof Player)) { + return false; + } + if (Board.getInstance().getFactionAt(new FLocation(damagee.getLocation())).isSafeZone()) { + return true; + } + return false; + } + + public boolean canDamagerHurtDamagee(EntityDamageByEntityEvent sub) { + return canDamagerHurtDamagee(sub, true); + } + + public boolean canDamagerHurtDamagee(EntityDamageByEntityEvent sub, boolean notify) { + Entity damager = sub.getDamager(); + Entity damagee = sub.getEntity(); + + if (!(damagee instanceof Player)) { + return true; + } + + FPlayer defender = FPlayers.getInstance().getByPlayer((Player) damagee); + + if (defender == null || defender.getPlayer() == null) { + return true; + } + + Location defenderLoc = defender.getPlayer().getLocation(); + Faction defLocFaction = Board.getInstance().getFactionAt(new FLocation(defenderLoc)); + + // for damage caused by projectiles, getDamager() returns the projectile... what we need to know is the source + if (damager instanceof Projectile) { + Projectile projectile = (Projectile) damager; + + if (!(projectile.getShooter() instanceof Entity)) { + return true; + } + + damager = (Entity) projectile.getShooter(); + } + + if (damager == damagee) // ender pearl usage and other self-inflicted damage + { + return true; + } + + // Players can not take attack damage in a SafeZone, or possibly peaceful territory + if (defLocFaction.noPvPInTerritory()) { + if (damager instanceof Player) { + if (notify) { + FPlayer attacker = FPlayers.getInstance().getByPlayer((Player) damager); + attacker.msg(TL.PLAYER_CANTHURT, (defLocFaction.isSafeZone() ? TL.REGION_SAFEZONE.toString() : TL.REGION_PEACEFUL.toString())); + } + return false; + } + return !defLocFaction.noMonstersInTerritory(); + } + + if (!(damager instanceof Player)) { + return true; + } + + FPlayer attacker = FPlayers.getInstance().getByPlayer((Player) damager); + + if (attacker == null || attacker.getPlayer() == null) { + return true; + } + + if (Conf.playersWhoBypassAllProtection.contains(attacker.getName())) { + return true; + } + + if (attacker.hasLoginPvpDisabled()) { + if (notify) { + attacker.msg(TL.PLAYER_PVP_LOGIN, Conf.noPVPDamageToOthersForXSecondsAfterLogin); + } + return false; + } + + Faction locFaction = Board.getInstance().getFactionAt(new FLocation(attacker)); + + // so we know from above that the defender isn't in a safezone... what about the attacker, sneaky dog that he might be? + if (locFaction.noPvPInTerritory()) { + if (notify) { + attacker.msg(TL.PLAYER_CANTHURT, (locFaction.isSafeZone() ? TL.REGION_SAFEZONE.toString() : TL.REGION_PEACEFUL.toString())); + } + return false; + } + + if (locFaction.isWarZone() && Conf.warZoneFriendlyFire) { + return true; + } + + if (Conf.worldsIgnorePvP.contains(defenderLoc.getWorld().getName())) { + return true; + } + + Faction defendFaction = defender.getFaction(); + Faction attackFaction = attacker.getFaction(); + + if (attackFaction.isWilderness() && Conf.disablePVPForFactionlessPlayers) { + if (notify) { + attacker.msg(TL.PLAYER_PVP_REQUIREFACTION); + } + return false; + } else if (defendFaction.isWilderness()) { + if (defLocFaction == attackFaction && Conf.enablePVPAgainstFactionlessInAttackersLand) { + // Allow PVP vs. Factionless in attacker's faction territory + return true; + } else if (Conf.disablePVPForFactionlessPlayers) { + if (notify) { + attacker.msg(TL.PLAYER_PVP_FACTIONLESS); + } + return false; + } + } + + if (defendFaction.isPeaceful()) { + if (notify) { + attacker.msg(TL.PLAYER_PVP_PEACEFUL); + } + return false; + } else if (attackFaction.isPeaceful()) { + if (notify) { + attacker.msg(TL.PLAYER_PVP_PEACEFUL); + } + return false; + } + + Relation relation = defendFaction.getRelationTo(attackFaction); + + // You can not hurt neutral factions + if (Conf.disablePVPBetweenNeutralFactions && relation.isNeutral()) { + if (notify) { + attacker.msg(TL.PLAYER_PVP_NEUTRAL); + } + return false; + } + + // Players without faction may be hurt anywhere + if (!defender.hasFaction()) { + return true; + } + + // You can never hurt faction members or allies + if (relation.isMember() || relation.isAlly()) { + if (notify) { + attacker.msg(TL.PLAYER_PVP_CANTHURT, defender.describeTo(attacker)); + } + return false; + } + + boolean ownTerritory = defender.isInOwnTerritory(); + + // You can not hurt neutrals in their own territory. + if (ownTerritory && relation.isNeutral()) { + if (notify) { + attacker.msg(TL.PLAYER_PVP_NEUTRALFAIL, defender.describeTo(attacker)); + defender.msg(TL.PLAYER_PVP_TRIED, attacker.describeTo(defender, true)); + } + return false; + } + + // Damage will be dealt. However check if the damage should be reduced. + /* + if (damage > 0.0 && ownTerritory && Conf.territoryShieldFactor > 0) { + double newDamage = Math.ceil(damage * (1D - Conf.territoryShieldFactor)); + sub.setDamage(newDamage); + + // Send message + if (notify) { + String perc = MessageFormat.format("{0,number,#%}", (Conf.territoryShieldFactor)); // TODO does this display correctly?? + defender.msg("Enemy damage reduced by %s.", perc); + } + } */ + + return true; + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onCreatureSpawn(CreatureSpawnEvent event) { + if (event.getLocation() == null) { + return; + } + + if (Conf.safeZoneNerfedCreatureTypes.contains(event.getEntityType()) && Board.getInstance().getFactionAt(new FLocation(event.getLocation())).noMonstersInTerritory()) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onEntityTarget(EntityTargetEvent event) { + // if there is a target + Entity target = event.getTarget(); + if (target == null) { + return; + } + + // We are interested in blocking targeting for certain mobs: + if (!Conf.safeZoneNerfedCreatureTypes.contains(MiscUtil.creatureTypeFromEntity(event.getEntity()))) { + return; + } + + // in case the target is in a safe zone. + if (Board.getInstance().getFactionAt(new FLocation(target.getLocation())).noMonstersInTerritory()) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onPaintingBreak(HangingBreakEvent event) { + if (event.getCause() == RemoveCause.EXPLOSION) { + Location loc = event.getEntity().getLocation(); + Faction faction = Board.getInstance().getFactionAt(new FLocation(loc)); + if (faction.noExplosionsInTerritory()) { + // faction is peaceful and has explosions set to disabled + event.setCancelled(true); + return; + } + + boolean online = faction.hasPlayersOnline(); + + if ((faction.isWilderness() && !Conf.worldsNoWildernessProtection.contains(loc.getWorld().getName()) && (Conf.wildernessBlockCreepers || Conf.wildernessBlockFireballs || Conf.wildernessBlockTNT)) || + (faction.isNormal() && (online ? (Conf.territoryBlockCreepers || Conf.territoryBlockFireballs || Conf.territoryBlockTNT) : (Conf.territoryBlockCreepersWhenOffline || Conf.territoryBlockFireballsWhenOffline || Conf.territoryBlockTNTWhenOffline))) || + (faction.isWarZone() && (Conf.warZoneBlockCreepers || Conf.warZoneBlockFireballs || Conf.warZoneBlockTNT)) || + faction.isSafeZone()) { + // explosion which needs prevention + event.setCancelled(true); + } + } + + if (!(event instanceof HangingBreakByEntityEvent)) { + return; + } + + Entity breaker = ((HangingBreakByEntityEvent) event).getRemover(); + if (!(breaker instanceof Player)) { + return; + } + + if (!FactionsBlockListener.playerCanBuildDestroyBlock((Player) breaker, event.getEntity().getLocation(), "remove paintings", false)) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onPaintingPlace(HangingPlaceEvent event) { + if (!FactionsBlockListener.playerCanBuildDestroyBlock(event.getPlayer(), event.getBlock().getLocation(), "place paintings", false)) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onEntityChangeBlock(EntityChangeBlockEvent event) { + Entity entity = event.getEntity(); + + // for now, only interested in Enderman and Wither boss tomfoolery + if (!(entity instanceof Enderman) && !(entity instanceof Wither)) { + return; + } + + Location loc = event.getBlock().getLocation(); + + if (entity instanceof Enderman) { + if (stopEndermanBlockManipulation(loc)) { + event.setCancelled(true); + } + } else if (entity instanceof Wither) { + Faction faction = Board.getInstance().getFactionAt(new FLocation(loc)); + // it's a bit crude just using fireball protection, but I'd rather not add in a whole new set of xxxBlockWitherExplosion or whatever + if ((faction.isWilderness() && Conf.wildernessBlockFireballs && !Conf.worldsNoWildernessProtection.contains(loc.getWorld().getName())) || + (faction.isNormal() && (faction.hasPlayersOnline() ? Conf.territoryBlockFireballs : Conf.territoryBlockFireballsWhenOffline)) || + (faction.isWarZone() && Conf.warZoneBlockFireballs) || + faction.isSafeZone()) { + event.setCancelled(true); + } + } + } + + @EventHandler + public void onTravel(PlayerPortalEvent event) { + if (!P.p.getConfig().getBoolean("portals.limit", false)) { + return; // Don't do anything if they don't want us to. + } + + TravelAgent agent = event.getPortalTravelAgent(); + + // If they aren't able to find a portal, it'll try to create one. + if (event.useTravelAgent() && agent.getCanCreatePortal() && agent.findPortal(event.getTo()) == null) { + FLocation loc = new FLocation(event.getTo()); + Faction faction = Board.getInstance().getFactionAt(loc); + if (faction.isWilderness()) { + return; // We don't care about wilderness. + } else if (!faction.isNormal() && !event.getPlayer().isOp()) { + // Don't let non ops make portals in safezone or warzone. + event.setCancelled(true); + return; + } + + FPlayer fp = FPlayers.getInstance().getByPlayer(event.getPlayer()); + String mininumRelation = P.p.getConfig().getString("portals.minimum-relation", "MEMBER"); // Defaults to Neutral if typed wrong. + if (!fp.getFaction().getRelationTo(faction).isAtLeast(Relation.fromString(mininumRelation))) { + event.setCancelled(true); + } + } + } + + private boolean stopEndermanBlockManipulation(Location loc) { + if (loc == null) { + return false; + } + // quick check to see if all Enderman deny options are enabled; if so, no need to check location + if (Conf.wildernessDenyEndermanBlocks && + Conf.territoryDenyEndermanBlocks && + Conf.territoryDenyEndermanBlocksWhenOffline && + Conf.safeZoneDenyEndermanBlocks && + Conf.warZoneDenyEndermanBlocks) { + return true; + } + + FLocation fLoc = new FLocation(loc); + Faction claimFaction = Board.getInstance().getFactionAt(fLoc); + + if (claimFaction.isWilderness()) { + return Conf.wildernessDenyEndermanBlocks; + } else if (claimFaction.isNormal()) { + return claimFaction.hasPlayersOnline() ? Conf.territoryDenyEndermanBlocks : Conf.territoryDenyEndermanBlocksWhenOffline; + } else if (claimFaction.isSafeZone()) { + return Conf.safeZoneDenyEndermanBlocks; + } else if (claimFaction.isWarZone()) { + return Conf.warZoneDenyEndermanBlocks; + } + + return false; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/listeners/FactionsExploitListener.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/listeners/FactionsExploitListener.java new file mode 100644 index 0000000..61846ec --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/listeners/FactionsExploitListener.java @@ -0,0 +1,62 @@ +package com.massivecraft.factions.listeners; + +import com.massivecraft.factions.Conf; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockFromToEvent; +import org.bukkit.event.player.PlayerTeleportEvent; + + +public class FactionsExploitListener implements Listener { + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void obsidianGenerator(BlockFromToEvent event) { + if (!Conf.handleExploitObsidianGenerators) { + return; + } + + // thanks to ObGenBlocker and WorldGuard for this method + Block block = event.getToBlock(); + int source = event.getBlock().getTypeId(); + int target = block.getTypeId(); + if ((target == 55 || target == 132) && (source == 0 || source == 10 || source == 11)) { + block.setTypeId(0); + } + } + + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void enderPearlTeleport(PlayerTeleportEvent event) { + if (!Conf.handleExploitEnderPearlClipping) { + return; + } + if (event.getCause() != PlayerTeleportEvent.TeleportCause.ENDER_PEARL) { + return; + } + + // this exploit works when the target location is within 0.31 blocks or so of a door or glass block or similar... + Location target = event.getTo(); + Location from = event.getFrom(); + + // blocks who occupy less than 1 block width or length wise need to be handled differently + Material mat = event.getTo().getBlock().getType(); + if (((mat == Material.THIN_GLASS || mat == Material.IRON_FENCE) && clippingThrough(target, from, 0.65)) || ((mat == Material.FENCE || mat == Material.NETHER_FENCE) && clippingThrough(target, from, 0.45))) { + event.setTo(from); + return; + } + + // simple fix otherwise: ender pearl target locations are standardized to be in the center (X/Z) of the target block, not at the edges + target.setX(target.getBlockX() + 0.5); + target.setZ(target.getBlockZ() + 0.5); + event.setTo(target); + + } + + public static boolean clippingThrough(Location target, Location from, double thickness) { + return ((from.getX() > target.getX() && (from.getX() - target.getX() < thickness)) || (target.getX() > from.getX() && (target.getX() - from.getX() < thickness)) || (from.getZ() > target.getZ() && (from.getZ() - target.getZ() < thickness)) || (target.getZ() > from.getZ() && (target.getZ() - from.getZ() < thickness))); + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/listeners/FactionsPlayerListener.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/listeners/FactionsPlayerListener.java new file mode 100644 index 0000000..aeaab2b --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/listeners/FactionsPlayerListener.java @@ -0,0 +1,594 @@ +package com.massivecraft.factions.listeners; + +import com.massivecraft.factions.*; +import com.massivecraft.factions.event.FPlayerJoinEvent; +import com.massivecraft.factions.event.FPlayerLeaveEvent; +import com.massivecraft.factions.scoreboards.FScoreboard; +import com.massivecraft.factions.scoreboards.FTeamWrapper; +import com.massivecraft.factions.scoreboards.sidebar.FDefaultSidebar; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.struct.Relation; +import com.massivecraft.factions.struct.Role; +import com.massivecraft.factions.util.VisualizeUtil; +import com.massivecraft.factions.zcore.persist.MemoryFPlayer; +import com.massivecraft.factions.zcore.util.TL; +import com.massivecraft.factions.zcore.util.TextUtil; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.*; +import org.bukkit.util.NumberConversions; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.UUID; +import java.util.logging.Level; + + +public class FactionsPlayerListener implements Listener { + + public P p; + + public FactionsPlayerListener(P p) { + this.p = p; + for (Player player : p.getServer().getOnlinePlayers()) { + initPlayer(player); + } + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onPlayerJoin(PlayerJoinEvent event) { + initPlayer(event.getPlayer()); + } + + private void initPlayer(Player player) { + // Make sure that all online players do have a fplayer. + final FPlayer me = FPlayers.getInstance().getByPlayer(player); + ((MemoryFPlayer) me).setName(player.getName()); + + // Update the lastLoginTime for this fplayer + me.setLastLoginTime(System.currentTimeMillis()); + + // Store player's current FLocation and notify them where they are + me.setLastStoodAt(new FLocation(player.getLocation())); + + me.login(); // set kills / deaths + + // Check for Faction announcements. Let's delay this so they actually see it. + Bukkit.getScheduler().runTaskLater(P.p, new Runnable() { + @Override + public void run() { + if (me.isOnline()) { + me.getFaction().sendUnreadAnnouncements(me); + } + } + }, 33L); // Don't ask me why. + + if (P.p.getConfig().getBoolean("scoreboard.default-enabled", false)) { + FScoreboard.init(me); + FScoreboard.get(me).setDefaultSidebar(new FDefaultSidebar(), P.p.getConfig().getInt("default-update-interval", 20)); + FScoreboard.get(me).setSidebarVisibility(me.showScoreboard()); + } + + Faction myFaction = me.getFaction(); + if (!myFaction.isWilderness()) { + for (FPlayer other : myFaction.getFPlayersWhereOnline(true)) { + if (other != me && other.isMonitoringJoins()) { + other.msg(TL.FACTION_LOGIN, me.getName()); + } + } + } + + if (me.isSpyingChat() && !player.hasPermission(Permission.CHATSPY.node)) { + me.setSpyingChat(false); + P.p.log(Level.INFO, "Found %s spying chat without permission on login. Disabled their chat spying.", player.getName()); + } + + if (me.isAdminBypassing() && !player.hasPermission(Permission.BYPASS.node)) { + me.setIsAdminBypassing(false); + P.p.log(Level.INFO, "Found %s on admin Bypass without permission on login. Disabled it for them.", player.getName()); + } + + // If they have the permission, don't let them autoleave. Bad inverted setter :\ + me.setAutoLeave(!player.hasPermission(Permission.AUTO_LEAVE_BYPASS.node)); + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onPlayerQuit(PlayerQuitEvent event) { + FPlayer me = FPlayers.getInstance().getByPlayer(event.getPlayer()); + + // Make sure player's power is up to date when they log off. + me.getPower(); + // and update their last login time to point to when the logged off, for auto-remove routine + me.setLastLoginTime(System.currentTimeMillis()); + + me.logout(); // cache kills / deaths + + // if player is waiting for fstuck teleport but leaves, remove + if (P.p.getStuckMap().containsKey(me.getPlayer().getUniqueId())) { + FPlayers.getInstance().getByPlayer(me.getPlayer()).msg(TL.COMMAND_STUCK_CANCELLED); + P.p.getStuckMap().remove(me.getPlayer().getUniqueId()); + P.p.getTimers().remove(me.getPlayer().getUniqueId()); + } + + Faction myFaction = me.getFaction(); + if (!myFaction.isWilderness()) { + myFaction.memberLoggedOff(); + } + + if (!myFaction.isWilderness()) { + for (FPlayer player : myFaction.getFPlayersWhereOnline(true)) { + if (player != me && player.isMonitoringJoins()) { + player.msg(TL.FACTION_LOGOUT, me.getName()); + } + } + } + + FScoreboard.remove(me); + } + + // Holds the next time a player can have a map shown. + private HashMap showTimes = new HashMap(); + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onPlayerMove(PlayerMoveEvent event) { + Player player = event.getPlayer(); + FPlayer me = FPlayers.getInstance().getByPlayer(player); + + // clear visualization + if (event.getFrom().getBlockX() != event.getTo().getBlockX() || event.getFrom().getBlockY() != event.getTo().getBlockY() || event.getFrom().getBlockZ() != event.getTo().getBlockZ()) { + VisualizeUtil.clear(event.getPlayer()); + if (me.isWarmingUp()) { + me.clearWarmup(); + me.msg(TL.WARMUPS_CANCELLED); + } + } + + // quick check to make sure player is moving between chunks; good performance boost + if (event.getFrom().getBlockX() >> 4 == event.getTo().getBlockX() >> 4 && event.getFrom().getBlockZ() >> 4 == event.getTo().getBlockZ() >> 4 && event.getFrom().getWorld() == event.getTo().getWorld()) { + return; + } + + // Did we change coord? + FLocation from = me.getLastStoodAt(); + FLocation to = new FLocation(event.getTo()); + + if (from.equals(to)) { + return; + } + + // Yes we did change coord (: + + me.setLastStoodAt(to); + + // Did we change "host"(faction)? + Faction factionFrom = Board.getInstance().getFactionAt(from); + Faction factionTo = Board.getInstance().getFactionAt(to); + boolean changedFaction = (factionFrom != factionTo); + + if (me.isMapAutoUpdating()) { + if (showTimes.containsKey(player.getUniqueId()) && (showTimes.get(player.getUniqueId()) > System.currentTimeMillis())) { + if (P.p.getConfig().getBoolean("findfactionsexploit.log", false)) { + P.p.log(Level.WARNING, "%s tried to show a cartel map too soon and triggered exploit blocker.", player.getName()); + } + } else { + me.sendMessage(Board.getInstance().getMap(me.getFaction(), to, player.getLocation().getYaw())); + showTimes.put(player.getUniqueId(), System.currentTimeMillis() + P.p.getConfig().getLong("findfactionsexploit.cooldown", 2000)); + } + } else { + Faction myFaction = me.getFaction(); + String ownersTo = myFaction.getOwnerListString(to); + + if (changedFaction) { + me.sendFactionHereMessage(factionFrom); + if (Conf.ownedAreasEnabled && Conf.ownedMessageOnBorder && myFaction == factionTo && !ownersTo.isEmpty()) { + me.sendMessage(TL.GENERIC_OWNERS.format(ownersTo)); + } + } else if (Conf.ownedAreasEnabled && Conf.ownedMessageInsideTerritory && myFaction == factionTo && !myFaction.isWilderness()) { + String ownersFrom = myFaction.getOwnerListString(from); + if (Conf.ownedMessageByChunk || !ownersFrom.equals(ownersTo)) { + if (!ownersTo.isEmpty()) { + me.sendMessage(TL.GENERIC_OWNERS.format(ownersTo)); + } else if (!TL.GENERIC_PUBLICLAND.toString().isEmpty()) { + me.sendMessage(TL.GENERIC_PUBLICLAND.toString()); + } + } + } + } + + if (me.getAutoClaimFor() != null) { + me.attemptClaim(me.getAutoClaimFor(), event.getTo(), true); + } else if (me.isAutoSafeClaimEnabled()) { + if (!Permission.MANAGE_SAFE_ZONE.has(player)) { + me.setIsAutoSafeClaimEnabled(false); + } else { + if (!Board.getInstance().getFactionAt(to).isSafeZone()) { + Board.getInstance().setFactionAt(Factions.getInstance().getSafeZone(), to); + me.msg(TL.PLAYER_SAFEAUTO); + } + } + } else if (me.isAutoWarClaimEnabled()) { + if (!Permission.MANAGE_WAR_ZONE.has(player)) { + me.setIsAutoWarClaimEnabled(false); + } else { + if (!Board.getInstance().getFactionAt(to).isWarZone()) { + Board.getInstance().setFactionAt(Factions.getInstance().getWarZone(), to); + me.msg(TL.PLAYER_WARAUTO); + } + } + } + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onPlayerInteract(PlayerInteractEvent event) { + // only need to check right-clicks and physical as of MC 1.4+; good performance boost + if (event.getAction() != Action.RIGHT_CLICK_BLOCK && event.getAction() != Action.PHYSICAL) { + return; + } + + Block block = event.getClickedBlock(); + Player player = event.getPlayer(); + + if (block == null) { + return; // clicked in air, apparently + } + + if (!canPlayerUseBlock(player, block, false)) { + event.setCancelled(true); + if (Conf.handleExploitInteractionSpam) { + String name = player.getName(); + InteractAttemptSpam attempt = interactSpammers.get(name); + if (attempt == null) { + attempt = new InteractAttemptSpam(); + interactSpammers.put(name, attempt); + } + int count = attempt.increment(); + if (count >= 10) { + FPlayer me = FPlayers.getInstance().getByPlayer(player); + me.msg(TL.PLAYER_OUCH); + player.damage(NumberConversions.floor((double) count / 10)); + } + } + return; + } + + if (event.getAction() != Action.RIGHT_CLICK_BLOCK) { + return; // only interested on right-clicks for below + } + + if (!playerCanUseItemHere(player, block.getLocation(), event.getMaterial(), false)) { + event.setCancelled(true); + } + } + + + // for handling people who repeatedly spam attempts to open a door (or similar) in another faction's territory + private Map interactSpammers = new HashMap(); + + private static class InteractAttemptSpam { + private int attempts = 0; + private long lastAttempt = System.currentTimeMillis(); + + // returns the current attempt count + public int increment() { + long Now = System.currentTimeMillis(); + if (Now > lastAttempt + 2000) { + attempts = 1; + } else { + attempts++; + } + lastAttempt = Now; + return attempts; + } + } + + + public static boolean playerCanUseItemHere(Player player, Location location, Material material, boolean justCheck) { + if(player.isOp()) + return true; + String name = player.getName(); + if (Conf.playersWhoBypassAllProtection.contains(name)) { + return true; + } + + FPlayer me = FPlayers.getInstance().getByPlayer(player); + if (me.isAdminBypassing()) { + return true; + } + + FLocation loc = new FLocation(location); + Faction otherFaction = Board.getInstance().getFactionAt(loc); + + if (P.p.getConfig().getBoolean("hcf.raidable", false) && otherFaction.getLandRounded() >= otherFaction.getPowerRounded()) { + return true; + } + + if (otherFaction.hasPlayersOnline()) { + if (!Conf.territoryDenyUseageMaterials.contains(material)) { + return true; // Item isn't one we're preventing for online factions. + } + } else { + if (!Conf.territoryDenyUseageMaterialsWhenOffline.contains(material)) { + return true; // Item isn't one we're preventing for offline factions. + } + } + + if (otherFaction.isWilderness()) { + if (!Conf.wildernessDenyUseage || Conf.worldsNoWildernessProtection.contains(location.getWorld().getName())) { + return true; // This is not faction territory. Use whatever you like here. + } + + if (!justCheck) { + me.msg(TL.PLAYER_USE_WILDERNESS, TextUtil.getMaterialName(material)); + } + + return false; + } else if (otherFaction.isSafeZone()) { + if (!Conf.safeZoneDenyUseage || Permission.MANAGE_SAFE_ZONE.has(player)) { + return true; + } + + if (!justCheck) { + me.msg(TL.PLAYER_USE_SAFEZONE, TextUtil.getMaterialName(material)); + } + + return false; + } else if (otherFaction.isWarZone()) { + if (!Conf.warZoneDenyUseage || Permission.MANAGE_WAR_ZONE.has(player)) { + return true; + } + + if (!justCheck) { + me.msg(TL.PLAYER_USE_WARZONE, TextUtil.getMaterialName(material)); + } + + return false; + } + + Faction myFaction = me.getFaction(); + Relation rel = myFaction.getRelationTo(otherFaction); + + // Cancel if we are not in our own territory + if (rel.confDenyUseage()) { + if (!justCheck) { + me.msg(TL.PLAYER_USE_TERRITORY, TextUtil.getMaterialName(material), otherFaction.getTag(myFaction)); + } + + return false; + } + + // Also cancel if player doesn't have ownership rights for this claim + if (Conf.ownedAreasEnabled && Conf.ownedAreaDenyUseage && !otherFaction.playerHasOwnershipRights(me, loc)) { + if (!justCheck) { + me.msg(TL.PLAYER_USE_OWNED, TextUtil.getMaterialName(material), otherFaction.getOwnerListString(loc)); + } + + return false; + } + + return true; + } + + public static boolean canPlayerUseBlock(Player player, Block block, boolean justCheck) { + if(player.isOp()) + return true; + if (Conf.playersWhoBypassAllProtection.contains(player.getName())) { + return true; + } + + FPlayer me = FPlayers.getInstance().getByPlayer(player); + if (me.isAdminBypassing()) { + return true; + } + + Material material = block.getType(); + FLocation loc = new FLocation(block); + Faction otherFaction = Board.getInstance().getFactionAt(loc); + + // no door/chest/whatever protection in wilderness, war zones, or safe zones + if (!otherFaction.isNormal()) { + return true; + } + + if (P.p.getConfig().getBoolean("hcf.raidable", false) && otherFaction.getLandRounded() >= otherFaction.getPowerRounded()) { + return true; + } + + // Dupe fix. + Faction myFaction = me.getFaction(); + Relation rel = myFaction.getRelationTo(otherFaction); + if (!rel.isMember() || !otherFaction.playerHasOwnershipRights(me, loc) && player.getItemInHand() != null) { + switch (player.getItemInHand().getType()) { + case CHEST: + case SIGN_POST: + case TRAPPED_CHEST: + case SIGN: + case WOOD_DOOR: + case IRON_DOOR: + return false; + default: + break; + } + } + + // We only care about some material types. + if (otherFaction.hasPlayersOnline()) { + if (!Conf.territoryProtectedMaterials.contains(material)) { + return true; + } + } else { + if (!Conf.territoryProtectedMaterialsWhenOffline.contains(material)) { + return true; + } + } + + // You may use any block unless it is another faction's territory... + if (rel.isNeutral() || (rel.isEnemy() && Conf.territoryEnemyProtectMaterials) || (rel.isAlly() && Conf.territoryAllyProtectMaterials) || (rel.isTruce() && Conf.territoryTruceProtectMaterials)) { + if (!justCheck) { + me.msg(TL.PLAYER_USE_TERRITORY, (material == Material.SOIL ? "trample " : "use ") + TextUtil.getMaterialName(material), otherFaction.getTag(myFaction)); + } + + return false; + } + + // Also cancel if player doesn't have ownership rights for this claim + if (Conf.ownedAreasEnabled && Conf.ownedAreaProtectMaterials && !otherFaction.playerHasOwnershipRights(me, loc)) { + if (!justCheck) { + me.msg(TL.PLAYER_USE_OWNED, TextUtil.getMaterialName(material), otherFaction.getOwnerListString(loc)); + } + + return false; + } + + return true; + } + + @EventHandler(priority = EventPriority.HIGH) + public void onPlayerRespawn(PlayerRespawnEvent event) { + FPlayer me = FPlayers.getInstance().getByPlayer(event.getPlayer()); + + me.getPower(); // update power, so they won't have gained any while dead + + Location home = me.getFaction().getHome(); + if (Conf.homesEnabled && + Conf.homesTeleportToOnDeath && + home != null && + (Conf.homesRespawnFromNoPowerLossWorlds || !Conf.worldsNoPowerLoss.contains(event.getPlayer().getWorld().getName()))) { + event.setRespawnLocation(home); + } + } + + // For some reason onPlayerInteract() sometimes misses bucket events depending on distance (something like 2-3 blocks away isn't detected), + // but these separate bucket events below always fire without fail + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onPlayerBucketEmpty(PlayerBucketEmptyEvent event) { + Block block = event.getBlockClicked(); + Player player = event.getPlayer(); + + if (!playerCanUseItemHere(player, block.getLocation(), event.getBucket(), false)) { + event.setCancelled(true); + return; + } + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onPlayerBucketFill(PlayerBucketFillEvent event) { + Block block = event.getBlockClicked(); + Player player = event.getPlayer(); + + if (!playerCanUseItemHere(player, block.getLocation(), event.getBucket(), false)) { + event.setCancelled(true); + return; + } + } + + public static boolean preventCommand(String fullCmd, Player player) { + if(player.isOp()) + return false; + if ((Conf.territoryNeutralDenyCommands.isEmpty() && Conf.territoryEnemyDenyCommands.isEmpty() && Conf.permanentFactionMemberDenyCommands.isEmpty() && Conf.warzoneDenyCommands.isEmpty())) { + return false; + } + + fullCmd = fullCmd.toLowerCase(); + + FPlayer me = FPlayers.getInstance().getByPlayer(player); + + String shortCmd; // command without the slash at the beginning + if (fullCmd.startsWith("/")) { + shortCmd = fullCmd.substring(1); + } else { + shortCmd = fullCmd; + fullCmd = "/" + fullCmd; + } + + if (me.hasFaction() && + !me.isAdminBypassing() && + !Conf.permanentFactionMemberDenyCommands.isEmpty() && + me.getFaction().isPermanent() && + isCommandInList(fullCmd, shortCmd, Conf.permanentFactionMemberDenyCommands.iterator())) { + me.msg(TL.PLAYER_COMMAND_PERMANENT, fullCmd); + return true; + } + + Faction at = Board.getInstance().getFactionAt(new FLocation(player.getLocation())); + if (at.isWilderness() && !Conf.wildernessDenyCommands.isEmpty() && !me.isAdminBypassing() && isCommandInList(fullCmd, shortCmd, Conf.wildernessDenyCommands.iterator())) { + me.msg(TL.PLAYER_COMMAND_WILDERNESS, fullCmd); + return true; + } + + Relation rel = at.getRelationTo(me); + if (at.isNormal() && rel.isAlly() && !Conf.territoryAllyDenyCommands.isEmpty() && !me.isAdminBypassing() && isCommandInList(fullCmd, shortCmd, Conf.territoryAllyDenyCommands.iterator())) { + me.msg(TL.PLAYER_COMMAND_ALLY, fullCmd); + return false; + } + + if (at.isNormal() && rel.isNeutral() && !Conf.territoryNeutralDenyCommands.isEmpty() && !me.isAdminBypassing() && isCommandInList(fullCmd, shortCmd, Conf.territoryNeutralDenyCommands.iterator())) { + me.msg(TL.PLAYER_COMMAND_NEUTRAL, fullCmd); + return true; + } + + if (at.isNormal() && rel.isEnemy() && !Conf.territoryEnemyDenyCommands.isEmpty() && !me.isAdminBypassing() && isCommandInList(fullCmd, shortCmd, Conf.territoryEnemyDenyCommands.iterator())) { + me.msg(TL.PLAYER_COMMAND_ENEMY, fullCmd); + return true; + } + + if (at.isWarZone() && !Conf.warzoneDenyCommands.isEmpty() && !me.isAdminBypassing() && isCommandInList(fullCmd, shortCmd, Conf.warzoneDenyCommands.iterator())) { + me.msg(TL.PLAYER_COMMAND_WARZONE, fullCmd); + return true; + } + + return false; + } + + private static boolean isCommandInList(String fullCmd, String shortCmd, Iterator iter) { + String cmdCheck; + while (iter.hasNext()) { + cmdCheck = iter.next(); + if (cmdCheck == null) { + iter.remove(); + continue; + } + + cmdCheck = cmdCheck.toLowerCase(); + if (fullCmd.startsWith(cmdCheck) || shortCmd.startsWith(cmdCheck)) { + return true; + } + } + return false; + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onPlayerKick(PlayerKickEvent event) { + FPlayer badGuy = FPlayers.getInstance().getByPlayer(event.getPlayer()); + if (badGuy == null) { + return; + } + + // if player was banned (not just kicked), get rid of their stored info + if (Conf.removePlayerDataWhenBanned && event.getReason().equals("Banned by admin.")) { + if (badGuy.getRole() == Role.ADMIN) { + badGuy.getFaction().promoteNewLeader(); + } + + badGuy.leave(false); + badGuy.remove(); + } + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + final public void onFactionJoin(FPlayerJoinEvent event) { + FTeamWrapper.applyUpdatesLater(event.getFaction()); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onFactionLeave(FPlayerLeaveEvent event) { + FTeamWrapper.applyUpdatesLater(event.getFaction()); + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/listeners/MenuListener.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/listeners/MenuListener.java new file mode 100644 index 0000000..cc3f04e --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/listeners/MenuListener.java @@ -0,0 +1,236 @@ +package com.massivecraft.factions.listeners; + +import com.massivecraft.factions.*; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.menus.Menu; +import net.grandtheftmc.core.menus.MenuClickEvent; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.menus.MenuOpenEvent; +import net.grandtheftmc.core.util.Utils; +import org.apache.commons.lang.StringUtils; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +/** + * Created by Timothy Lampen on 2017-09-22. + */ +public class MenuListener implements Listener{ + + @EventHandler + public void onOpen(MenuOpenEvent e) { + Player player = e.getPlayer(); + FPlayer fme = FPlayers.getInstance().getByPlayer(player); + Menu menu = e.getMenu(); + + switch (menu.getName()) { + case "carteltop" : { + player.sendMessage(Lang.VICE.f("&7Organizing &6" + Factions.getInstance().getAllFactions().size() + "&7 factions...")); + new BukkitRunnable() { + @Override + public void run() { + // Get all Factions and remove non player ones. + ArrayList factionList = Factions.getInstance().getAllFactions(); + factionList.remove(Factions.getInstance().getWilderness()); + factionList.remove(Factions.getInstance().getSafeZone()); + factionList.remove(Factions.getInstance().getWarZone()); + Collections.sort(factionList, new Comparator() { + @Override + public int compare(Faction o1, Faction o2) { + + double f1Worth = o1.getStash(); + for(int i =0; i < o1.getAllClaims().size(); i++ ) + f1Worth += Conf.econCostClaimWilderness + (Conf.econCostClaimWilderness * Conf.econClaimAdditionalMultiplier * i); + + double f2Worth = o2.getStash(); + for(int i =0; i < o2.getAllClaims().size(); i++ ) + f2Worth += Conf.econCostClaimWilderness + (Conf.econCostClaimWilderness * Conf.econClaimAdditionalMultiplier * i); + //takes 0.08ms to complete the entire sort. + + if(f1Worth < f2Worth) + return 1; + else if(f1Worth > f2Worth) + return -1; + return 0; + } + }); + boolean containsSender = false; + ArrayList items = new ArrayList(); + for(int i = 0; i<(factionList.size()>=20 ? 20 : factionList.size()); i++) { + Faction f = factionList.get(i); + if(f.getFPlayers().contains(fme)) + containsSender = true; + items.add(generateRankingItem(fme, f, i+1)); + } + final boolean finalContainsSender = containsSender; + new BukkitRunnable() { + @Override + public void run() { + if(!player.isOnline()) + return; + Inventory inv = Bukkit.createInventory(player, 54, Utils.f("&cTop Cartels")); + setPhoneDefaults(inv); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + int counter = 0; + for (ItemStack is : items) { + int slot = slots[counter]; + inv.setItem(slot, is); + counter++; + } + if (!finalContainsSender && !Factions.getInstance().getWilderness().getFPlayers().contains(fme)) { + inv.setItem(49, generateRankingItem(fme, fme.getFaction(), -1)); + } + inv.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lClose Menu")); + player.openInventory(inv); + player.updateInventory(); + } + }.runTaskLater(P.p, 5); + } + }.runTaskAsynchronously(P.p); + break; + } + } + } + + @EventHandler + public void onClick(MenuClickEvent e){ + Player player = e.getPlayer(); + FPlayer fme = FPlayers.getInstance().getByPlayer(player); + Menu menu = e.getMenu(); + ItemStack clicked = e.getItem(); + if(clicked==null || clicked.getType()==Material.STAINED_GLASS_PANE || clicked.getType()==Material.AIR) + return; + + switch (menu.getName()) { + case "carteltop" : { + switch (clicked.getType()) { + case REDSTONE: + player.closeInventory(); + break; + } + break; + } + } + } + + private ItemStack generateRankingItem(FPlayer fme, Faction f, int rank){ + ItemStack item = new ItemStack(Material.SKULL_ITEM, 1, (short)3); + SkullMeta im = (SkullMeta)item.getItemMeta(); + im.setDisplayName((rank==-1 ? ChatColor.GREEN + "Your Faction" : ChatColor.GREEN +"#" + ChatColor.GOLD + rank + ChatColor.GREEN + " Rank")); + ArrayList lore = new ArrayList(); + lore.add(ChatColor.GOLD + "Name: " + ChatColor.GRAY + f.getTag()); + lore.add(ChatColor.GOLD + "Owner: " + ChatColor.GRAY + (f.getFPlayerAdmin()==null ? "Wilderness" : f.getFPlayerAdmin().getName())); + im.setOwner(f.getFPlayerAdmin().getName()); + + double worth = f.getStash(); + for(int i =0; i < f.getAllClaims().size(); i++ ) + worth += Conf.econCostClaimWilderness + (Conf.econCostClaimWilderness * Conf.econClaimAdditionalMultiplier * i); + lore.add(ChatColor.GOLD + "Worth: " + ChatColor.GRAY + Utils.formatMoney(worth)); + + lore.add(ChatColor.GOLD + "Members: " + ChatColor.GRAY + f.getFPlayers().size()); + lore.add(ChatColor.GOLD + "Relation: " + f.getRelationTo(fme).getColor() + StringUtils.capitalize(f.getRelationTo(fme).nicename)); + + im.setLore(lore); + item.setItemMeta(im); + return item; + } + + + public void setPhoneDefaults(MenuOpenEvent e) { + ItemStack whiteGlass = Utils.createItem(Material.STAINED_GLASS_PANE, "&a"); + ItemStack grayGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a"); + ItemStack blackGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 15, "&a"); + ItemStack lightGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 8, "&a"); + for (int i : new int[]{1, 10, 19, 28, 37, 46, 7, 16, 25, 34, 43, 52}) e.setItem(i, whiteGlass); + for (int i : new int[]{2, 3, 4, 5, 6}) e.setItem(i, blackGlass); + for (int i : new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42, 47, 48, + 49, 50, 51}) + e.setItem(i, grayGlass); + for (int i : new int[]{0, 8, 9, 17, 18, 26, 27, 35, 36, 44, 45, 53}) e.setItem(i, lightGlass); + } + + public void setPhoneDefaults(Inventory inv) { + ItemStack whiteGlass = Utils.createItem(Material.STAINED_GLASS_PANE, "&a"); + ItemStack grayGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a"); + ItemStack blackGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 15, "&a"); + ItemStack lightGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 8, "&a"); + for (int i : new int[]{1, 10, 19, 28, 37, 46, 7, 16, 25, 34, 43, 52}) inv.setItem(i, whiteGlass); + for (int i : new int[]{2, 3, 4, 5, 6}) inv.setItem(i, blackGlass); + for (int i : new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42, 47, 48, + 49, 50, 51}) + inv.setItem(i, grayGlass); + for (int i : new int[]{0, 8, 9, 17, 18, 26, 27, 35, 36, 44, 45, 53}) inv.setItem(i, lightGlass); + } + + public void setGPSDefaults(MenuOpenEvent e) { + ItemStack whiteGlass = Utils.createItem(Material.STAINED_GLASS_PANE, "&a"); + ItemStack grayGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a"); + ItemStack blackGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 15, "&a"); + for (int i : new int[]{0, 9, 18, 27, 36, 45, 8, 17, 26, 35, 44, 53}) e.setItem(i, whiteGlass); + for (int i : new int[]{1, 2, 3, 4, 5, 6, 7}) e.setItem(i, blackGlass); + for (int i : new int[]{10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, 33, 34, 37, + 38, 39, 40, 41, 42, 43, 46, 47, 48, 49, 50, 51, 52}) + e.setItem(i, grayGlass); + } + + public void setGPSDefaults(Inventory inv) { + ItemStack whiteGlass = Utils.createItem(Material.STAINED_GLASS_PANE, "&a"); + ItemStack grayGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a"); + ItemStack blackGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 15, "&a"); + for (int i : new int[]{0, 9, 18, 27, 36, 45, 8, 17, 26, 35, 44, 53}) + inv.setItem(i, whiteGlass); + for (int i : new int[]{1, 2, 3, 4, 5, 6, 7}) + inv.setItem(i, blackGlass); + for (int i : new int[]{10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, 33, 34, 37, + 38, 39, 40, 41, 42, 43, 46, 47, 48, 49, 50, 51, 52}) + inv.setItem(i, grayGlass); + } + + private void setConfirmDefaults(MenuOpenEvent e) { + this.setConfirmDefaults(e, "&a&lConfirm", "&c&lCancel"); + } + + private void setConfirmDefaults(MenuOpenEvent e, String confirmMessage, String cancelMessage) { + ItemStack whiteGlass = Utils.createItem(Material.STAINED_GLASS_PANE, "&a"); + ItemStack grayGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a"); + ItemStack blackGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 15, "&a"); + ItemStack lightGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 8, "&a"); + ItemStack greenGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 5, confirmMessage); + ItemStack redGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 14, cancelMessage); + for (int i : new int[]{1, 10, 19, 28, 37, 46, 7, 16, 25, 34, 43, 52}) e.setItem(i, whiteGlass); + for (int i : new int[]{2, 3, 4, 5, 6}) e.setItem(i, blackGlass); + for (int i : new int[]{13, 22, 31, 40, 49,}) e.setItem(i, grayGlass); + for (int i : new int[]{0, 8, 9, 17, 18, 26, 27, 35, 36, 44, 45, 53}) e.setItem(i, lightGlass); + for (int i : new int[]{11, 12, 20, 21, 29, 30, 38, 39, 47, 48}) e.setItem(i, greenGlass); + for (int i : new int[]{14, 15, 23, 24, 32, 33, 41, 42, 50, 51}) e.setItem(i, redGlass); + } + + private void setConfirmDefaults(MenuOpenEvent e, String confirmMessage, String cancelMessage, List confirmLore, List cancelLore) { + ItemStack whiteGlass = Utils.createItem(Material.STAINED_GLASS_PANE, "&a"); + ItemStack grayGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a"); + ItemStack lightGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 8, "&a"); + ItemStack blackGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 15, "&a"); + ItemStack greenGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 5, confirmMessage, confirmLore == null ? new ArrayList<>() : confirmLore); + ItemStack redGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 14, cancelMessage, cancelLore == null ? new ArrayList<>() : cancelLore); + for (int i : new int[]{1, 10, 19, 28, 37, 46, 7, 16, 25, 34, 43, 52}) e.setItem(i, whiteGlass); + for (int i : new int[]{2, 3, 4, 5, 6}) e.setItem(i, blackGlass); + for (int i : new int[]{13, 22, 31, 40, 49,}) e.setItem(i, grayGlass); + for (int i : new int[]{0, 8, 9, 17, 18, 26, 27, 35, 36, 44, 45, 53}) e.setItem(i, lightGlass); + for (int i : new int[]{11, 12, 20, 21, 29, 30, 38, 39, 47, 48}) e.setItem(i, greenGlass); + for (int i : new int[]{14, 15, 23, 24, 32, 33, 41, 42, 50, 51}) e.setItem(i, redGlass); + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/scoreboards/BufferedObjective.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/scoreboards/BufferedObjective.java new file mode 100644 index 0000000..335b0bb --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/scoreboards/BufferedObjective.java @@ -0,0 +1,165 @@ +package com.massivecraft.factions.scoreboards; + +import com.google.common.base.Splitter; +import org.bukkit.ChatColor; +import org.bukkit.scoreboard.DisplaySlot; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Scoreboard; +import org.bukkit.scoreboard.Team; + +import java.lang.reflect.Method; +import java.util.*; + +public class BufferedObjective { + private static final Method addEntryMethod; + private static final int MAX_LINE_LENGTH; + + private final Scoreboard scoreboard; + private final String baseName; + + private Objective current; + private List currentTeams = new ArrayList(); + private String title; + private DisplaySlot displaySlot; + + private int objPtr; + private int teamPtr; + private boolean requiresUpdate = false; + + private final Map contents = new HashMap(); + + static { + // Check for long line support. + // We require use of Spigot's `addEntry(String)` method on + // Teams, as adding OfflinePlayers to a team is far too slow. + + Method addEntryMethodLookup = null; + try { + addEntryMethodLookup = Team.class.getMethod("addEntry", String.class); + } catch (NoSuchMethodException ignored) { + } + + addEntryMethod = addEntryMethodLookup; + + if (addEntryMethod != null) { + MAX_LINE_LENGTH = 48; + } else { + MAX_LINE_LENGTH = 16; + } + } + + public BufferedObjective(Scoreboard scoreboard) { + this.scoreboard = scoreboard; + this.baseName = createBaseName(); + + current = scoreboard.registerNewObjective(getNextObjectiveName(), "dummy"); + } + + private String createBaseName() { + Random random = new Random(); + StringBuilder builder = new StringBuilder(); + while (builder.length() < 14) { + builder.append(Integer.toHexString(random.nextInt())); + } + return builder.toString().substring(0, 14); + } + + public void setTitle(String title) { + if (this.title == null || !this.title.equals(title)) { + this.title = title; + requiresUpdate = true; + } + } + + public void setDisplaySlot(DisplaySlot slot) { + this.displaySlot = slot; + current.setDisplaySlot(slot); + } + + public void setAllLines(List lines) { + if (lines.size() != contents.size()) { + contents.clear(); + } + for (int i = 0; i < lines.size(); i++) { + setLine(lines.size() - i, lines.get(i)); + } + } + + public void setLine(int lineNumber, String content) { + if (content.length() > MAX_LINE_LENGTH) { + content = content.substring(0, MAX_LINE_LENGTH); + } + content = ChatColor.translateAlternateColorCodes('&', content); + + if (contents.get(lineNumber) == null || !contents.get(lineNumber).equals(content)) { + contents.put(lineNumber, content); + requiresUpdate = true; + } + } + + // Hides the objective from the display slot until flip() is called + public void hide() { + if (displaySlot != null) { + scoreboard.clearSlot(displaySlot); + } + } + + public void flip() { + if (!requiresUpdate) { + return; + } + requiresUpdate = false; + + Objective buffer = scoreboard.registerNewObjective(getNextObjectiveName(), "dummy"); + buffer.setDisplayName(title); + + List bufferTeams = new ArrayList(); + + for (Map.Entry entry : contents.entrySet()) { + if (entry.getValue().length() > 16) { + Team team = scoreboard.registerNewTeam(getNextTeamName()); + bufferTeams.add(team); + + Iterator split = Splitter.fixedLength(16).split(entry.getValue()).iterator(); + + team.setPrefix(split.next()); + String name = split.next(); + if (split.hasNext()) { // We only guarantee two splits + team.setSuffix(split.next()); + } + + try { + addEntryMethod.invoke(team, name); + } catch (ReflectiveOperationException ignored) { + } + buffer.getScore(name).setScore(entry.getKey()); + } else { + buffer.getScore(entry.getValue()).setScore(entry.getKey()); + } + } + + if (displaySlot != null) { + buffer.setDisplaySlot(displaySlot); + } + + // Unregister _ALL_ the old things + current.unregister(); + + Iterator it = currentTeams.iterator(); + while (it.hasNext()) { + it.next().unregister(); + it.remove(); + } + + current = buffer; + currentTeams = bufferTeams; + } + + private String getNextObjectiveName() { + return baseName + "_" + ((objPtr++) % 2); + } + + private String getNextTeamName() { + return baseName.substring(0, 10) + "_" + ((teamPtr++) % 999999); + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/scoreboards/FScoreboard.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/scoreboards/FScoreboard.java new file mode 100644 index 0000000..86bcd88 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/scoreboards/FScoreboard.java @@ -0,0 +1,149 @@ +package com.massivecraft.factions.scoreboards; + +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.FPlayers; +import com.massivecraft.factions.P; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scoreboard.DisplaySlot; +import org.bukkit.scoreboard.Scoreboard; + +import java.util.HashMap; +import java.util.Map; + +public class FScoreboard { + private static final Map fscoreboards = new HashMap(); + + private final Scoreboard scoreboard; + private final FPlayer fplayer; + private final BufferedObjective bufferedObjective; + private FSidebarProvider defaultProvider; + private FSidebarProvider temporaryProvider; + private boolean removed = false; + + // Glowstone doesn't support scoreboards. + // All references to this and related workarounds can be safely + // removed when scoreboards are supported. + public static boolean isSupportedByServer() { + return Bukkit.getScoreboardManager() != null; + } + + public static void init(FPlayer fplayer) { + FScoreboard fboard = new FScoreboard(fplayer); + fscoreboards.put(fplayer, fboard); + + if (fplayer.hasFaction()) { + FTeamWrapper.applyUpdates(fplayer.getFaction()); + } + FTeamWrapper.track(fboard); + } + + public static void remove(FPlayer fplayer) { + FScoreboard fboard = fscoreboards.remove(fplayer); + + if (fboard != null) { + fboard.removed = true; + FTeamWrapper.untrack(fboard); + } + } + + public static FScoreboard get(FPlayer fplayer) { + return fscoreboards.get(fplayer); + } + + public static FScoreboard get(Player player) { + return fscoreboards.get(FPlayers.getInstance().getByPlayer(player)); + } + + private FScoreboard(FPlayer fplayer) { + this.fplayer = fplayer; + + if (isSupportedByServer()) { + this.scoreboard = Bukkit.getScoreboardManager().getNewScoreboard(); + this.bufferedObjective = new BufferedObjective(scoreboard); + + fplayer.getPlayer().setScoreboard(scoreboard); + } else { + this.scoreboard = null; + this.bufferedObjective = null; + } + } + + protected FPlayer getFPlayer() { + return fplayer; + } + + protected Scoreboard getScoreboard() { + return scoreboard; + } + + public void setSidebarVisibility(boolean visible) { + if (!isSupportedByServer()) { + return; + } + + bufferedObjective.setDisplaySlot(visible ? DisplaySlot.SIDEBAR : null); + } + + public void setDefaultSidebar(final FSidebarProvider provider, int updateInterval) { + if (!isSupportedByServer()) { + return; + } + + defaultProvider = provider; + if (temporaryProvider == null) { + // We have no temporary provider; update the BufferedObjective! + updateObjective(); + } + + new BukkitRunnable() { + @Override + public void run() { + if (removed || provider != defaultProvider) { + cancel(); + return; + } + + if (temporaryProvider == null) { + updateObjective(); + } + } + }.runTaskTimer(P.p, updateInterval, updateInterval); + } + + public void setTemporarySidebar(final FSidebarProvider provider) { + if (!isSupportedByServer()) { + return; + } + + temporaryProvider = provider; + updateObjective(); + + new BukkitRunnable() { + @Override + public void run() { + if (removed) { + return; + } + + if (temporaryProvider == provider) { + temporaryProvider = null; + updateObjective(); + } + } + }.runTaskLater(P.p, P.p.getConfig().getInt("scoreboard.expiration", 7) * 20); + } + + private void updateObjective() { + FSidebarProvider provider = temporaryProvider != null ? temporaryProvider : defaultProvider; + + if (provider == null) { + bufferedObjective.hide(); + } else { + bufferedObjective.setTitle(provider.getTitle(fplayer)); + bufferedObjective.setAllLines(provider.getLines(fplayer)); + bufferedObjective.flip(); + } + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/scoreboards/FSidebarProvider.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/scoreboards/FSidebarProvider.java new file mode 100644 index 0000000..1a2ed9b --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/scoreboards/FSidebarProvider.java @@ -0,0 +1,36 @@ +package com.massivecraft.factions.scoreboards; + +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.P; +import com.massivecraft.factions.zcore.util.TL; +import com.massivecraft.factions.zcore.util.TagUtil; + +import java.util.List; + +public abstract class FSidebarProvider { + + public abstract String getTitle(FPlayer fplayer); + + public abstract List getLines(FPlayer fplayer); + + public String replaceTags(FPlayer fPlayer, String s) { + return qualityAssure(TagUtil.parsePlain(fPlayer, s)); + } + + public String replaceTags(Faction faction, FPlayer fPlayer, String s) { + return qualityAssure(TagUtil.parsePlain(faction, fPlayer, s)); + } + + private String qualityAssure(String line) { + if (line.contains("{notFrozen}") || line.contains("{notPermanent}")) { + return "n/a"; // we dont support support these error variables in scoreboards + } + if (line.contains("{ig}")) { + // since you can't really fit a whole "Faction Home: world, x, y, z" on one line + // we assume it's broken up into two lines, so returning our tl will suffice. + return TL.COMMAND_SHOW_NOHOME.toString(); + } + return P.p.txt.parse(line); // finally add color :) + } +} \ No newline at end of file diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/scoreboards/FTeamWrapper.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/scoreboards/FTeamWrapper.java new file mode 100644 index 0000000..2d27317 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/scoreboards/FTeamWrapper.java @@ -0,0 +1,207 @@ +package com.massivecraft.factions.scoreboards; + +import com.massivecraft.factions.*; +import com.massivecraft.factions.zcore.util.TL; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.scoreboard.Scoreboard; +import org.bukkit.scoreboard.Team; + +import java.util.*; + +public class FTeamWrapper { + private static final Map wrappers = new HashMap(); + private static final List tracking = new ArrayList(); + private static int factionTeamPtr; + private static final Set updating = new HashSet(); + + private final Map teams = new HashMap(); + private final String teamName; + private final Faction faction; + private final Set members = new HashSet(); + + public static void applyUpdatesLater(final Faction faction) { + if (!FScoreboard.isSupportedByServer()) { + return; + } + + if (faction.isWilderness()) { + return; + } + + if (!P.p.getConfig().getBoolean("scoreboard.default-prefixes", false)) { + return; + } + + + if (updating.add(faction)) { + Bukkit.getScheduler().runTask(P.p, new Runnable() { + @Override + public void run() { + updating.remove(faction); + applyUpdates(faction); + } + }); + } + } + + public static void applyUpdates(Faction faction) { + if (!FScoreboard.isSupportedByServer()) { + return; + } + + if (faction.isWilderness()) { + return; + } + + if (!P.p.getConfig().getBoolean("scoreboard.default-prefixes", false)) { + return; + } + + if (updating.contains(faction)) { + // Faction will be updated soon. + return; + } + + FTeamWrapper wrapper = wrappers.get(faction); + Set factionMembers = faction.getFPlayers(); + + if (wrapper != null && Factions.getInstance().getFactionById(faction.getId()) == null) { + // Faction was disbanded + wrapper.unregister(); + wrappers.remove(faction); + return; + } + + if (wrapper == null) { + wrapper = new FTeamWrapper(faction); + wrappers.put(faction, wrapper); + } + + for (OfflinePlayer player : wrapper.getPlayers()) { + if (!player.isOnline() || !factionMembers.contains(FPlayers.getInstance().getByOfflinePlayer(player))) { + // Player is offline or no longer in faction + wrapper.removePlayer(player); + } + } + + for (FPlayer fmember : factionMembers) { + if (!fmember.isOnline()) { + continue; + } + + // Scoreboard might not have player; add him/her + wrapper.addPlayer(fmember.getPlayer()); + } + + wrapper.updatePrefixes(); + } + + public static void updatePrefixes(Faction faction) { + if (!FScoreboard.isSupportedByServer()) { + return; + } + + if (!wrappers.containsKey(faction)) { + applyUpdates(faction); + } else { + wrappers.get(faction).updatePrefixes(); + } + } + + protected static void track(FScoreboard fboard) { + if (!FScoreboard.isSupportedByServer()) { + return; + } + tracking.add(fboard); + for (FTeamWrapper wrapper : wrappers.values()) { + wrapper.add(fboard); + } + } + + protected static void untrack(FScoreboard fboard) { + if (!FScoreboard.isSupportedByServer()) { + return; + } + tracking.remove(fboard); + for (FTeamWrapper wrapper : wrappers.values()) { + wrapper.remove(fboard); + } + } + + + private FTeamWrapper(Faction faction) { + this.teamName = "faction_" + (factionTeamPtr++); + this.faction = faction; + + for (FScoreboard fboard : tracking) { + add(fboard); + } + } + + private void add(FScoreboard fboard) { + Scoreboard board = fboard.getScoreboard(); + Team team = board.registerNewTeam(teamName); + teams.put(fboard, team); + + for (OfflinePlayer player : getPlayers()) { + team.addPlayer(player); + } + + updatePrefix(fboard); + } + + private void remove(FScoreboard fboard) { + teams.remove(fboard).unregister(); + } + + private void updatePrefixes() { + if (P.p.getConfig().getBoolean("scoreboard.default-prefixes", false)) { + for (FScoreboard fboard : teams.keySet()) { + updatePrefix(fboard); + } + } + } + + private void updatePrefix(FScoreboard fboard) { + if (P.p.getConfig().getBoolean("scoreboard.default-prefixes", false)) { + FPlayer fplayer = fboard.getFPlayer(); + Team team = teams.get(fboard); + + String prefix = TL.DEFAULT_PREFIX.toString(); + prefix = prefix.replace("{relationcolor}", faction.getRelationTo(fplayer).getColor().toString()); + prefix = prefix.replace("{faction}", faction.getTag().substring(0, Math.min("{faction}".length() + 16 - prefix.length(), faction.getTag().length()))); + if (team.getPrefix() == null || !team.getPrefix().equals(prefix)) { + team.setPrefix(prefix); + } + } + } + + private void addPlayer(OfflinePlayer player) { + if (members.add(player)) { + for (Team team : teams.values()) { + team.addPlayer(player); + } + } + } + + private void removePlayer(OfflinePlayer player) { + if (members.remove(player)) { + for (Team team : teams.values()) { + team.removePlayer(player); + } + } + } + + private Set getPlayers() { + return new HashSet(this.members); + } + + private void unregister() { + for (Team team : teams.values()) { + team.unregister(); + } + teams.clear(); + } +} + diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/scoreboards/sidebar/FDefaultSidebar.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/scoreboards/sidebar/FDefaultSidebar.java new file mode 100644 index 0000000..af93921 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/scoreboards/sidebar/FDefaultSidebar.java @@ -0,0 +1,41 @@ +package com.massivecraft.factions.scoreboards.sidebar; + +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.P; +import com.massivecraft.factions.scoreboards.FSidebarProvider; + +import java.util.ArrayList; +import java.util.List; +import java.util.ListIterator; + +public class FDefaultSidebar extends FSidebarProvider { + + @Override + public String getTitle(FPlayer fplayer) { + return replaceTags(fplayer, P.p.getConfig().getString("scoreboard.default-title", "{name}")); + } + + @Override + public List getLines(FPlayer fplayer) { + if (fplayer.hasFaction()) { + return getOutput(fplayer, "scoreboard.default"); + } else if (P.p.getConfig().getBoolean("scoreboard.factionless-enabled", false)) { + return getOutput(fplayer, "scoreboard.factionless"); + } + return getOutput(fplayer, "scoreboard.default"); // no faction, factionless-board disabled + } + + public List getOutput(FPlayer fplayer, String list) { + List lines = P.p.getConfig().getStringList(list); + + if (lines == null || lines.isEmpty()) { + return new ArrayList(); + } + + ListIterator it = lines.listIterator(); + while (it.hasNext()) { + it.set(replaceTags(fplayer, it.next())); + } + return lines; + } +} \ No newline at end of file diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/scoreboards/sidebar/FInfoSidebar.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/scoreboards/sidebar/FInfoSidebar.java new file mode 100644 index 0000000..d375272 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/scoreboards/sidebar/FInfoSidebar.java @@ -0,0 +1,33 @@ +package com.massivecraft.factions.scoreboards.sidebar; + +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.P; +import com.massivecraft.factions.scoreboards.FSidebarProvider; + +import java.util.List; +import java.util.ListIterator; + +public class FInfoSidebar extends FSidebarProvider { + private final Faction faction; + + public FInfoSidebar(Faction faction) { + this.faction = faction; + } + + @Override + public String getTitle(FPlayer fplayer) { + return faction.getRelationTo(fplayer).getColor() + faction.getTag(); + } + + @Override + public List getLines(FPlayer fplayer) { + List lines = P.p.getConfig().getStringList("scoreboard.finfo"); + + ListIterator it = lines.listIterator(); + while (it.hasNext()) { + it.set(replaceTags(faction, fplayer, it.next())); + } + return lines; + } +} \ No newline at end of file diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/struct/ChatMode.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/struct/ChatMode.java new file mode 100644 index 0000000..020dfb2 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/struct/ChatMode.java @@ -0,0 +1,41 @@ +package com.massivecraft.factions.struct; + +import com.massivecraft.factions.zcore.util.TL; + +public enum ChatMode { + FACTION(3, TL.CHAT_FACTION), + ALLIANCE(2, TL.CHAT_ALLIANCE), + TRUCE(1, TL.CHAT_TRUCE), + PUBLIC(0, TL.CHAT_PUBLIC); + + public final int value; + public final TL nicename; + + private ChatMode(final int value, final TL nicename) { + this.value = value; + this.nicename = nicename; + } + + public boolean isAtLeast(ChatMode role) { + return this.value >= role.value; + } + + public boolean isAtMost(ChatMode role) { + return this.value <= role.value; + } + + @Override + public String toString() { + return this.nicename.toString(); + } + + public ChatMode getNext() { + if (this == PUBLIC) { + return ALLIANCE; + } + if (this == ALLIANCE) { + return FACTION; + } + return PUBLIC; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/struct/Permission.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/struct/Permission.java new file mode 100644 index 0000000..b5edbb8 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/struct/Permission.java @@ -0,0 +1,98 @@ +package com.massivecraft.factions.struct; + +import com.massivecraft.factions.P; +import org.bukkit.command.CommandSender; + +public enum Permission { + MANAGE_SAFE_ZONE("managesafezone"), + MANAGE_WAR_ZONE("managewarzone"), + OWNERSHIP_BYPASS("ownershipbypass"), + ADMIN("admin"), + ADMIN_ANY("admin.any"), + AHOME("ahome"), + ANNOUNCE("announce"), + AUTOCLAIM("autoclaim"), + AUTO_LEAVE_BYPASS("autoleavebypass"), + BYPASS("bypass"), + CHAT("chat"), + CHATSPY("chatspy"), + CLAIM("claim"), + CLAIM_LINE("claim.line"), + CLAIM_RADIUS("claim.radius"), + CONFIG("config"), + CREATE("create"), + DEINVITE("deinvite"), + DESCRIPTION("description"), + DISBAND("disband"), + DISBAND_ANY("disband.any"), + HELP("help"), + HOME("home"), + INVITE("invite"), + JOIN("join"), + JOIN_ANY("join.any"), + JOIN_OTHERS("join.others"), + KICK("kick"), + KICK_ANY("kick.any"), + LEAVE("leave"), + LIST("list"), + LOCK("lock"), + MAP("map"), + MOD("mod"), + MOD_ANY("mod.any"), + MODIFY_POWER("modifypower"), + MONEY_BALANCE("money.balance"), + MONEY_BALANCE_ANY("money.balance.any"), + MONEY_DEPOSIT("money.deposit"), + MONEY_WITHDRAW("money.withdraw"), + MONEY_WITHDRAW_ANY("money.withdraw.any"), + MONEY_F2F("money.f2f"), + MONEY_F2P("money.f2p"), + MONEY_P2F("money.p2f"), + MONITOR_LOGINS("monitorlogins"), + NO_BOOM("noboom"), + OPEN("open"), + OWNER("owner"), + OWNERLIST("ownerlist"), + SET_PEACEFUL("setpeaceful"), + SET_PERMANENT("setpermanent"), + SET_PERMANENTPOWER("setpermanentpower"), + SHOW_INVITES("showinvites"), + POWERBOOST("powerboost"), + POWER("power"), + POWER_ANY("power.any"), + RELATION("relation"), + RELOAD("reload"), + SAVE("save"), + SETHOME("sethome"), + SETHOME_ANY("sethome.any"), + SHOW("show"), + STATUS("status"), + STUCK("stuck"), + TAG("tag"), + TITLE("title"), + TOGGLE_ALLIANCE_CHAT("togglealliancechat"), + UNCLAIM("unclaim"), + UNCLAIM_ALL("unclaimall"), + VERSION("version"), + SCOREBOARD("scoreboard"), + SEECHUNK("seechunk"), + SETWARP("setwarp"), + TOP("top"), + VAULT("vault"), + SETMAXVAULTS("setmaxvaults"), + WARP("warp"); + + public final String node; + + Permission(final String node) { + this.node = "factions." + node; + } + + public boolean has(CommandSender sender, boolean informSenderIfNot) { + return P.p.perm.has(sender, this.node, informSenderIfNot); + } + + public boolean has(CommandSender sender) { + return has(sender, false); + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/struct/Relation.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/struct/Relation.java new file mode 100644 index 0000000..2dd92c4 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/struct/Relation.java @@ -0,0 +1,186 @@ +package com.massivecraft.factions.struct; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.zcore.util.TL; +import org.bukkit.ChatColor; + + +public enum Relation { + MEMBER(4, "member"), + ALLY(3, "ally"), + TRUCE(2, "truce"), + NEUTRAL(1, "neutral"), + ENEMY(0, "enemy"); + + public final int value; + public final String nicename; + + private Relation(final int value, final String nicename) { + this.value = value; + this.nicename = nicename; + } + + @Override + public String toString() { + return this.nicename; + } + + public static Relation fromString(String s) { + // Because Java 6 doesn't allow String switches :( + if (s.equalsIgnoreCase("member")) { + return MEMBER; + } else if (s.equalsIgnoreCase("ally")) { + return ALLY; + } else if (s.equalsIgnoreCase("truce")) { + return TRUCE; + } else if (s.equalsIgnoreCase("enemy")) { + return ENEMY; + } else { + return NEUTRAL; // If they somehow mess things up, go back to default behavior. + } + } + + public String getTranslation() { + try { + return TL.valueOf("RELATION_" + name() + "_SINGULAR").toString(); + } catch (IllegalArgumentException e) { + return toString(); + } + } + + public String getPluralTranslation() { + for (TL t : TL.values()) { + if (t.name().equalsIgnoreCase("RELATION_" + name() + "_PLURAL")) { + return t.toString(); + } + } + return toString(); + } + + public boolean isMember() { + return this == MEMBER; + } + + public boolean isAlly() { + return this == ALLY; + } + + public boolean isTruce() { + return this == TRUCE; + } + + public boolean isNeutral() { + return this == NEUTRAL; + } + + public boolean isEnemy() { + return this == ENEMY; + } + + public boolean isAtLeast(Relation relation) { + return this.value >= relation.value; + } + + public boolean isAtMost(Relation relation) { + return this.value <= relation.value; + } + + public ChatColor getColor() { + if (this == MEMBER) { + return Conf.colorMember; + } else if (this == ALLY) { + return Conf.colorAlly; + } else if (this == NEUTRAL) { + return Conf.colorNeutral; + } else if (this == TRUCE) { + return Conf.colorTruce; + } else { + return Conf.colorEnemy; + } + } + + // return appropriate Conf setting for DenyBuild based on this relation and their online status + public boolean confDenyBuild(boolean online) { + if (isMember()) { + return false; + } + + if (online) { + if (isEnemy()) { + return Conf.territoryEnemyDenyBuild; + } else if (isAlly()) { + return Conf.territoryAllyDenyBuild; + } else if (isTruce()) { + return Conf.territoryTruceDenyBuild; + } else { + return Conf.territoryDenyBuild; + } + } else { + if (isEnemy()) { + return Conf.territoryEnemyDenyBuildWhenOffline; + } else if (isAlly()) { + return Conf.territoryAllyDenyBuildWhenOffline; + } else if (isTruce()) { + return Conf.territoryTruceDenyBuildWhenOffline; + } else { + return Conf.territoryDenyBuildWhenOffline; + } + } + } + + // return appropriate Conf setting for PainBuild based on this relation and their online status + public boolean confPainBuild(boolean online) { + if (isMember()) { + return false; + } + + if (online) { + if (isEnemy()) { + return Conf.territoryEnemyPainBuild; + } else if (isAlly()) { + return Conf.territoryAllyPainBuild; + } else if (isTruce()) { + return Conf.territoryTrucePainBuild; + } else { + return Conf.territoryPainBuild; + } + } else { + if (isEnemy()) { + return Conf.territoryEnemyPainBuildWhenOffline; + } else if (isAlly()) { + return Conf.territoryAllyPainBuildWhenOffline; + } else if (isTruce()) { + return Conf.territoryTrucePainBuildWhenOffline; + } else { + return Conf.territoryPainBuildWhenOffline; + } + } + } + + // return appropriate Conf setting for DenyUseage based on this relation + public boolean confDenyUseage() { + if (isMember()) { + return false; + } else if (isEnemy()) { + return Conf.territoryEnemyDenyUseage; + } else if (isAlly()) { + return Conf.territoryAllyDenyUseage; + } else if (isTruce()) { + return Conf.territoryTruceDenyUseage; + } else { + return Conf.territoryDenyUseage; + } + } + + public double getRelationCost() { + if (isEnemy()) { + return Conf.econCostEnemy; + } else if (isAlly()) { + return Conf.econCostAlly; + } else if (isTruce()) { + return Conf.econCostTruce; + } else { + return Conf.econCostNeutral; + } + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/struct/Role.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/struct/Role.java new file mode 100644 index 0000000..cf81e8a --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/struct/Role.java @@ -0,0 +1,49 @@ +package com.massivecraft.factions.struct; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.zcore.util.TL; + +public enum Role { + ADMIN(2, TL.ROLE_ADMIN), + MODERATOR(1, TL.ROLE_MODERATOR), + NORMAL(0, TL.ROLE_NORMAL); + + public final int value; + public final String nicename; + public final TL translation; + + private Role(final int value, final TL translation) { + this.value = value; + this.nicename = translation.toString(); + this.translation = translation; + } + + public boolean isAtLeast(Role role) { + return this.value >= role.value; + } + + public boolean isAtMost(Role role) { + return this.value <= role.value; + } + + @Override + public String toString() { + return this.nicename; + } + + public TL getTranslation(){ + return translation; + } + + public String getPrefix() { + if (this == Role.ADMIN) { + return Conf.prefixAdmin; + } + + if (this == Role.MODERATOR) { + return Conf.prefixMod; + } + + return ""; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/AsciiCompass.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/AsciiCompass.java new file mode 100644 index 0000000..7d52b36 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/AsciiCompass.java @@ -0,0 +1,110 @@ +package com.massivecraft.factions.util; + +import com.massivecraft.factions.zcore.util.TL; +import org.bukkit.ChatColor; + +import java.util.ArrayList; + +public class AsciiCompass { + + public enum Point { + + N('N'), + NE('/'), + E('E'), + SE('\\'), + S('S'), + SW('/'), + W('W'), + NW('\\'); + + public final char asciiChar; + + private Point(final char asciiChar) { + this.asciiChar = asciiChar; + } + + @Override + public String toString() { + return String.valueOf(this.asciiChar); + } + + public String getTranslation() { + if (this == N) { + return TL.COMPASS_SHORT_NORTH.toString(); + } + if (this == E) { + return TL.COMPASS_SHORT_EAST.toString(); + } + if (this == S) { + return TL.COMPASS_SHORT_SOUTH.toString(); + } + if (this == W) { + return TL.COMPASS_SHORT_WEST.toString(); + } + return toString(); + } + + public String toString(boolean isActive, ChatColor colorActive, String colorDefault) { + return (isActive ? colorActive : colorDefault) + getTranslation(); + } + } + + public static AsciiCompass.Point getCompassPointForDirection(double inDegrees) { + double degrees = (inDegrees - 180) % 360; + if (degrees < 0) { + degrees += 360; + } + + if (0 <= degrees && degrees < 22.5) { + return AsciiCompass.Point.N; + } else if (22.5 <= degrees && degrees < 67.5) { + return AsciiCompass.Point.NE; + } else if (67.5 <= degrees && degrees < 112.5) { + return AsciiCompass.Point.E; + } else if (112.5 <= degrees && degrees < 157.5) { + return AsciiCompass.Point.SE; + } else if (157.5 <= degrees && degrees < 202.5) { + return AsciiCompass.Point.S; + } else if (202.5 <= degrees && degrees < 247.5) { + return AsciiCompass.Point.SW; + } else if (247.5 <= degrees && degrees < 292.5) { + return AsciiCompass.Point.W; + } else if (292.5 <= degrees && degrees < 337.5) { + return AsciiCompass.Point.NW; + } else if (337.5 <= degrees && degrees < 360.0) { + return AsciiCompass.Point.N; + } else { + return null; + } + } + + public static ArrayList getAsciiCompass(Point point, ChatColor colorActive, String colorDefault) { + ArrayList ret = new ArrayList(); + String row; + + row = ""; + row += Point.NW.toString(Point.NW == point, colorActive, colorDefault); + row += Point.N.toString(Point.N == point, colorActive, colorDefault); + row += Point.NE.toString(Point.NE == point, colorActive, colorDefault); + ret.add(row); + + row = ""; + row += Point.W.toString(Point.W == point, colorActive, colorDefault); + row += colorDefault + "+"; + row += Point.E.toString(Point.E == point, colorActive, colorDefault); + ret.add(row); + + row = ""; + row += Point.SW.toString(Point.SW == point, colorActive, colorDefault); + row += Point.S.toString(Point.S == point, colorActive, colorDefault); + row += Point.SE.toString(Point.SE == point, colorActive, colorDefault); + ret.add(row); + + return ret; + } + + public static ArrayList getAsciiCompass(double inDegrees, ChatColor colorActive, String colorDefault) { + return getAsciiCompass(getCompassPointForDirection(inDegrees), colorActive, colorDefault); + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/AutoLeaveProcessTask.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/AutoLeaveProcessTask.java new file mode 100644 index 0000000..26e656b --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/AutoLeaveProcessTask.java @@ -0,0 +1,93 @@ +package com.massivecraft.factions.util; + +import com.massivecraft.factions.*; +import com.massivecraft.factions.struct.Role; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.ArrayList; +import java.util.ListIterator; +import java.util.logging.Level; + +public class AutoLeaveProcessTask extends BukkitRunnable { + + private transient boolean readyToGo = false; + private transient boolean finished = false; + private transient ListIterator iterator; + private transient double toleranceMillis; + + public AutoLeaveProcessTask() { + ArrayList fplayers = (ArrayList) FPlayers.getInstance().getAllFPlayers(); + this.iterator = fplayers.listIterator(); + this.toleranceMillis = Conf.autoLeaveAfterDaysOfInactivity * 24 * 60 * 60 * 1000; + this.readyToGo = true; + this.finished = false; + } + + public void run() { + if (Conf.autoLeaveAfterDaysOfInactivity <= 0.0 || Conf.autoLeaveRoutineMaxMillisecondsPerTick <= 0.0) { + this.stop(); + return; + } + + if (!readyToGo) { + return; + } + // this is set so it only does one iteration at a time, no matter how frequently the timer fires + readyToGo = false; + // and this is tracked to keep one iteration from dragging on too long and possibly choking the system if there are a very large number of players to go through + long loopStartTime = System.currentTimeMillis(); + + while (iterator.hasNext()) { + long now = System.currentTimeMillis(); + + // if this iteration has been running for maximum time, stop to take a breather until next tick + if (now > loopStartTime + Conf.autoLeaveRoutineMaxMillisecondsPerTick) { + readyToGo = true; + return; + } + + FPlayer fplayer = iterator.next(); + + // Check if they should be exempt from this. + if (!fplayer.willAutoLeave()) { + P.p.debug(Level.INFO, fplayer.getName() + " was going to be auto-removed but was set not to."); + continue; + } + + if (fplayer.isOffline() && now - fplayer.getLastLoginTime() > toleranceMillis) { + if (Conf.logFactionLeave || Conf.logFactionKick) { + P.p.log("Player " + fplayer.getName() + " was auto-removed due to inactivity."); + } + + // if player is faction admin, sort out the faction since he's going away + if (fplayer.getRole() == Role.ADMIN) { + Faction faction = fplayer.getFaction(); + if (faction != null) { + fplayer.getFaction().promoteNewLeader(); + } + } + + fplayer.leave(false); + iterator.remove(); // go ahead and remove this list's link to the FPlayer object + if (Conf.autoLeaveDeleteFPlayerData) { + fplayer.remove(); + } + } + } + + // looks like we've finished + this.stop(); + } + + // we're done, shut down + public void stop() { + readyToGo = false; + finished = true; + + this.cancel(); + } + + public boolean isFinished() { + return finished; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/AutoLeaveTask.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/AutoLeaveTask.java new file mode 100644 index 0000000..6a1bda4 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/AutoLeaveTask.java @@ -0,0 +1,28 @@ +package com.massivecraft.factions.util; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.P; + +public class AutoLeaveTask implements Runnable { + + private static AutoLeaveProcessTask task; + double rate; + + public AutoLeaveTask() { + this.rate = Conf.autoLeaveRoutineRunsEveryXMinutes; + } + + public synchronized void run() { + if (task != null && !task.isFinished()) { + return; + } + + task = new AutoLeaveProcessTask(); + task.runTaskTimer(P.p, 1, 1); + + // maybe setting has been changed? if so, restart this task at new rate + if (this.rate != Conf.autoLeaveRoutineRunsEveryXMinutes) { + P.p.startAutoLeaveTask(true); + } + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/EnumTypeAdapter.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/EnumTypeAdapter.java new file mode 100644 index 0000000..8e8f6fc --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/EnumTypeAdapter.java @@ -0,0 +1,67 @@ +package com.massivecraft.factions.util; + +import com.google.gson.Gson; +import com.google.gson.TypeAdapter; +import com.google.gson.TypeAdapterFactory; +import com.google.gson.annotations.SerializedName; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; +import com.google.gson.stream.JsonWriter; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +public final class EnumTypeAdapter> extends TypeAdapter { + + private final Map nameToConstant = new HashMap(); + private final Map constantToName = new HashMap(); + + public EnumTypeAdapter(Class classOfT) { + try { + for (T constant : classOfT.getEnumConstants()) { + String name = constant.name(); + SerializedName annotation = classOfT.getField(name).getAnnotation(SerializedName.class); + if (annotation != null) { + name = annotation.value(); + } + nameToConstant.put(name, constant); + constantToName.put(constant, name); + } + } catch (NoSuchFieldException e) { + // ignore since it could be a modified enum + } + } + + public T read(JsonReader in) throws IOException { + if (in.peek() == JsonToken.NULL) { + in.nextNull(); + return null; + } + return nameToConstant.get(in.nextString()); + } + + public void write(JsonWriter out, T value) throws IOException { + out.value(value == null ? null : constantToName.get(value)); + } + + public static final TypeAdapterFactory ENUM_FACTORY = newEnumTypeHierarchyFactory(); + + public static TypeAdapterFactory newEnumTypeHierarchyFactory() { + return new TypeAdapterFactory() { + @SuppressWarnings({"rawtypes", "unchecked"}) + public TypeAdapter create(Gson gson, TypeToken typeToken) { + Class rawType = typeToken.getRawType(); + if (!Enum.class.isAssignableFrom(rawType) || rawType == Enum.class) { + return null; + } + if (!rawType.isEnum()) { + rawType = rawType.getSuperclass(); // handle anonymous subclasses + } + return (TypeAdapter) new EnumTypeAdapter(rawType); + } + }; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/LazyLocation.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/LazyLocation.java new file mode 100644 index 0000000..a141bbc --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/LazyLocation.java @@ -0,0 +1,101 @@ +package com.massivecraft.factions.util; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; + +import java.io.Serializable; + +/* + * This class provides a lazy-load Location, so that World doesn't need to be initialized + * yet when an object of this class is created, only when the Location is first accessed. + */ + +public class LazyLocation implements Serializable { + private static final long serialVersionUID = -6049901271320963314L; + private transient Location location = null; + private String worldName; + private double x; + private double y; + private double z; + private float pitch; + private float yaw; + + public LazyLocation(Location loc) { + setLocation(loc); + } + + public LazyLocation(final String worldName, final double x, final double y, final double z) { + this(worldName, x, y, z, 0, 0); + } + + public LazyLocation(final String worldName, final double x, final double y, final double z, final float yaw, final float pitch) { + this.worldName = worldName; + this.x = x; + this.y = y; + this.z = z; + this.yaw = yaw; + this.pitch = pitch; + } + + // This returns the actual Location + public final Location getLocation() { + // make sure Location is initialized before returning it + initLocation(); + return location; + } + + // change the Location + public final void setLocation(Location loc) { + this.location = loc; + this.worldName = loc.getWorld().getName(); + this.x = loc.getX(); + this.y = loc.getY(); + this.z = loc.getZ(); + this.yaw = loc.getYaw(); + this.pitch = loc.getPitch(); + } + + + // This initializes the Location + private void initLocation() { + // if location is already initialized, simply return + if (location != null) { + return; + } + + // get World; hopefully it's initialized at this point + World world = Bukkit.getWorld(worldName); + if (world == null) { + return; + } + + // store the Location for future calls, and pass it on + location = new Location(world, x, y, z, yaw, pitch); + } + + + public final String getWorldName() { + return worldName; + } + + public final double getX() { + return x; + } + + public final double getY() { + return y; + } + + public final double getZ() { + return z; + } + + public final double getPitch() { + return pitch; + } + + public final double getYaw() { + return yaw; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/MapFLocToStringSetTypeAdapter.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/MapFLocToStringSetTypeAdapter.java new file mode 100644 index 0000000..eb9936a --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/MapFLocToStringSetTypeAdapter.java @@ -0,0 +1,104 @@ +package com.massivecraft.factions.util; + +import com.google.gson.*; +import com.massivecraft.factions.FLocation; +import com.massivecraft.factions.P; + +import java.lang.reflect.Type; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Level; + + +public class MapFLocToStringSetTypeAdapter implements JsonDeserializer>>, JsonSerializer>> { + + @Override + public Map> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + try { + JsonObject obj = json.getAsJsonObject(); + if (obj == null) { + return null; + } + + Map> locationMap = new ConcurrentHashMap>(); + Set nameSet; + Iterator iter; + String worldName; + String[] coords; + int x, z; + + for (Entry entry : obj.entrySet()) { + worldName = entry.getKey(); + for (Entry entry2 : entry.getValue().getAsJsonObject().entrySet()) { + coords = entry2.getKey().trim().split("[,\\s]+"); + x = Integer.parseInt(coords[0]); + z = Integer.parseInt(coords[1]); + + nameSet = new HashSet(); + iter = entry2.getValue().getAsJsonArray().iterator(); + while (iter.hasNext()) { + nameSet.add(iter.next().getAsString()); + } + + locationMap.put(new FLocation(worldName, x, z), nameSet); + } + } + + return locationMap; + + } catch (Exception ex) { + ex.printStackTrace(); + P.p.log(Level.WARNING, "Error encountered while deserializing a Map of FLocations to String Sets."); + return null; + } + } + + @Override + public JsonElement serialize(Map> src, Type typeOfSrc, JsonSerializationContext context) { + JsonObject obj = new JsonObject(); + + try { + if (src != null) { + FLocation loc; + String locWorld; + Set nameSet; + Iterator iter; + JsonArray nameArray; + JsonPrimitive nameElement; + + for (Entry> entry : src.entrySet()) { + loc = entry.getKey(); + locWorld = loc.getWorldName(); + nameSet = entry.getValue(); + + if (nameSet == null || nameSet.isEmpty()) { + continue; + } + + nameArray = new JsonArray(); + iter = nameSet.iterator(); + while (iter.hasNext()) { + nameElement = new JsonPrimitive(iter.next()); + nameArray.add(nameElement); + } + + if (!obj.has(locWorld)) { + obj.add(locWorld, new JsonObject()); + } + + obj.get(locWorld).getAsJsonObject().add(loc.getCoordString(), nameArray); + } + } + return obj; + + } catch (Exception ex) { + ex.printStackTrace(); + P.p.log(Level.WARNING, "Error encountered while serializing a Map of FLocations to String Sets."); + return obj; + } + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/MiscUtil.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/MiscUtil.java new file mode 100644 index 0000000..b59ff55 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/MiscUtil.java @@ -0,0 +1,113 @@ +package com.massivecraft.factions.util; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.P; +import com.massivecraft.factions.zcore.util.TL; +import org.bukkit.ChatColor; +import org.bukkit.entity.Creature; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; + +public class MiscUtil { + + public static EntityType creatureTypeFromEntity(Entity entity) { + if (!(entity instanceof Creature)) { + return null; + } + + String name = entity.getClass().getSimpleName(); + name = name.substring(5); // Remove "Craft" + + return EntityType.fromName(name); + } + + // Inclusive range + public static long[] range(long start, long end) { + long[] values = new long[(int) Math.abs(end - start) + 1]; + + if (end < start) { + long oldstart = start; + start = end; + end = oldstart; + } + + for (long i = start; i <= end; i++) { + values[(int) (i - start)] = i; + } + + return values; + } + + /// TODO create tag whitelist!! + public static HashSet substanceChars = new HashSet(Arrays.asList(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"})); + + public static String getComparisonString(String str) { + String ret = ""; + + str = ChatColor.stripColor(str); + str = str.toLowerCase(); + + for (char c : str.toCharArray()) { + if (substanceChars.contains(String.valueOf(c))) { + ret += c; + } + } + return ret.toLowerCase(); + } + + public static ArrayList validateTag(String str) { + ArrayList errors = new ArrayList(); + + if (getComparisonString(str).length() < Conf.factionTagLengthMin) { + errors.add(P.p.txt.parse(TL.GENERIC_FACTIONTAG_TOOSHORT.toString(), Conf.factionTagLengthMin)); + } + + if (str.length() > Conf.factionTagLengthMax) { + errors.add(P.p.txt.parse(TL.GENERIC_FACTIONTAG_TOOLONG.toString(), Conf.factionTagLengthMax)); + } + + for (char c : str.toCharArray()) { + if (!substanceChars.contains(String.valueOf(c))) { + errors.add(P.p.txt.parse(TL.GENERIC_FACTIONTAG_ALPHANUMERIC.toString(), c)); + } + } + + return errors; + } + + public static Iterable rankOrder(Iterable players) { + List admins = new ArrayList(); + List moderators = new ArrayList(); + List normal = new ArrayList(); + + for (FPlayer player : players) { + switch (player.getRole()) { + case ADMIN: + admins.add(player); + break; + + case MODERATOR: + moderators.add(player); + break; + + case NORMAL: + normal.add(player); + break; + } + } + + List ret = new ArrayList(); + ret.addAll(admins); + ret.addAll(moderators); + ret.addAll(normal); + return ret; + } +} + diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/MyLocationTypeAdapter.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/MyLocationTypeAdapter.java new file mode 100644 index 0000000..c68fca6 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/MyLocationTypeAdapter.java @@ -0,0 +1,59 @@ +package com.massivecraft.factions.util; + +import com.google.gson.*; +import com.massivecraft.factions.P; + +import java.lang.reflect.Type; +import java.util.logging.Level; + + +public class MyLocationTypeAdapter implements JsonDeserializer, JsonSerializer { + + private static final String WORLD = "world"; + private static final String X = "x"; + private static final String Y = "y"; + private static final String Z = "z"; + private static final String YAW = "yaw"; + private static final String PITCH = "pitch"; + + @Override + public LazyLocation deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + try { + JsonObject obj = json.getAsJsonObject(); + + String worldName = obj.get(WORLD).getAsString(); + double x = obj.get(X).getAsDouble(); + double y = obj.get(Y).getAsDouble(); + double z = obj.get(Z).getAsDouble(); + float yaw = obj.get(YAW).getAsFloat(); + float pitch = obj.get(PITCH).getAsFloat(); + + return new LazyLocation(worldName, x, y, z, yaw, pitch); + + } catch (Exception ex) { + ex.printStackTrace(); + P.p.log(Level.WARNING, "Error encountered while deserializing a LazyLocation."); + return null; + } + } + + @Override + public JsonElement serialize(LazyLocation src, Type typeOfSrc, JsonSerializationContext context) { + JsonObject obj = new JsonObject(); + + try { + obj.addProperty(WORLD, src.getWorldName()); + obj.addProperty(X, src.getX()); + obj.addProperty(Y, src.getY()); + obj.addProperty(Z, src.getZ()); + obj.addProperty(YAW, src.getYaw()); + obj.addProperty(PITCH, src.getPitch()); + + return obj; + } catch (Exception ex) { + ex.printStackTrace(); + P.p.log(Level.WARNING, "Error encountered while serializing a LazyLocation."); + return obj; + } + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/RelationUtil.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/RelationUtil.java new file mode 100644 index 0000000..3c03cd2 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/RelationUtil.java @@ -0,0 +1,118 @@ +package com.massivecraft.factions.util; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.iface.RelationParticipator; +import com.massivecraft.factions.struct.Relation; +import com.massivecraft.factions.zcore.util.TL; +import com.massivecraft.factions.zcore.util.TextUtil; +import org.bukkit.ChatColor; + +public class RelationUtil { + + public static String describeThatToMe(RelationParticipator that, RelationParticipator me, boolean ucfirst) { + String ret = ""; + + Faction thatFaction = getFaction(that); + if (thatFaction == null) { + return "ERROR"; // ERROR + } + + Faction myFaction = getFaction(me); +// if (myFaction == null) return that.describeTo(null); // no relation, but can show basic name or tag + + if (that instanceof Faction) { + if (me instanceof FPlayer && myFaction == thatFaction) { + ret = TL.GENERIC_YOURFACTION.toString(); + } else { + ret = thatFaction.getTag(); + } + } else if (that instanceof FPlayer) { + FPlayer fplayerthat = (FPlayer) that; + if (that == me) { + ret = TL.GENERIC_YOU.toString(); + } else if (thatFaction == myFaction) { + ret = fplayerthat.getNameAndTitle(); + } else { + ret = fplayerthat.getNameAndTag(); + } + } + + if (ucfirst) { + ret = TextUtil.upperCaseFirst(ret); + } + + return "" + getColorOfThatToMe(that, me) + ret; + } + + public static String describeThatToMe(RelationParticipator that, RelationParticipator me) { + return describeThatToMe(that, me, false); + } + + public static Relation getRelationTo(RelationParticipator me, RelationParticipator that) { + return getRelationTo(that, me, false); + } + + public static Relation getRelationTo(RelationParticipator me, RelationParticipator that, boolean ignorePeaceful) { + Faction fthat = getFaction(that); + if (fthat == null) { + return Relation.NEUTRAL; // ERROR + } + + Faction fme = getFaction(me); + if (fme == null) { + return Relation.NEUTRAL; // ERROR + } + + if (!fthat.isNormal() || !fme.isNormal()) { + return Relation.NEUTRAL; + } + + if (fthat.equals(fme)) { + return Relation.MEMBER; + } + + if (!ignorePeaceful && (fme.isPeaceful() || fthat.isPeaceful())) { + return Relation.NEUTRAL; + } + + if (fme.getRelationWish(fthat).value >= fthat.getRelationWish(fme).value) { + return fthat.getRelationWish(fme); + } + + return fme.getRelationWish(fthat); + } + + public static Faction getFaction(RelationParticipator rp) { + if (rp instanceof Faction) { + return (Faction) rp; + } + + if (rp instanceof FPlayer) { + return ((FPlayer) rp).getFaction(); + } + + // ERROR + return null; + } + + public static ChatColor getColorOfThatToMe(RelationParticipator that, RelationParticipator me) { + Faction thatFaction = getFaction(that); + if (thatFaction != null) { + if (thatFaction.isPeaceful() && thatFaction != getFaction(me)) { + return Conf.colorPeaceful; + } + + if (thatFaction.isSafeZone() && thatFaction != getFaction(me)) { + return Conf.colorPeaceful; + } + + if (thatFaction.isWarZone() && thatFaction != getFaction(me)) { + return Conf.colorWar; + } + } + + return getRelationTo(that, me).getColor(); + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/SpiralTask.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/SpiralTask.java new file mode 100644 index 0000000..85afa1d --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/SpiralTask.java @@ -0,0 +1,209 @@ +package com.massivecraft.factions.util; + +import com.massivecraft.factions.FLocation; +import com.massivecraft.factions.P; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; + +import java.util.logging.Level; + + +/* + * reference diagram, task should move in this pattern out from chunk 0 in the center. + * 8 [>][>][>][>][>] etc. + * [^][6][>][>][>][>][>][6] + * [^][^][4][>][>][>][4][v] + * [^][^][^][2][>][2][v][v] + * [^][^][^][^][0][v][v][v] + * [^][^][^][1][1][v][v][v] + * [^][^][3][<][<][3][v][v] + * [^][5][<][<][<][<][5][v] + * [7][<][<][<][<][<][<][7] + */ + +public abstract class SpiralTask implements Runnable { + + // general task-related reference data + private transient World world = null; + private transient boolean readyToGo = false; + private transient int taskID = -1; + private transient int limit = 0; + + // values for the spiral pattern routine + private transient int x = 0; + private transient int z = 0; + private transient boolean isZLeg = false; + private transient boolean isNeg = false; + private transient int length = -1; + private transient int current = 0; + + @SuppressWarnings("LeakingThisInConstructor") + public SpiralTask(FLocation fLocation, int radius) { + // limit is determined based on spiral leg length for given radius; see insideRadius() + this.limit = (radius - 1) * 2; + + this.world = Bukkit.getWorld(fLocation.getWorldName()); + if (this.world == null) { + P.p.log(Level.WARNING, "[SpiralTask] A valid world must be specified!"); + this.stop(); + return; + } + + this.x = (int) fLocation.getX(); + this.z = (int) fLocation.getZ(); + + this.readyToGo = true; + + // get this party started + this.setTaskID(Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(P.p, this, 2, 2)); + } + + /* + * This is where the necessary work is done; you'll need to override this method with whatever you want + * done at each chunk in the spiral pattern. + * Return false if the entire task needs to be aborted, otherwise return true to continue. + */ + public abstract boolean work(); + + /* + * Returns an FLocation pointing at the current chunk X and Z values. + */ + public final FLocation currentFLocation() { + return new FLocation(world.getName(), x, z); + } + + /* + * Returns a Location pointing at the current chunk X and Z values. + * note that the Location is at the corner of the chunk, not the center. + */ + public final Location currentLocation() { + return new Location(world, FLocation.chunkToBlock(x), 65.0, FLocation.chunkToBlock(z)); + } + + /* + * Returns current chunk X and Z values. + */ + public final int getX() { + return x; + } + + public final int getZ() { + return z; + } + + + +/* + * Below are the guts of the class, which you normally wouldn't need to mess with. + */ + + public final void setTaskID(int ID) { + if (ID == -1) { + this.stop(); + } + taskID = ID; + } + + public final void run() { + if (!this.valid() || !readyToGo) { + return; + } + + // this is set so it only does one iteration at a time, no matter how frequently the timer fires + readyToGo = false; + + // make sure we're still inside the specified radius + if (!this.insideRadius()) { + return; + } + + // track this to keep one iteration from dragging on too long and possibly choking the system + long loopStartTime = now(); + + // keep going until the task has been running for 20ms or more, then stop to take a breather + while (now() < loopStartTime + 20) { + // run the primary task on the current X/Z coordinates + if (!this.work()) { + this.finish(); + return; + } + + // move on to next chunk in spiral + if (!this.moveToNext()) { + return; + } + } + + // ready for the next iteration to run + readyToGo = true; + } + + // step through chunks in spiral pattern from center; returns false if we're done, otherwise returns true + public final boolean moveToNext() { + if (!this.valid()) { + return false; + } + + // make sure we don't need to turn down the next leg of the spiral + if (current < length) { + current++; + + // if we're outside the radius, we're done + if (!this.insideRadius()) { + return false; + } + } else { // one leg/side of the spiral down... + current = 0; + isZLeg ^= true; + // every second leg (between X and Z legs, negative or positive), length increases + if (isZLeg) { + isNeg ^= true; + length++; + } + } + + // move one chunk further in the appropriate direction + if (isZLeg) { + z += (isNeg) ? -1 : 1; + } else { + x += (isNeg) ? -1 : 1; + } + + return true; + } + + public final boolean insideRadius() { + boolean inside = current < limit; + if (!inside) { + this.finish(); + } + return inside; + } + + // for successful completion + public void finish() { +// P.p.log("SpiralTask successfully completed!"); + this.stop(); + } + + // we're done, whether finished or cancelled + public final void stop() { + if (!this.valid()) { + return; + } + + readyToGo = false; + Bukkit.getServer().getScheduler().cancelTask(taskID); + taskID = -1; + } + + // is this task still valid/workable? + public final boolean valid() { + return taskID != -1; + } + + private static long now() { + return System.currentTimeMillis(); + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/VisualizeUtil.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/VisualizeUtil.java new file mode 100644 index 0000000..8ef7f91 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/VisualizeUtil.java @@ -0,0 +1,80 @@ +package com.massivecraft.factions.util; + +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; + +import java.util.*; +import java.util.Map.Entry; + +public class VisualizeUtil { + + protected static Map> playerLocations = new HashMap>(); + + public static Set getPlayerLocations(Player player) { + return getPlayerLocations(player.getUniqueId()); + } + + public static Set getPlayerLocations(UUID uuid) { + Set ret = playerLocations.get(uuid); + if (ret == null) { + ret = new HashSet(); + playerLocations.put(uuid, ret); + } + return ret; + } + + @SuppressWarnings("deprecation") + public static void addLocation(Player player, Location location, int typeId, byte data) { + getPlayerLocations(player).add(location); + player.sendBlockChange(location, typeId, data); + } + + @SuppressWarnings("deprecation") + public static void addLocation(Player player, Location location, int typeId) { + getPlayerLocations(player).add(location); + player.sendBlockChange(location, typeId, (byte) 0); + } + + @SuppressWarnings("deprecation") + public static void addLocations(Player player, Map locationMaterialIds) { + Set ploc = getPlayerLocations(player); + for (Entry entry : locationMaterialIds.entrySet()) { + ploc.add(entry.getKey()); + player.sendBlockChange(entry.getKey(), entry.getValue(), (byte) 0); + } + } + + @SuppressWarnings("deprecation") + public static void addLocations(Player player, Collection locations, int typeId) { + Set ploc = getPlayerLocations(player); + for (Location location : locations) { + ploc.add(location); + player.sendBlockChange(location, typeId, (byte) 0); + } + } + + @SuppressWarnings("deprecation") + public static void addBlocks(Player player, Collection blocks, int typeId) { + Set ploc = getPlayerLocations(player); + for (Block block : blocks) { + Location location = block.getLocation(); + ploc.add(location); + player.sendBlockChange(location, typeId, (byte) 0); + } + } + + @SuppressWarnings("deprecation") + public static void clear(Player player) { + Set locations = getPlayerLocations(player); + if (locations == null) { + return; + } + for (Location location : locations) { + Block block = location.getWorld().getBlockAt(location); + player.sendBlockChange(location, block.getTypeId(), block.getData()); + } + locations.clear(); + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/WarmUpUtil.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/WarmUpUtil.java new file mode 100644 index 0000000..14862ab --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/util/WarmUpUtil.java @@ -0,0 +1,42 @@ +package com.massivecraft.factions.util; + +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.P; +import com.massivecraft.factions.zcore.util.TL; + +public class WarmUpUtil { + + /** + * @param player The player to notify. + * @param translationKey The translation key used for notifying. + * @param action The action, inserted into the notification message. + * @param runnable The task to run after the delay. If the delay is 0, the task is instantly ran. + * @param delay The time used, in seconds, for the delay. + *

+ * note: for translations: %s = action, %d = delay + */ + public static void process(final FPlayer player, Warmup warmup, TL translationKey, String action, final Runnable runnable, long delay) { + if (delay > 0) { + if (player.isWarmingUp()) { + player.msg(TL.WARMUPS_ALREADY); + } else { + player.msg(translationKey.format(action, delay)); + int id = P.p.getServer().getScheduler().runTaskLater(P.p, new Runnable() { + @Override + public void run() { + player.stopWarmup(); + runnable.run(); + } + }, delay * 20).getTaskId(); + player.addWarmup(warmup, id); + } + } else { + runnable.run(); + } + } + + public enum Warmup { + HOME, WARP; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/CommandVisibility.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/CommandVisibility.java new file mode 100644 index 0000000..df588fb --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/CommandVisibility.java @@ -0,0 +1,7 @@ +package com.massivecraft.factions.zcore; + +public enum CommandVisibility { + VISIBLE, // Visible commands are visible to anyone. Even those who don't have permission to use it or is of invalid sender type. + SECRET, // Secret commands are visible only to those who can use the command. These commands are usually some kind of admin commands. + INVISIBLE; // Invisible commands are invisible to everyone, even those who can use the command. +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/MCommand.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/MCommand.java new file mode 100644 index 0000000..d67ee46 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/MCommand.java @@ -0,0 +1,491 @@ +package com.massivecraft.factions.zcore; + +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.P; +import com.massivecraft.factions.integration.Econ; +import com.massivecraft.factions.zcore.util.TL; +import com.massivecraft.factions.zcore.util.TextUtil; +import mkremins.fanciful.FancyMessage; +import org.apache.commons.lang.time.DurationFormatUtils; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map.Entry; +import java.util.UUID; + + +public abstract class MCommand { + + public T p; + + // The sub-commands to this command + public List> subCommands; + + public void addSubCommand(MCommand subCommand) { + subCommand.commandChain.addAll(this.commandChain); + subCommand.commandChain.add(this); + this.subCommands.add(subCommand); + } + + // The different names this commands will react to + public List aliases; + public boolean allowNoSlashAccess; + + // Information on the args + public List requiredArgs; + public LinkedHashMap optionalArgs; + public boolean errorOnToManyArgs = true; + + // FIELD: Help Short + // This field may be left blank and will in such case be loaded from the permissions node instead. + // Thus make sure the permissions node description is an action description like "eat hamburgers" or "do admin stuff". + private String helpShort; + + public void setHelpShort(String val) { + this.helpShort = val; + } + + public String getHelpShort() { + if (this.helpShort == null) { + return getUsageTranslation().toString(); + } + + return this.helpShort; + } + + public abstract TL getUsageTranslation(); + + public List helpLong; + public CommandVisibility visibility; + + // Some information on permissions + public boolean senderMustBePlayer; + public String permission; + + // Information available on execution of the command + public CommandSender sender; // Will always be set + public Player me; // Will only be set when the sender is a player + public boolean senderIsConsole; + public List args; // Will contain the arguments, or and empty list if there are none. + public List> commandChain = new ArrayList>(); // The command chain used to execute this command + + public MCommand(T p) { + this.p = p; + + this.permission = null; + + this.allowNoSlashAccess = false; + + this.subCommands = new ArrayList>(); + this.aliases = new ArrayList(); + + this.requiredArgs = new ArrayList(); + this.optionalArgs = new LinkedHashMap(); + + this.helpShort = null; + this.helpLong = new ArrayList(); + this.visibility = CommandVisibility.VISIBLE; + } + + // The commandChain is a list of the parent command chain used to get to this command. + public void execute(CommandSender sender, List args, List> commandChain) { + // Set the execution-time specific variables + this.sender = sender; + if (sender instanceof Player) { + this.me = (Player) sender; + this.senderIsConsole = false; + } else { + this.me = null; + this.senderIsConsole = true; + } + this.args = args; + this.commandChain = commandChain; + + // Is there a matching sub command? + if (args.size() > 0) { + for (MCommand subCommand : this.subCommands) { + if (subCommand.aliases.contains(args.get(0).toLowerCase())) { + args.remove(0); + commandChain.add(this); + subCommand.execute(sender, args, commandChain); + return; + } + } + } + + if (!validCall(this.sender, this.args)) { + return; + } + + if (!this.isEnabled()) { + return; + } + + perform(); + } + + public void execute(CommandSender sender, List args) { + execute(sender, args, new ArrayList>()); + } + + // This is where the command action is performed. + public abstract void perform(); + + + // -------------------------------------------- // + // Call Validation + // -------------------------------------------- // + + /** + * In this method we validate that all prerequisites to perform this command has been met. + */ + // TODO: There should be a boolean for silence + public boolean validCall(CommandSender sender, List args) { + return validSenderType(sender, true) && validSenderPermissions(sender, true) && validArgs(args, sender); + + } + + public boolean isEnabled() { + return true; + } + + public boolean validSenderType(CommandSender sender, boolean informSenderIfNot) { + if (this.senderMustBePlayer && !(sender instanceof Player)) { + if (informSenderIfNot) { + msg(TL.GENERIC_PLAYERONLY); + } + return false; + } + return true; + } + + public boolean validSenderPermissions(CommandSender sender, boolean informSenderIfNot) { + return this.permission == null || p.perm.has(sender, this.permission, informSenderIfNot); + } + + public boolean validArgs(List args, CommandSender sender) { + if (args.size() < this.requiredArgs.size()) { + if (sender != null) { + msg(TL.GENERIC_ARGS_TOOFEW); + sender.sendMessage(this.getUseageTemplate()); + } + return false; + } + + if (args.size() > this.requiredArgs.size() + this.optionalArgs.size() && this.errorOnToManyArgs) { + if (sender != null) { + // Get the to many string slice + List theToMany = args.subList(this.requiredArgs.size() + this.optionalArgs.size(), args.size()); + msg(TL.GENERIC_ARGS_TOOMANY, TextUtil.implode(theToMany, " ")); + sender.sendMessage(this.getUseageTemplate()); + } + return false; + } + return true; + } + + public boolean validArgs(List args) { + return this.validArgs(args, null); + } + + // -------------------------------------------- // + // Help and Usage information + // -------------------------------------------- // + + public String getUseageTemplate(List> commandChain, boolean addShortHelp) { + StringBuilder ret = new StringBuilder(); + ret.append(p.txt.parseTags("")); + ret.append('/'); + + for (MCommand mc : commandChain) { + ret.append(TextUtil.implode(mc.aliases, ",")); + ret.append(' '); + } + + ret.append(TextUtil.implode(this.aliases, ",")); + + List args = new ArrayList(); + + for (String requiredArg : this.requiredArgs) { + args.add("<" + requiredArg + ">"); + } + + for (Entry optionalArg : this.optionalArgs.entrySet()) { + String val = optionalArg.getValue(); + if (val == null) { + val = ""; + } else { + val = "=" + val; + } + args.add("[" + optionalArg.getKey() + val + "]"); + } + + if (args.size() > 0) { + ret.append(p.txt.parseTags("

+ * The FPlayer is linked to a minecraft player using the player name. + *

+ * The same instance is always returned for the same player. This means you can use the == operator. No .equals method + * necessary. + */ + +public abstract class MemoryFPlayer implements FPlayer { + + protected String factionId; + protected Role role; + protected String title; + protected double power; + protected double powerBoost; + protected long lastPowerUpdateTime; + protected long lastLoginTime; + protected ChatMode chatMode; + protected boolean ignoreAllianceChat = false; + protected String id; + protected String name; + protected boolean monitorJoins; + protected boolean spyingChat = false; + protected boolean showScoreboard = true; + protected WarmUpUtil.Warmup warmup; + protected int warmupTask; + protected boolean isAdminBypassing = false; + protected int kills, deaths; + protected boolean willAutoLeave = true; + + protected transient FLocation lastStoodAt = new FLocation(); // Where did this player stand the last time we checked? + protected transient boolean mapAutoUpdating; + protected transient Faction autoClaimFor; + protected transient boolean autoSafeZoneEnabled; + protected transient boolean autoWarZoneEnabled; + protected transient boolean loginPvpDisabled; + protected transient long lastFrostwalkerMessage; + + + public void login() { + this.kills = getPlayer().getStatistic(Statistic.PLAYER_KILLS); + this.deaths = getPlayer().getStatistic(Statistic.DEATHS); + } + + public void logout() { + this.kills = getPlayer().getStatistic(Statistic.PLAYER_KILLS); + this.deaths = getPlayer().getStatistic(Statistic.DEATHS); + } + + public Faction getFaction() { + if (this.factionId == null) { + this.factionId = "0"; + } + return Factions.getInstance().getFactionById(this.factionId); + } + + public String getFactionId() { + return this.factionId; + } + + public boolean hasFaction() { + return !factionId.equals("0"); + } + + public void setFaction(Faction faction) { + Faction oldFaction = this.getFaction(); + if (oldFaction != null) { + oldFaction.removeFPlayer(this); + } + faction.addFPlayer(this); + this.factionId = faction.getId(); + } + + public void setMonitorJoins(boolean monitor) { + this.monitorJoins = monitor; + } + + public boolean isMonitoringJoins() { + return this.monitorJoins; + } + + public Role getRole() { + return this.role; + } + + public void setRole(Role role) { + this.role = role; + } + + public double getPowerBoost() { + return this.powerBoost; + } + + public void setPowerBoost(double powerBoost) { + this.powerBoost = powerBoost; + } + + public boolean willAutoLeave() { + return this.willAutoLeave; + } + + public void setAutoLeave(boolean willLeave) { + this.willAutoLeave = willLeave; + P.p.debug(name + " set autoLeave to " + willLeave); + } + + public long getLastFrostwalkerMessage() { + return this.lastFrostwalkerMessage; + } + + public void setLastFrostwalkerMessage() { + this.lastFrostwalkerMessage = System.currentTimeMillis(); + } + + public Faction getAutoClaimFor() { + return autoClaimFor; + } + + public void setAutoClaimFor(Faction faction) { + this.autoClaimFor = faction; + if (this.autoClaimFor != null) { + // TODO: merge these into same autoclaim + this.autoSafeZoneEnabled = false; + this.autoWarZoneEnabled = false; + } + } + + public boolean isAutoSafeClaimEnabled() { + return autoSafeZoneEnabled; + } + + public void setIsAutoSafeClaimEnabled(boolean enabled) { + this.autoSafeZoneEnabled = enabled; + if (enabled) { + this.autoClaimFor = null; + this.autoWarZoneEnabled = false; + } + } + + public boolean isAutoWarClaimEnabled() { + return autoWarZoneEnabled; + } + + public void setIsAutoWarClaimEnabled(boolean enabled) { + this.autoWarZoneEnabled = enabled; + if (enabled) { + this.autoClaimFor = null; + this.autoSafeZoneEnabled = false; + } + } + + public boolean isAdminBypassing() { + return this.isAdminBypassing; + } + + public boolean isVanished() { + return Essentials.isVanished(getPlayer()); + } + + public void setIsAdminBypassing(boolean val) { + this.isAdminBypassing = val; + } + + public void setChatMode(ChatMode chatMode) { + this.chatMode = chatMode; + } + + public ChatMode getChatMode() { + if (this.factionId.equals("0") || !Conf.factionOnlyChat) { + this.chatMode = ChatMode.PUBLIC; + } + return chatMode; + } + + public void setIgnoreAllianceChat(boolean ignore) { + this.ignoreAllianceChat = ignore; + } + + public boolean isIgnoreAllianceChat() { + return ignoreAllianceChat; + } + + public void setSpyingChat(boolean chatSpying) { + this.spyingChat = chatSpying; + } + + public boolean isSpyingChat() { + return spyingChat; + } + + // FIELD: account + public String getAccountId() { + return this.getId(); + } + + public MemoryFPlayer() { + } + + public MemoryFPlayer(String id) { + this.id = id; + this.resetFactionData(false); + this.power = Conf.powerPlayerStarting; + this.lastPowerUpdateTime = System.currentTimeMillis(); + this.lastLoginTime = System.currentTimeMillis(); + this.mapAutoUpdating = false; + this.autoClaimFor = null; + this.autoSafeZoneEnabled = false; + this.autoWarZoneEnabled = false; + this.loginPvpDisabled = Conf.noPVPDamageToOthersForXSecondsAfterLogin > 0; + this.powerBoost = 0.0; + this.showScoreboard = P.p.getConfig().getBoolean("scoreboard.default-enabled", false); + this.kills = 0; + this.deaths = 0; + + if (!Conf.newPlayerStartingFactionID.equals("0") && Factions.getInstance().isValidFactionId(Conf.newPlayerStartingFactionID)) { + this.factionId = Conf.newPlayerStartingFactionID; + } + } + + public MemoryFPlayer(MemoryFPlayer other) { + this.factionId = other.factionId; + this.id = other.id; + this.power = other.power; + this.lastLoginTime = other.lastLoginTime; + this.mapAutoUpdating = other.mapAutoUpdating; + this.autoClaimFor = other.autoClaimFor; + this.autoSafeZoneEnabled = other.autoSafeZoneEnabled; + this.autoWarZoneEnabled = other.autoWarZoneEnabled; + this.loginPvpDisabled = other.loginPvpDisabled; + this.powerBoost = other.powerBoost; + this.role = other.role; + this.title = other.title; + this.chatMode = other.chatMode; + this.spyingChat = other.spyingChat; + this.lastStoodAt = other.lastStoodAt; + this.isAdminBypassing = other.isAdminBypassing; + this.showScoreboard = P.p.getConfig().getBoolean("scoreboard.default-enabled", true); + this.kills = other.kills; + this.deaths = other.deaths; + } + + public void resetFactionData(boolean doSpoutUpdate) { + // clean up any territory ownership in old faction, if there is one + if (factionId != null && Factions.getInstance().isValidFactionId(this.getFactionId())) { + Faction currentFaction = this.getFaction(); + currentFaction.removeFPlayer(this); + if (currentFaction.isNormal()) { + currentFaction.clearClaimOwnership(this); + } + } + + this.factionId = "0"; // The default neutral faction + this.chatMode = ChatMode.PUBLIC; + this.role = Role.NORMAL; + this.title = ""; + this.autoClaimFor = null; + } + + public void resetFactionData() { + this.resetFactionData(true); + } + + // -------------------------------------------- // + // Getters And Setters + // -------------------------------------------- // + + + public long getLastLoginTime() { + return lastLoginTime; + } + + + public void setLastLoginTime(long lastLoginTime) { + losePowerFromBeingOffline(); + this.lastLoginTime = lastLoginTime; + this.lastPowerUpdateTime = lastLoginTime; + if (Conf.noPVPDamageToOthersForXSecondsAfterLogin > 0) { + this.loginPvpDisabled = true; + } + } + + public boolean isMapAutoUpdating() { + return mapAutoUpdating; + } + + public void setMapAutoUpdating(boolean mapAutoUpdating) { + this.mapAutoUpdating = mapAutoUpdating; + } + + public boolean hasLoginPvpDisabled() { + if (!loginPvpDisabled) { + return false; + } + if (this.lastLoginTime + (Conf.noPVPDamageToOthersForXSecondsAfterLogin * 1000) < System.currentTimeMillis()) { + this.loginPvpDisabled = false; + return false; + } + return true; + } + + public FLocation getLastStoodAt() { + return this.lastStoodAt; + } + + public void setLastStoodAt(FLocation flocation) { + this.lastStoodAt = flocation; + } + + //----------------------------------------------// + // Title, Name, Faction CoreTag and Chat + //----------------------------------------------// + + // Base: + + public String getTitle() { + return this.hasFaction() ? title : TL.NOFACTION_PREFIX.toString(); + } + + public void setTitle(String title) { + this.title = title; + } + + public String getName() { + if (this.name == null) { + // Older versions of FactionsUUID don't save the name, + // so `name` will be null the first time it's retrieved + // after updating + OfflinePlayer offline = Bukkit.getOfflinePlayer(UUID.fromString(getId())); + this.name = offline.getName() != null ? offline.getName() : getId(); + } + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getTag() { + return this.hasFaction() ? this.getFaction().getTag() : ""; + } + + // Base concatenations: + + public String getNameAndSomething(String something) { + String ret = this.role.getPrefix(); + if (something.length() > 0) { + ret += something + " "; + } + ret += this.getName(); + return ret; + } + + public String getNameAndTitle() { + return this.getNameAndSomething(this.getTitle()); + } + + public String getNameAndTag() { + return this.getNameAndSomething(this.getTag()); + } + + // Colored concatenations: + // These are used in information messages + + public String getNameAndTitle(Faction faction) { + return this.getColorTo(faction) + this.getNameAndTitle(); + } + + public String getNameAndTitle(MemoryFPlayer fplayer) { + return this.getColorTo(fplayer) + this.getNameAndTitle(); + } + + // Chat CoreTag: + // These are injected into the format of global chat messages. + + public String getChatTag() { + return this.hasFaction() ? String.format(Conf.chatTagFormat, this.role.getPrefix() + this.getTag()) : ""; + } + + // Colored Chat CoreTag + public String getChatTag(Faction faction) { + return this.hasFaction() ? this.getRelationTo(faction).getColor() + getChatTag() : ""; + } + + public String getChatTag(MemoryFPlayer fplayer) { + return this.hasFaction() ? this.getColorTo(fplayer) + getChatTag() : ""; + } + + public int getKills() { + return isOnline() ? getPlayer().getStatistic(Statistic.PLAYER_KILLS) : this.kills; + } + + public int getDeaths() { + return isOnline() ? getPlayer().getStatistic(Statistic.DEATHS) : this.deaths; + + } + + // ------------------------------- + // Relation and relation colors + // ------------------------------- + + @Override + public String describeTo(RelationParticipator that, boolean ucfirst) { + return RelationUtil.describeThatToMe(this, that, ucfirst); + } + + @Override + public String describeTo(RelationParticipator that) { + return RelationUtil.describeThatToMe(this, that); + } + + @Override + public Relation getRelationTo(RelationParticipator rp) { + return RelationUtil.getRelationTo(this, rp); + } + + @Override + public Relation getRelationTo(RelationParticipator rp, boolean ignorePeaceful) { + return RelationUtil.getRelationTo(this, rp, ignorePeaceful); + } + + public Relation getRelationToLocation() { + return Board.getInstance().getFactionAt(new FLocation(this)).getRelationTo(this); + } + + @Override + public ChatColor getColorTo(RelationParticipator rp) { + return RelationUtil.getColorOfThatToMe(this, rp); + } + + //----------------------------------------------// + // Health + //----------------------------------------------// + public void heal(int amnt) { + Player player = this.getPlayer(); + if (player == null) { + return; + } + player.setHealth(player.getHealth() + amnt); + } + + + //----------------------------------------------// + // Power + //----------------------------------------------// + public double getPower() { + this.updatePower(); + return this.power; + } + + public void alterPower(double delta) { + this.power += delta; + if (this.power > this.getPowerMax()) { + this.power = this.getPowerMax(); + } else if (this.power < this.getPowerMin()) { + this.power = this.getPowerMin(); + } + } + + public double getPowerMax() { + return Conf.powerPlayerMax + this.powerBoost; + } + + public double getPowerMin() { + return Conf.powerPlayerMin + this.powerBoost; + } + + public int getPowerRounded() { + return (int) Math.round(this.getPower()); + } + + public int getPowerMaxRounded() { + return (int) Math.round(this.getPowerMax()); + } + + public int getPowerMinRounded() { + return (int) Math.round(this.getPowerMin()); + } + + public void updatePower() { + if (this.isOffline()) { + losePowerFromBeingOffline(); + if (!Conf.powerRegenOffline) { + return; + } + } else if (hasFaction() && getFaction().isPowerFrozen()) { + return; // Don't let power regen if faction power is frozen. + } + long now = System.currentTimeMillis(); + long millisPassed = now - this.lastPowerUpdateTime; + this.lastPowerUpdateTime = now; + + Player thisPlayer = this.getPlayer(); + if (thisPlayer != null && thisPlayer.isDead()) { + return; // don't let dead players regain power until they respawn + } + + int millisPerMinute = 60 * 1000; + this.alterPower(millisPassed * Conf.powerPerMinute / millisPerMinute); + } + + public void losePowerFromBeingOffline() { + if (Conf.powerOfflineLossPerDay > 0.0 && this.power > Conf.powerOfflineLossLimit) { + long now = System.currentTimeMillis(); + long millisPassed = now - this.lastPowerUpdateTime; + this.lastPowerUpdateTime = now; + + double loss = millisPassed * Conf.powerOfflineLossPerDay / (24 * 60 * 60 * 1000); + if (this.power - loss < Conf.powerOfflineLossLimit) { + loss = this.power; + } + this.alterPower(-loss); + } + } + + public void onDeath() { + this.updatePower(); + this.alterPower(-Conf.powerPerDeath); + if (hasFaction()) { + getFaction().setLastDeath(System.currentTimeMillis()); + } + } + + //----------------------------------------------// + // Territory + //----------------------------------------------// + public boolean isInOwnTerritory() { + return Board.getInstance().getFactionAt(new FLocation(this)) == this.getFaction(); + } + + public boolean isInOthersTerritory() { + Faction factionHere = Board.getInstance().getFactionAt(new FLocation(this)); + return factionHere != null && factionHere.isNormal() && factionHere != this.getFaction(); + } + + public boolean isInAllyTerritory() { + return Board.getInstance().getFactionAt(new FLocation(this)).getRelationTo(this).isAlly(); + } + + public boolean isInNeutralTerritory() { + return Board.getInstance().getFactionAt(new FLocation(this)).getRelationTo(this).isNeutral(); + } + + public boolean isInEnemyTerritory() { + return Board.getInstance().getFactionAt(new FLocation(this)).getRelationTo(this).isEnemy(); + } + + public void sendFactionHereMessage(Faction from) { + Faction toShow = Board.getInstance().getFactionAt(getLastStoodAt()); + boolean showChat = true; + if (showInfoBoard(toShow)) { + FScoreboard.get(this).setTemporarySidebar(new FInfoSidebar(toShow)); + showChat = P.p.getConfig().getBoolean("scoreboard.also-send-chat", true); + } + if (showChat) { + this.sendMessage(P.p.txt.parse(TL.FACTION_LEAVE.format(from.getTag(this), toShow.getTag(this)))); + } + } + + /** + * Check if the scoreboard should be shown. Simple method to be used by above method. + * + * @param toShow Faction to be shown. + * + * @return true if should show, otherwise false. + */ + public boolean showInfoBoard(Faction toShow) { + return showScoreboard && !toShow.isWarZone() && !toShow.isWilderness() && !toShow.isSafeZone() && P.p.getConfig().contains("scoreboard.finfo") && P.p.getConfig().getBoolean("scoreboard.finfo-enabled", false) && FScoreboard.get(this) != null; + } + + @Override + public boolean showScoreboard() { + return this.showScoreboard; + } + + @Override + public void setShowScoreboard(boolean show) { + this.showScoreboard = show; + } + + // ------------------------------- + // Actions + // ------------------------------- + + public void leave(boolean makePay) { + Faction myFaction = this.getFaction(); + makePay = makePay && Econ.shouldBeUsed() && !this.isAdminBypassing(); + + if (myFaction == null) { + resetFactionData(); + return; + } + + boolean perm = myFaction.isPermanent(); + + if (!perm && this.getRole() == Role.ADMIN && myFaction.getFPlayers().size() > 1) { + msg(TL.LEAVE_PASSADMIN); + return; + } + + if (!Conf.canLeaveWithNegativePower && this.getPower() < 0) { + msg(TL.LEAVE_NEGATIVEPOWER); + return; + } + + // if economy is enabled and they're not on the bypass list, make sure they can pay + if (makePay && !Econ.hasAtLeast(this, Conf.econCostLeave, TL.LEAVE_TOLEAVE.toString())) { + return; + } + + FPlayerLeaveEvent leaveEvent = new FPlayerLeaveEvent(this, myFaction, FPlayerLeaveEvent.PlayerLeaveReason.LEAVE); + Bukkit.getServer().getPluginManager().callEvent(leaveEvent); + if (leaveEvent.isCancelled()) { + return; + } + + // then make 'em pay (if applicable) + if (makePay && !Econ.modifyMoney(this, -Conf.econCostLeave, TL.LEAVE_TOLEAVE.toString(), TL.LEAVE_FORLEAVE.toString())) { + return; + } + + // Am I the last one in the faction? + if (myFaction.getFPlayers().size() == 1) { + // Transfer all money + if (Econ.shouldBeUsed()) { + Econ.transferMoney(this, myFaction, this, Econ.getBalance(myFaction.getAccountId())); + } + } + + if (myFaction.isNormal()) { + for (FPlayer fplayer : myFaction.getFPlayersWhereOnline(true)) { + fplayer.msg(TL.LEAVE_LEFT, this.describeTo(fplayer, true), myFaction.describeTo(fplayer)); + } + + if (Conf.logFactionLeave) { + P.p.log(TL.LEAVE_LEFT.format(this.getName(), myFaction.getTag())); + } + } + + myFaction.removeAnnouncements(this); + this.resetFactionData(); + + if (myFaction.isNormal() && !perm && myFaction.getFPlayers().isEmpty()) { + // Remove this faction + for (FPlayer fplayer : FPlayers.getInstance().getOnlinePlayers()) { + fplayer.msg(TL.LEAVE_DISBANDED, myFaction.describeTo(fplayer, true)); + } + + Factions.getInstance().removeFaction(myFaction.getId()); + if (Conf.logFactionDisband) { + P.p.log(TL.LEAVE_DISBANDEDLOG.format(myFaction.getTag(), myFaction.getId(), this.getName())); + } + } + } + + public boolean canClaimForFaction(Faction forFaction) { + return !forFaction.isWilderness() && (this.isAdminBypassing() || (forFaction == this.getFaction() && this.getRole().isAtLeast(Role.MODERATOR)) || (forFaction.isSafeZone() && Permission.MANAGE_SAFE_ZONE.has(getPlayer())) || (forFaction.isWarZone() && Permission.MANAGE_WAR_ZONE.has(getPlayer()))); + } + + public boolean canClaimForFactionAtLocation(Faction forFaction, Location location, boolean notifyFailure) { + String error = null; + FLocation flocation = new FLocation(location); + Faction myFaction = getFaction(); + Faction currentFaction = Board.getInstance().getFactionAt(flocation); + int ownedLand = forFaction.getLandRounded(); + int factionBuffer = P.p.getConfig().getInt("hcf.buffer-zone", 0); + int worldBuffer = P.p.getConfig().getInt("world-border.buffer", 0); + + if (Conf.worldGuardChecking && Worldguard.checkForRegionsInChunk(location)) { + // Checks for WorldGuard regions in the chunk attempting to be claimed + error = P.p.txt.parse(TL.CLAIM_PROTECTED.toString()); + } else if (Conf.worldsNoClaiming.contains(flocation.getWorldName())) { + error = P.p.txt.parse(TL.CLAIM_DISABLED.toString()); + } else if (this.isAdminBypassing()) { + return true; + } else if (forFaction.isSafeZone() && Permission.MANAGE_SAFE_ZONE.has(getPlayer())) { + return true; + } else if (forFaction.isWarZone() && Permission.MANAGE_WAR_ZONE.has(getPlayer())) { + return true; + } else if (myFaction != forFaction) { + error = P.p.txt.parse(TL.CLAIM_CANTCLAIM.toString(), forFaction.describeTo(this)); + } else if (forFaction == currentFaction) { + error = P.p.txt.parse(TL.CLAIM_ALREADYOWN.toString(), forFaction.describeTo(this, true)); + } else if (this.getRole().value < Role.MODERATOR.value) { + error = P.p.txt.parse(TL.CLAIM_MUSTBE.toString(), Role.MODERATOR.getTranslation()); + } else if (forFaction.getFPlayers().size() < Conf.claimsRequireMinFactionMembers) { + error = P.p.txt.parse(TL.CLAIM_MEMBERS.toString(), Conf.claimsRequireMinFactionMembers); + } else if (currentFaction.isSafeZone()) { + error = P.p.txt.parse(TL.CLAIM_SAFEZONE.toString()); + } else if (currentFaction.isWarZone()) { + error = P.p.txt.parse(TL.CLAIM_WARZONE.toString()); + } else if (P.p.getConfig().getBoolean("hcf.allow-overclaim", true) && ownedLand >= forFaction.getPowerRounded()) { + error = P.p.txt.parse(TL.CLAIM_POWER.toString()); + } else if (Conf.claimedLandsMax != 0 && ownedLand >= Conf.claimedLandsMax && forFaction.isNormal()) { + error = P.p.txt.parse(TL.CLAIM_LIMIT.toString()); + } else if (currentFaction.getRelationTo(forFaction) == Relation.ALLY) { + error = P.p.txt.parse(TL.CLAIM_ALLY.toString()); + } else if (Conf.claimsMustBeConnected && !this.isAdminBypassing() && myFaction.getLandRoundedInWorld(flocation.getWorldName()) > 0 && !Board.getInstance().isConnectedLocation(flocation, myFaction) && (!Conf.claimsCanBeUnconnectedIfOwnedByOtherFaction || !currentFaction.isNormal())) { + if (Conf.claimsCanBeUnconnectedIfOwnedByOtherFaction) { + error = P.p.txt.parse(TL.CLAIM_CONTIGIOUS.toString()); + } else { + error = P.p.txt.parse(TL.CLAIM_FACTIONCONTIGUOUS.toString()); + } + } else if (factionBuffer > 0 && Board.getInstance().hasFactionWithin(flocation, myFaction, factionBuffer)) { + error = P.p.txt.parse(TL.CLAIM_TOOCLOSETOOTHERFACTION.format(factionBuffer)); + } else if (flocation.isOutsideWorldBorder(worldBuffer)) { + if (worldBuffer > 0) { + error = P.p.txt.parse(TL.CLAIM_OUTSIDEBORDERBUFFER.format(worldBuffer)); + } else { + error = P.p.txt.parse(TL.CLAIM_OUTSIDEWORLDBORDER.toString()); + } + } else if (currentFaction.isNormal()) { + if (myFaction.isPeaceful()) { + error = P.p.txt.parse(TL.CLAIM_PEACEFUL.toString(), currentFaction.getTag(this)); + } else if (currentFaction.isPeaceful()) { + error = P.p.txt.parse(TL.CLAIM_PEACEFULTARGET.toString(), currentFaction.getTag(this)); + } else if (!currentFaction.hasLandInflation()) { + // TODO more messages WARN current faction most importantly + error = P.p.txt.parse(TL.CLAIM_THISISSPARTA.toString(), currentFaction.getTag(this)); + } else if (currentFaction.hasLandInflation() && !P.p.getConfig().getBoolean("hcf.allow-overclaim", true)) { + // deny over claim when it normally would be allowed. + error = P.p.txt.parse(TL.CLAIM_OVERCLAIM_DISABLED.toString()); + } else if (!Board.getInstance().isBorderLocation(flocation)) { + error = P.p.txt.parse(TL.CLAIM_BORDER.toString()); + } + } + // TODO: Add more else if statements. + + if (notifyFailure && error != null) { + msg(error); + } + return error == null; + } + + public boolean attemptClaim(Faction forFaction, Location location, boolean notifyFailure) { + // notifyFailure is false if called by auto-claim; no need to notify on every failure for it + // return value is false on failure, true on success + + FLocation flocation = new FLocation(location); + Faction currentFaction = Board.getInstance().getFactionAt(flocation); + + int ownedLand = forFaction.getLandRounded(); + + if (!this.canClaimForFactionAtLocation(forFaction, location, notifyFailure)) { + return false; + } + + // if economy is enabled and they're not on the bypass list, make sure they can pay + boolean mustPay = /*Econ.shouldBeUsed() &&*/Conf.econCostClaimWilderness > 0 && !this.isAdminBypassing() && !forFaction.isSafeZone() && !forFaction.isWarZone(); + double cost = 0.0; + EconomyParticipator payee = null; + if (mustPay) { + cost = Econ.calculateClaimCost(ownedLand, currentFaction.isNormal()); + + if (Conf.econClaimUnconnectedFee != 0.0 && forFaction.getLandRoundedInWorld(flocation.getWorldName()) > 0 && !Board.getInstance().isConnectedLocation(flocation, forFaction)) { + cost += Conf.econClaimUnconnectedFee; + } + +// if (Conf.bankEnabled && Conf.bankFactionPaysLandCosts && this.hasFaction()) { +// payee = this.getFaction(); +// } else { +// payee = this; +// } + +// if (!Econ.hasAtLeast(payee, cost, TL.CLAIM_TOCLAIM.toString())) { +// return false; +// } + + EcoResult result = getFaction().takeFromStash(cost); + if(result == EcoResult.LOW_FUNDS) { + msg("%s can't afford %s %s.", getFaction().describeTo(getFaction(), true), NumeralUtil.toCurrency(cost, Locale.US), TL.CLAIM_TOCLAIM.toString()); + return false; + } + + if(result != EcoResult.SUCCESS) return false; + } + + LandClaimEvent claimEvent = new LandClaimEvent(flocation, forFaction, this); + Bukkit.getServer().getPluginManager().callEvent(claimEvent); + if (claimEvent.isCancelled()) { + return false; + } + +// // then make 'em pay (if applicable) +// if (mustPay && !Econ.modifyMoney(payee, -cost, TL.CLAIM_TOCLAIM.toString(), TL.CLAIM_FORCLAIM.toString())) { +// return false; +// } +// +// // Was an over claim +// if (currentFaction.isNormal() && currentFaction.hasLandInflation()) { +// // Give them money for over claiming. +// Econ.modifyMoney(payee, Conf.econOverclaimRewardMultiplier, TL.CLAIM_TOOVERCLAIM.toString(), TL.CLAIM_FOROVERCLAIM.toString()); +// } + + // announce success + Set informTheseFPlayers = new HashSet(); + informTheseFPlayers.add(this); + informTheseFPlayers.addAll(forFaction.getFPlayersWhereOnline(true)); + for (FPlayer fp : informTheseFPlayers) { + fp.msg(TL.CLAIM_CLAIMED, this.describeTo(fp, true), forFaction.describeTo(fp), currentFaction.describeTo(fp)); + } + + Board.getInstance().setFactionAt(forFaction, flocation); + + if (Conf.logLandClaims) { + P.p.log(TL.CLAIM_CLAIMEDLOG.toString(), this.getName(), flocation.getCoordString(), forFaction.getTag()); + } + + return true; + } + + public boolean shouldBeSaved() { + if (!this.hasFaction() && (this.getPowerRounded() == this.getPowerMaxRounded() || this.getPowerRounded() == (int) Math.round(Conf.powerPlayerStarting))) { + return false; + } + return true; + } + + public void msg(String str, Object... args) { + this.sendMessage(P.p.txt.parse(str, args)); + } + + public void msg(TL translation, Object... args) { + this.msg(translation.toString(), args); + } + + public Player getPlayer() { + return Bukkit.getPlayer(UUID.fromString(this.getId())); + } + + public boolean isOnline() { + return this.getPlayer() != null; + } + + // make sure target player should be able to detect that this player is online + public boolean isOnlineAndVisibleTo(Player player) { + Player target = this.getPlayer(); + return target != null && player.canSee(target); + } + + public boolean isOffline() { + return !isOnline(); + } + + // -------------------------------------------- // + // Message Sending Helpers + // -------------------------------------------- // + + public void sendMessage(String msg) { + if (msg.contains("{null}")) { + return; // user wants this message to not send + } + if (msg.contains("/n/")) { + for (String s : msg.split("/n/")) { + sendMessage(s); + } + return; + } + Player player = this.getPlayer(); + if (player == null) { + return; + } + player.sendMessage(msg); + } + + public void sendMessage(List msgs) { + for (String msg : msgs) { + this.sendMessage(msg); + } + } + + public String getNameAndTitle(FPlayer fplayer) { + return this.getColorTo(fplayer) + this.getNameAndTitle(); + } + + @Override + public String getChatTag(FPlayer fplayer) { + return this.hasFaction() ? this.getRelationTo(fplayer).getColor() + getChatTag() : ""; + } + + @Override + public String getId() { + return id; + } + + public abstract void remove(); + + @Override + public void setId(String id) { + this.id = id; + } + + @Override + public void clearWarmup() { + if (warmup != null) { + Bukkit.getScheduler().cancelTask(warmupTask); + this.stopWarmup(); + } + } + + @Override + public void stopWarmup() { + warmup = null; + } + + @Override + public boolean isWarmingUp() { + return warmup != null; + } + + @Override + public WarmUpUtil.Warmup getWarmupType() { + return warmup; + } + + @Override + public void addWarmup(WarmUpUtil.Warmup warmup, int taskId) { + if (this.warmup != null) { + this.clearWarmup(); + } + this.warmup = warmup; + this.warmupTask = taskId; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFPlayers.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFPlayers.java new file mode 100644 index 0000000..196c473 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFPlayers.java @@ -0,0 +1,66 @@ +package com.massivecraft.factions.zcore.persist; + +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.FPlayers; +import com.massivecraft.factions.Factions; +import com.massivecraft.factions.P; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; + +import java.util.*; +import java.util.concurrent.ConcurrentSkipListMap; + +public abstract class MemoryFPlayers extends FPlayers { + public Map fPlayers = new ConcurrentSkipListMap(String.CASE_INSENSITIVE_ORDER); + + public void clean() { + for (FPlayer fplayer : this.fPlayers.values()) { + if (!Factions.getInstance().isValidFactionId(fplayer.getFactionId())) { + P.p.log("Reset faction data (invalid faction:" + fplayer.getFactionId() + ") for player " + fplayer.getName()); + fplayer.resetFactionData(false); + } + } + } + + public Collection getOnlinePlayers() { + Set entities = new HashSet(); + for (Player player : Bukkit.getServer().getOnlinePlayers()) { + entities.add(this.getByPlayer(player)); + } + return entities; + } + + @Override + public FPlayer getByPlayer(Player player) { + return getById(player.getUniqueId().toString()); + } + + @Override + public List getAllFPlayers() { + return new ArrayList(fPlayers.values()); + } + + @Override + public abstract void forceSave(); + + public abstract void load(); + + @Override + public FPlayer getByOfflinePlayer(OfflinePlayer player) { + return getById(player.getUniqueId().toString()); + } + + @Override + public FPlayer getById(String id) { + FPlayer player = fPlayers.get(id); + if (player == null) { + player = generateFPlayer(id); + } + return player; + } + + public abstract FPlayer generateFPlayer(String id); + + public abstract void convertFrom(MemoryFPlayers old); +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFaction.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFaction.java new file mode 100644 index 0000000..02d8c54 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFaction.java @@ -0,0 +1,893 @@ +package com.massivecraft.factions.zcore.persist; + +import com.massivecraft.factions.*; +import com.massivecraft.factions.eco.EcoResult; +import com.massivecraft.factions.iface.EconomyParticipator; +import com.massivecraft.factions.iface.RelationParticipator; +import com.massivecraft.factions.integration.Econ; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.struct.Relation; +import com.massivecraft.factions.struct.Role; +import com.massivecraft.factions.util.LazyLocation; +import com.massivecraft.factions.util.MiscUtil; +import com.massivecraft.factions.util.RelationUtil; +import com.massivecraft.factions.zcore.util.TL; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; + +import java.util.*; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; + +public abstract class MemoryFaction implements Faction, EconomyParticipator { + protected String id = null; + protected boolean peacefulExplosionsEnabled; + protected boolean permanent; + protected String tag; + protected String description; + protected boolean open; + protected boolean peaceful; + protected Integer permanentPower; + protected LazyLocation home; + protected long foundedDate; + protected transient long lastPlayerLoggedOffTime; + protected double money = 0; + protected double powerBoost; + protected Map relationWish = new HashMap(); + protected Map> claimOwnership = new ConcurrentHashMap>(); + protected transient Set fplayers = new HashSet(); + protected Set invites = new HashSet(); + protected HashMap> announcements = new HashMap>(); + protected ConcurrentHashMap warps = new ConcurrentHashMap(); + private long lastDeath; + protected int maxVaults; + + public HashMap> getAnnouncements() { + return this.announcements; + } + + public void addAnnouncement(FPlayer fPlayer, String msg) { + List list = announcements.containsKey(fPlayer.getId()) ? announcements.get(fPlayer.getId()) : new ArrayList(); + list.add(msg); + announcements.put(fPlayer.getId(), list); + } + + public void sendUnreadAnnouncements(FPlayer fPlayer) { + if (!announcements.containsKey(fPlayer.getId())) { + return; + } + fPlayer.sendMessage(ChatColor.LIGHT_PURPLE + "--Unread Cartel Announcements--"); + for (String s : announcements.get(fPlayer.getPlayer().getUniqueId().toString())) { + fPlayer.sendMessage(s); + } + fPlayer.sendMessage(ChatColor.LIGHT_PURPLE + "--Unread Cartel Announcements--"); + announcements.remove(fPlayer.getId()); + } + + public void removeAnnouncements(FPlayer fPlayer) { + if (announcements.containsKey(fPlayer.getId())) { + announcements.remove(fPlayer.getId()); + } + } + + public ConcurrentHashMap getWarps() { + return this.warps; + } + + public LazyLocation getWarp(String name) { + return this.warps.get(name); + } + + public void setWarp(String name, LazyLocation loc) { + this.warps.put(name, loc); + } + + public boolean isWarp(String name) { + return this.warps.containsKey(name); + } + + public boolean removeWarp(String name) { + return warps.remove(name) != null; + } + + public void clearWarps() { + warps.clear(); + } + + public int getMaxVaults() { + return this.maxVaults; + } + + public void setMaxVaults(int value) { + this.maxVaults = value; + } + + public Set getInvites() { + return invites; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public void invite(FPlayer fplayer) { + this.invites.add(fplayer.getId()); + } + + public void deinvite(FPlayer fplayer) { + this.invites.remove(fplayer.getId()); + } + + public boolean isInvited(FPlayer fplayer) { + return this.invites.contains(fplayer.getId()); + } + + public boolean getOpen() { + return open; + } + + public void setOpen(boolean isOpen) { + open = isOpen; + } + + public boolean isPeaceful() { + return this.peaceful; + } + + public void setPeaceful(boolean isPeaceful) { + this.peaceful = isPeaceful; + } + + public void setPeacefulExplosionsEnabled(boolean val) { + peacefulExplosionsEnabled = val; + } + + public boolean getPeacefulExplosionsEnabled() { + return this.peacefulExplosionsEnabled; + } + + public boolean noExplosionsInTerritory() { + return this.peaceful && !peacefulExplosionsEnabled; + } + + public boolean isPermanent() { + return permanent || !this.isNormal(); + } + + public void setPermanent(boolean isPermanent) { + permanent = isPermanent; + } + + public String getTag() { + return this.tag; + } + + public String getTag(String prefix) { + return prefix + this.tag; + } + + public String getTag(Faction otherFaction) { + if (otherFaction == null) { + return getTag(); + } + return this.getTag(this.getColorTo(otherFaction).toString()); + } + + public String getTag(FPlayer otherFplayer) { + if (otherFplayer == null) { + return getTag(); + } + return this.getTag(this.getColorTo(otherFplayer).toString()); + } + + public void setTag(String str) { + if (Conf.factionTagForceUpperCase) { + str = str.toUpperCase(); + } + this.tag = str; + } + + public String getComparisonTag() { + return MiscUtil.getComparisonString(this.tag); + } + + public String getDescription() { + return this.description; + } + + public void setDescription(String value) { + this.description = value; + } + + public void setHome(Location home) { + this.home = new LazyLocation(home); + } + + public boolean hasHome() { + return this.getHome() != null; + } + + public Location getHome() { + confirmValidHome(); + return (this.home != null) ? this.home.getLocation() : null; + } + + public long getFoundedDate() { + if (this.foundedDate == 0) { + setFoundedDate(System.currentTimeMillis()); + } + return this.foundedDate; + } + + public void setFoundedDate(long newDate) { + this.foundedDate = newDate; + } + + public void confirmValidHome() { + if (!Conf.homesMustBeInClaimedTerritory || this.home == null || (this.home.getLocation() != null && Board.getInstance().getFactionAt(new FLocation(this.home.getLocation())) == this)) { + return; + } + + msg("Your cartel home has been un-set since it is no longer in your territory."); + this.home = null; + } + + public String getAccountId() { + String aid = "faction-" + this.getId(); + + // We need to override the default money given to players. + if (!Econ.hasAccount(aid)) { + Econ.setBalance(aid, 0); + } + + return aid; + } + + public Integer getPermanentPower() { + return this.permanentPower; + } + + public void setPermanentPower(Integer permanentPower) { + this.permanentPower = permanentPower; + } + + public boolean hasPermanentPower() { + return this.permanentPower != null; + } + + public double getPowerBoost() { + return this.powerBoost; + } + + public void setPowerBoost(double powerBoost) { + this.powerBoost = powerBoost; + } + + public boolean isPowerFrozen() { + int freezeSeconds = P.p.getConfig().getInt("hcf.powerfreeze", 0); + if (freezeSeconds == 0) { + return false; + } + + return System.currentTimeMillis() - lastDeath < freezeSeconds * 1000; + } + + public void setLastDeath(long time) { + this.lastDeath = time; + } + + public long getLastDeath() { + return this.lastDeath; + } + + public int getKills() { + int kills = 0; + for (FPlayer fp : getFPlayers()) { + kills += fp.getKills(); + } + + return kills; + } + + public int getDeaths() { + int deaths = 0; + for (FPlayer fp : getFPlayers()) { + deaths += fp.getDeaths(); + } + + return deaths; + } + + // -------------------------------------------- // + // Construct + // -------------------------------------------- // + public MemoryFaction() { + } + + public MemoryFaction(String id) { + this.id = id; + this.open = Conf.newFactionsDefaultOpen; + this.tag = "???"; + this.description = TL.GENERIC_DEFAULTDESCRIPTION.toString(); + this.lastPlayerLoggedOffTime = 0; + this.peaceful = false; + this.peacefulExplosionsEnabled = false; + this.permanent = false; + this.money = 0.0; + this.powerBoost = 0.0; + this.foundedDate = System.currentTimeMillis(); + this.maxVaults = Conf.defaultMaxVaults; + } + + public MemoryFaction(MemoryFaction old) { + id = old.id; + peacefulExplosionsEnabled = old.peacefulExplosionsEnabled; + permanent = old.permanent; + tag = old.tag; + description = old.description; + open = old.open; + foundedDate = old.foundedDate; + peaceful = old.peaceful; + permanentPower = old.permanentPower; + home = old.home; + lastPlayerLoggedOffTime = old.lastPlayerLoggedOffTime; + money = old.money; + powerBoost = old.powerBoost; + relationWish = old.relationWish; + claimOwnership = old.claimOwnership; + fplayers = new HashSet(); + invites = old.invites; + announcements = old.announcements; + } + + // -------------------------------------------- // + // Extra Getters And Setters + // -------------------------------------------- // + public boolean noPvPInTerritory() { + return isSafeZone() || (peaceful && Conf.peacefulTerritoryDisablePVP); + } + + public boolean noMonstersInTerritory() { + return isSafeZone() || (peaceful && Conf.peacefulTerritoryDisableMonsters); + } + + // ------------------------------- + // Understand the types + // ------------------------------- + + public boolean isNormal() { + return !(this.isWilderness() || this.isSafeZone() || this.isWarZone()); + } + + public boolean isNone() { + return this.getId().equals("0"); + } + + public boolean isWilderness() { + return this.getId().equals("0"); + } + + public boolean isSafeZone() { + return this.getId().equals("-1"); + } + + public boolean isWarZone() { + return this.getId().equals("-2"); + } + + public boolean isPlayerFreeType() { + return this.isSafeZone() || this.isWarZone(); + } + + // ------------------------------- + // Relation and relation colors + // ------------------------------- + + @Override + public String describeTo(RelationParticipator that, boolean ucfirst) { + return RelationUtil.describeThatToMe(this, that, ucfirst); + } + + @Override + public String describeTo(RelationParticipator that) { + return RelationUtil.describeThatToMe(this, that); + } + + @Override + public Relation getRelationTo(RelationParticipator rp) { + return RelationUtil.getRelationTo(this, rp); + } + + @Override + public Relation getRelationTo(RelationParticipator rp, boolean ignorePeaceful) { + return RelationUtil.getRelationTo(this, rp, ignorePeaceful); + } + + @Override + public ChatColor getColorTo(RelationParticipator rp) { + return RelationUtil.getColorOfThatToMe(this, rp); + } + + public Relation getRelationWish(Faction otherFaction) { + if (this.relationWish.containsKey(otherFaction.getId())) { + return this.relationWish.get(otherFaction.getId()); + } + return Relation.fromString(P.p.getConfig().getString("default-relation", "neutral")); // Always default to old behavior. + } + + public void setRelationWish(Faction otherFaction, Relation relation) { + if (this.relationWish.containsKey(otherFaction.getId()) && relation.equals(Relation.NEUTRAL)) { + this.relationWish.remove(otherFaction.getId()); + } else { + this.relationWish.put(otherFaction.getId(), relation); + } + } + + public int getRelationCount(Relation relation) { + int count = 0; + for (Faction faction : Factions.getInstance().getAllFactions()) { + if (faction.getRelationTo(this) == relation) { + count++; + } + } + return count; + } + + // ----------------------------------------------// + // Power + // ----------------------------------------------// + public double getPower() { + if (this.hasPermanentPower()) { + return this.getPermanentPower(); + } + + double ret = 0; + for (FPlayer fplayer : fplayers) { + ret += fplayer.getPower(); + } + if (Conf.powerFactionMax > 0 && ret > Conf.powerFactionMax) { + ret = Conf.powerFactionMax; + } + return ret + this.powerBoost; + } + + public double getPowerMax() { + if (this.hasPermanentPower()) { + return this.getPermanentPower(); + } + + double ret = 0; + for (FPlayer fplayer : fplayers) { + ret += fplayer.getPowerMax(); + } + if (Conf.powerFactionMax > 0 && ret > Conf.powerFactionMax) { + ret = Conf.powerFactionMax; + } + return ret + this.powerBoost; + } + + public int getPowerRounded() { + return (int) Math.round(this.getPower()); + } + + public int getPowerMaxRounded() { + return (int) Math.round(this.getPowerMax()); + } + + public int getLandRounded() { + return Board.getInstance().getFactionCoordCount(this); + } + + public int getLandRoundedInWorld(String worldName) { + return Board.getInstance().getFactionCoordCountInWorld(this, worldName); + } + + public boolean hasLandInflation() { + return this.getLandRounded() > this.getPowerRounded(); + } + + // ------------------------------- + // FPlayers + // ------------------------------- + + // maintain the reference list of FPlayers in this faction + public void refreshFPlayers() { + fplayers.clear(); + if (this.isPlayerFreeType()) { + return; + } + + for (FPlayer fplayer : FPlayers.getInstance().getAllFPlayers()) { + if (fplayer.getFactionId().equalsIgnoreCase(id)) { + fplayers.add(fplayer); + } + } + } + + public boolean addFPlayer(FPlayer fplayer) { + return !this.isPlayerFreeType() && fplayers.add(fplayer); + + } + + public boolean removeFPlayer(FPlayer fplayer) { + return !this.isPlayerFreeType() && fplayers.remove(fplayer); + + } + + public int getSize() { + return fplayers.size(); + } + + public Set getFPlayers() { + // return a shallow copy of the FPlayer list, to prevent tampering and + // concurrency issues + return new HashSet(fplayers); + } + + public Set getFPlayersWhereOnline(boolean online) { + Set ret = new HashSet(); + if (!this.isNormal()) { + return ret; + } + + for (FPlayer fplayer : fplayers) { + if (fplayer.isOnline() == online) { + ret.add(fplayer); + } + } + + return ret; + } + + public FPlayer getFPlayerAdmin() { + if (!this.isNormal()) { + return null; + } + + for (FPlayer fplayer : fplayers) { + if (fplayer.getRole() == Role.ADMIN) { + return fplayer; + } + } + return null; + } + + public ArrayList getFPlayersWhereRole(Role role) { + ArrayList ret = new ArrayList(); + if (!this.isNormal()) { + return ret; + } + + for (FPlayer fplayer : fplayers) { + if (fplayer.getRole() == role) { + ret.add(fplayer); + } + } + + return ret; + } + + public ArrayList getOnlinePlayers() { + ArrayList ret = new ArrayList(); + if (this.isPlayerFreeType()) { + return ret; + } + + for (Player player : P.p.getServer().getOnlinePlayers()) { + FPlayer fplayer = FPlayers.getInstance().getByPlayer(player); + if (fplayer.getFaction() == this) { + ret.add(player); + } + } + + return ret; + } + + // slightly faster check than getOnlinePlayers() if you just want to see if + // there are any players online + public boolean hasPlayersOnline() { + // only real factions can have players online, not safe zone / war zone + if (this.isPlayerFreeType()) { + return false; + } + + for (Player player : P.p.getServer().getOnlinePlayers()) { + FPlayer fplayer = FPlayers.getInstance().getByPlayer(player); + if (fplayer != null && fplayer.getFaction() == this) { + return true; + } + } + + // even if all players are technically logged off, maybe someone was on + // recently enough to not consider them officially offline yet + return Conf.considerFactionsReallyOfflineAfterXMinutes > 0 && System.currentTimeMillis() < lastPlayerLoggedOffTime + (Conf.considerFactionsReallyOfflineAfterXMinutes * 60000); + } + + public void memberLoggedOff() { + if (this.isNormal()) { + lastPlayerLoggedOffTime = System.currentTimeMillis(); + } + } + + // used when current leader is about to be removed from the faction; + // promotes new leader, or disbands faction if no other members left + public void promoteNewLeader() { + if (!this.isNormal()) { + return; + } + if (this.isPermanent() && Conf.permanentFactionsDisableLeaderPromotion) { + return; + } + + FPlayer oldLeader = this.getFPlayerAdmin(); + + // get list of moderators, or list of normal members if there are no moderators + ArrayList replacements = this.getFPlayersWhereRole(Role.MODERATOR); + if (replacements == null || replacements.isEmpty()) { + replacements = this.getFPlayersWhereRole(Role.NORMAL); + } + + if (replacements == null || replacements.isEmpty()) { // faction admin is the only member; one-man faction + if (this.isPermanent()) { + if (oldLeader != null) { + oldLeader.setRole(Role.NORMAL); + } + return; + } + + // no members left and faction isn't permanent, so disband it + if (Conf.logFactionDisband) { + P.p.log("The cartel " + this.getTag() + " (" + this.getId() + ") has been disbanded since it has no members left."); + } + + for (FPlayer fplayer : FPlayers.getInstance().getOnlinePlayers()) { + fplayer.msg("The cartel %s was disbanded.", this.getTag(fplayer)); + } + + Factions.getInstance().removeFaction(getId()); + } else { // promote new faction admin + if (oldLeader != null) { + oldLeader.setRole(Role.NORMAL); + } + replacements.get(0).setRole(Role.ADMIN); + //TODO:TL + this.msg("Cartel boss %s has been removed. %s has been promoted as the new cartel boss.", oldLeader == null ? "" : oldLeader.getName(), replacements.get(0).getName()); + P.p.log("Cartel " + this.getTag() + " (" + this.getId() + ") boss was removed. Replacement boss: " + replacements.get(0).getName()); + } + } + + // ----------------------------------------------// + // Messages + // ----------------------------------------------// + public void msg(String message, Object... args) { + message = P.p.txt.parse(message, args); + + for (FPlayer fplayer : this.getFPlayersWhereOnline(true)) { + fplayer.sendMessage(message); + } + } + + public void msg(TL translation, Object... args) { + msg(translation.toString(), args); + } + + public void sendMessage(String message) { + for (FPlayer fplayer : this.getFPlayersWhereOnline(true)) { + fplayer.sendMessage(message); + } + } + + public void sendMessage(List messages) { + for (FPlayer fplayer : this.getFPlayersWhereOnline(true)) { + fplayer.sendMessage(messages); + } + } + + // ----------------------------------------------// + // Ownership of specific claims + // ----------------------------------------------// + + public Map> getClaimOwnership() { + return claimOwnership; + } + + public void clearAllClaimOwnership() { + claimOwnership.clear(); + } + + public void clearClaimOwnership(FLocation loc) { + claimOwnership.remove(loc); + } + + public void clearClaimOwnership(FPlayer player) { + if (id == null || id.isEmpty()) { + return; + } + + Set ownerData; + + for (Entry> entry : claimOwnership.entrySet()) { + ownerData = entry.getValue(); + + if (ownerData == null) { + continue; + } + + Iterator iter = ownerData.iterator(); + while (iter.hasNext()) { + if (iter.next().equals(player.getId())) { + iter.remove(); + } + } + + if (ownerData.isEmpty()) { + claimOwnership.remove(entry.getKey()); + } + } + } + + public int getCountOfClaimsWithOwners() { + return claimOwnership.isEmpty() ? 0 : claimOwnership.size(); + } + + public boolean doesLocationHaveOwnersSet(FLocation loc) { + if (claimOwnership.isEmpty() || !claimOwnership.containsKey(loc)) { + return false; + } + + Set ownerData = claimOwnership.get(loc); + return ownerData != null && !ownerData.isEmpty(); + } + + public boolean isPlayerInOwnerList(FPlayer player, FLocation loc) { + if (claimOwnership.isEmpty()) { + return false; + } + Set ownerData = claimOwnership.get(loc); + if (ownerData == null) { + return false; + } + return ownerData.contains(player.getId()); + } + + public void setPlayerAsOwner(FPlayer player, FLocation loc) { + Set ownerData = claimOwnership.get(loc); + if (ownerData == null) { + ownerData = new HashSet(); + } + ownerData.add(player.getId()); + claimOwnership.put(loc, ownerData); + } + + public void removePlayerAsOwner(FPlayer player, FLocation loc) { + Set ownerData = claimOwnership.get(loc); + if (ownerData == null) { + return; + } + ownerData.remove(player.getId()); + claimOwnership.put(loc, ownerData); + } + + public Set getOwnerList(FLocation loc) { + return claimOwnership.get(loc); + } + + public String getOwnerListString(FLocation loc) { + Set ownerData = claimOwnership.get(loc); + if (ownerData == null || ownerData.isEmpty()) { + return ""; + } + + String ownerList = ""; + + Iterator iter = ownerData.iterator(); + while (iter.hasNext()) { + if (!ownerList.isEmpty()) { + ownerList += ", "; + } + OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(UUID.fromString(iter.next())); + //TODO:TL + ownerList += offlinePlayer != null ? offlinePlayer.getName() : "null player"; + } + return ownerList; + } + + public boolean playerHasOwnershipRights(FPlayer fplayer, FLocation loc) { + // in own faction, with sufficient role or permission to bypass + // ownership? + if (fplayer.getFaction() == this && (fplayer.getRole().isAtLeast(Conf.ownedAreaModeratorsBypass ? Role.MODERATOR : Role.ADMIN) || Permission.OWNERSHIP_BYPASS.has(fplayer.getPlayer()))) { + return true; + } + + // make sure claimOwnership is initialized + if (claimOwnership.isEmpty()) { + return true; + } + + // need to check the ownership list, then + Set ownerData = claimOwnership.get(loc); + + // if no owner list, owner list is empty, or player is in owner list, + // they're allowed + return ownerData == null || ownerData.isEmpty() || ownerData.contains(fplayer.getId()); + } + + // ----------------------------------------------// + // Persistance and entity management + // ----------------------------------------------// + public void remove() { + if (Econ.shouldBeUsed()) { + Econ.setBalance(getAccountId(), 0); + } + + // Clean the board + ((MemoryBoard) Board.getInstance()).clean(id); + + for (FPlayer fPlayer : fplayers) { + fPlayer.resetFactionData(false); + } + } + + public Set getAllClaims() { + return Board.getInstance().getAllClaims(this); + } + + @Override + public double getStash() { + return this.money; + } + + @Override + public EcoResult addToStash(double amount) { + if(this.money >= Double.MAX_VALUE || amount >= Double.MAX_VALUE) + return EcoResult.OVERWEIGHT; + + if((this.money + amount) > Double.MAX_VALUE) { + this.money = Double.MAX_VALUE; + return EcoResult.SUCCESS; + } + + if(amount <= 0) + return EcoResult.UNKNOWN; + + this.money += amount; + return EcoResult.SUCCESS; + } + + @Override + public EcoResult takeFromStash(double amount) { + if(this.money <= 0) + return EcoResult.LOW_FUNDS; + + if((this.money - amount) < 0) + return EcoResult.LOW_FUNDS; + + if(amount <= 0) + return EcoResult.UNKNOWN; + + this.money -= amount; + return EcoResult.SUCCESS; + } + + @Override + public void setStash(double amount) { + if(amount >= Double.MAX_VALUE) { + this.money = Double.MAX_VALUE - 1; + return; + } + + if(amount <= 0) { + this.money = 0; + return; + } + + this.money = amount; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFactions.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFactions.java new file mode 100644 index 0000000..8bb3f17 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFactions.java @@ -0,0 +1,176 @@ +package com.massivecraft.factions.zcore.persist; + +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.Factions; +import com.massivecraft.factions.util.MiscUtil; +import com.massivecraft.factions.zcore.util.TL; +import org.bukkit.ChatColor; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +public abstract class MemoryFactions extends Factions { + public Map factions = new ConcurrentHashMap(); + public int nextId = 1; + + public void load() { + // Make sure the default neutral faction exists + if (!factions.containsKey("0")) { + Faction faction = generateFactionObject("0"); + factions.put("0", faction); + faction.setTag(TL.WILDERNESS.toString()); + faction.setDescription(TL.WILDERNESS_DESCRIPTION.toString()); + } else { + Faction faction = factions.get("0"); + if (!faction.getTag().equalsIgnoreCase(TL.WILDERNESS.toString())) { + faction.setTag(TL.WILDERNESS.toString()); + } + if (!faction.getDescription().equalsIgnoreCase(TL.WILDERNESS_DESCRIPTION.toString())) { + faction.setDescription(TL.WILDERNESS_DESCRIPTION.toString()); + } + } + + // Make sure the safe zone faction exists + if (!factions.containsKey("-1")) { + Faction faction = generateFactionObject("-1"); + factions.put("-1", faction); + faction.setTag(TL.SAFEZONE.toString()); + faction.setDescription(TL.SAFEZONE_DESCRIPTION.toString()); + } else { + Faction faction = factions.get("-1"); + if (!faction.getTag().equalsIgnoreCase(TL.SAFEZONE.toString())) { + faction.setTag(TL.SAFEZONE.toString()); + } + if (!faction.getDescription().equalsIgnoreCase(TL.SAFEZONE_DESCRIPTION.toString())) { + faction.setDescription(TL.SAFEZONE_DESCRIPTION.toString()); + } + // if SafeZone has old pre-1.6.0 name, rename it to remove troublesome " " + if (faction.getTag().contains(" ")) { + faction.setTag(TL.SAFEZONE.toString()); + } + } + + // Make sure the war zone faction exists + if (!factions.containsKey("-2")) { + Faction faction = generateFactionObject("-2"); + factions.put("-2", faction); + faction.setTag(TL.WARZONE.toString()); + faction.setDescription(TL.WARZONE_DESCRIPTION.toString()); + } else { + Faction faction = factions.get("-2"); + if (!faction.getTag().equalsIgnoreCase(TL.WARZONE.toString())) { + faction.setTag(TL.WARZONE.toString()); + } + if (!faction.getDescription().equalsIgnoreCase(TL.WARZONE_DESCRIPTION.toString())) { + faction.setDescription(TL.WARZONE_DESCRIPTION.toString()); + } + // if WarZone has old pre-1.6.0 name, rename it to remove troublesome " " + if (faction.getTag().contains(" ")) { + faction.setTag(TL.WARZONE.toString()); + } + } + } + + public Faction getFactionById(String id) { + return factions.get(id); + } + + public abstract Faction generateFactionObject(String string); + + public Faction getByTag(String str) { + String compStr = MiscUtil.getComparisonString(str); + for (Faction faction : factions.values()) { + if (faction.getComparisonTag().equals(compStr)) { + return faction; + } + } + return null; + } + + public Faction getBestTagMatch(String start) { + int best = 0; + start = start.toLowerCase(); + int minlength = start.length(); + Faction bestMatch = null; + for (Faction faction : factions.values()) { + String candidate = faction.getTag(); + candidate = ChatColor.stripColor(candidate); + if (candidate.length() < minlength) { + continue; + } + if (!candidate.toLowerCase().startsWith(start)) { + continue; + } + + // The closer to zero the better + int lendiff = candidate.length() - minlength; + if (lendiff == 0) { + return faction; + } + if (lendiff < best || best == 0) { + best = lendiff; + bestMatch = faction; + } + } + + return bestMatch; + } + + public boolean isTagTaken(String str) { + return this.getByTag(str) != null; + } + + public boolean isValidFactionId(String id) { + return factions.containsKey(id); + } + + public Faction createFaction() { + Faction faction = generateFactionObject(); + factions.put(faction.getId(), faction); + return faction; + } + + public Set getFactionTags() { + Set tags = new HashSet(); + for (Faction faction : factions.values()) { + tags.add(faction.getTag()); + } + return tags; + } + + public abstract Faction generateFactionObject(); + + public void removeFaction(String id) { + factions.remove(id).remove(); + } + + @Override + public ArrayList getAllFactions() { + return new ArrayList(factions.values()); + } + + @Override + public Faction getNone() { + return factions.get("0"); + } + + @Override + public Faction getWilderness() { + return factions.get("0"); + } + + @Override + public Faction getSafeZone() { + return factions.get("-1"); + } + + @Override + public Faction getWarZone() { + return factions.get("-2"); + } + + public abstract void convertFrom(MemoryFactions old); +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/SaveTask.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/SaveTask.java new file mode 100644 index 0000000..232c9d2 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/SaveTask.java @@ -0,0 +1,30 @@ +package com.massivecraft.factions.zcore.persist; + +import com.massivecraft.factions.Board; +import com.massivecraft.factions.FPlayers; +import com.massivecraft.factions.Factions; +import com.massivecraft.factions.zcore.MPlugin; + +public class SaveTask implements Runnable { + + private static boolean running = false; + + MPlugin p; + + public SaveTask(MPlugin p) { + this.p = p; + } + + public void run() { + if (!p.getAutoSave() || running) { + return; + } + running = true; + p.preAutoSave(); + Factions.getInstance().forceSave(false); + FPlayers.getInstance().forceSave(false); + Board.getInstance().forceSave(false); + p.postAutoSave(); + running = false; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/json/FactionsJSON.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/json/FactionsJSON.java new file mode 100644 index 0000000..2cc1c83 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/json/FactionsJSON.java @@ -0,0 +1,45 @@ +package com.massivecraft.factions.zcore.persist.json; + +import com.massivecraft.factions.*; +import com.massivecraft.factions.zcore.persist.MemoryBoard; +import com.massivecraft.factions.zcore.persist.MemoryFPlayers; +import com.massivecraft.factions.zcore.persist.MemoryFactions; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.logging.Logger; + +public class FactionsJSON { + + public static void convertTo() { + if (!(Factions.getInstance() instanceof MemoryFactions)) { + return; + } + if (!(FPlayers.getInstance() instanceof MemoryFPlayers)) { + return; + } + if (!(Board.getInstance() instanceof MemoryBoard)) { + return; + } + new BukkitRunnable() { + @Override + public void run() { + Logger logger = P.p.getLogger(); + logger.info("Beginning Board conversion to JSON"); + new JSONBoard().convertFrom((MemoryBoard) Board.getInstance()); + logger.info("Board Converted"); + logger.info("Beginning FPlayers conversion to JSON"); + new JSONFPlayers().convertFrom((MemoryFPlayers) FPlayers.getInstance()); + logger.info("FPlayers Converted"); + logger.info("Beginning Factions conversion to JSON"); + new JSONFactions().convertFrom((MemoryFactions) Factions.getInstance()); + logger.info("Factions Converted"); + logger.info("Refreshing object caches"); + for (FPlayer fPlayer : FPlayers.getInstance().getAllFPlayers()) { + Faction faction = Factions.getInstance().getFactionById(fPlayer.getFactionId()); + faction.addFPlayer(fPlayer); + } + logger.info("Conversion Complete"); + } + }.runTaskAsynchronously(P.p); + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/json/JSONBoard.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/json/JSONBoard.java new file mode 100644 index 0000000..d81afb4 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/json/JSONBoard.java @@ -0,0 +1,103 @@ +package com.massivecraft.factions.zcore.persist.json; + +import com.google.gson.reflect.TypeToken; +import com.massivecraft.factions.Board; +import com.massivecraft.factions.FLocation; +import com.massivecraft.factions.P; +import com.massivecraft.factions.zcore.persist.MemoryBoard; +import com.massivecraft.factions.zcore.util.DiscUtil; + +import java.io.File; +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; + + +public class JSONBoard extends MemoryBoard { + private static transient File file = new File(P.p.getDataFolder(), "board.json"); + + // -------------------------------------------- // + // Persistance + // -------------------------------------------- // + + public Map> dumpAsSaveFormat() { + Map> worldCoordIds = new HashMap>(); + + String worldName, coords; + String id; + + for (Entry entry : flocationIds.entrySet()) { + worldName = entry.getKey().getWorldName(); + coords = entry.getKey().getCoordString(); + id = entry.getValue(); + if (!worldCoordIds.containsKey(worldName)) { + worldCoordIds.put(worldName, new TreeMap()); + } + + worldCoordIds.get(worldName).put(coords, id); + } + + return worldCoordIds; + } + + public void loadFromSaveFormat(Map> worldCoordIds) { + flocationIds.clear(); + + String worldName; + String[] coords; + int x, z; + String factionId; + + for (Entry> entry : worldCoordIds.entrySet()) { + worldName = entry.getKey(); + for (Entry entry2 : entry.getValue().entrySet()) { + coords = entry2.getKey().trim().split("[,\\s]+"); + x = Integer.parseInt(coords[0]); + z = Integer.parseInt(coords[1]); + factionId = entry2.getValue(); + flocationIds.put(new FLocation(worldName, x, z), factionId); + } + } + } + + public void forceSave() { + forceSave(true); + } + + public void forceSave(boolean sync) { + DiscUtil.writeCatch(file, P.p.gson.toJson(dumpAsSaveFormat()), sync); + } + + public boolean load() { + P.p.log("Loading board from disk"); + + if (!file.exists()) { + P.p.log("No board to load from disk. Creating new file."); + forceSave(); + return true; + } + + try { + Type type = new TypeToken>>() { + }.getType(); + Map> worldCoordIds = P.p.gson.fromJson(DiscUtil.read(file), type); + loadFromSaveFormat(worldCoordIds); + P.p.log("Loaded " + flocationIds.size() + " board locations"); + } catch (Exception e) { + e.printStackTrace(); + P.p.log("Failed to load the board from disk."); + return false; + } + + return true; + } + + @Override + public void convertFrom(MemoryBoard old) { + this.flocationIds = old.flocationIds; + forceSave(); + Board.instance = this; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/json/JSONFPlayer.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/json/JSONFPlayer.java new file mode 100644 index 0000000..71d451d --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/json/JSONFPlayer.java @@ -0,0 +1,28 @@ +package com.massivecraft.factions.zcore.persist.json; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.FPlayers; +import com.massivecraft.factions.zcore.persist.MemoryFPlayer; + +public class JSONFPlayer extends MemoryFPlayer { + + public JSONFPlayer(MemoryFPlayer arg0) { + super(arg0); + } + + public JSONFPlayer(String id) { + super(id); + } + + @Override + public void remove() { + ((JSONFPlayers) FPlayers.getInstance()).fPlayers.remove(getId()); + } + + public boolean shouldBeSaved() { + if (!this.hasFaction() && (this.getPowerRounded() == this.getPowerMaxRounded() || this.getPowerRounded() == (int) Math.round(Conf.powerPlayerStarting))) { + return false; + } + return true; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/json/JSONFPlayers.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/json/JSONFPlayers.java new file mode 100644 index 0000000..c5a2ec6 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/json/JSONFPlayers.java @@ -0,0 +1,193 @@ +package com.massivecraft.factions.zcore.persist.json; + +import com.google.common.base.Function; +import com.google.common.collect.Maps; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.FPlayers; +import com.massivecraft.factions.P; +import com.massivecraft.factions.zcore.persist.MemoryFPlayer; +import com.massivecraft.factions.zcore.persist.MemoryFPlayers; +import com.massivecraft.factions.zcore.util.DiscUtil; +import com.massivecraft.factions.zcore.util.UUIDFetcher; +import org.apache.commons.lang.StringUtils; +import org.bukkit.Bukkit; + +import java.io.File; +import java.io.IOException; +import java.util.*; +import java.util.Map.Entry; +import java.util.logging.Level; + +public class JSONFPlayers extends MemoryFPlayers { + // Info on how to persist + private Gson gson; + + public Gson getGson() { + return gson; + } + + public void setGson(Gson gson) { + this.gson = gson; + } + + private File file; + + public JSONFPlayers() { + file = new File(P.p.getDataFolder(), "players.json"); + gson = P.p.gson; + } + + public void convertFrom(MemoryFPlayers old) { + this.fPlayers.putAll(Maps.transformValues(old.fPlayers, new Function() { + @Override + public JSONFPlayer apply(FPlayer arg0) { + return new JSONFPlayer((MemoryFPlayer) arg0); + } + })); + forceSave(); + FPlayers.instance = this; + } + + public void forceSave() { + forceSave(true); + } + + public void forceSave(boolean sync) { + final Map entitiesThatShouldBeSaved = new HashMap(); + for (FPlayer entity : this.fPlayers.values()) { + if (((MemoryFPlayer) entity).shouldBeSaved()) { + entitiesThatShouldBeSaved.put(entity.getId(), (JSONFPlayer) entity); + } + } + + saveCore(file, entitiesThatShouldBeSaved, sync); + } + + private boolean saveCore(File target, Map data, boolean sync) { + return DiscUtil.writeCatch(target, this.gson.toJson(data), sync); + } + + public void load() { + Map fplayers = this.loadCore(); + if (fplayers == null) { + return; + } + this.fPlayers.clear(); + this.fPlayers.putAll(fplayers); + P.p.log("Loaded " + fPlayers.size() + " players"); + } + + private Map loadCore() { + if (!this.file.exists()) { + return new HashMap(); + } + + String content = DiscUtil.readCatch(this.file); + if (content == null) { + return null; + } + + Map data = this.gson.fromJson(content, new TypeToken>() { + }.getType()); + Set list = new HashSet(); + Set invalidList = new HashSet(); + for (Entry entry : data.entrySet()) { + String key = entry.getKey(); + entry.getValue().setId(key); + if (doesKeyNeedMigration(key)) { + if (!isKeyInvalid(key)) { + list.add(key); + } else { + invalidList.add(key); + } + } + } + + if (list.size() > 0) { + // We've got some converting to do! + Bukkit.getLogger().log(Level.INFO, "Factions is now updating players.json"); + + // First we'll make a backup, because god forbid anybody heed a + // warning + File file = new File(this.file.getParentFile(), "players.json.old"); + try { + file.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + saveCore(file, (Map) data, true); + Bukkit.getLogger().log(Level.INFO, "Backed up your old data at " + file.getAbsolutePath()); + + // Start fetching those UUIDs + Bukkit.getLogger().log(Level.INFO, "Please wait while Factions converts " + list.size() + " old player names to UUID. This may take a while."); + UUIDFetcher fetcher = new UUIDFetcher(new ArrayList(list)); + try { + Map response = fetcher.call(); + for (String s : list) { + // Are we missing any responses? + if (!response.containsKey(s)) { + // They don't have a UUID so they should just be removed + invalidList.add(s); + } + } + for (String value : response.keySet()) { + // For all the valid responses, let's replace their old + // named entry with a UUID key + String id = response.get(value).toString(); + + JSONFPlayer player = data.get(value); + + if (player == null) { + // The player never existed here, and shouldn't persist + invalidList.add(value); + continue; + } + + player.setId(id); // Update the object so it knows + + data.remove(value); // Out with the old... + data.put(id, player); // And in with the new + } + } catch (Exception e) { + e.printStackTrace(); + } + if (invalidList.size() > 0) { + for (String name : invalidList) { + // Remove all the invalid names we collected + data.remove(name); + } + Bukkit.getLogger().log(Level.INFO, "While converting we found names that either don't have a UUID or aren't players and removed them from storage."); + Bukkit.getLogger().log(Level.INFO, "The following names were detected as being invalid: " + StringUtils.join(invalidList, ", ")); + } + saveCore(this.file, (Map) data, true); // Update the + // flatfile + Bukkit.getLogger().log(Level.INFO, "Done converting players.json to UUID."); + } + return (Map) data; + } + + private boolean doesKeyNeedMigration(String key) { + if (!key.matches("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}")) { + // Not a valid UUID.. + if (key.matches("[a-zA-Z0-9_]{2,16}")) { + // Valid playername, we'll mark this as one for conversion + // to UUID + return true; + } + } + return false; + } + + private boolean isKeyInvalid(String key) { + return !key.matches("[a-zA-Z0-9_]{2,16}"); + } + + @Override + public FPlayer generateFPlayer(String id) { + FPlayer player = new JSONFPlayer(id); + this.fPlayers.put(player.getId(), player); + return player; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/json/JSONFaction.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/json/JSONFaction.java new file mode 100644 index 0000000..af1b4e8 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/json/JSONFaction.java @@ -0,0 +1,17 @@ +package com.massivecraft.factions.zcore.persist.json; + +import com.massivecraft.factions.zcore.persist.MemoryFaction; + +public class JSONFaction extends MemoryFaction { + + public JSONFaction(MemoryFaction arg0) { + super(arg0); + } + + public JSONFaction() { + } + + public JSONFaction(String id) { + super(id); + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/json/JSONFactions.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/json/JSONFactions.java new file mode 100644 index 0000000..4183d58 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/json/JSONFactions.java @@ -0,0 +1,263 @@ +package com.massivecraft.factions.zcore.persist.json; + +import com.google.common.base.Function; +import com.google.common.collect.Maps; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.massivecraft.factions.FLocation; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.Factions; +import com.massivecraft.factions.P; +import com.massivecraft.factions.zcore.persist.MemoryFaction; +import com.massivecraft.factions.zcore.persist.MemoryFactions; +import com.massivecraft.factions.zcore.util.DiscUtil; +import com.massivecraft.factions.zcore.util.UUIDFetcher; +import org.bukkit.Bukkit; + +import java.io.File; +import java.io.IOException; +import java.util.*; +import java.util.Map.Entry; +import java.util.logging.Level; + +public class JSONFactions extends MemoryFactions { + // Info on how to persist + private Gson gson; + + public Gson getGson() { + return gson; + } + + public void setGson(Gson gson) { + this.gson = gson; + } + + private File file; + + public File getFile() { + return file; + } + + public void setFile(File file) { + this.file = file; + } + + // -------------------------------------------- // + // CONSTRUCTORS + // -------------------------------------------- // + + public JSONFactions() { + this.file = new File(P.p.getDataFolder(), "factions.json"); + this.gson = P.p.gson; + this.nextId = 1; + } + + public void forceSave() { + forceSave(true); + } + + public void forceSave(boolean sync) { + final Map entitiesThatShouldBeSaved = new HashMap(); + for (Faction entity : this.factions.values()) { + entitiesThatShouldBeSaved.put(entity.getId(), (JSONFaction) entity); + } + + saveCore(file, entitiesThatShouldBeSaved, sync); + } + + private boolean saveCore(File target, Map entities, boolean sync) { + return DiscUtil.writeCatch(target, this.gson.toJson(entities), sync); + } + + public void load() { + Map factions = this.loadCore(); + if (factions == null) { + return; + } + this.factions.putAll(factions); + + super.load(); + P.p.log("Loaded " + factions.size() + " Factions"); + } + + private Map loadCore() { + if (!this.file.exists()) { + return new HashMap(); + } + + String content = DiscUtil.readCatch(this.file); + if (content == null) { + return null; + } + + Map data = this.gson.fromJson(content, new TypeToken>() { + }.getType()); + + this.nextId = 1; + // Do we have any names that need updating in claims or invites? + + int needsUpdate = 0; + for (Entry entry : data.entrySet()) { + String id = entry.getKey(); + Faction f = entry.getValue(); + f.setId(id); + this.updateNextIdForId(id); + needsUpdate += whichKeysNeedMigration(f.getInvites()).size(); + for (Set keys : f.getClaimOwnership().values()) { + needsUpdate += whichKeysNeedMigration(keys).size(); + } + } + + if (needsUpdate > 0) { + // We've got some converting to do! + Bukkit.getLogger().log(Level.INFO, "Factions is now updating factions.json"); + + // First we'll make a backup, because god forbid anybody heed a + // warning + File file = new File(this.file.getParentFile(), "factions.json.old"); + try { + file.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + saveCore(file, (Map) data, true); + Bukkit.getLogger().log(Level.INFO, "Backed up your old data at " + file.getAbsolutePath()); + + Bukkit.getLogger().log(Level.INFO, "Please wait while Factions converts " + needsUpdate + " old player names to UUID. This may take a while."); + + // Update claim ownership + + for (String string : data.keySet()) { + Faction f = data.get(string); + Map> claims = f.getClaimOwnership(); + for (FLocation key : claims.keySet()) { + Set set = claims.get(key); + + Set list = whichKeysNeedMigration(set); + + if (list.size() > 0) { + UUIDFetcher fetcher = new UUIDFetcher(new ArrayList(list)); + try { + Map response = fetcher.call(); + for (String value : response.keySet()) { + // Let's replace their old named entry with a + // UUID key + String id = response.get(value).toString(); + set.remove(value.toLowerCase()); // Out with the + // old... + set.add(id); // And in with the new + } + } catch (Exception e) { + e.printStackTrace(); + } + claims.put(key, set); // Update + } + } + } + + // Update invites + + for (String string : data.keySet()) { + Faction f = data.get(string); + Set invites = f.getInvites(); + Set list = whichKeysNeedMigration(invites); + + if (list.size() > 0) { + UUIDFetcher fetcher = new UUIDFetcher(new ArrayList(list)); + try { + Map response = fetcher.call(); + for (String value : response.keySet()) { + // Let's replace their old named entry with a UUID + // key + String id = response.get(value).toString(); + invites.remove(value.toLowerCase()); // Out with the + // old... + invites.add(id); // And in with the new + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + saveCore(this.file, (Map) data, true); // Update the flatfile + Bukkit.getLogger().log(Level.INFO, "Done converting factions.json to UUID."); + } + return data; + } + + private Set whichKeysNeedMigration(Set keys) { + HashSet list = new HashSet(); + for (String value : keys) { + if (!value.matches("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}")) { + // Not a valid UUID.. + if (value.matches("[a-zA-Z0-9_]{2,16}")) { + // Valid playername, we'll mark this as one for conversion + // to UUID + list.add(value); + } + } + } + return list; + } + + // -------------------------------------------- // + // ID MANAGEMENT + // -------------------------------------------- // + + public String getNextId() { + while (!isIdFree(this.nextId)) { + this.nextId += 1; + } + return Integer.toString(this.nextId); + } + + public boolean isIdFree(String id) { + return !this.factions.containsKey(id); + } + + public boolean isIdFree(int id) { + return this.isIdFree(Integer.toString(id)); + } + + protected synchronized void updateNextIdForId(int id) { + if (this.nextId < id) { + this.nextId = id + 1; + } + } + + protected void updateNextIdForId(String id) { + try { + int idAsInt = Integer.parseInt(id); + this.updateNextIdForId(idAsInt); + } catch (Exception ignored) { + } + } + + @Override + public Faction generateFactionObject() { + String id = getNextId(); + Faction faction = new JSONFaction(id); + updateNextIdForId(id); + return faction; + } + + @Override + public Faction generateFactionObject(String id) { + Faction faction = new JSONFaction(id); + return faction; + } + + @Override + public void convertFrom(MemoryFactions old) { + this.factions.putAll(Maps.transformValues(old.factions, new Function() { + @Override + public JSONFaction apply(Faction arg0) { + return new JSONFaction((MemoryFaction) arg0); + } + })); + this.nextId = old.nextId; + forceSave(); + Factions.instance = this; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/util/DiscUtil.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/util/DiscUtil.java new file mode 100644 index 0000000..cae9dda --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/util/DiscUtil.java @@ -0,0 +1,137 @@ +package com.massivecraft.factions.zcore.util; + +import com.massivecraft.factions.P; +import org.bukkit.Bukkit; + +import java.io.*; +import java.util.HashMap; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +public class DiscUtil { + + // -------------------------------------------- // + // CONSTANTS + // -------------------------------------------- // + + private final static String UTF8 = "UTF-8"; + + // -------------------------------------------- // + // BYTE + // -------------------------------------------- // + + + public static byte[] readBytes(File file) throws IOException { + int length = (int) file.length(); + byte[] output = new byte[length]; + InputStream in = new FileInputStream(file); + int offset = 0; + while (offset < length) { + offset += in.read(output, offset, (length - offset)); + } + in.close(); + return output; + } + + public static void writeBytes(File file, byte[] bytes) throws IOException { + FileOutputStream out = new FileOutputStream(file); + out.write(bytes); + out.close(); + } + + // -------------------------------------------- // + // STRING + // -------------------------------------------- // + + public static void write(File file, String content) throws IOException { + writeBytes(file, utf8(content)); + } + + public static String read(File file) throws IOException { + return utf8(readBytes(file)); + } + + // -------------------------------------------- // + // CATCH + // -------------------------------------------- // + + private static HashMap locks = new HashMap(); + + public static boolean writeCatch(final File file, final String content, boolean sync) { + final byte[] bytes = utf8(content); + String name = file.getName(); + final Lock lock; + + // Create lock for each file if there isn't already one. + if (locks.containsKey(name)) { + lock = locks.get(name); + } else { + ReadWriteLock rwl = new ReentrantReadWriteLock(); + lock = rwl.writeLock(); + locks.put(name, lock); + } + + if (sync) { + lock.lock(); + try { + FileOutputStream out = new FileOutputStream(file); + out.write(bytes); + out.close(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + lock.unlock(); + } + } else { + Bukkit.getScheduler().runTaskAsynchronously(P.p, new Runnable() { + @Override + public void run() { + lock.lock(); + try { + FileOutputStream out = new FileOutputStream(file); + out.write(bytes); + out.close(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + lock.unlock(); + } + } + }); + } + + return true; // don't really care but for some reason this is a boolean. + } + + public static String readCatch(File file) { + try { + return read(file); + } catch (IOException e) { + return null; + } + } + + // -------------------------------------------- // + // UTF8 ENCODE AND DECODE + // -------------------------------------------- // + + public static byte[] utf8(String string) { + try { + return string.getBytes(UTF8); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + return null; + } + } + + public static String utf8(byte[] bytes) { + try { + return new String(bytes, UTF8); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + return null; + } + } + +} \ No newline at end of file diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/util/PermUtil.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/util/PermUtil.java new file mode 100644 index 0000000..f5cfb75 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/util/PermUtil.java @@ -0,0 +1,86 @@ +package com.massivecraft.factions.zcore.util; + +import com.massivecraft.factions.zcore.MPlugin; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.permissions.Permission; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + + +public class PermUtil { + + public Map permissionDescriptions = new HashMap(); + + protected MPlugin p; + + public PermUtil(MPlugin p) { + this.p = p; + this.setup(); + } + + public String getForbiddenMessage(String perm) { + return p.txt.parse(TL.GENERIC_NOPERMISSION.toString(), getPermissionDescription(perm)); + } + + /** + * This method hooks into all permission plugins we are supporting + */ + public final void setup() { + for (Permission permission : p.getDescription().getPermissions()) { + //p.log("\""+permission.getName()+"\" = \""+permission.getDescription()+"\""); + this.permissionDescriptions.put(permission.getName(), permission.getDescription()); + } + } + + public String getPermissionDescription(String perm) { + String desc = permissionDescriptions.get(perm); + if (desc == null) { + return TL.GENERIC_DOTHAT.toString(); + } + return desc; + } + + /** + * This method tests if me has a certain permission and returns true if me has. Otherwise false + */ + public boolean has(CommandSender me, String perm) { + if (me == null) { + return false; + } + + if (!(me instanceof Player)) { + return me.hasPermission(perm); + } + + return me.hasPermission(perm); + } + + public boolean has(CommandSender me, String perm, boolean informSenderIfNot) { + if (has(me, perm)) { + return true; + } else if (informSenderIfNot && me != null) { + me.sendMessage(this.getForbiddenMessage(perm)); + } + return false; + } + + public T pickFirstVal(CommandSender me, Map perm2val) { + if (perm2val == null) { + return null; + } + T ret = null; + + for (Entry entry : perm2val.entrySet()) { + ret = entry.getValue(); + if (has(me, entry.getKey())) { + break; + } + } + + return ret; + } + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/util/Persist.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/util/Persist.java new file mode 100644 index 0000000..0d15027 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/util/Persist.java @@ -0,0 +1,154 @@ +package com.massivecraft.factions.zcore.util; + +import com.massivecraft.factions.zcore.MPlugin; + +import java.io.File; +import java.lang.reflect.Type; +import java.util.logging.Level; + +// TODO: Give better name and place to differentiate from the entity-orm-ish system in "com.massivecraft.core.persist". + +public class Persist { + + private MPlugin p; + + public Persist(MPlugin p) { + this.p = p; + } + + // ------------------------------------------------------------ // + // GET NAME - What should we call this type of object? + // ------------------------------------------------------------ // + + public static String getName(Class clazz) { + return clazz.getSimpleName().toLowerCase(); + } + + public static String getName(Object o) { + return getName(o.getClass()); + } + + public static String getName(Type type) { + return getName(type.getClass()); + } + + // ------------------------------------------------------------ // + // GET FILE - In which file would we like to store this object? + // ------------------------------------------------------------ // + + public File getFile(String name) { + return new File(p.getDataFolder(), name + ".json"); + } + + public File getFile(Class clazz) { + return getFile(getName(clazz)); + } + + public File getFile(Object obj) { + return getFile(getName(obj)); + } + + public File getFile(Type type) { + return getFile(getName(type)); + } + + + // NICE WRAPPERS + + public T loadOrSaveDefault(T def, Class clazz) { + return loadOrSaveDefault(def, clazz, getFile(clazz)); + } + + public T loadOrSaveDefault(T def, Class clazz, String name) { + return loadOrSaveDefault(def, clazz, getFile(name)); + } + + public T loadOrSaveDefault(T def, Class clazz, File file) { + if (!file.exists()) { + p.log("Creating default: " + file); + this.save(def, file); + return def; + } + + T loaded = this.load(clazz, file); + + if (loaded == null) { + p.log(Level.WARNING, "Using default as I failed to load: " + file); + + // backup bad file, so user can attempt to recover their changes from it + File backup = new File(file.getPath() + "_bad"); + if (backup.exists()) { + backup.delete(); + } + p.log(Level.WARNING, "Backing up copy of bad file to: " + backup); + file.renameTo(backup); + + return def; + } + + return loaded; + } + + // SAVE + + public boolean save(Object instance) { + return save(instance, getFile(instance)); + } + + public boolean save(Object instance, String name) { + return save(instance, getFile(name)); + } + + public boolean save(Object instance, File file) { + return DiscUtil.writeCatch(file, p.gson.toJson(instance), true); + } + + // LOAD BY CLASS + + public T load(Class clazz) { + return load(clazz, getFile(clazz)); + } + + public T load(Class clazz, String name) { + return load(clazz, getFile(name)); + } + + public T load(Class clazz, File file) { + String content = DiscUtil.readCatch(file); + if (content == null) { + return null; + } + + try { + T instance = p.gson.fromJson(content, clazz); + return instance; + } catch (Exception ex) { // output the error message rather than full stack trace; error parsing the file, most likely + p.log(Level.WARNING, ex.getMessage()); + } + + return null; + } + + + // LOAD BY TYPE + @SuppressWarnings("unchecked") + public T load(Type typeOfT, String name) { + return (T) load(typeOfT, getFile(name)); + } + + @SuppressWarnings("unchecked") + public T load(Type typeOfT, File file) { + String content = DiscUtil.readCatch(file); + if (content == null) { + return null; + } + + try { + return (T) p.gson.fromJson(content, typeOfT); + } catch (Exception ex) { // output the error message rather than full stack trace; error parsing the file, most likely + p.log(Level.WARNING, ex.getMessage()); + } + + return null; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/util/SmokeUtil.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/util/SmokeUtil.java new file mode 100644 index 0000000..6451a69 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/util/SmokeUtil.java @@ -0,0 +1,82 @@ +package com.massivecraft.factions.zcore.util; + +import org.bukkit.Effect; +import org.bukkit.Location; + +import java.util.Collection; +import java.util.Random; + +// http://mc.kev009.com/Protocol +// ----------------------------- +// Smoke Directions +// ----------------------------- +// Direction ID Direction +// 0 South - East +// 1 South +// 2 South - West +// 3 East +// 4 (Up or middle ?) +// 5 West +// 6 North - East +// 7 North +// 8 North - West +//----------------------------- + +public class SmokeUtil { + + public static Random random = new Random(); + + // -------------------------------------------- // + // Spawn once + // -------------------------------------------- // + + // Single ======== + public static void spawnSingle(Location location, int direction) { + if (location == null) { + return; + } + location.getWorld().playEffect(location.clone(), Effect.SMOKE, direction); + } + + public static void spawnSingle(Location location) { + spawnSingle(location, 4); + } + + public static void spawnSingleRandom(Location location) { + spawnSingle(location, random.nextInt(9)); + } + + // Simple Cloud ======== + public static void spawnCloudSimple(Location location) { + for (int i = 0; i <= 8; i++) { + spawnSingle(location, i); + } + } + + public static void spawnCloudSimple(Collection locations) { + for (Location location : locations) { + spawnCloudSimple(location); + } + } + + // Random Cloud ======== + public static void spawnCloudRandom(Location location, float thickness) { + int singles = (int) Math.floor(thickness * 9); + for (int i = 0; i < singles; i++) { + spawnSingleRandom(location.clone()); + } + } + + public static void spawnCloudRandom(Collection locations, float thickness) { + for (Location location : locations) { + spawnCloudRandom(location, thickness); + } + } + + // -------------------------------------------- // + // Attach continuous effects to or locations + // -------------------------------------------- // + + // TODO + +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/util/TL.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/util/TL.java new file mode 100644 index 0000000..ed3cbfc --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/util/TL.java @@ -0,0 +1,798 @@ +/* + * Copyright (C) 2013 drtshock + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.massivecraft.factions.zcore.util; + +import org.bukkit.ChatColor; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.text.SimpleDateFormat; + +/** + * An enum for requesting strings from the language file. The contents of this enum file may be subject to frequent + * changes. + */ +public enum TL { + /** + * Translation meta + */ + _AUTHOR("misc"), + _RESPONSIBLE("misc"), + _LANGUAGE("English"), + _ENCODING("UTF-8"), + _LOCALE("en_US"), + _REQUIRESUNICODE("false"), + _DEFAULT("true"), + _STATE("complete"), //incomplete, limited, partial, majority, complete + + /** + * Localised translation meta + */ + _LOCAL_AUTHOR("misc"), + _LOCAL_RESPONSIBLE("misc"), + _LOCAL_LANGUAGE("English"), + _LOCAL_REGION("US"), + _LOCAL_STATE("complete"), //And this is the English version. It's not ever going to be not complete. + + /** + * Command translations + */ + COMMAND_ADMIN_NOTMEMBER("%1$s is not a member in your cartel."), + COMMAND_ADMIN_NOTADMIN("You are not the cartel boss."), + COMMAND_ADMIN_TARGETSELF("The target player musn't be yourself."), + COMMAND_ADMIN_DEMOTES("You have demoted %1$s from the position of cartel boss."), + COMMAND_ADMIN_DEMOTED("You have been demoted from the position of cartel boss by %1$s."), + COMMAND_ADMIN_PROMOTES("You have promoted %1$s to the position of cartel boss."), + COMMAND_ADMIN_PROMOTED("%1$s gave %2$s the leadership of %3$s."), + COMMAND_ADMIN_DESCRIPTION("Hand over your boss rights"), + + COMMAND_AHOME_DESCRIPTION("Send a player to their cartel home no matter what."), + COMMAND_AHOME_NOHOME("%1$s doesn't have a cartel home."), + COMMAND_AHOME_SUCCESS("$1%s was sent to their cartel home."), + COMMAND_AHOME_OFFLINE("%1$s is offline."), + COMMAND_AHOME_TARGET("You were sent to your cartel home."), + + COMMAND_ANNOUNCE_DESCRIPTION("Announce a message to players in cartel."), + + COMMAND_AUTOCLAIM_ENABLED("Now auto-claiming land for %1$s."), + COMMAND_AUTOCLAIM_DISABLED("Auto-claiming of land disabled."), + COMMAND_AUTOCLAIM_REQUIREDRANK("You must be %1$s to claim land."), + COMMAND_AUTOCLAIM_OTHERFACTION("You can't claim land for %1$s."), + COMMAND_AUTOCLAIM_DESCRIPTION("Auto-claim land as you walk around"), + + COMMAND_AUTOHELP_HELPFOR("Help for command \""), + + COMMAND_BOOM_PEACEFULONLY("This command is only usable by cartels which are specifically designated as peaceful."), + COMMAND_BOOM_TOTOGGLE("to toggle explosions"), + COMMAND_BOOM_FORTOGGLE("for toggling explosions"), + COMMAND_BOOM_ENABLED("%1$s has %2$s explosions in your cartel's territory."), + COMMAND_BOOM_DESCRIPTION("Toggle explosions (peaceful cartels only)"), + + COMMAND_BYPASS_ENABLE("You have enabled admin bypass mode. You will be able to build or destroy anywhere."), + COMMAND_BYPASS_ENABLELOG(" has ENABLED admin bypass mode."), + COMMAND_BYPASS_DISABLE("You have disabled admin bypass mode."), + COMMAND_BYPASS_DISABLELOG(" has DISABLED admin bypass mode."), + COMMAND_BYPASS_DESCRIPTION("Enable admin bypass mode"), + + COMMAND_CHAT_DISABLED("The built in chat channels are disabled on this server."), + COMMAND_CHAT_INVALIDMODE("Unrecognised chat mode. Please enter either 'a','c' or 'p'"),//TODO Don't forget, change character to c for chatmode. + COMMAND_CHAT_DESCRIPTION("Change chat mode"), + + COMMAND_CHAT_MODE_PUBLIC("Public chat mode."), + COMMAND_CHAT_MODE_ALLIANCE("Alliance only chat mode."), + COMMAND_CHAT_MODE_TRUCE("Truce only chat mode."), + COMMAND_CHAT_MODE_FACTION("Cartel only chat mode."), + + COMMAND_CHATSPY_ENABLE("You have enabled chat spying mode."), + COMMAND_CHATSPY_ENABLELOG(" has ENABLED chat spying mode."), + COMMAND_CHATSPY_DISABLE("You have disabled chat spying mode."), + COMMAND_CHATSPY_DISABLELOG(" has DISABLED chat spying mode."), + COMMAND_CHATSPY_DESCRIPTION("Enable admin chat spy mode"), + + COMMAND_CLAIM_INVALIDRADIUS("If you specify a radius, it must be at least 1."), + COMMAND_CLAIM_DENIED("You do not have permission to claim in a radius."), + COMMAND_CLAIM_DESCRIPTION("Claim land from where you are standing"), + + COMMAND_CLAIMLINE_INVALIDRADIUS("If you specify a distance, it must be at least 1."), + COMMAND_CLAIMLINE_DENIED("You do not have permission to claim in a line."), + COMMAND_CLAIMLINE_DESCRIPTION("Claim land in a straight line."), + COMMAND_CLAIMLINE_ABOVEMAX("The maximum limit for claim line is %s."), + COMMAND_CLAIMLINE_NOTVALID("%s is not a cardinal direction. You may use north, east, south or west."), + + COMMAND_CONFIG_NOEXIST("No configuration setting \"%1$s\" exists."), + COMMAND_CONFIG_SET_TRUE("\" option set to true (enabled)."), + COMMAND_CONFIG_SET_FALSE("\" option set to false (disabled)."), + COMMAND_CONFIG_OPTIONSET("\" option set to "), + COMMAND_CONFIG_COLOURSET("\" color option set to \""), + COMMAND_CONFIG_INTREQUIRED("Cannot set \"%1$s\": An integer (whole number) value required."), + COMMAND_CONFIG_LONGREQUIRED("Cannot set \"%1$s\": A long integer (whole number) value required."), + COMMAND_CONFIG_DOUBLEREQUIRED("Cannot set \"%1$s\": A double (numeric) value required."), + COMMAND_CONFIG_FLOATREQUIRED("Cannot set \"%1$s\": A float (numeric) value required."), + COMMAND_CONFIG_INVALID_COLOUR("Cannot set \"%1$s\": \"%2$s\" is not a valid color."), + COMMAND_CONFIG_INVALID_COLLECTION("\"%1$s\" is not a data collection type which can be modified with this command."), + COMMAND_CONFIG_INVALID_MATERIAL("Cannot change \"%1$s\" set: \"%2$s\" is not a valid material."), + COMMAND_CONFIG_INVALID_TYPESET("\"%1$s\" is not a data type set which can be modified with this command."), + COMMAND_CONFIG_MATERIAL_ADDED("\"%1$s\" set: Material \"%2$s\" added."), + COMMAND_CONFIG_MATERIAL_REMOVED("\"%1$s\" set: Material \"%2$s\" removed."), + COMMAND_CONFIG_SET_ADDED("\"%1$s\" set: \"%2$s\" added."), + COMMAND_CONFIG_SET_REMOVED("\"%1$s\" set: \"%2$s\" removed."), + COMMAND_CONFIG_LOG(" (Command was run by %1$s.)"), + COMMAND_CONFIG_ERROR_SETTING("Error setting configuration setting \"%1$s\" to \"%2$s\"."), + COMMAND_CONFIG_ERROR_MATCHING("Configuration setting \"%1$s\" couldn't be matched, though it should be... please report this error."), + COMMAND_CONFIG_ERROR_TYPE("'%1$s' is of type '%2$s', which cannot be modified with this command."), + COMMAND_CONFIG_DESCRIPTION("Change a conf.json setting"), + + COMMAND_CONVERT_BACKEND_RUNNING("Already running that backend."), + COMMAND_CONVERT_BACKEND_INVALID("Invalid backend"), + COMMAND_CONVERT_DESCRIPTION("Convert the plugin backend"), + + COMMAND_CREATE_MUSTLEAVE("You must leave your current cartel first."), + COMMAND_CREATE_INUSE("That tag is already in use."), + COMMAND_CREATE_TOCREATE("to create a new cartel"), + COMMAND_CREATE_FORCREATE("for creating a new cartel"), + COMMAND_CREATE_ERROR("There was an internal error while trying to create your cartel. Please try again."), + COMMAND_CREATE_CREATED("%1$s created a new cartel %2$s"), + COMMAND_CREATE_YOUSHOULD("You should now: %1$s"), + COMMAND_CREATE_CREATEDLOG(" created a new cartel: "), + COMMAND_CREATE_DESCRIPTION("Create a new cartel"), + + COMMAND_DEINVITE_CANDEINVITE("Players you can deinvite: "), + COMMAND_DEINVITE_CLICKTODEINVITE("Click to revoke invite for %1$s"), + COMMAND_DEINVITE_ALREADYMEMBER("%1$s is already a member of %2$s"), + COMMAND_DEINVITE_MIGHTWANT("You might want to: %1$s"), + COMMAND_DEINVITE_REVOKED("%1$s revoked your invitation to %2$s."), + COMMAND_DEINVITE_REVOKES("%1$s revoked %2$s's invitation."), + COMMAND_DEINVITE_DESCRIPTION("Remove a pending invitation"), + + COMMAND_DELFWARP_DELETED("Deleted warp %1$s"), + COMMAND_DELFWARP_INVALID("Couldn't find warp %1$s"), + COMMAND_DELFWARP_TODELETE("to delete warp"), + COMMAND_DELFWARP_FORDELETE("for deleting warp"), + COMMAND_DELFWARP_DESCRIPTION("Delete a cartel warp"), + + COMMAND_DESCRIPTION_CHANGES("You have changed the description for %1$s to:"), + COMMAND_DESCRIPTION_CHANGED("The cartel %1$s changed their description to:"), + COMMAND_DESCRIPTION_TOCHANGE("to change cartel description"), + COMMAND_DESCRIPTION_FORCHANGE("for changing cartel description"), + COMMAND_DESCRIPTION_DESCRIPTION("Change the cartel description"), + + COMMAND_DISBAND_IMMUTABLE("You cannot disband the Wilderness, SafeZone, or WarZone."), + COMMAND_DISBAND_MARKEDPERMANENT("This cartel is designated as permanent, so you cannot disband it."), + COMMAND_DISBAND_BROADCAST_YOURS("%1$s disbanded your cartel."), + COMMAND_DISBAND_BROADCAST_NOTYOURS("%1$s disbanded the cartel %2$s."), + COMMAND_DISBAND_HOLDINGS("You have been given the disbanded cartel's bank, totaling %1$s."), + COMMAND_DISBAND_DESCRIPTION("Disband a cartel"), + + COMMAND_FWARP_CLICKTOWARP("Click to warp!"), + COMMAND_FWARP_COMMANDFORMAT("/f warp "), + COMMAND_FWARP_WARPED("Warped to %1$s"), + COMMAND_FWARP_INVALID("Couldn't find warp %1$s"), + COMMAND_FWARP_TOWARP("to warp"), + COMMAND_FWARP_FORWARPING("for warping"), + COMMAND_FWARP_WARPS("Warps: "), + COMMAND_FWARP_DESCRIPTION("Teleport to a cartel warp"), + + COMMAND_HELP_404("This page does not exist"), + COMMAND_HELP_NEXTCREATE("Learn how to create a cartel on the next page."), + COMMAND_HELP_INVITATIONS("command.help.invitations", "You might want to close it and use invitations:"), + COMMAND_HELP_HOME("And don't forget to set your home:"), + COMMAND_HELP_BANK_1("Your cartel has a bank which is used to pay for certain"), + COMMAND_HELP_BANK_2("things, so it will need to have money deposited into it."), + COMMAND_HELP_BANK_3("To learn more, use the money command."), + COMMAND_HELP_PLAYERTITLES("Player titles are just for fun. No rules connected to them."), + COMMAND_HELP_OWNERSHIP_1("Claimed land with ownership set is further protected so"), + COMMAND_HELP_OWNERSHIP_2("that only the owner(s), cartel boss, and possibly the"), + COMMAND_HELP_OWNERSHIP_3("cartel underbosses have full access."), + COMMAND_HELP_RELATIONS_1("Set the relation you WISH to have with another cartel."), + COMMAND_HELP_RELATIONS_2("Your default relation with other cartels will be neutral."), + COMMAND_HELP_RELATIONS_3("If BOTH cartels choose \"ally\" you will be allies."), + COMMAND_HELP_RELATIONS_4("If ONE cartel chooses \"enemy\" you will be enemies."), + COMMAND_HELP_RELATIONS_5("You can never hurt members or allies."), + COMMAND_HELP_RELATIONS_6("You can not hurt neutrals in their own territory."), + COMMAND_HELP_RELATIONS_7("You can always hurt enemies and players without cartel."), + COMMAND_HELP_RELATIONS_8(""), + COMMAND_HELP_RELATIONS_9("Damage from enemies is reduced in your own territory."), + COMMAND_HELP_RELATIONS_10("When you die you lose power. It is restored over time."), + COMMAND_HELP_RELATIONS_11("The power of a cartel is the sum of all member power."), + COMMAND_HELP_RELATIONS_12("The power of a cartel determines how much land it can hold."), + COMMAND_HELP_RELATIONS_13("You can claim land from cartels with too little power."), + COMMAND_HELP_PERMISSIONS_1("Only cartel members can build and destroy in their own"), + COMMAND_HELP_PERMISSIONS_2("territory. Usage of the following items is also restricted:"), + COMMAND_HELP_PERMISSIONS_3("Door, Chest, Furnace, Dispenser, Diode."), + COMMAND_HELP_PERMISSIONS_4(""), + COMMAND_HELP_PERMISSIONS_5("Make sure to put pressure plates in front of doors for your"), + COMMAND_HELP_PERMISSIONS_6("guest visitors. Otherwise they can't get through. You can"), + COMMAND_HELP_PERMISSIONS_7("also use this to create member only areas."), + COMMAND_HELP_PERMISSIONS_8("As dispensers are protected, you can create traps without"), + COMMAND_HELP_PERMISSIONS_9("worrying about those arrows getting stolen."), + COMMAND_HELP_ADMIN_1("/c claim safezone claim land for the Safe Zone"), + COMMAND_HELP_ADMIN_2("/c claim warzone claim land for the War Zone"), + COMMAND_HELP_ADMIN_3("/c autoclaim [safezone|warzone] take a guess"), + COMMAND_HELP_MOAR_1("Finally some commands for the server admins:"), + COMMAND_HELP_MOAR_2("More commands for server admins:"), + COMMAND_HELP_MOAR_3("Even more commands for server admins:"), + COMMAND_HELP_DESCRIPTION("Display a help page"), + + COMMAND_HOME_DISABLED("Sorry, Cartel homes are disabled on this server."), + COMMAND_HOME_TELEPORTDISABLED("Sorry, the ability to teleport to Cartel homes is disabled on this server."), + COMMAND_HOME_NOHOME("Your cartel does not have a home. "), + COMMAND_HOME_INENEMY("You cannot teleport to your cartel home while in the territory of an enemy cartel."), + COMMAND_HOME_WRONGWORLD("You cannot teleport to your cartel home while in a different world."), + COMMAND_HOME_ENEMYNEAR("You cannot teleport to your cartel home while an enemy is within %s blocks of you."), + COMMAND_HOME_TOTELEPORT("to teleport to your cartel home"), + COMMAND_HOME_FORTELEPORT("for teleporting to your cartel home"), + COMMAND_HOME_DESCRIPTION("Teleport to the cartel home"), + + COMMAND_INVITE_TOINVITE("to invite someone"), + COMMAND_INVITE_FORINVITE("for inviting someone"), + COMMAND_INVITE_CLICKTOJOIN("Click to join!"), + COMMAND_INVITE_INVITEDYOU(" has invited you to join "), + COMMAND_INVITE_INVITED("%1$s invited %2$s to your cartel."), + COMMAND_INVITE_ALREADYMEMBER("%1$s is already a member of %2$s"), + COMMAND_INVITE_DESCRIPTION("Invite a player to your cartel"), + + COMMAND_JOIN_CANNOTFORCE("You do not have permission to move other players into a cartel."), + COMMAND_JOIN_SYSTEMFACTION("Players may only join normal cartels. This is a system cartel."), + COMMAND_JOIN_ALREADYMEMBER("%1$s %2$s already a member of %3$s"), + COMMAND_JOIN_ATLIMIT(" ! The cartel %1$s is at the limit of %2$d members, so %3$s cannot currently join."), + COMMAND_JOIN_INOTHERFACTION("%1$s must leave %2$s current cartel first."), + COMMAND_JOIN_NEGATIVEPOWER("%1$s cannot join a cartel with a negative power level."), + COMMAND_JOIN_REQUIRESINVITATION("This cartel requires invitation."), + COMMAND_JOIN_ATTEMPTEDJOIN("%1$s tried to join your cartel."), + COMMAND_JOIN_TOJOIN("to join a cartel"), + COMMAND_JOIN_FORJOIN("for joining a cartel"), + COMMAND_JOIN_SUCCESS("%1$s successfully joined %2$s."), + COMMAND_JOIN_MOVED("%1$s moved you into the cartel %2$s."), + COMMAND_JOIN_JOINED("%1$s joined your cartel."), + COMMAND_JOIN_JOINEDLOG("%1$s joined the cartel %2$s."), + COMMAND_JOIN_MOVEDLOG("%1$s moved the player %2$s into the cartel %3$s."), + COMMAND_JOIN_DESCRIPTION("Join a cartel"), + + COMMAND_KICK_CANDIDATES("Players you can kick: "), + COMMAND_KICK_CLICKTOKICK("Click to kick "), + COMMAND_KICK_SELF("You cannot kick yourself."), + COMMAND_KICK_NONE("That player is not in a cartel."), + COMMAND_KICK_NOTMEMBER("%1$s is not a member of %2$s"), + COMMAND_KICK_INSUFFICIENTRANK("Your rank is too low to kick this player."), + COMMAND_KICK_NEGATIVEPOWER("You cannot kick that member until their power is positive."), + COMMAND_KICK_TOKICK("to kick someone from the cartel"), + COMMAND_KICK_FORKICK("for kicking someone from the cartel"), + COMMAND_KICK_FACTION("%1$s kicked %2$s from the cartel! :O"), //message given to cartel members + COMMAND_KICK_KICKS("You kicked %1$s from the cartel %2$s!"), //kicker perspective + COMMAND_KICK_KICKED("%1$s kicked you from %2$s! :O"), //kicked player perspective + COMMAND_KICK_DESCRIPTION("Kick a player from the cartel"), + + COMMAND_LIST_FACTIONLIST("Cartel List "), + COMMAND_LIST_TOLIST("to list the cartels"), + COMMAND_LIST_FORLIST("for listing the cartels"), + COMMAND_LIST_ONLINEFACTIONLESS("Online cartelless: "), + COMMAND_LIST_DESCRIPTION("See a list of the cartels"), + + COMMAND_LOCK_LOCKED("Cartels is now locked"), + COMMAND_LOCK_UNLOCKED("Cartels in now unlocked"), + COMMAND_LOCK_DESCRIPTION("Lock all write stuff. Apparently."), + + COMMAND_LOGINS_TOGGLE("Set login / logout notifications for Cartel members to: %s"), + COMMAND_LOGINS_DESCRIPTION("Toggle(?) login / logout notifications for Cartel members"), + + COMMAND_MAP_TOSHOW("to show the map"), + COMMAND_MAP_FORSHOW("for showing the map"), + COMMAND_MAP_UPDATE_ENABLED("Map auto update ENABLED."), + COMMAND_MAP_UPDATE_DISABLED("Map auto update DISABLED."), + COMMAND_MAP_DESCRIPTION("Show the territory map, and set optional auto update"), + + COMMAND_MOD_CANDIDATES("Players you can promote: "), + COMMAND_MOD_CLICKTOPROMOTE("Click to promote "), + COMMAND_MOD_NOTMEMBER("%1$s is not a member in your cartel."), + COMMAND_MOD_NOTADMIN("You are not the cartel boss."), + COMMAND_MOD_SELF("The target player musn't be yourself."), + COMMAND_MOD_TARGETISADMIN("The target player is a cartel boss. Demote them first."), + COMMAND_MOD_REVOKES("You have removed underbos status from %1$s."), + COMMAND_MOD_REVOKED("%1$s is no longer underbos in your cartel."), + COMMAND_MOD_PROMOTES("%1$s was promoted to underbos in your cartel."), + COMMAND_MOD_PROMOTED("You have promoted %1$s to underbos."), + COMMAND_MOD_DESCRIPTION("Give or revoke underbos rights"), + + COMMAND_MODIFYPOWER_ADDED("Added %1$f power to %2$s. New total rounded power: %3$d"), + COMMAND_MODIFYPOWER_DESCRIPTION("Modify the power of a cartel/player"), + + COMMAND_MONEY_LONG("The cartel money commands."), + COMMAND_MONEY_DESCRIPTION("Cartel money commands"), + + COMMAND_MONEYBALANCE_SHORT("show cartel balance"), + COMMAND_MONEYBALANCE_DESCRIPTION("Show your cartels current money balance"), + + COMMAND_MONEYDEPOSIT_DESCRIPTION("Deposit money"), + COMMAND_MONEYDEPOSIT_DEPOSITED("%1$s deposited %2$s in the cartel bank: %3$s"), + + COMMAND_MONEYTRANSFERFF_DESCRIPTION("Transfer f -> f"), + COMMAND_MONEYTRANSFERFF_TRANSFER("%1$s transferred %2$s from the cartel \"%3$s\" to the cartel \"%4$s\""), + + COMMAND_MONEYTRANSFERFP_DESCRIPTION("Transfer f -> p"), + COMMAND_MONEYTRANSFERFP_TRANSFER("%1$s transferred %2$s from the cartel \"%3$s\" to the player \"%4$s\""), + + COMMAND_MONEYTRANSFERPF_DESCRIPTION("Transfer p -> f"), + COMMAND_MONEYTRANSFERPF_TRANSFER("%1$s transferred %2$s from the player \"%3$s\" to the cartel \"%4$s\""), + + COMMAND_MONEYWITHDRAW_DESCRIPTION("Withdraw money"), + COMMAND_MONEYWITHDRAW_WITHDRAW("%1$s withdrew %2$s from the cartel bank: %3$s"), + + COMMAND_OPEN_TOOPEN("to open or close the cartel"), + COMMAND_OPEN_FOROPEN("for opening or closing the cartel"), + COMMAND_OPEN_OPEN("open"), + COMMAND_OPEN_CLOSED("closed"), + COMMAND_OPEN_CHANGES("%1$s changed the cartel to %2$s."), + COMMAND_OPEN_CHANGED("The cartel %1$s is now %2$s"), + COMMAND_OPEN_DESCRIPTION("Switch if invitation is required to join"), + + COMMAND_OWNER_DISABLED("Sorry, but owned areas are disabled on this server."), + COMMAND_OWNER_LIMIT("Sorry, but you have reached the server's limit of %1$d owned areas per cartel."), + COMMAND_OWNER_WRONGFACTION("This land is not claimed by your cartel, so you can't set ownership of it."), + COMMAND_OWNER_NOTCLAIMED("This land is not claimed by a cartel. Ownership is not possible."), + COMMAND_OWNER_NOTMEMBER("%1$s is not a member of this cartel."), + COMMAND_OWNER_CLEARED("You have cleared ownership for this claimed area."), + COMMAND_OWNER_REMOVED("You have removed ownership of this claimed land from %1$s."), + COMMAND_OWNER_TOSET("to set ownership of claimed land"), + COMMAND_OWNER_FORSET("for setting ownership of claimed land"), + COMMAND_OWNER_ADDED("You have added %1$s to the owner list for this claimed land."), + COMMAND_OWNER_DESCRIPTION("Set ownership of claimed land"), + + COMMAND_OWNERLIST_DISABLED("Sorry, but owned areas are disabled on this server."),//dup-> + COMMAND_OWNERLIST_WRONGFACTION("This land is not claimed by your cartel."),//eq + COMMAND_OWNERLIST_NOTCLAIMED("This land is not claimed by any cartel, thus no owners."),//eq + COMMAND_OWNERLIST_NONE("No owners are set here; everyone in the cartel has access."), + COMMAND_OWNERLIST_OWNERS("Current owner(s) of this land: %1$s"), + COMMAND_OWNERLIST_DESCRIPTION("List owner(s) of this claimed land"), + + COMMAND_PEACEFUL_DESCRIPTION("Set a cartel to peaceful"), + COMMAND_PEACEFUL_YOURS("%1$s has %2$s your cartel"), + COMMAND_PEACEFUL_OTHER("%s has %s the cartel '%s'."), + COMMAND_PEACEFUL_GRANT("granted peaceful status to"), + COMMAND_PEACEFUL_REVOKE("removed peaceful status from"), + + COMMAND_PERMANENT_DESCRIPTION("Toggles a cartel's permanence"), //TODO: Real word? + COMMAND_PERMANENT_GRANT("added permanent status to"), + COMMAND_PERMANENT_REVOKE("removed permanent status from"), + COMMAND_PERMANENT_YOURS("%1$s has %2$s your cartel"), + COMMAND_PERMANENT_OTHER("%s has %s the cartel '%s'."), + + COMMAND_PERMANENTPOWER_DESCRIPTION("Toggle cartel power permanence"), //TODO: This a real word? + COMMAND_PERMANENTPOWER_GRANT("added permanentpower status to"), + COMMAND_PERMANENTPOWER_REVOKE("removed permanentpower status from"), + COMMAND_PERMANENTPOWER_SUCCESS("You %s %s."), + COMMAND_PERMANENTPOWER_FACTION("%s %s your cartel"), + + COMMAND_POWER_TOSHOW("to show player power info"), + COMMAND_POWER_FORSHOW("for showing player power info"), + COMMAND_POWER_POWER("%1$s - Power / Maxpower: %2$d / %3$d %4$s"), + COMMAND_POWER_BONUS(" (bonus: "), + COMMAND_POWER_PENALTY(" (penalty: "), + COMMAND_POWER_DESCRIPTION("Show player power info"), + + COMMAND_POWERBOOST_HELP_1("You must specify \"p\" or \"player\" to target a player or \"f\" or \"cartel\" to target a cartel."), + COMMAND_POWERBOOST_HELP_2("ex. /c powerboost p SomePlayer 0.5 -or- /c powerboost c SomeCartel -5"), + COMMAND_POWERBOOST_INVALIDNUM("You must specify a valid numeric value for the power bonus/penalty amount."), + COMMAND_POWERBOOST_PLAYER("Player \"%1$s\""), + COMMAND_POWERBOOST_FACTION("Cartel \"%1$s\""), + COMMAND_POWERBOOST_BOOST("%1$s now has a power bonus/penalty of %2$d to min and max power levels."), + COMMAND_POWERBOOST_BOOSTLOG("%1$s has set the power bonus/penalty for %2$s to %3$d."), + COMMAND_POWERBOOST_DESCRIPTION("Apply permanent power bonus/penalty to specified player or cartel"), + + COMMAND_RELATIONS_ALLTHENOPE("Nope! You can't."), + COMMAND_RELATIONS_MORENOPE("Nope! You can't declare a relation to yourself :)"), + COMMAND_RELATIONS_ALREADYINRELATIONSHIP("You already have that relation wish set with %1$s."), + COMMAND_RELATIONS_TOMARRY("to change a relation wish"), + COMMAND_RELATIONS_FORMARRY("for changing a relation wish"), + COMMAND_RELATIONS_MUTUAL("Your cartel is now %1$s to %2$s"), + COMMAND_RELATIONS_PEACEFUL("This will have no effect while your cartel is peaceful."), + COMMAND_RELATIONS_PEACEFULOTHER("This will have no effect while their cartel is peaceful."), + COMMAND_RELATIONS_DESCRIPTION("Set relation wish to another cartel"), + COMMAND_RELATIONS_EXCEEDS_ME("Failed to set relation wish. You can only have %1$s %2$s."), + COMMAND_RELATIONS_EXCEEDS_THEY("Failed to set relation wish. They can only have %1$s %2$s."), + + COMMAND_RELATIONS_PROPOSAL_1("%1$s wishes to be your %2$s"), + COMMAND_RELATIONS_PROPOSAL_2("Type /%1$s %2$s %3$s to accept."), + COMMAND_RELATIONS_PROPOSAL_SENT("%1$s were informed that you wish to be %2$s"), + + COMMAND_RELOAD_TIME("Reloaded all configuration files from disk, took %1$d ms."), + COMMAND_RELOAD_DESCRIPTION("Reload data file(s) from disk"), + + COMMAND_SAFEUNCLAIMALL_DESCRIPTION("Unclaim all safezone land"), + COMMAND_SAFEUNCLAIMALL_UNCLAIMED("You unclaimed ALL safe zone land."), + COMMAND_SAFEUNCLAIMALL_UNCLAIMEDLOG("%1$s unclaimed all safe zones."), + + COMMAND_SAVEALL_SUCCESS("Cartels saved to disk!"), + COMMAND_SAVEALL_DESCRIPTION("Save all data to disk"), + + COMMAND_SCOREBOARD_DESCRIPTION("Scoreboardy things"), + + COMMAND_SETFWARP_NOTCLAIMED("You can only set warps in your cartel territory."), + COMMAND_SETFWARP_LIMIT("Your Cartel already has the max amount of warps set (%1$d)."), + COMMAND_SETFWARP_SET("Set warp %1$s to your location."), + COMMAND_SETFWARP_TOSET("to set warp"), + COMMAND_SETFWARP_FORSET("for setting warp"), + COMMAND_SETFWARP_DESCRIPTION("Set a cartel warp"), + + COMMAND_SETHOME_DISABLED("Sorry, Cartel homes are disabled on this server."), + COMMAND_SETHOME_NOTCLAIMED("Sorry, your cartel home can only be set inside your own claimed territory."), + COMMAND_SETHOME_TOSET("to set the cartel home"), + COMMAND_SETHOME_FORSET("for setting the cartel home"), + COMMAND_SETHOME_SET("%1$s set the home for your cartel. You can now use:"), + COMMAND_SETHOME_SETOTHER("You have set the home for the %1$s cartel."), + COMMAND_SETHOME_DESCRIPTION("Set the cartel home"), + + COMMAND_SETMAXVAULTS_DESCRIPTION("Set max vaults for a Cartel."), + COMMAND_SETMAXVAULTS_SUCCESS("&aSet max vaults for &e%s &ato &b%d"), + + COMMAND_VAULT_DESCRIPTION("/c vault to open one of your Cartel's vaults."), + COMMAND_VAULT_TOOHIGH("&cYou tried to open vault %d but your Cartel only has %d vaults."), + + COMMAND_SHOW_NOFACTION_SELF("You are not in a cartel"), + COMMAND_SHOW_NOFACTION_OTHER("That's not a cartel"), + COMMAND_SHOW_TOSHOW("to show cartel information"), + COMMAND_SHOW_FORSHOW("for showing cartel information"), + COMMAND_SHOW_DESCRIPTION("Description: %1$s"), + COMMAND_SHOW_PEACEFUL("This cartel is Peaceful"), + COMMAND_SHOW_PERMANENT("This cartel is permanent, remaining even with no members."), + COMMAND_SHOW_JOINING("Joining: %1$s "), + COMMAND_SHOW_INVITATION("invitation is required"), + COMMAND_SHOW_UNINVITED("no invitation is needed"), + COMMAND_SHOW_NOHOME("n/a"), + COMMAND_SHOW_POWER("Land / Power / Maxpower: %1$d/%2$d/%3$d %4$s."), + COMMAND_SHOW_BONUS(" (bonus: "), + COMMAND_SHOW_PENALTY(" (penalty: "), + COMMAND_SHOW_DEPRECIATED("(%1$s depreciated)"), //This is spelled correctly. + COMMAND_SHOW_LANDVALUE("Total land value: %1$s %2$s"), + COMMAND_SHOW_BANKCONTAINS("Bank contains: %1$s"), + COMMAND_SHOW_ALLIES("Allies: "), + COMMAND_SHOW_ENEMIES("Enemies: "), + COMMAND_SHOW_MEMBERSONLINE("Members online: "), + COMMAND_SHOW_MEMBERSOFFLINE("Members offline: "), + COMMAND_SHOW_COMMANDDESCRIPTION("Show cartel information"), + COMMAND_SHOW_DEATHS_TIL_RAIDABLE("DTR: %1$d"), + COMMAND_SHOW_EXEMPT("This cartel is exempt and cannot be seen."), + + COMMAND_SHOWINVITES_PENDING("Players with pending invites: "), + COMMAND_SHOWINVITES_CLICKTOREVOKE("Click to revoke invite for %1$s"), + COMMAND_SHOWINVITES_DESCRIPTION("Show pending cartel invites"), + + COMMAND_STATUS_FORMAT("%1$s Power: %2$s Last Seen: %3$s"), + COMMAND_STATUS_ONLINE("Online"), + COMMAND_STATUS_AGOSUFFIX(" ago."), + COMMAND_STATUS_DESCRIPTION("Show the status of a player"), + + COMMAND_STUCK_TIMEFORMAT("m 'minutes', s 'seconds.'"), + COMMAND_STUCK_CANCELLED("Teleport cancelled because you were damaged"), + COMMAND_STUCK_OUTSIDE("Teleport cancelled because you left %1$d block radius"), + COMMAND_STUCK_EXISTS("You are already teleporting, you must wait %1$s"), + COMMAND_STUCK_START("Teleport will commence in %s. Don't take or deal damage. "), + COMMAND_STUCK_TELEPORT("Teleported safely to %1$d, %2$d, %3$d."), + COMMAND_STUCK_TOSTUCK("to safely teleport %1$s out"), + COMMAND_STUCK_FORSTUCK("for %1$s initiating a safe teleport out"), + COMMAND_STUCK_DESCRIPTION("Safely teleports you out of enemy cartel"), + + COMMAND_TAG_TAKEN("That tag is already taken"), + COMMAND_TAG_TOCHANGE("to change the cartel tag"), + COMMAND_TAG_FORCHANGE("for changing the cartel tag"), + COMMAND_TAG_FACTION("%1$s changed your cartel tag to %2$s"), + COMMAND_TAG_CHANGED("The cartel %1$s changed their name to %2$s."), + COMMAND_TAG_DESCRIPTION("Change the cartel tag"), + + COMMAND_TITLE_TOCHANGE("to change a players title"), + COMMAND_TITLE_FORCHANGE("for changing a players title"), + COMMAND_TITLE_CHANGED("%1$s changed a title: %2$s"), + COMMAND_TITLE_DESCRIPTION("Set or remove a players title"), + + COMMAND_TOGGLEALLIANCECHAT_DESCRIPTION("Toggles whether or not you will see alliance chat"), + COMMAND_TOGGLEALLIANCECHAT_IGNORE("Alliance chat is now ignored"), + COMMAND_TOGGLEALLIANCECHAT_UNIGNORE("Alliance chat is no longer ignored"), + + COMMAND_TOGGLESB_DISABLED("You can't toggle scoreboards while they are disabled."), + + COMMAND_TOP_DESCRIPTION("Sort Cartels to see the top of some criteria."), + COMMAND_TOP_TOP("Top Cartels by %s. Page %d/%d"), + COMMAND_TOP_LINE("%d. &6%s: &c%s"), // Rank. Cartel: Value + COMMAND_TOP_INVALID("Could not sort by %s. Try balance, online, members, power or land."), + + COMMAND_UNCLAIM_SAFEZONE_SUCCESS("Safe zone was unclaimed."), + COMMAND_UNCLAIM_SAFEZONE_NOPERM("This is a safe zone. You lack permissions to unclaim."), + COMMAND_UNCLAIM_WARZONE_SUCCESS("War zone was unclaimed."), + COMMAND_UNCLAIM_WARZONE_NOPERM("This is a war zone. You lack permissions to unclaim."), + COMMAND_UNCLAIM_UNCLAIMED("%1$s unclaimed some of your land."), + COMMAND_UNCLAIM_UNCLAIMS("You unclaimed this land."), + COMMAND_UNCLAIM_LOG("%1$s unclaimed land at (%2$s) from the cartel: %3$s"), + COMMAND_UNCLAIM_WRONGFACTION("You don't own this land."), + COMMAND_UNCLAIM_TOUNCLAIM("to unclaim this land"), + COMMAND_UNCLAIM_FORUNCLAIM("for unclaiming this land"), + COMMAND_UNCLAIM_FACTIONUNCLAIMED("%1$s unclaimed some land."), + COMMAND_UNCLAIM_DESCRIPTION("Unclaim the land where you are standing"), + + COMMAND_UNCLAIMALL_TOUNCLAIM("to unclaim all cartel land"), + COMMAND_UNCLAIMALL_FORUNCLAIM("for unclaiming all cartel land"), + COMMAND_UNCLAIMALL_UNCLAIMED("%1$s unclaimed ALL of your cartel's land."), + COMMAND_UNCLAIMALL_LOG("%1$s unclaimed everything for the cartel: %2$s"), + COMMAND_UNCLAIMALL_DESCRIPTION("Unclaim all of your cartels land"), + + COMMAND_VERSION_VERSION("You are running %1$s"), + COMMAND_VERSION_DESCRIPTION("Show plugin and translation version information"), + + COMMAND_WARUNCLAIMALL_DESCRIPTION("Unclaim all warzone land"), + COMMAND_WARUNCLAIMALL_SUCCESS("You unclaimed ALL war zone land."), + COMMAND_WARUNCLAIMALL_LOG("%1$s unclaimed all war zones."), + + /** + * Leaving - This is accessed through a command, and so it MAY need a COMMAND_* slug :s + */ + LEAVE_PASSADMIN("You must give the boss role to someone else first."), + LEAVE_NEGATIVEPOWER("You cannot leave until your power is positive."), + LEAVE_TOLEAVE("to leave your cartel."), + LEAVE_FORLEAVE("for leaving your cartel."), + LEAVE_LEFT("%s left cartel %s."), + LEAVE_DISBANDED("%s was disbanded."), + LEAVE_DISBANDEDLOG("The cartel %s (%s) was disbanded due to the last player (%s) leaving."), + LEAVE_DESCRIPTION("Leave your cartel"), + + /** + * Claiming - Same as above basically. No COMMAND_* because it's not in a command class, but... + */ + CLAIM_PROTECTED("This land is protected"), + CLAIM_DISABLED("Sorry, this world has land claiming disabled."), + CLAIM_CANTCLAIM("You can't claim land for %s."), + CLAIM_ALREADYOWN("%s already own this land."), + CLAIM_MUSTBE("You must be %s to claim land."), + CLAIM_MEMBERS("Cartels must have at least %s members to claim land."), + CLAIM_SAFEZONE("You can not claim a Safe Zone."), + CLAIM_WARZONE("You can not claim a War Zone."), + CLAIM_POWER("You can't claim more land! You need more power!"), + CLAIM_LIMIT("Limit reached. You can't claim more land!"), + CLAIM_ALLY("You can't claim the land of your allies."), + CLAIM_CONTIGIOUS("You can only claim additional land which is connected to your first claim or controlled by another cartel!"), + CLAIM_FACTIONCONTIGUOUS("You can only claim additional land which is connected to your first claim!"), + CLAIM_PEACEFUL("%s owns this land. Your cartel is peaceful, so you cannot claim land from other cartels."), + CLAIM_PEACEFULTARGET("%s owns this land, and is a peaceful cartel. You cannot claim land from them."), + CLAIM_THISISSPARTA("%s owns this land and is strong enough to keep it."), + CLAIM_BORDER("You must start claiming land at the border of the territory."), + CLAIM_TOCLAIM("to claim this land"), + CLAIM_FORCLAIM("for claiming this land"), + CLAIM_TOOVERCLAIM("to overclaim this land"), + CLAIM_FOROVERCLAIM("for over claiming this land"), + CLAIM_CLAIMED("%s claimed land for %s from %s."), + CLAIM_CLAIMEDLOG("%s claimed land at (%s) for the cartel: %s"), + CLAIM_OVERCLAIM_DISABLED("Over claiming is disabled on this server."), + CLAIM_TOOCLOSETOOTHERFACTION("Your claim is too close to another Cartel. Buffer required is %d"), + CLAIM_OUTSIDEWORLDBORDER("Your claim is outside the border."), + CLAIM_OUTSIDEBORDERBUFFER("Your claim is outside the border. %d chunks away world edge required."), + /** + * More generic, or less easily categorisable translations, which may apply to more than one class + */ + GENERIC_YOU("you"), + GENERIC_YOURFACTION("your cartel"), + GENERIC_NOPERMISSION("You don't have permission to %1$s."), + GENERIC_DOTHAT("do that"), //Ugh nuke this from high orbit + GENERIC_NOPLAYERMATCH("No player match found for \"

%1$s\"."), + GENERIC_NOPLAYERFOUND("No player \"

%1$s\" could not be found."), + GENERIC_ARGS_TOOFEW("Too few arguments. Use like this:"), + GENERIC_ARGS_TOOMANY("Strange argument \"

%1$s\". Use the command like this:"), + GENERIC_DEFAULTDESCRIPTION("Default cartel description :("), + GENERIC_OWNERS("Owner(s): %1$s"), + GENERIC_PUBLICLAND("Public cartel land."), + GENERIC_FACTIONLESS("cartelless"), + GENERIC_SERVERADMIN("A server admin"), + GENERIC_DISABLED("disabled"), + GENERIC_ENABLED("enabled"), + GENERIC_INFINITY("∞"), + GENERIC_CONSOLEONLY("This command cannot be run as a player."), + GENERIC_PLAYERONLY("This command can only be used by ingame players."), + GENERIC_ASKYOURLEADER(" Ask your boss to:"), + GENERIC_YOUSHOULD("You should:"), + GENERIC_YOUMAYWANT("You may want to: "), + GENERIC_TRANSLATION_VERSION("Translation: %1$s(%2$s,%3$s) State: %4$s"), + GENERIC_TRANSLATION_CONTRIBUTORS("Translation contributors: %1$s"), + GENERIC_TRANSLATION_RESPONSIBLE("Responsible for translation: %1$s"), + GENERIC_FACTIONTAG_TOOSHORT("The cartel tag can't be shorter than %1$s chars."), + GENERIC_FACTIONTAG_TOOLONG("The cartel tag can't be longer than %s chars."), + GENERIC_FACTIONTAG_ALPHANUMERIC("Cartel tag must be alphanumeric. \"%s\" is not allowed."), + GENERIC_PLACEHOLDER(""), + + /** + * ASCII compass (for chat map) + */ + COMPASS_SHORT_NORTH("N"), + COMPASS_SHORT_EAST("E"), + COMPASS_SHORT_SOUTH("S"), + COMPASS_SHORT_WEST("W"), + + /** + * Chat modes + */ + CHAT_FACTION("cartel chat"), + CHAT_ALLIANCE("alliance chat"), + CHAT_TRUCE("truce chat"), + CHAT_PUBLIC("public chat"), + + /** + * Economy stuff + */ + + ECON_OFF("no %s"), // no balance, no value, no refund, etc + + /** + * Relations + */ + RELATION_MEMBER_SINGULAR("member"), + RELATION_MEMBER_PLURAL("members"), + RELATION_ALLY_SINGULAR("ally"), + RELATION_ALLY_PLURAL("allies"), + RELATION_TRUCE_SINGULAR("truce"), + RELATION_TRUCE_PLURAL("truces"), + RELATION_NEUTRAL_SINGULAR("neutral"), + RELATION_NEUTRAL_PLURAL("neutrals"), + RELATION_ENEMY_SINGULAR("enemy"), + RELATION_ENEMY_PLURAL("enemies"), + + /** + * Roles + */ + ROLE_ADMIN("boss"), + ROLE_MODERATOR("underbos"), + ROLE_NORMAL("goon"), + + /** + * Region types. + */ + REGION_SAFEZONE("safezone"), + REGION_WARZONE("warzone"), + REGION_WILDERNESS("wilderness"), + + REGION_PEACEFUL("peaceful territory"), + /** + * In the player and entity listeners + */ + PLAYER_CANTHURT("You may not harm other players in %s"), + PLAYER_SAFEAUTO("This land is now a safe zone."), + PLAYER_WARAUTO("This land is now a war zone."), + PLAYER_OUCH("Ouch, that is starting to hurt. You should give it a rest."), + PLAYER_USE_WILDERNESS("You can't use %s in the wilderness."), + PLAYER_USE_SAFEZONE("You can't use %s in a safe zone."), + PLAYER_USE_WARZONE("You can't use %s in a war zone."), + PLAYER_USE_TERRITORY("You can't %s in the territory of %s."), + PLAYER_USE_OWNED("You can't use %s in this territory, it is owned by: %s."), + PLAYER_COMMAND_WARZONE("You can't use the command '%s' in warzone."), + PLAYER_COMMAND_NEUTRAL("You can't use the command '%s' in neutral territory."), + PLAYER_COMMAND_ENEMY("You can't use the command '%s' in enemy territory."), + PLAYER_COMMAND_PERMANENT("You can't use the command '%s' because you are in a permanent cartel."), + PLAYER_COMMAND_ALLY("You can't use the command '%s' in ally territory."), + PLAYER_COMMAND_WILDERNESS("You can't use the command '%s' in the wilderness."), + + PLAYER_POWER_NOLOSS_PEACEFUL("You didn't lose any power since you are in a peaceful cartel."), + PLAYER_POWER_NOLOSS_WORLD("You didn't lose any power due to the world you died in."), + PLAYER_POWER_NOLOSS_WILDERNESS("You didn't lose any power since you were in the wilderness."), + PLAYER_POWER_NOLOSS_WARZONE("You didn't lose any power since you were in a war zone."), + PLAYER_POWER_LOSS_WARZONE("The world you are in has power loss normally disabled, but you still lost power since you were in a war zone.\nYour power is now %d / %d"), + PLAYER_POWER_NOW("Your power is now %d / %d"), + + PLAYER_PVP_LOGIN("You can't hurt other players for %d seconds after logging in."), + PLAYER_PVP_REQUIREFACTION("You can't hurt other players until you join a cartel."), + PLAYER_PVP_FACTIONLESS("You can't hurt players who are not currently in a cartel."), + PLAYER_PVP_PEACEFUL("Peaceful players cannot participate in combat."), + PLAYER_PVP_NEUTRAL("You can't hurt neutral cartels. Declare them as an enemy."), + PLAYER_PVP_CANTHURT("You can't hurt %s."), + + PLAYER_PVP_NEUTRALFAIL("You can't hurt %s in their own territory unless you declare them as an enemy."), + PLAYER_PVP_TRIED("%s tried to hurt you."), + + /** + * Strings lying around in other bits of the plugins + */ + NOPAGES("Sorry. No Pages available."), + INVALIDPAGE("Invalid page. Must be between 1 and %1$d"), + + /** + * The ones here before I started messing around with this + */ + TITLE("title", "&bCartels &0|&r"), + WILDERNESS("wilderness", "&2Wilderness"), + WILDERNESS_DESCRIPTION("wilderness-description", ""), + WARZONE("warzone", "&4Warzone"), + WARZONE_DESCRIPTION("warzone-description", "Not the safest place to be."), + SAFEZONE("safezone", "&6Safezone"), + SAFEZONE_DESCRIPTION("safezone-description", "Free from pvp and monsters."), + TOGGLE_SB("toggle-sb", "You now have scoreboards set to {value}"), + FACTION_LEAVE("faction-leave", "Leaving %1$s, Entering %2$s"), + DEFAULT_PREFIX("default-prefix", "{relationcolor}[{cartel}] &r"), + FACTION_LOGIN("faction-login", "&e%1$s &9logged in."), + FACTION_LOGOUT("faction-logout", "&e%1$s &9logged out.."), + NOFACTION_PREFIX("nofactions-prefix", "&6[&a4-&6]&r"), + DATE_FORMAT("date-format", "MM/d/yy h:ma"), // 3/31/15 07:49AM + + /** + * Raidable is used in multiple places. Allow more than just true/false. + */ + RAIDABLE_TRUE("raidable-true", "true"), + RAIDABLE_FALSE("raidable-false", "false"), + /** + * Warmups + */ + WARMUPS_NOTIFY_TELEPORT("&eYou will teleport to &d%1$s &ein &d%2$d &eseconds."), + WARMUPS_ALREADY("&cYou are already warming up."), + WARMUPS_CANCELLED("&cYou have cancelled your warmup."); + + private String path; + private String def; + private static YamlConfiguration LANG; + public static SimpleDateFormat sdf; + + /** + * Lang enum constructor. + * + * @param path The string path. + * @param start The default string. + */ + TL(String path, String start) { + this.path = path; + this.def = start; + } + + /** + * Lang enum constructor. Use this when your desired path simply exchanges '_' for '.' + * + * @param start The default string. + */ + TL(String start) { + this.path = this.name().replace('_', '.'); + if (this.path.startsWith(".")) { + path = "root" + path; + } + this.def = start; + } + + /** + * Set the {@code YamlConfiguration} to use. + * + * @param config The config to set. + */ + public static void setFile(YamlConfiguration config) { + LANG = config; + sdf = new SimpleDateFormat(DATE_FORMAT.toString()); + } + + @Override + public String toString() { + return this == TITLE ? ChatColor.translateAlternateColorCodes('&', LANG.getString(this.path, def)) + " " : ChatColor.translateAlternateColorCodes('&', LANG.getString(this.path, def)); + } + + public String format(Object... args) { + return String.format(toString(), args); + } + + /** + * Get the default value of the path. + * + * @return The default value of the path. + */ + public String getDefault() { + return this.def; + } + + /** + * Get the path to the string. + * + * @return The path to the string. + */ + public String getPath() { + return this.path; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/util/TagReplacer.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/util/TagReplacer.java new file mode 100644 index 0000000..ace0c8a --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/util/TagReplacer.java @@ -0,0 +1,280 @@ +package com.massivecraft.factions.zcore.util; + +import com.massivecraft.factions.*; +import com.massivecraft.factions.integration.Econ; +import com.massivecraft.factions.struct.Relation; +import org.apache.commons.lang.time.DurationFormatUtils; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +/** + * Link between config and in-game messages
Changes based on faction / player
Interfaces the config lists with + * {} variables to plugin + */ +public enum TagReplacer { + + /** + * Fancy variables, used by f show + */ + ALLIES_LIST(TagType.FANCY, "{allies-list}"), + ONLINE_LIST(TagType.FANCY, "{online-list}"), + ENEMIES_LIST(TagType.FANCY, "{enemies-list}"), + OFFLINE_LIST(TagType.FANCY, "{offline-list}"), + + /** + * Player variables, require a player + */ + PLAYER_GROUP(TagType.PLAYER, "{group}"), + LAST_SEEN(TagType.PLAYER, "{lastSeen}"), + PLAYER_BALANCE(TagType.PLAYER, "{balance}"), + PLAYER_POWER(TagType.PLAYER, "{player-power}"), + PLAYER_MAXPOWER(TagType.PLAYER, "{player-maxpower}"), + PLAYER_KILLS(TagType.PLAYER, "{player-kills}"), + PLAYER_DEATHS(TagType.PLAYER, "{player-deaths}"), + + /** + * Faction variables, require at least a player + */ + HOME_X(TagType.FACTION, "{x}"), + HOME_Y(TagType.FACTION, "{y}"), + HOME_Z(TagType.FACTION, "{z}"), + CHUNKS(TagType.FACTION, "{chunks}"), + WARPS(TagType.FACTION, "{warps}"), + HEADER(TagType.FACTION, "{header}"), + POWER(TagType.FACTION, "{power}"), + MAX_POWER(TagType.FACTION, "{maxPower}"), + POWER_BOOST(TagType.FACTION, "{power-boost}"), + LEADER(TagType.FACTION, "{leader}"), + JOINING(TagType.FACTION, "{joining}"), + FACTION(TagType.FACTION, "{faction}"), + PLAYER_NAME(TagType.FACTION, "{name}"), + HOME_WORLD(TagType.FACTION, "{world}"), + RAIDABLE(TagType.FACTION, "{raidable}"), + PEACEFUL(TagType.FACTION, "{peaceful}"), + PERMANENT(TagType.FACTION, "permanent"), // no braces needed + TIME_LEFT(TagType.FACTION, "{time-left}"), + LAND_VALUE(TagType.FACTION, "{land-value}"), + DESCRIPTION(TagType.FACTION, "{description}"), + CREATE_DATE(TagType.FACTION, "{create-date}"), + LAND_REFUND(TagType.FACTION, "{land-refund}"), + BANK_BALANCE(TagType.FACTION, "{faction-balance}"), + ALLIES_COUNT(TagType.FACTION, "{allies}"), + ENEMIES_COUNT(TagType.FACTION, "{enemies}"), + ONLINE_COUNT(TagType.FACTION, "{online}"), + OFFLINE_COUNT(TagType.FACTION, "{offline}"), + FACTION_SIZE(TagType.FACTION, "{members}"), + FACTION_KILLS(TagType.FACTION, "{faction-kills}"), + FACTION_DEATHS(TagType.FACTION, "{faction-deaths}"), + FACTION_STASH(TagType.FACTION, "{stash}"), + + /** + * General variables, require no faction or player + */ + MAX_WARPS(TagType.GENERAL, "{max-warps}"), + MAX_ALLIES(TagType.GENERAL, "{max-allies}"), + MAX_ENEMIES(TagType.GENERAL, "{max-enemies}"), + FACTIONLESS(TagType.GENERAL, "{factionless}"), + TOTAL_ONLINE(TagType.GENERAL, "{total-online}"); + + private TagType type; + private String tag; + + protected enum TagType { + FANCY(0), PLAYER(1), FACTION(2), GENERAL(3); + public int id; + + TagType(int id) { + this.id = id; + } + } + + TagReplacer(TagType type, String tag) { + this.type = type; + this.tag = tag; + } + + /** + * Protected access to this generic server related variable + * + * @return value for this generic server related variable
+ */ + protected String getValue() { + switch (this) { + case TOTAL_ONLINE: + return String.valueOf(Bukkit.getOnlinePlayers().size()); + case FACTIONLESS: + return String.valueOf(Factions.getInstance().getNone().getFPlayersWhereOnline(true).size()); + case MAX_ALLIES: + if (P.p.getConfig().getBoolean("max-relations.enabled", true)) { + return String.valueOf(P.p.getConfig().getInt("max-relations.ally", 10)); + } + return TL.GENERIC_INFINITY.toString(); + case MAX_ENEMIES: + if (P.p.getConfig().getBoolean("max-relations.enabled", true)) { + return String.valueOf(P.p.getConfig().getInt("max-relations.enemy", 10)); + } + return TL.GENERIC_INFINITY.toString(); + case MAX_WARPS: + return String.valueOf(P.p.getConfig().getInt("max-warps", 5)); + } + return null; + } + + /** + * Gets the value for this (as in the instance this is called from) variable! + * + * @param fac Target faction + * @param fp Target player (can be null) + * + * @return the value for this enum! + */ + protected String getValue(Faction fac, FPlayer fp) { + if (this.type == TagType.GENERAL) { + return getValue(); + } + + boolean minimal = P.p.getConfig().getBoolean("minimal-show", false); + + if (fp != null) { + switch (this) { + case HEADER: + return P.p.txt.titleize(fac.getTag(fp)); + case PLAYER_NAME: + return fp.getName(); + case FACTION: + return !fac.isWilderness() ? fac.getTag(fp) : TL.GENERIC_FACTIONLESS.toString(); + case LAST_SEEN: + String humanized = DurationFormatUtils.formatDurationWords(System.currentTimeMillis() - fp.getLastLoginTime(), true, true) + TL.COMMAND_STATUS_AGOSUFFIX; + return fp.isOnline() ? ChatColor.GREEN + TL.COMMAND_STATUS_ONLINE.toString() : (System.currentTimeMillis() - fp.getLastLoginTime() < 432000000 ? ChatColor.YELLOW + humanized : ChatColor.RED + humanized); + case PLAYER_GROUP: + return P.p.getPrimaryGroup(Bukkit.getOfflinePlayer(UUID.fromString(fp.getId()))); + case PLAYER_BALANCE: + return Econ.isSetup() ? Econ.getFriendlyBalance(fp) : TL.ECON_OFF.format("balance"); + case PLAYER_POWER: + return String.valueOf(fp.getPowerRounded()); + case PLAYER_MAXPOWER: + return String.valueOf(fp.getPowerMaxRounded()); + case PLAYER_KILLS: + return String.valueOf(fp.getKills()); + case PLAYER_DEATHS: + return String.valueOf(fp.getDeaths()); + } + } + switch (this) { + case DESCRIPTION: + return fac.getDescription(); + case FACTION: + return fac.getTag(); + case JOINING: + return (fac.getOpen() ? TL.COMMAND_SHOW_UNINVITED.toString() : TL.COMMAND_SHOW_INVITATION.toString()); + case PEACEFUL: + return fac.isPeaceful() ? Conf.colorNeutral + TL.COMMAND_SHOW_PEACEFUL.toString() : ""; + case PERMANENT: + return fac.isPermanent() ? "permanent" : "{notPermanent}"; + case CHUNKS: + return String.valueOf(fac.getLandRounded()); + case POWER: + return String.valueOf(fac.getPowerRounded()); + case MAX_POWER: + return String.valueOf(fac.getPowerMaxRounded()); + case POWER_BOOST: + double powerBoost = fac.getPowerBoost(); + return (powerBoost == 0.0) ? "" : (powerBoost > 0.0 ? TL.COMMAND_SHOW_BONUS.toString() : TL.COMMAND_SHOW_PENALTY.toString() + powerBoost + ")"); + case LEADER: + FPlayer fAdmin = fac.getFPlayerAdmin(); + return fAdmin == null ? "Server" : fAdmin.getName().substring(0, fAdmin.getName().length() > 14 ? 13 : fAdmin.getName().length()); + case WARPS: + return String.valueOf(fac.getWarps().size()); + case CREATE_DATE: + return TL.sdf.format(fac.getFoundedDate()); + case RAIDABLE: + boolean raid = P.p.getConfig().getBoolean("hcf.raidable", false) && fac.getLandRounded() >= fac.getPowerRounded(); + return raid ? TL.RAIDABLE_TRUE.toString() : TL.RAIDABLE_FALSE.toString(); + case HOME_WORLD: + return fac.hasHome() ? fac.getHome().getWorld().getName() : minimal ? null : "{ig}"; + case HOME_X: + return fac.hasHome() ? String.valueOf(fac.getHome().getBlockX()) : minimal ? null : "{ig}"; + case HOME_Y: + return fac.hasHome() ? String.valueOf(fac.getHome().getBlockY()) : minimal ? null : "{ig}"; + case HOME_Z: + return fac.hasHome() ? String.valueOf(fac.getHome().getBlockZ()) : minimal ? null : "{ig}"; + case LAND_VALUE: + return Econ.shouldBeUsed() ? Econ.moneyString(Econ.calculateTotalLandValue(fac.getLandRounded())) : minimal ? null : TL.ECON_OFF.format("value"); + case LAND_REFUND: + return Econ.shouldBeUsed() ? Econ.moneyString(Econ.calculateTotalLandRefund(fac.getLandRounded())) : minimal ? null : TL.ECON_OFF.format("refund"); + case BANK_BALANCE: + if (Econ.shouldBeUsed()) { + return Conf.bankEnabled ? Econ.moneyString(Econ.getBalance(fac.getAccountId())) : minimal ? null : TL.ECON_OFF.format("balance"); + } + return minimal ? null : TL.ECON_OFF.format("balance"); + case ALLIES_COUNT: + return String.valueOf(fac.getRelationCount(Relation.ALLY)); + case ENEMIES_COUNT: + return String.valueOf(fac.getRelationCount(Relation.ENEMY)); + case ONLINE_COUNT: + return String.valueOf(fac.getOnlinePlayers().size()); + case OFFLINE_COUNT: + return String.valueOf(fac.getFPlayers().size() - fac.getOnlinePlayers().size()); + case FACTION_SIZE: + return String.valueOf(fac.getFPlayers().size()); + case FACTION_KILLS: + return String.valueOf(fac.getKills()); + case FACTION_DEATHS: + return String.valueOf(fac.getDeaths()); + } + return null; + } + + /** + * Returns a list of all the variables we can use for this type
+ * + * @param type the type we want + * + * @return a list of all the variables with this type + */ + protected static List getByType(TagType type) { + List tagReplacers = new ArrayList(); + for (TagReplacer tagReplacer : TagReplacer.values()) { + if (type == TagType.FANCY) { + if (tagReplacer.type == TagType.FANCY) { + tagReplacers.add(tagReplacer); + } + } else if (tagReplacer.type.id >= type.id) { + tagReplacers.add(tagReplacer); + } + } + return tagReplacers; + } + + /** + * @param original raw line with variables + * @param value what to replace var in raw line with + * + * @return the string with the new value + */ + public String replace(String original, String value) { + return original.replace(tag, value); + } + + /** + * @param toSearch raw line with variables + * + * @return if the raw line contains this enums variable + */ + public boolean contains(String toSearch) { + return toSearch.contains(tag); + } + + /** + * Gets the tag associated with this enum that we should replace + * + * @return the {....} variable that is located in config + */ + public String getTag() { + return this.tag; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/util/TagUtil.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/util/TagUtil.java new file mode 100644 index 0000000..b89165d --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/util/TagUtil.java @@ -0,0 +1,236 @@ +package com.massivecraft.factions.zcore.util; + + +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.Factions; +import com.massivecraft.factions.P; +import com.massivecraft.factions.util.MiscUtil; +import mkremins.fanciful.FancyMessage; +import org.bukkit.ChatColor; + +import java.util.ArrayList; +import java.util.List; + +import static com.massivecraft.factions.zcore.util.TagReplacer.TagType; + +public class TagUtil { + + private static final int ARBITRARY_LIMIT = 25000; + + /** + * Replaces all variables in a plain raw line for a faction + * + * @param faction for faction + * @param line raw line from config with variables to replace for + * + * @return clean line + */ + public static String parsePlain(Faction faction, String line) { + for (TagReplacer tagReplacer : TagReplacer.getByType(TagType.FACTION)) { + if (tagReplacer.contains(line)) { + line = tagReplacer.replace(line, tagReplacer.getValue(faction, null)); + } + } + return line; + } + + /** + * Replaces all variables in a plain raw line for a player + * + * @param fplayer for player + * @param line raw line from config with variables to replace for + * + * @return clean line + */ + public static String parsePlain(FPlayer fplayer, String line) { + for (TagReplacer tagReplacer : TagReplacer.getByType(TagType.PLAYER)) { + if (tagReplacer.contains(line)) { + String rep = tagReplacer.getValue(fplayer.getFaction(), fplayer); + if (rep == null) { + rep = ""; // this should work, but it's not a good way to handle whatever is going wrong + } + line = tagReplacer.replace(line, rep); + } + } + return line; + } + + /** + * Replaces all variables in a plain raw line for a faction, using relations from fplayer + * + * @param faction for faction + * @param fplayer from player + * @param line raw line from config with variables to replace for + * + * @return clean line + */ + public static String parsePlain(Faction faction, FPlayer fplayer, String line) { + for (TagReplacer tagReplacer : TagReplacer.getByType(TagType.PLAYER)) { + if (tagReplacer.contains(line)) { + String value = tagReplacer.getValue(faction, fplayer); + if (value != null) { + line = tagReplacer.replace(line, value); + } else { + return null; // minimal show, entire line to be ignored + } + } + } + return line; + } + + /** + * Scan a line and parse the fancy variable into a fancy list + * + * @param faction for faction (viewers faction) + * @param fme for player (viewer) + * @param line fancy message prefix + * + * @return + */ + public static List parseFancy(Faction faction, FPlayer fme, String line) { + for (TagReplacer tagReplacer : TagReplacer.getByType(TagType.FANCY)) { + if (tagReplacer.contains(line)) { + String clean = line.replace(tagReplacer.getTag(), ""); // remove tag + return getFancy(faction, fme, tagReplacer, clean); + } + } + return null; + } + + /** + * Checks if a line has fancy variables + * + * @param line raw line from config with variables + * + * @return if the line has fancy variables + */ + public static boolean hasFancy(String line) { + for (TagReplacer tagReplacer : TagReplacer.getByType(TagType.FANCY)) { + if (tagReplacer.contains(line)) { + return true; + } + } + return false; + } + + /** + * Lets get fancy. + * + * @param target Faction to get relate from + * @param fme Player to relate to + * @param prefix First part of the fancy message + * + * @return list of fancy messages to send + */ + protected static List getFancy(Faction target, FPlayer fme, TagReplacer type, String prefix) { + List fancyMessages = new ArrayList(); + boolean minimal = P.p.getConfig().getBoolean("minimal-show", false); + + switch (type) { + case ALLIES_LIST: + FancyMessage currentAllies = P.p.txt.parseFancy(prefix); + boolean firstAlly = true; + for (Faction otherFaction : Factions.getInstance().getAllFactions()) { + if (otherFaction == target) { + continue; + } + String s = otherFaction.getTag(fme); + if (otherFaction.getRelationTo(target).isAlly()) { + currentAllies.then(firstAlly ? s : ", " + s); + currentAllies.tooltip(tipFaction(otherFaction)).color(fme.getColorTo(otherFaction)); + firstAlly = false; + if (currentAllies.toJSONString().length() > ARBITRARY_LIMIT) { + fancyMessages.add(currentAllies); + currentAllies = new FancyMessage(""); + } + } + } + fancyMessages.add(currentAllies); + return firstAlly && minimal ? null : fancyMessages; // we must return here and not outside the switch + case ENEMIES_LIST: + FancyMessage currentEnemies = P.p.txt.parseFancy(prefix); + boolean firstEnemy = true; + for (Faction otherFaction : Factions.getInstance().getAllFactions()) { + if (otherFaction == target) { + continue; + } + String s = otherFaction.getTag(fme); + if (otherFaction.getRelationTo(target).isEnemy()) { + currentEnemies.then(firstEnemy ? s : ", " + s); + currentEnemies.tooltip(tipFaction(otherFaction)).color(fme.getColorTo(otherFaction)); + firstEnemy = false; + if (currentEnemies.toJSONString().length() > ARBITRARY_LIMIT) { + fancyMessages.add(currentEnemies); + currentEnemies = new FancyMessage(""); + } + } + } + fancyMessages.add(currentEnemies); + return firstEnemy && minimal ? null : fancyMessages; // we must return here and not outside the switch + case ONLINE_LIST: + FancyMessage currentOnline = P.p.txt.parseFancy(prefix); + boolean firstOnline = true; + for (FPlayer p : MiscUtil.rankOrder(target.getFPlayersWhereOnline(true))) { + String name = p.getNameAndTitle(); + currentOnline.then(firstOnline ? name : ", " + name); + currentOnline.tooltip(tipPlayer(p)).color(fme.getColorTo(p)); + firstOnline = false; + if (currentOnline.toJSONString().length() > ARBITRARY_LIMIT) { + fancyMessages.add(currentOnline); + currentOnline = new FancyMessage(""); + } + } + fancyMessages.add(currentOnline); + return firstOnline && minimal ? null : fancyMessages; // we must return here and not outside the switch + case OFFLINE_LIST: + FancyMessage currentOffline = P.p.txt.parseFancy(prefix); + boolean firstOffline = true; + for (FPlayer p : MiscUtil.rankOrder(target.getFPlayers())) { + String name = p.getNameAndTitle(); + if (!p.isOnline()) { + currentOffline.then(firstOffline ? name : ", " + name); + currentOffline.tooltip(tipPlayer(p)).color(fme.getColorTo(p)); + firstOffline = false; + if (currentOffline.toJSONString().length() > ARBITRARY_LIMIT) { + fancyMessages.add(currentOffline); + currentOffline = new FancyMessage(""); + } + } + } + fancyMessages.add(currentOffline); + return firstOffline && minimal ? null : fancyMessages; // we must return here and not outside the switch + } + return null; + } + + /** + * Parses tooltip variables from config
Supports variables for factions only (type 2) + * + * @param faction faction to tooltip for + * + * @return list of tooltips for a fancy message + */ + private static List tipFaction(Faction faction) { + List lines = new ArrayList(); + for (String line : P.p.getConfig().getStringList("tooltips.list")) { + lines.add(ChatColor.translateAlternateColorCodes('&', TagUtil.parsePlain(faction, line))); + } + return lines; + } + + /** + * Parses tooltip variables from config
Supports variables for players and factions (types 1 and 2) + * + * @param fplayer player to tooltip for + * + * @return list of tooltips for a fancy message + */ + private static List tipPlayer(FPlayer fplayer) { + List lines = new ArrayList(); + for (String line : P.p.getConfig().getStringList("tooltips.show")) { + lines.add(ChatColor.translateAlternateColorCodes('&', TagUtil.parsePlain(fplayer, line))); + } + return lines; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/util/TextUtil.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/util/TextUtil.java new file mode 100644 index 0000000..577ebcc --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/util/TextUtil.java @@ -0,0 +1,242 @@ +package com.massivecraft.factions.zcore.util; + +import mkremins.fanciful.FancyMessage; +import org.bukkit.ChatColor; +import org.bukkit.Material; + +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class TextUtil { + + public Map tags; + + public TextUtil() { + this.tags = new HashMap(); + } + + // -------------------------------------------- // + // Top-level parsing functions. + // -------------------------------------------- // + + public String parse(String str, Object... args) { + return String.format(this.parse(str), args); + } + + public String parse(String str) { + return this.parseTags(parseColor(str)); + } + + // -------------------------------------------- // + // CoreTag parsing + // -------------------------------------------- // + + public String parseTags(String str) { + return replaceTags(str, this.tags); + } + + public static final transient Pattern patternTag = Pattern.compile("<([a-zA-Z0-9_]*)>"); + + public static String replaceTags(String str, Map tags) { + StringBuffer ret = new StringBuffer(); + Matcher matcher = patternTag.matcher(str); + while (matcher.find()) { + String tag = matcher.group(1); + String repl = tags.get(tag); + if (repl == null) { + matcher.appendReplacement(ret, "<" + tag + ">"); + } else { + matcher.appendReplacement(ret, repl); + } + } + matcher.appendTail(ret); + return ret.toString(); + } + + // -------------------------------------------- // + // Fancy parsing + // -------------------------------------------- // + + public FancyMessage parseFancy(String prefix) { + return toFancy(parse(prefix)); + } + + public static FancyMessage toFancy(String first) { + String text = ""; + FancyMessage message = new FancyMessage(text); + ChatColor color = null; + char[] chars = first.toCharArray(); + + for (int i = 0; i < chars.length; i++) { + if (chars[i] == '§') { + if (color != null) { + if (color.isColor()) { + message.then(text).color(color); + } else { + message.then(text).style(color); + } + text = ""; + color = ChatColor.getByChar(chars[i + 1]); + } else { + color = ChatColor.getByChar(chars[i + 1]); + } + i++; // skip color char + } else { + text += chars[i]; + } + } + if (text.length() > 0) { + if (color != null) { + if (color.isColor()) { + message.then(text).color(color); + } else { + message.then(text).style(color); + } + } else { + message.text(text); + } + } + return message; + } + + // -------------------------------------------- // + // Color parsing + // -------------------------------------------- // + + public static String parseColor(String string) { + string = parseColorAmp(string); + string = parseColorAcc(string); + string = parseColorTags(string); + return ChatColor.translateAlternateColorCodes('&', string); + } + + public static String parseColorAmp(String string) { + string = string.replaceAll("(§([a-z0-9]))", "\u00A7$2"); + string = string.replaceAll("(&([a-z0-9]))", "\u00A7$2"); + string = string.replace("&&", "&"); + return string; + } + + public static String parseColorAcc(String string) { + return string.replace("`e", "").replace("`r", ChatColor.RED.toString()).replace("`R", ChatColor.DARK_RED.toString()).replace("`y", ChatColor.YELLOW.toString()).replace("`Y", ChatColor.GOLD.toString()).replace("`g", ChatColor.GREEN.toString()).replace("`G", ChatColor.DARK_GREEN.toString()).replace("`a", ChatColor.AQUA.toString()).replace("`A", ChatColor.DARK_AQUA.toString()).replace("`b", ChatColor.BLUE.toString()).replace("`B", ChatColor.DARK_BLUE.toString()).replace("`p", ChatColor.LIGHT_PURPLE.toString()).replace("`P", ChatColor.DARK_PURPLE.toString()).replace("`k", ChatColor.BLACK.toString()).replace("`s", ChatColor.GRAY.toString()).replace("`S", ChatColor.DARK_GRAY.toString()).replace("`w", ChatColor.WHITE.toString()); + } + + public static String parseColorTags(String string) { + return string.replace("", "").replace("", "\u00A70").replace("", "\u00A71").replace("", "\u00A72").replace("", "\u00A73").replace("", "\u00A74").replace("", "\u00A75").replace("", "\u00A76").replace("", "\u00A77").replace("", "\u00A78").replace("", "\u00A79").replace("", "\u00A7a").replace("", "\u00A7b").replace("", "\u00A7c").replace("", "\u00A7d").replace("", "\u00A7e").replace("", "\u00A7f"); + } + + // -------------------------------------------- // + // Standard utils like UCFirst, implode and repeat. + // -------------------------------------------- // + + public static String upperCaseFirst(String string) { + return string.substring(0, 1).toUpperCase() + string.substring(1); + } + + public static String implode(List list, String glue) { + StringBuilder ret = new StringBuilder(); + for (int i = 0; i < list.size(); i++) { + if (i != 0) { + ret.append(glue); + } + ret.append(list.get(i)); + } + return ret.toString(); + } + + public static String repeat(String s, int times) { + if (times <= 0) { + return ""; + } else { + return s + repeat(s, times - 1); + } + } + + // -------------------------------------------- // + // Material name tools + // -------------------------------------------- // + + public static String getMaterialName(Material material) { + return material.toString().replace('_', ' ').toLowerCase(); + } + + public static String getMaterialName(int materialId) { + return getMaterialName(Material.getMaterial(materialId)); + } + + // -------------------------------------------- // + // Paging and chrome-tools like titleize + // -------------------------------------------- // + + private final static String titleizeLine = repeat("_", 52); + private final static int titleizeBalance = -1; + + public String titleize(String str) { + String center = ".[ " + parseTags("") + str + parseTags("
") + " ]."; + int centerlen = ChatColor.stripColor(center).length(); + int pivot = titleizeLine.length() / 2; + int eatLeft = (centerlen / 2) - titleizeBalance; + int eatRight = (centerlen - eatLeft) + titleizeBalance; + + if (eatLeft < pivot) { + return parseTags("") + titleizeLine.substring(0, pivot - eatLeft) + center + titleizeLine.substring(pivot + eatRight); + } else { + return parseTags("") + center; + } + } + + public ArrayList getPage(List lines, int pageHumanBased, String title) { + ArrayList ret = new ArrayList(); + int pageZeroBased = pageHumanBased - 1; + int pageheight = 9; + int pagecount = (lines.size() / pageheight) + 1; + + ret.add(this.titleize(title + " " + pageHumanBased + "/" + pagecount)); + + if (pagecount == 0) { + ret.add(this.parseTags(TL.NOPAGES.toString())); + return ret; + } else if (pageZeroBased < 0 || pageHumanBased > pagecount) { + ret.add(this.parseTags(TL.INVALIDPAGE.format(pagecount))); + return ret; + } + + int from = pageZeroBased * pageheight; + int to = from + pageheight; + if (to > lines.size()) { + to = lines.size(); + } + + ret.addAll(lines.subList(from, to)); + + return ret; + } + + public static String getBestStartWithCI(Collection candidates, String start) { + String ret = null; + int best = 0; + + start = start.toLowerCase(); + int minlength = start.length(); + for (String candidate : candidates) { + if (candidate.length() < minlength) { + continue; + } + if (!candidate.toLowerCase().startsWith(start)) { + continue; + } + + // The closer to zero the better + int lendiff = candidate.length() - minlength; + if (lendiff == 0) { + return candidate; + } + if (lendiff < best || best == 0) { + best = lendiff; + ret = candidate; + } + } + return ret; + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/util/UUIDFetcher.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/util/UUIDFetcher.java new file mode 100644 index 0000000..e41da56 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/util/UUIDFetcher.java @@ -0,0 +1,100 @@ +package com.massivecraft.factions.zcore.util; + +import com.google.common.collect.ImmutableList; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; + +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.ByteBuffer; +import java.util.*; +import java.util.concurrent.Callable; + +/** + * @author evilmidget38 + */ + +public class UUIDFetcher implements Callable> { + private static final double PROFILES_PER_REQUEST = 100; + private static final String PROFILE_URL = "https://api.mojang.com/profiles/minecraft"; + private final JSONParser jsonParser = new JSONParser(); + private final List names; + private final boolean rateLimiting; + + public UUIDFetcher(List names, boolean rateLimiting) { + this.names = ImmutableList.copyOf(names); + this.rateLimiting = rateLimiting; + } + + public UUIDFetcher(List names) { + this(names, true); + } + + public Map call() throws Exception { + Map uuidMap = new HashMap(); + int requests = (int) Math.ceil(names.size() / PROFILES_PER_REQUEST); + for (int i = 0; i < requests; i++) { + HttpURLConnection connection = createConnection(); + String body = JSONArray.toJSONString(names.subList(i * 100, Math.min((i + 1) * 100, names.size()))); + writeBody(connection, body); + JSONArray array = (JSONArray) jsonParser.parse(new InputStreamReader(connection.getInputStream())); + for (Object profile : array) { + JSONObject jsonProfile = (JSONObject) profile; + String id = (String) jsonProfile.get("id"); + String name = (String) jsonProfile.get("name"); + UUID uuid = UUIDFetcher.getUUID(id); + uuidMap.put(name, uuid); + } + if (rateLimiting && i != requests - 1) { + Thread.sleep(100L); + } + } + return uuidMap; + } + + private static void writeBody(HttpURLConnection connection, String body) throws Exception { + OutputStream stream = connection.getOutputStream(); + stream.write(body.getBytes()); + stream.flush(); + stream.close(); + } + + private static HttpURLConnection createConnection() throws Exception { + URL url = new URL(PROFILE_URL); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("POST"); + connection.setRequestProperty("Content-Type", "application/json"); + connection.setUseCaches(false); + connection.setDoInput(true); + connection.setDoOutput(true); + return connection; + } + + private static UUID getUUID(String id) { + return UUID.fromString(id.substring(0, 8) + "-" + id.substring(8, 12) + "-" + id.substring(12, 16) + "-" + id.substring(16, 20) + "-" + id.substring(20, 32)); + } + + public static byte[] toBytes(UUID uuid) { + ByteBuffer byteBuffer = ByteBuffer.wrap(new byte[16]); + byteBuffer.putLong(uuid.getMostSignificantBits()); + byteBuffer.putLong(uuid.getLeastSignificantBits()); + return byteBuffer.array(); + } + + public static UUID fromBytes(byte[] array) { + if (array.length != 16) { + throw new IllegalArgumentException("Illegal byte array length: " + array.length); + } + ByteBuffer byteBuffer = ByteBuffer.wrap(array); + long mostSignificant = byteBuffer.getLong(); + long leastSignificant = byteBuffer.getLong(); + return new UUID(mostSignificant, leastSignificant); + } + + public static UUID getUUIDOf(String name) throws Exception { + return new UUIDFetcher(Arrays.asList(name)).call().get(name); + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/resources/config.yml b/cartels-master@e4f5c2ecec5/src/main/resources/config.yml new file mode 100644 index 0000000..835eddd --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/resources/config.yml @@ -0,0 +1,355 @@ +# FactionsUUID by drtshock +# Report issues https://github.com/drtshock/Factions/issues?state=open +# Live support http://webchat.esper.net/?channels=factions&prompt=1 + +# Made with love <3 + +# Debug +# Turn this on if you are having issues with something and working on resolving them. +# This will spam your console with information that is useful if you know how to read the source. +# It's suggested that you only turn this on at the direction of a developer. +debug: false + +# Prevent find factions exploit +# This will help limit how many times a player can be sent a map of factions. +# Set this to the cooldown you want, in miliseconds, for a map to be shown to a player. +# If you want to log when a player violates this (only happens on chunk enter so it shouldn't be too spammy), +# set log to true and it will be logged to console as "player tried to show a faction map too soon and triggered exploit blocker." +findfactionsexploit: + cooldown: 2000 # in miliseconds. 2000 = 2 seconds. + log: false + +### Hard Core Settings ### +# Many of the features that are / are to come in this section have been requested by +# people in relation to HCF servers. All settings are set to the normal Factions +# behavior by default. + +# Default Relation allows you to change the default relation for Factions. +# Example usage would be so people can't leave then make a new Faction while Raiding +# in order to be able to execute commands if the default relation is neutral. +# This has always been neutral. +default-relation: "neutral" + +# Portal Creation +# Do you want to limit portal creation? +portals: + limit: false # will disable the below check if set to false + + # What should the minimum relation be to create a portal in territory? + # Goes in the order of: ENEMY, NEUTRAL, ALLY, MEMBER. + # Minimum relation allows that and all listed to the right to create portals. + # Example: put ALLY to allow ALLY and MEMBER to be able to create portals. + minimum-relation: MEMBER # If typed incorrectly, defaults to NEUTRAL. + +### Hard Core Settings ### + +# Warps +# What should be the max amount of warps that a Factoin can set? +max-warps: 5 + +# This is the cost section for warps. +# It will charge them each time the command would be successful. (won't charge on erroneous /f warp attempts). +# You can use decimal places here. +# If enabled is set to false, it will ignore the values. +warp-cost: + enabled: false + setwarp: 5 + delwarp: 5 + warp: 5 + +# Pistons +# Should we disable pistons in Faction territory? This will prevent people from doing something like: +# http://i.gyazo.com/6a1a31222e58a5d60ff341c13f6a8404.gif +disable-pistons-in-territory: false + +# ToolTips +# This section is to configure tooltips for things like /f list +tooltips: + + # List + # This shows up when someone does /f list for the top factions. + # It will not sure up for factionless of course, just actual factions. + # You can use color codes here. + list: + - "&6Boss: &f{leader}" + - "&6Claimed: &f{chunks}" + - "&6Raidable: &f{raidable}" + - "&6Warps: &f{warps}" + - "&6Power: &f{power}/{maxPower}" + - "&6Members: &f{online}/{members}" + + # Show + # This shows up when someone does /f show. + # It adds tooltips to each player in the list here, nothing else. + # {group} will show the players primary group if you have vault installed. + # {balance} will show their balance if you have vault installed. + # {lastSeen} will show human readable info on when the player was last seen, or online. + show: + - "&6Last Seen: &f{lastSeen}" + - "&6Power: &f{power}" + - "&6Rank: &f{group}" + - "&6Balance: &a${player-balance}" + +# Configuration section for Scoreboards +# This will allow you to completely customize how your scoreboards look. +# Make sure that no lines are duplicates of each other otherwise only the first will display. +# Use &0-9a-f for colors and include messages in "quotes" +scoreboard: + +# send faction change message as well when scoreboard is up? + also-send-chat: true +# How long do we want scoreboards to stay if set temporarily. + expiration: 7 + +# FInfo scoreboard is displayed when a player walks into a new Faction's territory. +# Scoreboard disappears after seconds. +# Things to be replaced in this: +# {power} - faction's power. {chunks} - total claimed chunks. {members} - total members. +# {online} - online members. {leader} - faction's leader. {open} - shows either true or false if open. +# {raidable} - true if the faction can be claimed over, otherwise false. +# {warps} - the number of warps that a faction has set. +# The title of the scoreboard will be the Faction's tag and colored according to the relation with the player's Faction. +# Commenting this section out will cause the info to appear in chat as the plugin originally did. + finfo-enabled: false # Default to false to keep original functionality. + finfo: + - "&6Power" + - "{power}" + - "&3Members" + - "{online}/{members}" + - "&4Drug Lord" + - "{leader}" + - "&bTerritory" + - "{chunks}" + +# Default board that will always show up if a player wants it to. +# This can show any arbitrary text or you can use a lot of variables to replace things. +# Replace {name} - player's name. {faction} - player's faction title, factionless if none. +# {totalOnline} - total players on the server. {balance} - player's balance. +# {maxPower} - player's max power. +# {powerBoost} - player's powerboost. + + default-enabled: false # Default to false to keep original functionality. + default-title: "cartels" # Can use any of the values from above but this won't update once it's set (so don't set {balance}). + default-update-interval: 2 # in seconds. + + # This will show faction prefixes colored based on relation on nametags and in the tab. + # The scoreboard needs to be enabled for this to work. + default-prefixes: true + + default: + - "&6Your Cartel" + - "{faction}" + - "&3Your Power" + - "{power}" + - "&aBalance" + - "${stash}" + + factionless-enabled: false + factionless: + - "Make a new Cartel" + - "Use /c create" + +# Configration section for warmups. +# Warmup times are in seconds - if a value of 0 is set, there is no warmup. +warmups: + # Delay for /f home + f-home: 0 + # Delay for /f warp + f-warp: 0 + +###################################################### +#################### HCF Features #################### +###################################################### +# These features were requested as part of Hardcore Factions or something. +# All of them are disabled by default. + +# Max Relation Types +# Limits factions to having a max number of each relation. +# Setting to 0 means none allowed. -1 for disabled. +# This will have no effect on default or existing relations, only when relations are changed. +# It is advised that you set the default relation to -1 so they can always go back to that. +# Otherwise Factions could be stuck with not being able to unenemy other Factions. +max-relations: + enabled: false + ally: 10 + truce: 10 + neutral: -1 + enemy: 10 + +# WorldBorder support +# A buffer of 0 means faction claims can go right up to the border of the world. +# The buffer is in chunks, so 1 as a buffer means an entire chunk of buffer between +# the border of the world and what can be claimed to factions +world-border: + buffer: 0 + +# Raids +# Allow a faction to be raided if they have more land than power. +# This will make claimed territory lose all protections +# allowing factions to open chests, break blocks, etc. if they +# have claimed chunks >= power. +hcf: + raidable: false + + # DTR (death til raidable) will be in /f show if enabled. Configure the message in the lang.yml + dtr: false + + # Should we allow Factions to over claim if they are raidable (above has no effect on this)? + # This has always been true, allowing factions to over claim others. + allow-overclaim: true + + # Power Freeze + # After a player dies, how long should the faction not be able to regen power? + # This resets on each death but does not accumulate. + # Set to 0 for no freeze. Time is in seconds. + powerfreeze: 0 + + # Buffer Zone + # Buffer Zone is an chunk area required between claims of different Factions. + # This is default to 0 and has always been that way. Meaning Factions can have + # claims that border each other. + # If this is set to 3, then Factions need to have 3 chunks between their claim + # and another Faction's claim. + # It's recommended to keep this pretty low as the radius check could be a + # heavy operation if set to a large number. + # If this is set to 0, we won't even bother checking which is how Factions has + # always been. + buffer-zone: 0 + + stuck: + delay: 30 + radius: 10 + +############################################################ +# +------------------------------------------------------+ # +# | Configurable /f show | # +# +------------------------------------------------------+ # +############################################################ + +# You can use any variable here, including fancy messages. Color codes and or tags work fine. +# Lines that arent defined wont be sent (home not set, faction not peaceful / permanent, dtr freeze) +show: + # First line can be {header} for default header, or any string (we recommend &m for smooth lines ;p) + - '{header}' + - 'Description: {description}' + - 'Joining: {joining} {peaceful}' + - 'Land / Power / Maxpower: {chunks}/{power}/{maxPower}' + - 'Founded: {create-date}' + - 'This cartel is permanent, remaining even with no members.' # only shows if faction is permanent + - 'Land value: {land-value} {land-refund}' + - 'Cartel Stash: {stash}' + - 'Allies({allies}/{max-allies}): {allies-list} ' + - 'Online: ({online}/{members}): {online-list}' + - 'Offline: ({offline}/{members}): {offline-list}' + +# For a /f show that does not display fancy messages that are essentially empty, use minimal-show +minimal-show: false + +# Factions that should be exempt from /f show, case sensitive, useful for a +# serverteam faction, since the command shows vanished players otherwise +show-exempt: + - Put_faction_tag_here + +############################################################ +# +------------------------------------------------------+ # +# | Configurable /f list | # +# +------------------------------------------------------+ # +############################################################ + +list: + # You can only use {pagenumber} and {pagecount} in the header + header: '&e&m----------&r&e[ &2Cartel List &9{pagenumber}&e/&9{pagecount} &e]&m----------' + # You can use any variables here + factionless: 'Cartel-less {factionless} online' + # You can use any variable here + entry: '{faction} {online} / {members} online, Land / Power / Maxpower: {chunks}/{power}/{maxPower}' + +############################################################ +# +------------------------------------------------------+ # +# | Configurable /f help | # +# +------------------------------------------------------+ # +############################################################ + +# set to true to use legacy factions help +use-old-help: true + +help: + # You can change the page name to whatever you like + # We use '1' to preserve default functionality of /f help 1 + '1': + - '&e&m----------------------------------------------' + - ' &c&lCartel Help ' + - '&e&m----------------------------------------------' + - '&3/c create &e>> &7Create your own cartel' + - '&3/c who &e>> &7Show cartel info' + - '&3/c tag &e>> &7Change cartel tag' + - '&3/c join &e>> &7Join cartel' + - '&3/c list &e>> &7List all cartel' + - '&e&m--------------&r &2/c help 2 for more &e&m--------------' + '2': + - '&e&m------------------&r&c&l Page 2 &e&m--------------------' + - '&3/c home &e>> &7Teleport to cartel home' + - '&3/c sethome &e>> &7Set your cartel home' + - '&3/c leave &e>> &7Leave your cartel' + - '&3/c invite &e>> &7Invite a player to your cartel' + - '&3/c deinvite &e>> &7Revoke invitation to player' + - '&e&m--------------&r &2/c help 3 for more &e&m--------------' + '3': + - '&e&m------------------&r&c&l Page 3 &e&m--------------------' + - '&3/c claim &e>> &7Claim land' + - '&3/c unclaim &e>> &7Unclaim land' + - '&3/c kick &e>> &7Kick player from your cartel' + - '&3/c mod &e>> &7Set player role in cartel' + - '&3/c chat &e>> &7Switch to cartel chat' + - '&e&m--------------&r &2/c help 4 for more &e&m--------------' + '4': + - '&e&m------------------&r&c&l Page 4 &e&m--------------------' + - '&3/c version &e>> &7Display version information' + - '&e&m--------------&r&2 End of /c help &e&m-----------------' + +############################################################ +# +------------------------------------------------------+ # +# | Big List of variables | # +# +------------------------------------------------------+ # +############################################################ +# Fancy variables. Can only be used in /f show +# - {allies-list} : Lists each faction ally with tooltips +# - {enemies-list} : Lists each faction enemy with tooltips +# - {online-list} : Lists all online members with tooltips +# - {offline-list} : Lists all offline members with tooltips +# Player variables. Can be used in tooltips.show, scoreboards, or /f show +# - {group} : Players group +# - {name} : Players name +# - {lastSeen} : Last time player was seen (if offline), or just 'Online' +# - {balance} : Players balance +# - {player-kills} : # of kills the player has +# - {player-deaths}: # of deaths the player has +# Faction variables. Can be used in tooltips.list, scoreboards, or /f show +# - {header} : Default factions header (ex. /f show) +# - {faction} : Factions tag (if none, uses lang.yml for factionless name) +# - {joining} : How to join this faction +# - {power} : Factions deaths until raidable value +# - {power-boost} : DTR Symbol based on current DTR (max, regen, frozen, raidable) +# - {maxPower} : Factions max deaths until raidable value +# - {chunks} : # of claims faction has (in chunks) +# - {warps} : # of warps faction has +# - {description} : Factions description +# - {create-date} : Date faction was created +# - {leader} : Faction leader +# - {land-value} : Value of all claims +# - {land-refund} : Calculated refund value +# - {allies} : # of allies faction has +# - {enemies} : # of enemies faction has +# - {online} : # of faction members online +# - {offline} : # of faction members offline +# - {members} : # of faction members (includes offline) +# - {faction-balance} : Faction bank balance +# - {world}, {x}, {y}, {z} : Faction home variables. You don't need to use them all. +# - {faction-kills} : # of kills the faction has +# - {faction-deaths}: # of deaths the faction has +# General variables. Can be used anywhere. +# - {total-online} : Total # of players on the server +# - {max-warps} : Max # of warps a faction can set +# - {max-allies} : Max # of allies a faction can have +# - {max-enemies} : Max # of enemies a faction can have +# - {factionless} : Count of all factionless players online \ No newline at end of file diff --git a/cartels-master@e4f5c2ecec5/src/main/resources/lang.yml b/cartels-master@e4f5c2ecec5/src/main/resources/lang.yml new file mode 100644 index 0000000..b889fd3 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/resources/lang.yml @@ -0,0 +1,5 @@ +# Lang file for FactionsUUID by drtshock +# Use & for color codes. +# Made with love <3 + + diff --git a/cartels-master@e4f5c2ecec5/src/main/resources/lang/en_GB.yml b/cartels-master@e4f5c2ecec5/src/main/resources/lang/en_GB.yml new file mode 100644 index 0000000..d69fe60 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/resources/lang/en_GB.yml @@ -0,0 +1,31 @@ +# Lang file for FactionsUUID by drtshock +# Use & for color codes. +# Made with love <3 + +#Slightly different localised variant for UK-style english (Color→Colour, etc) +#It's cut down to the sections that were actually changed. Ie basically nothing. What ho, dear chap! + +root: + AUTHOR: misc + RESPONSIBLE: Korikisulda + LANGUAGE: English + ENCODING: UTF-8 + LOCALE: en_GB + EXTENDS: en_US + REQUIRESUNICODE: 'false' + DEFAULT: 'false' + STATE: complete + LOCAL: + AUTHOR: misc + RESPONSIBLE: Korikisulda + LANGUAGE: English + REGION: UK + STATE: complete +COMMAND: + CONFIG: + COLOURSET: '" colour option set to "' + INVALID: + COLOUR: 'Cannot set "%1$s": "%2$s" is not a valid colour.' + COLLECTION: '"%1$s" is not a data collection type which can be modified with this + command.' + diff --git a/cartels-master@e4f5c2ecec5/src/main/resources/lang/en_US.yml b/cartels-master@e4f5c2ecec5/src/main/resources/lang/en_US.yml new file mode 100644 index 0000000..536816d --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/resources/lang/en_US.yml @@ -0,0 +1,505 @@ +# Lang file for FactionsUUID by drtshock +# Use & for color codes. +# Made with love <3 + + + +root: + AUTHOR: misc + RESPONSIBLE: misc + LANGUAGE: English + ENCODING: UTF-8 + LOCALE: en_US + REQUIRESUNICODE: 'false' + DEFAULT: 'true' + STATE: complete + LOCAL: + AUTHOR: misc + RESPONSIBLE: misc + LANGUAGE: English + REGION: US + STATE: complete +COMMAND: + ADMIN: + NOTMEMBER: '%1$s is not a member in your cartel.' + NOTADMIN: You are not the cartel admin. + TARGETSELF: The target player musn't be yourself. + DEMOTES: You have demoted %1$s from the position of cartel admin. + DEMOTED: You have been demoted from the position of cartel admin by %1$s. + PROMOTES: You have promoted %1$s to the position of cartel admin. + PROMOTED: '%1$s gave %2$s the leadership of %3$s.' + AUTOCLAIM: + ENABLED: Now auto-claiming land for %1$s. + DISABLED: Auto-claiming of land disabled. + REQUIREDRANK: You must be %1$s to claim land. + OTHERFACTION: You can't claim land for %1$s. + AUTOHELP: + HELPFOR: Help for command " + BOOM: + PEACEFULONLY: This command is only usable by cartels which are specifically designated as peaceful. + TOTOGGLE: to toggle explosions + FORTOGGLE: for toggling explosions + ENABLED: '%1$s has %2$s explosions in your cartel''s territory.' + BYPASS: + ENABLE: You have enabled admin bypass mode. You will be able to build or destroy anywhere. + ENABLELOG: ' has ENABLED admin bypass mode.' + DISABLE: You have disabled admin bypass mode. + DISABLELOG: ' has DISABLED admin bypass mode.' + CHAT: + DISABLED: The built in chat chat channels are disabled on this server. + INVALIDMODE: Unrecognised chat mode. Please enter either 'a','f' or 'p' + MODE: + PUBLIC: Public chat mode. + ALLIANCE: Alliance only chat mode. + FACTION: Faction only chat mode. + CHATSPY: + ENABLE: You have enabled chat spying mode. + ENABLELOG: ' has ENABLED chat spying mode.' + DISABLE: You have disabled chat spying mode. + DISABLELOG: ' has DISABLED chat spying mode.' + CLAIM: + INVALIDRADIUS: If you specify a radius, it must be at least 1. + DENIED: You do not have permission to claim in a radius. + CONFIG: + NOEXIST: No configuration setting "%1$s" exists. + SET: + 'TRUE': '" option set to true (enabled).' + 'FALSE': '" option set to false (disabled).' + ADDED: '"%1$s" set: "%2$s" added.' + REMOVED: '"%1$s" set: "%2$s" removed.' + OPTIONSET: '" option set to ' + COLOURSET: '" color option set to "' + INTREQUIRED: 'Cannot set "%1$s": An integer (whole number) value required.' + LONGREQUIRED: 'Cannot set "%1$s": A long integer (whole number) value required.' + DOUBLEREQUIRED: 'Cannot set "%1$s": A double (numeric) value required.' + FLOATREQUIRED: 'Cannot set "%1$s": A float (numeric) value required.' + INVALID: + COLOUR: 'Cannot set "%1$s": "%2$s" is not a valid color.' + COLLECTION: '"%1$s" is not a data collection type which can be modified with + this command.' + MATERIAL: 'Cannot change "%1$s" set: "%2$s" is not a valid material.' + TYPESET: '"%1$s" is not a data type set which can be modified with this command.' + MATERIAL: + ADDED: '"%1$s" set: Material "%2$s" added.' + REMOVED: '"%1$s" set: Material "%2$s" removed.' + LOG: ' (Command was run by %1$s.)' + ERROR: + SETTING: Error setting configuration setting "%1$s" to "%2$s". + MATCHING: Configuration setting "%1$s" couldn't be matched, though it should be... please report this error. + TYPE: '''%1$s'' is of type ''%2$s'', which cannot be modified with this command.' + CREATE: + MUSTLEAVE: You must leave your current cartel first. + INUSE: That tag is already in use. + TOCREATE: to create a new cartel + FORCREATE: for creating a new cartel + ERROR: There was an internal error while trying to create your cartel. Please try again. + CREATED: '%1$s created a new cartel %2$s' + YOUSHOULD: 'You should now: %1$s' + CREATEDLOG: ' created a new cartel: ' + DEINVITE: + CANDEINVITE: 'Players you can deinvite: ' + CLICKTODEINVITE: Click to revoke invite for %1$s + ALREADYMEMBER: '%1$s is already a member of %2$s' + MIGHTWANT: 'You might want to: %1$s' + REVOKED: '%1$s revoked your invitation to %2$s.' + REVOKES: '%1$s revoked %2$s''s invitation.' + DELFWARP: + DELETED: Deleted warp %1$s + INVALID: Couldn't find warp %1$s + TODELETE: to delete warp + FORDELETE: for deleting warp + DESCRIPTION: + CHANGES: 'You have changed the description for %1$s to:' + CHANGED: 'The cartel %1$s changed their description to:' + TOCHANGE: to change cartel description + FORCHANGE: for changing cartel description + DISBAND: + IMMUTABLE: You cannot disband the Wilderness, SafeZone, or WarZone. + MARKEDPERMANENT: This cartel is designated as permanent, so you cannot disband it. + BROADCAST: + YOURS: %1$s disbanded your cartel. + NOTYOURS: %1$s disbanded the cartel %2$s. + HOLDINGS: You have been given the disbanded cartel's bank, totaling %1$s. + FWARP: + CLICKTOWARP: Click to warp! + COMMANDFORMAT: /c warp + WARPED: Warped to %1$s + INVALID: Couldn't find warp %1$s + TOWARP: to warp + FORWARPING: for warping + WARPS: 'Warps: ' + HELP: + '404': This page does not exist + NEXTCREATE: Learn how to create a cartel on the next page. + HOME: 'And don''t forget to set your home:' + BANK: + '1': Your cartel has a bank which is used to pay for certain + '2': things, so it will need to have money deposited into it. + '3': To learn more, use the money command. + PLAYERTITLES: Player titles are just for fun. No rules connected to them. + OWNERSHIP: + '1': Claimed land with ownership set is further protected so + '2': that only the owner(s), cartel admin, and possibly the + '3': cartel moderators have full access. + RELATIONS: + '1': Set the relation you WISH to have with another cartel. + '2': Your default relation with other cartels will be neutral. + '3': If BOTH cartels choose "ally" you will be allies. + '4': If ONE cartel chooses "enemy" you will be enemies. + '5': You can never hurt members or allies. + '6': You can not hurt neutrals in their own territory. + '7': You can always hurt enemies and players without cartel. + '8': '' + '9': Damage from enemies is reduced in your own territory. + '10': When you die you lose power. It is restored over time. + '11': The power of a cartel is the sum of all member power. + '12': The power of a cartel determines how much land it can hold. + '13': You can claim land from cartels with too little power. + PERMISSIONS: + '1': Only cartel members can build and destroy in their own + '2': 'territory. Usage of the following items is also restricted:' + '3': Door, Chest, Furnace, Dispenser, Diode. + '4': '' + '5': Make sure to put pressure plates in front of doors for your + '6': guest visitors. Otherwise they can't get through. You can + '7': also use this to create member only areas. + '8': As dispensers are protected, you can create traps without + '9': worrying about those arrows getting stolen. + ADMIN: + '1': /c claim safezone claim land for the Safe Zone + '2': /c claim warzone claim land for the War Zone + '3': /c autoclaim [safezone|warzone] take a guess + MOAR: + '1': 'Finally some commands for the server admins:' + '2': 'More commands for server admins:' + '3': 'Even more commands for server admins:' + HOME: + DISABLED: Sorry, Cartel homes are disabled on this server. + TELEPORTDISABLED: Sorry, the ability to teleport to Cartel homes is disabled on this server. + NOHOME: 'Your cartel does not have a home. ' + INENEMY: You cannot teleport to your cartel home while in the territory of an enemy cartel. + WRONGWORLD: You cannot teleport to your cartel home while in a different world. + ENEMYNEAR: You cannot teleport to your cartel home while an enemy is within %s blocks of you. + TOTELEPORT: to teleport to your cartel home + FORTELEPORT: for teleporting to your cartel home + INVITE: + TOINVITE: to invite someone + FORINVITE: for inviting someone + CLICKTOJOIN: Click to join! + INVITEDYOU: ' has invited you to join ' + INVITED: '%1$s invited %2$s to your cartel.' + ALREADYMEMBER: '%1$s is already a member of %2$s' + JOIN: + CANNOTFORCE: You do not have permission to move other players into a cartel. + SYSTEMFACTION: Players may only join normal cartels. This is a system cartel. + ALREADYMEMBER: %1$s %2$s already a member of %3$s + ATLIMIT: ' ! The cartel %1$s is at the limit of %2$d members, so %3$s + cannot currently join.' + INOTHERFACTION: %1$s must leave %2$s current cartel first. + NEGATIVEPOWER: %1$s cannot join a cartel with a negative power level. + REQUIRESINVITATION: This cartel requires invitation. + ATTEMPTEDJOIN: '%1$s tried to join your cartel.' + TOJOIN: to join a cartel + FORJOIN: for joining a cartel + SUCCESS: %1$s successfully joined %2$s. + MOVED: %1$s moved you into the cartel %2$s. + JOINED: %1$s joined your cartel. + JOINEDLOG: '%1$s joined the cartel %2$s.' + MOVEDLOG: '%1$s moved the player %2$s into the cartel %3$s.' + KICK: + CANDIDATES: 'Players you can kick: ' + CLICKTOKICK: 'Click to kick ' + SELF: You cannot kick yourself. + NONE: That player is not in a cartel. + NOTMEMBER: '%1$s is not a member of %2$s' + INSUFFICIENTRANK: Your rank is too low to kick this player. + NEGATIVEPOWER: You cannot kick that member until their power is positive. + TOKICK: to kick someone from the cartel + FORKICK: for kicking someone from the cartel + FACTION: '%1$s kicked %2$s from the cartel! :O' + KICKS: You kicked %1$s from the cartel %2$s! + KICKED: '%1$s kicked you from %2$s! :O' + LIST: + FACTIONLIST: 'Cartel List ' + TOLIST: to list the cartels + FORLIST: for listing the cartels + ONLINEFACTIONLESS: 'Online cartelless: ' + LOCK: + LOCKED: Cartels is now locked + UNLOCKED: Cartels in now unlocked + LOGINS: + TOGGLE: 'Set login / logout notifications for Cartel members to: %s' + MAP: + TOSHOW: to show the map + FORSHOW: for showing the map + UPDATE: + ENABLED: Map auto update ENABLED. + DISABLED: Map auto update DISABLED. + MOD: + CANDIDATES: 'Players you can promote: ' + CLICKTOPROMOTE: 'Click to promote ' + NOTMEMBER: '%1$s is not a member in your cartel.' + NOTADMIN: You are not the cartel admin. + SELF: The target player musn't be yourself. + TARGETISADMIN: The target player is a cartel admin. Demote them first. + REVOKES: You have removed moderator status from %1$s. + REVOKED: '%1$s is no longer moderator in your cartel.' + PROMOTES: '%1$s was promoted to moderator in your cartel.' + PROMOTED: You have promoted %1$s to moderator. + MODIFYPOWER: + ADDED: 'Added %1$f power to %2$s. New total rounded power: %3$d' + MONEY: + SHORT: cartel money commands + LONG: The cartel money commands. + MONEYBALANCE: + SHORT: show cartel balance + MONEYDEPOSIT: + SHORT: deposit money + DEPOSITED: '%1$s deposited %2$s in the cartel bank: %3$s' + MONEYTRANSFERFF: + SHORT: transfer f -> f + TRANSFER: '%1$s transferred %2$s from the cartel "%3$s" to the cartel "%4$s"' + MONEYTRANSFERFP: + SHORT: transfer f -> p + TRANSFER: '%1$s transferred %2$s from the cartel "%3$s" to the player "%4$s"' + MONEYTRANSFERPF: + SHORT: transfer p -> f + TRANSFER: '%1$s transferred %2$s from the player "%3$s" to the cartel "%4$s"' + MONEYWITHDRAW: + SHORT: withdraw money + WITHDRAW: '%1$s withdrew %2$s from the cartel bank: %3$s' + OPEN: + TOOPEN: to open or close the cartel + FOROPEN: for opening or closing the cartel + OPEN: open + CLOSED: closed + CHANGES: '%1$s changed the cartel to %2$s.' + CHANGED: The cartel %1$s is now %2$s + OWNER: + DISABLED: Sorry, but owned areas are disabled on this server. + LIMIT: Sorry, but you have reached the server's limit of %1$d owned areas per cartel. + WRONGFACTION: This land is not claimed by your cartel, so you can't set ownership of it. + NOTCLAIMED: This land is not claimed by a cartel. Ownership is not possible. + NOTMEMBER: '%1$s is not a member of this cartel.' + CLEARED: You have cleared ownership for this claimed area. + REMOVED: You have removed ownership of this claimed land from %1$s. + TOSET: to set ownership of claimed land + FORSET: for setting ownership of claimed land + ADDED: You have added %1$s to the owner list for this claimed land. + OWNERLIST: + DISABLED: Sorry, but owned areas are disabled on this server. + WRONGFACTION: This land is not claimed by your cartel. + NOTCLAIMED: This land is not claimed by any cartel, thus no owners. + NONE: No owners are set here; everyone in the cartel has access. + OWNERS: 'Current owner(s) of this land: %1$s' + POWER: + TOSHOW: to show player power info + FORSHOW: for showing player power info + POWER: '%1$s - Power / Maxpower: %2$d / %3$d %4$s' + BONUS: ' (bonus: ' + PENALTY: ' (penalty: ' + POWERBOOST: + HELP: + '1': You must specify "p" or "player" to target a player or "c" or "cartel" to target a cartel. + '2': ex. /c powerboost p SomePlayer 0.5 -or- /c powerboost c SomeCartel -5 + INVALIDNUM: You must specify a valid numeric value for the power bonus/penalty amount. + PLAYER: Player "%1$s" + FACTION: Cartel "%1$s" + BOOST: %1$s now has a power bonus/penalty of %2$d to min and max power levels. + BOOSTLOG: '%1$s has set the power bonus/penalty for %2$s to %3$d.' + RELOAD: + TIME: Reloaded conf.json from disk, took %1$d ms. + SAFEUNCLAIMALL: + SHORT: Unclaim all safezone land + UNCLAIMED: You unclaimed ALL safe zone land. + UNCLAIMEDLOG: '%1$s unclaimed all safe zones.' + SAVEALL: Cartels saved to disk! + SETFWARP: + NOTCLAIMED: You can only set warps in your cartel territory. + LIMIT: Your Cartel already has the max amount of warps set (%1$d). + SET: Set warp %1$s to your location. + TOSET: to set warp + FORSET: for setting warp + SETHOME: + DISABLED: Sorry, Cartel homes are disabled on this server. + NOTCLAIMED: Sorry, your cartel home can only be set inside your own claimed territory. + TOSET: to set the cartel home + FORSET: for setting the cartel home + SET: '%1$s set the home for your cartel. You can now use:' + SETOTHER: You have set the home for the %1$s cartel. + SHOW: + NOFACTION: + SELF: You are not in a cartel + OTHER: That's not a cartel + TOSHOW: to show cartel information + FORSHOW: for showing cartel information + DESCRIPTION: 'Description: %1$s' + PEACEFUL: This cartel is Peaceful + PERMANENT: This cartel is permanent, remaining even with no members. + JOINING: 'Joining: %1$s ' + INVITATION: invitation is required + UNINVITED: no invitation is needed + POWER: 'Land / Power / Maxpower: %1$d/%2$d/%3$d %4$s' + BONUS: ' (bonus: ' + PENALTY: ' (penalty: ' + DEPRECIATED: (%1$s depreciated) + LANDVALUE: 'Total land value: %1$s %2$s' + BANKCONTAINS: 'Bank contains: %1$s' + ALLIES: 'Allies: ' + ENEMIES: 'Enemies: ' + MEMBERSONLINE: 'Members online: ' + MEMBERSOFFLINE: 'Members offline: ' + SHOWINVITES: + PENDING: 'Players with pending invites: ' + CLICKTOREVOKE: Click to revoke invite for %1$s + STATUS: + FORMAT: '%1$s Power: %2$s Last Seen: %3$s' + ONLINE: Online + AGOSUFFIX: ' ago.' + TAG: + TAKEN: That tag is already taken + TOCHANGE: to change the cartel tag + FORCHANGE: for changing the cartel tag + FACTION: '%1$s changed your cartel tag to %2$s' + CHANGED: The cartel %1$s changed their name to %2$s. + TITLE: + TOCHANGE: to change a players title + FORCHANGE: for changing a players title + CHANGED: '%1$s changed a title: %2$s' + UNCLAIM: + SAFEZONE: + SUCCESS: Safe zone was unclaimed. + NOPERM: This is a safe zone. You lack permissions to unclaim. + WARZONE: + SUCCESS: War zone was unclaimed. + NOPERM: This is a war zone. You lack permissions to unclaim. + UNCLAIMED: '%1$s unclaimed some of your land.' + UNCLAIMS: You unclaimed this land. + LOG: '%1$s unclaimed land at (%2$s) from the cartel: %3$s' + WRONGFACTION: You don't own this land. + TOUNCLAIM: to unclaim this land + FORUNCLAIM: for unclaiming this land + FACTIONUNCLAIMED: '%1$s unclaimed some land.' + UNCLAIMALL: + TOUNCLAIM: to unclaim all cartel land + FORUNCLAIM: for unclaiming all cartel land + UNCLAIMED: '%1$s unclaimed ALL of your cartel''s land.' + LOG: '%1$s unclaimed everything for the cartel: %2$s' + VERSION: + VERSION: You are running %1$s + WARUNCLAIMALL: + SHORT: unclaim all warzone land + SUCCESS: You unclaimed ALL war zone land. + LOG: '%1$s unclaimed all war zones.' + RELATIONS: + ALLTHENOPE: Nope! You can't. + MORENOPE: Nope! You can't declare a relation to yourself :) + ALREADYINRELATIONSHIP: You already have that relation wish set with %1$s. + TOMARRY: to change a relation wish + FORMARRY: for changing a relation wish + MUTUAL: Your cartel is now %1$s to %2$s + PEACEFUL: This will have no effect while your cartel is peaceful. + PEACEFULOTHER: This will have no effect while their cartel is peaceful. + PROPOSAL: + '1': '%1$s wishes to be your %2$s' + '2': Type /%1$s %2$s %3$s to accept. + SENT: '%1$s were informed that you wish to be %2$s' +command: + convert: + backend: + running: Already running that backend. + invalid: Invalid backend + help: + invitations: 'You might want to close it and use invitations:' +LEAVE: + PASSADMIN: You must give the admin role to someone else first. + NEGATIVEPOWER: You cannot leave until your power is positive. + TOLEAVE: to leave your cartel. + FORLEAVE: for leaving your cartel. + LEFT: '%s left cartel %s.' + DISBANDED: %s was disbanded. + DISBANDEDLOG: The cartel %s (%s) was disbanded due to the last player (%s) leaving. +CLAIM: + PROTECTED: This land is protected + DISABLED: Sorry, this world has land claiming disabled. + CANTCLAIM: You can't claim land for %s. + ALREADYOWN: '%s already own this land.' + MUSTBE: You must be %s to claim land. + MEMBERS: Cartels must have at least %s members to claim land. + SAFEZONE: You can not claim a Safe Zone. + WARZONE: You can not claim a War Zone. + POWER: You can't claim more land! You need more power! + LIMIT: Limit reached. You can't claim more land! + ALLY: You can't claim the land of your allies. + CONTIGIOUS: You can only claim additional land which is connected to your first claim or controlled by another cartel! + FACTIONCONTIGUOUS: You can only claim additional land which is connected to your first claim! + PEACEFUL: '%s owns this land. Your cartel is peaceful, so you cannot claim land + from other cartels.' + PEACEFULTARGET: '%s owns this land, and is a peaceful cartel. You cannot claim + land from them.' + THISISSPARTA: '%s owns this land and is strong enough to keep it.' + BORDER: You must start claiming land at the border of the territory. + TOCLAIM: to claim this land + FORCLAIM: for claiming this land + CLAIMED: %s claimed land for %s from %s. + CLAIMEDLOG: '%s claimed land at (%s) for the cartel: %s' +GENERIC: + NOPERMISSION: You don't have permission to %1$s. + DOTHAT: do that + NOPLAYERMATCH: No player match found for "

%1$s". + NOPLAYERFOUND: No player "

%1$s" could not be found. + ARGS: + TOOFEW: 'Too few arguments. Use like this:' + TOOMANY: 'Strange argument "

%1$s". Use the command like this:' + OWNERS: 'Owner(s): %1$s' + PUBLICLAND: Public cartel land. + FACTIONLESS: cartelless + SERVERADMIN: A server admin + DISABLED: disabled + ENABLED: enabled + CONSOLEONLY: This command cannot be run as a player. + PLAYERONLY: This command can only be used by ingame players. + ASKYOURLEADER: ' Ask your boss to:' + YOUSHOULD: 'You should:' + YOUMAYWANT: 'You may want to: ' + TRANSLATION: + VERSION: 'Translation: %1$s(%2$s,%3$s) State: %4$s' + CONTRIBUTORS: 'Translation contributors: %1$s' + RESPONSIBLE: 'Responsible for translation: %1$s' + FACTIONTAG: + TOOSHORT: The cartel tag can't be shorter than %1$s chars. + TOOLONG: The cartel tag can't be longer than %s chars. + ALPHANUMERIC: Cartel tag must be alphanumeric. "%s" is not allowed. +COMPASS: + SHORT: + NORTH: N + EAST: E + SOUTH: S + WEST: W +CHAT: + FACTION: cartel chat + ALLIANCE: alliance chat + PUBLIC: public chat +RELATION: + MEMBER: member + ALLY: ally + NEUTRAL: neutral + ENEMY: enemy +NOPAGES: Sorry. No Pages available. +INVALIDPAGE: Invalid page. Must be between 1 and %1$d +title: '&bCartels &0|&r' +wilderness: '&2Wilderness' +wilderness-description: '' +warzone: '&4Warzone' +warzone-description: Not the safest place to be. +safezone: '&6Safezone' +safezone-description: Free from pvp and monsters. +toggle-sb: You now have scoreboards set to {value} +default-prefix: '{relationcolor}[{faction}] &r' +faction-login: '&e%1$s &9logged in.' +faction-logout: '&e%1$s &9logged out..' +WARMUPS: + NOTIFY: + TELEPORT: '&eYou will teleport to &d%1$s &ein &d%2$d &eseconds.' + ALREADY: '&cYou are already warming up.' + CANCELLED: '&cYou have cancelled your warmup.' diff --git a/cartels-master@e4f5c2ecec5/src/main/resources/lang/ja_JP.yml b/cartels-master@e4f5c2ecec5/src/main/resources/lang/ja_JP.yml new file mode 100644 index 0000000..f19fae0 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/resources/lang/ja_JP.yml @@ -0,0 +1,434 @@ +# FactionsUUID「党派・一意な利用者識別子」言語ファイル +# &為に色コード使用 +# 愛で造った〜♥ + +root: + AUTHOR: Korikisulda + RESPONSIBLE: Korikisulda + LANGUAGE: Japanese + ENCODING: UTF-8 + LOCALE: ja_JP + REQUIRESUNICODE: 'true' + DEFAULT: 'false' + STATE: partial + LOCAL: + AUTHOR: エヴェリン雪「korikisulda」 + RESPONSIBLE: 'エヴェリン雪・ツイッター、IRC:「korikisulda」' + LANGUAGE: 日本語 + REGION: 日本 + STATE: 不全 +COMMAND: + ADMIN: + NOTMEMBER: '%sは党派の員になっていませんよ・' + NOTADMIN: アドミンではありません・ + TARGETSELF: 自分はターゲットになれません・ + DEMOTES: 党派アドミンから%sをデモートしました・ + DEMOTED: 党派アドミンから%sはデモートしました・. + PROMOTES: 党派アドミンに%sをプロモートしました + PROMOTED: '%sは%sを%sの党派アドミンにあげりました・' + AUTOCLAIM: + ENABLED: %s為にオート引取っています・ + DISABLED: オート引取っていません・ + REQUIREDRANK: %sになりません・ + OTHERFACTION: %s為に引取れません・. + AUTOHELP: + HELPFOR: ヘルプ・コマンド" + BOOM: + PEACEFULONLY: 安らかじゃない党派は爆発トグルが禁止です・ + TOTOGGLE: 爆発トグルし + FORTOGGLE: 爆発トグルした + ENABLED: '%s は爆発を%sしました' + BYPASS: + ENABLE: アドミンバイパスモードで入っています + ENABLELOG: はアドミンバイパスモードで入っています + DISABLE: アドミンバイパスモードで出た + DISABLELOG: はアドミンバイパスモードで出た + CHAT: + DISABLED: 党派チャットは禁止されました・ + INVALIDMODE: 不正なチャットモード・a,fかpと入力して下さい・ + MODE: + PUBLIC: 只公開チャットモード + ALLIANCE: 只連盟チャットモード + FACTION: 只党派チャットモード + CHATSPY: + ENABLE: チャットスパイモードで入ってします + ENABLELOG: はチャットスパイモードで入ってします + DISABLE: チャットスパイモードで出た + DISABLELOG: はチャットスパイモードで出た + CLAIM: + INVALIDRADIUS: 半径を指定しますなら1以上を指定して下さい・ + DENIED: 半径で引き取る許可がありません・ + CONFIG: + NOEXIST: 設定オプション"%s"はありません・ + SET: + 'TRUE': '"オプションは正に変わりました' + 'FALSE': '"オプションは正じゃなくに変わりました' + ADDED: '"%s" set: "%s" added.' + REMOVED: '"%s" set: "%s" removed.' + OPTIONSET: '" option set to ' + COLOURSET: '" color option set to "' + INTREQUIRED: 'Cannot set "%s": An integer (whole number) value required.' + LONGREQUIRED: 'Cannot set "%s": A long integer (whole number) value required.' + DOUBLEREQUIRED: 'Cannot set "%s": A double (numeric) value required.' + FLOATREQUIRED: 'Cannot set "%s": A float (numeric) value required.' + INVALID: + COLOUR: 'Cannot set "%s": "%s" is not a valid color.' + COLLECTION: '"%s" is not a data collection type which can be modified with this command.' + MATERIAL: 'Cannot change "%s" set: "%s" is not a valid material.' + TYPESET: '"%s" is not a data type set which can be modified with this command.' + MATERIAL: + ADDED: '"%s" set: Material "%s" added.' + REMOVED: '"%s" set: Material "%s" removed.' + LOG: ' (Command was run by %s.)' + ERROR: + SETTING: Error setting configuration setting "%s" to "%s". + MATCHING: Configuration setting "%s" couldn't be matched, though it should be... please report this error. + TYPE: '''%s'' is of type ''%s'', which cannot be modified with this command.' + CREATE: + MUSTLEAVE: You must leave your current faction first. + INUSE: That tag is already in use. + TOCREATE: to create a new faction + FORCREATE: for creating a new faction + ERROR: There was an internal error while trying to create your faction. Please try again. + CREATED: %s created a new faction %s + CREATEDLOG: ' は新しい党派を造りました: ' + YOUSHOULD: 'You should now: %s' + DEINVITE: + CANDEINVITE: 'Players you can deinvite: ' + CLICKTODEINVITE: 'Click to revoke invite for %s' + ALREADYMEMBER: '%s is already a member of %s' + MIGHTWANT: 'You might want to: %s' + REVOKED: '%s revoked your invitation to %s.' + REVOKES: '%s revoked %s''s invitation.' + DELFWARP: + DELETED: Deleted warp %s + INVALID: Couldn't find warp %s + TODELETE: to delete warp + FORDELETE: for deleting warp + DESCRIPTION: + CHANGES: 'You have changed the description for %s to:' + CHANGED: 'The faction %s changed their description to:' + TOCHANGE: to change faction description + FORCHANGE: for changing faction description + DISBAND: + IMMUTABLE: You cannot disband the Wilderness, SafeZone, or WarZone. + MARKEDPERMANENT: This faction is designated as permanent, so you cannot disband it. + BROADCAST: + YOURS: %s disbanded your faction. + NOTYOURS: %s disbanded the faction %s. + HOLDINGS: You have been given the disbanded faction's bank, totaling %s. + FWARP: + CLICKTOWARP: クリック為にワープ「テレポート」! + COMMANDFORMAT: /f warp <ワープ名> + WARPED: %sにテレポートしました + INVALID: %sが見つかりません + TOWARP: ワープし + FORWARPING: ワープした + WARPS: 'ワープリスト: ' + HELP: + '404': 指定ページは不正です・ + NEXTCREATE: Learn how to create a faction on the next page. + HOME: 'And don''t forget to set your home:' + BANK: + '1': Your faction has a bank which is used to pay for certain + '2': things, so it will need to have money deposited into it. + '3': To learn more, use the money command. + PLAYERTITLES: Player titles are just for fun. No rules connected to them. + OWNERSHIP: + '1': Claimed land with ownership set is further protected so + '2': that only the owner(s), faction admin, and possibly the + '3': faction moderators have full access. + RELATIONS: + '1': Set the relation you WISH to have with another faction. + '2': Your default relation with other factions will be neutral. + '3': If BOTH factions choose "ally" you will be allies. + '4': If ONE faction chooses "enemy" you will be enemies. + '5': You can never hurt members or allies. + '6': You can not hurt neutrals in their own territory. + '7': You can always hurt enemies and players without faction. + '8': '' + '9': Damage from enemies is reduced in your own territory. + '10': When you die you lose power. It is restored over time. + '11': The power of a faction is the sum of all member power. + '12': The power of a faction determines how much land it can hold. + '13': You can claim land from factions with too little power. + PERMISSIONS: + '1': Only faction members can build and destroy in their own + '2': 'territory. Usage of the following items is also restricted:' + '3': Door, Chest, Furnace, Dispenser, Diode. + '4': '' + '5': Make sure to put pressure plates in front of doors for your + '6': guest visitors. Otherwise they can't get through. You can + '7': also use this to create member only areas. + '8': As dispensers are protected, you can create traps without + '9': worrying about those arrows getting stolen. + ADMIN: + '1': /f claim safezone claim land for the Safe Zone + '2': /f claim warzone claim land for the War Zone + '3': /f autoclaim [safezone|warzone] take a guess + MOAR: + '1': 'Finally some commands for the server admins:' + '2': 'More commands for server admins:' + '3': 'Even more commands for server admins:' + HOME: + DISABLED: 党派ホームは禁止されました・ + TELEPORTDISABLED: 党派ホームテレポートは禁止されました・ + NOHOME: '党派のホームはありません' + INENEMY: You cannot teleport to your faction home while in the territory of an enemy faction. + WRONGWORLD: You cannot teleport to your faction home while in a different world. + ENEMYNEAR: You cannot teleport to your faction home while an enemy is within %s blocks of you. + TOTELEPORT: to teleport to your faction home + FORTELEPORT: for teleporting to your faction home + INVITE: + TOINVITE: to invite someone + FORINVITE: for inviting someone + CLICKTOJOIN: Click to join! + INVITEDYOU: ' has invited you to join ' + INVITED: '%s invited %s to your faction.' + ALREADYMEMBER: '%s is already a member of %s' + JOIN: + CANNOTFORCE: You do not have permission to move other players into a faction. + SYSTEMFACTION: Players may only join normal factions. This is a system faction. + ALREADYMEMBER: %s %s already a member of %s + ATLIMIT: ' ! The faction %s is at the limit of %d members, so %s cannot + currently join.' + INOTHERFACTION: %s must leave %s current faction first. + NEGATIVEPOWER: %s cannot join a faction with a negative power level. + REQUIRESINVITATION: This faction requires invitation. + ATTEMPTEDJOIN: '%s tried to join your faction.' + TOJOIN: to join a faction + FORJOIN: for joining a faction + SUCCESS: %s successfully joined %s. + MOVED: %s moved you into the faction %s. + JOINED: %s joined your faction. + JOINEDLOG: '%s joined the faction %s.' + MOVEDLOG: '%s moved the player %s into the faction %s.' + KICK: + CANDIDATES: 'Players you can kick: ' + CLICKTOKICK: 'Click to kick ' + SELF: You cannot kick yourself. + NONE: That player is not in a faction. + NOTMEMBER: '%s is not a member of %s' + INSUFFICIENTRANK: Your rank is too low to kick this player. + NEGATIVEPOWER: You cannot kick that member until their power is positive. + TOKICK: to kick someone from the faction + FORKICK: for kicking someone from the faction + FACTION: '%s kicked %s from the faction! :O' + KICKS: You kicked %s from the faction %s! + KICKED: '%s kicked you from %s! :O' + LIST: + FACTIONLIST: 'Faction List ' + TOLIST: to list the factions + FORLIST: for listing the factions + ONLINEFACTIONLESS: 'Online factionless: ' + LOCK: + LOCKED: Factions is now locked + UNLOCKED: Factions in now unlocked + MAP: + TOSHOW: to show the map + FORSHOW: for showing the map + UPDATE: + ENABLED: Map auto update ENABLED. + DISABLED: Map auto update DISABLED. + MOD: + CANDIDATES: 'Players you can promote: ' + CLICKTOPROMOTE: 'Click to promote ' + NOTMEMBER: '%s is not a member in your faction.' + NOTADMIN: You are not the faction admin. + SELF: The target player musn't be yourself. + TARGETISADMIN: The target player is a faction admin. Demote them first. + REVOKES: You have removed moderator status from %s. + REVOKED: '%s is no longer moderator in your faction.' + PROMOTES: '%s was promoted to moderator in your faction.' + PROMOTED: You have promoted %s to moderator. + MODIFYPOWER: + ADDED: 'Added %f power to %s. New total rounded power: %d' + MONEY: + SHORT: faction money commands + LONG: The faction money commands. + MONEYBALANCE: + SHORT: show faction balance + MONEYDEPOSIT: + SHORT: deposit money + DEPOSITED: '%s deposited %s in the faction bank: %s' + MONEYTRANSFERFF: + SHORT: transfer f -> f + TRANSFER: '%s transferred %s from the faction "%s" to the faction "%s"' + MONEYTRANSFERFP: + SHORT: transfer f -> p + TRANSFER: '%s transferred %s from the faction "%s" to the player "%s"' + MONEYTRANSFERPF: + SHORT: transfer p -> f + TRANSFER: '%s transferred %s from the player "%s" to the faction "%s"' + MONEYWITHDRAW: + SHORT: withdraw money + WITHDRAW: '%s withdrew %s from the faction bank: %s' + OPEN: + TOOPEN: to open or close the faction + FOROPEN: for opening or closing the faction + OPEN: open + CLOSED: closed + CHANGES: '%s changed the faction to %s.' + CHANGED: The faction %s is now %s + OWNER: + DISABLED: Sorry, but owned areas are disabled on this server. + LIMIT: Sorry, but you have reached the server's limit of %d owned areas per faction. + WRONGFACTION: This land is not claimed by your faction, so you can't set ownership of it. + NOTCLAIMED: This land is not claimed by a faction. Ownership is not possible. + NOTMEMBER: '%s is not a member of this faction.' + CLEARED: You have cleared ownership for this claimed area. + REMOVED: You have removed ownership of this claimed land from %s. + TOSET: to set ownership of claimed land + FORSET: for setting ownership of claimed land + ADDED: You have added %s to the owner list for this claimed land. + OWNERLIST: + DISABLED: Sorry, but owned areas are disabled on this server. + WRONGFACTION: This land is not claimed by your faction. + NOTCLAIMED: This land is not claimed by any faction, thus no owners. + NONE: No owners are set here; everyone in the faction has access. + OWNERS: 'Current owner(s) of this land: %s' + POWER: + TOSHOW: to show player power info + FORSHOW: for showing player power info + POWER: '%s - Power / Maxpower: %d / %d %s' + BONUS: ' (bonus: ' + PENALTY: ' (penalty: ' + POWERBOOST: + HELP: + '1': You must specify "p" or "player" to target a player or "f" or "faction" to target a faction. + '2': ex. /f powerboost p SomePlayer 0.5 -or- /f powerboost f SomeFaction -5 + INVALIDNUM: You must specify a valid numeric value for the power bonus/penalty amount. + PLAYER: Player "%s" + FACTION: Faction "%s" + BOOST: %s now has a power bonus/penalty of %d to min and max power levels. + BOOSTLOG: '%s has set the power bonus/penalty for %s to %d.' + RELOAD: + TIME: conf.json をリロードしました・%dミリ秒〜. + SAFEUNCLAIMALL: + SHORT: Unclaim all safezone land + UNCLAIMED: You unclaimed ALL safe zone land. + UNCLAIMEDLOG: '%s unclaimed all safe zones.' + SAVEALL: Factions saved to disk! + SETFWARP: + NOTCLAIMED: You can only set warps in your faction territory. + LIMIT: Your Faction already has the max amount of warps set (%d). + SET: Set warp %s to your location. + TOSET: to set warp + FORSET: for setting warp + SETHOME: + DISABLED: 党派ホームは禁止されました・ + NOTCLAIMED: Sorry, your faction home can only be set inside your own claimed territory. + TOSET: to set the faction home + FORSET: for setting the faction home + SET: '%s set the home for your faction. You can now use:' + SETOTHER: You have set the home for the %s faction. + SHOW: + TOSHOW: to show faction information + FORSHOW: for showing faction information + DESCRIPTION: 'Description: %s' + PEACEFUL: This faction is Peaceful + PERMANENT: This faction is permanent, remaining even with no members. + JOINING: 'Joining: %s ' + INVITATION: invitation is required + UNINVITED: no invitation is needed + POWER: 'Land / Power / Maxpower: %d/%d/%d %s' + BONUS: ' (bonus: ' + PENALTY: ' (penalty: ' + DEPRECIATED: (%s depreciated) + LANDVALUE: 'トータル地価: %s%s' + BANKCONTAINS: '残高: %s' + ALLIES: 'Allies: ' + ENEMIES: 'Enemies: ' + MEMBERSONLINE: 'Members online: ' + MEMBERSOFFLINE: 'Members offline: ' + SHOWINVITES: + PENDING: 'Players with pending invites: ' + CLICKTOREVOKE: Click to revoke invite for %s + STATUS: + FORMAT: '%s パワー:%s 最終オンライン:%s' + ONLINE: オンライン + AGOSUFFIX: '間・' + TAG: + TAKEN: That tag is already taken + TOCHANGE: to change the faction tag + FORCHANGE: for changing the faction tag + FACTION: '%s changed your faction tag to %s' + CHANGED: 党派「%s」は名が%sに変わりました・ + TITLE: + TOCHANGE: to change a players title + FORCHANGE: for changing a players title + CHANGED: '%sはタイトルが変わりました: %s' + UNCLAIM: + SAFEZONE: + SUCCESS: この安全地帯は原に変わりました・ + NOPERM: This is a safe zone. You lack permissions to unclaim. + WARZONE: + SUCCESS: この戦場は原に変わりました・ + NOPERM: This is a war zone. You lack permissions to unclaim. + UNCLAIMED: '%s unclaimed some of your land.' + UNCLAIMS: You unclaimed this land. + LOG: '%s unclaimed land at (%s) from the faction: %s' + WRONGFACTION: You don't own this land. + TOUNCLAIM: to unclaim this land + FORUNCLAIM: for unclaiming this land + FACTIONUNCLAIMED: '%s unclaimed some land.' + UNCLAIMALL: + TOUNCLAIM: to unclaim all faction land + FORUNCLAIM: for unclaiming all faction land + UNCLAIMED: '%s unclaimed ALL of your faction''s land.' + LOG: '%s unclaimed everything for the faction: %s' + VERSION: + VERSION: 現在バーション %s + WARUNCLAIMALL: + SHORT: unclaim all warzone land + SUCCESS: You unclaimed ALL war zone land. + LOG: '%s unclaimed all war zones.' + RELATIONS: + ALLTHENOPE: いいえ!出来ません・ + MORENOPE: いいえ・自分は自分には関係出来ません・ + ALREADYINRELATIONSHIP: %sの関係はもうありますよ・ + TOMARRY: 関係は変わり + FORMARRY: 関係は変わった + MUTUAL: Your faction is now %s to %s + PEACEFUL: This will have no effect while your faction is peaceful. + PEACEFULOTHER: This will have no effect while their faction is peaceful. + PROPOSAL: + '1': '%s wishes to be your %s' + '2': Type /%s %s %s to accept. + SENT: '%s were informed that you wish to be %s' +command: + convert: + backend: + running: そのバックエンドは使用中です・ + invalid: バックエンドは不正です・ + help: + invitations: 'You might want to close it and use invitations:' +GENERIC: + ASKYOURLEADER: ' Ask your boss to:' + YOUSHOULD: 'You should:' + YOUMAYWANT: 'You may want to: ' + SERVERADMIN: サーバアドミン + DISABLED: ディセーブル + ENABLED: エネーブル + CONSOLEONLY: プレーヤはそのコマンド使用出来ませんよ・ + TRASLATION: + VERSION: 翻訳:%s・%s「%s」%s + CONTRIBUTORS: 翻訳者:%s + RESPONSIBLE: 翻訳の主任:%s +RELATION: + MEMBER: 員 + ALLY: 連盟 + NEUTRAL: 中立 + ENEMY: 敵 +NOPAGES: 申し訳ありません・ページはありません・ +INVALIDPAGE: 指定ページは不正です・1から%dまで・ + +title: '&b党派 &0|&r' +wilderness: '&2原' +wilderness-description: ' ' +warzone: '&4戦場' +warzone-description: 安全じゃない地帯 +safezone: '&6安全地帯' +safezone-description: プレーヤコンバットとモンスターはありません・ +toggle-sb: 今、スコアーボードは{value}になっています・ +default-prefix: '{relationcolor}[{faction}] &r' diff --git a/cartels-master@e4f5c2ecec5/src/main/resources/plugin.yml b/cartels-master@e4f5c2ecec5/src/main/resources/plugin.yml new file mode 100644 index 0000000..c635b06 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/resources/plugin.yml @@ -0,0 +1,277 @@ +name: Factions +version: ${project.version} +main: com.massivecraft.factions.P +authors: [Olof Larsson, Brett Flannigan, drtshock, Presidentx, Teddeh] +depend: [Core] +softdepend: [PlayerVaults, PermissionsEx, Permissions, Essentials, EssentialsChat, HeroChat, iChat, LocalAreaChat, LWC, nChat, ChatManager, CAPI, AuthMe, Vault, Spout, WorldEdit, WorldGuard, AuthDB, CaptureThePoints, CombatTag, dynmap] +commands: + cartels: + description: Reference command for Cartels. + aliases: [c, cartel, f, faction, factions] +permissions: + factions.kit.admin: + description: All faction permissions. + children: + factions.kit.mod: true + factions.config: true + factions.lock: true + factions.reload: true + factions.save: true + factions.modifypower: true + factions.ahome: true + factions.setmaxvaults: true + factions.*: + description: This is just an alias for factions.kit.admin + children: + factions.kit.admin: true + factions.kit.mod: + description: All faction permissions but configuration and persistance. + children: + factions.kit.halfmod: true + factions.disband.any: true + factions.setpeaceful: true + factions.setpermanent: true + factions.setpermanentpower: true + factions.powerboost: true + factions.sethome.any: true + factions.money.*: true + factions.join.any: true + factions.join.others: true + factions.admin.any: true + factions.mod.any: true + factions.kit.halfmod: + description: Zones, bypassing, kicking, and chatspy + children: + factions.kit.fullplayer: true + factions.managesafezone: true + factions.managewarzone: true + factions.bypass: true + factions.kick.any: true + factions.ownershipbypass: true + factions.chatspy: true + factions.show.bypassexempt: true + factions.kit.fullplayer: + default: true + description: Can also create new factions. + children: + factions.kit.halfplayer: true + factions.create: true + factions.kit.halfplayer: + description: Can do all but create factions. + children: + factions.admin: true + factions.autoclaim: true + factions.chat: true + factions.claim: true + factions.claim.line: true + factions.claim.radius: true + factions.deinvite: true + factions.description: true + factions.disband: true + factions.help: true + factions.home: true + factions.invite: true + factions.join: true + factions.kick: true + factions.leave: true + factions.list: true + factions.map: true + factions.mod: true + factions.money.kit.standard: true + factions.noboom: true + factions.open: true + factions.owner: true + factions.ownerlist: true + factions.power: true + factions.power.any: true + factions.relation: true + factions.sethome: true + factions.show: true + factions.stuck: true + factions.tag: true + factions.title: true + factions.version: true + factions.unclaim: true + factions.unclaimall: true + factions.scoreboard: true + factions.showinvites: true + factions.seechunk: true + factions.monitorlogins: true + factions.top: true + factions.togglealliancechat: true + factions.vault: true + factions.admin: + description: hand over your admin rights + factions.admin.any: + description: give or revoke admin status for any player in any faction + factions.announce: + description: announce things to the peasants + factions.autoclaim: + description: auto-claim land as you walk around + factions.bypass: + description: enable admin bypass mode + factions.chat: + description: change chat mode + factions.chatspy: + description: enable admin chat spy mode + factions.claim: + description: claim land where you are standing + factions.claim.radius: + description: claim land in a large radius + factions.config: + description: change a conf.json setting + factions.create: + description: create a new faction + factions.deinvite: + description: remove a pending invitation + factions.description: + description: change the faction description + factions.disband: + description: disband a faction + factions.disband.any: + description: disband another faction + factions.help: + description: display a help page + factions.home: + description: teleport to the faction home + factions.invite: + description: invite a player to your faction + factions.join: + description: join a faction + factions.join.any: + description: join any faction, bypassing invitation process for closed factions + factions.join.others: + description: specify another player in the join command, to move them to the specified faction + factions.kick: + description: kick a player from the faction + factions.kick.any: + description: kick anyone from any faction + factions.leave: + description: leave your faction + factions.list: + description: see a list of the factions + factions.lock: + description: lock all write stuff + factions.managesafezone: + description: claim land as a safe zone and build/destroy within safe zones + factions.managewarzone: + description: claim land as a war zone and build/destroy within war zones + factions.map: + description: show the territory map, and set optional auto update + factions.mod: + description: give or revoke moderator rights + factions.mod.any: + description: give or revoke moderator rights for any player in any faction + factions.money.balance: + description: show your factions current money balance + factions.money.balance.any: + description: show money balance for factions other than your own + factions.money.deposit: + description: deposit money into a faction bank + factions.money.withdraw: + description: withdraw money from your faction bank + factions.money.withdraw.any: + description: withdraw money from your factions other than your own + factions.money.f2f: + description: transfer money from faction to faction + factions.money.f2p: + description: transfer money from faction to player + factions.money.p2f: + description: transfer money from player to faction + factions.money.kit.standard: + children: + factions.money.balance: true + factions.money.balance.any: true + factions.money.deposit: true + factions.money.withdraw: true + factions.money.f2f: true + factions.money.f2p: true + factions.money.p2f: true + factions.money.*: + children: + factions.money.kit.standard: true + factions.money.balance.any: true + factions.money.deposit: true + factions.money.withdraw: true + factions.money.withdraw.any: true + factions.money.f2f: true + factions.money.f2p: true + factions.money.p2f: true + factions.noboom: + description: toggle explosions (peaceful factions only) + factions.open: + description: switch if invitation is required to join + factions.owner: + description: set ownership of claimed land + factions.ownerlist: + description: list owner(s) of this claimed land + factions.ownershipbypass: + description: bypass ownership restrictions within own faction's territory + factions.setpeaceful: + description: designate a faction as peaceful + factions.setpermanent: + description: designate a faction as permanent + factions.setpermanentpower: + description: set permanent power for a faction + factions.stuck: + description: teleports player outside a faction + factions.power: + description: show player power info + factions.power.any: + description: view an other players power level + factions.powerboost: + description: apply permanent power bonus/penalty to specified player or faction + factions.relation: + description: set relation wish to another faction + factions.reload: + description: reload data file(s) from disk + factions.save: + description: save all data to disk + factions.sethome: + description: set the faction home + factions.sethome.any: + description: set faction home for another faction + factions.show: + description: show faction information + factions.show.bypassexempt: + description: show exempt faction information + factions.tag: + description: change the faction tag + factions.title: + description: set or remove a players title + factions.version: + description: see the version of the plugin + factions.unclaim: + description: unclaim the land where you are standing + factions.unclaimall: + description: unclaim all of your factions land + factions.scoreboard: + description: ability to toggle scoreboards + factions.showinvites: + description: show pending invites to your faction + factions.seechunk: + description: see the chunk you stand in + factions.setwarp: + description: set a warp for your faction + factions.warp: + description: access your faction warps + factions.modifypower: + description: modify other player's power + factions.monitorlogins: + description: monitor join and leaves of faction members + factions.claim.line: + description: claim in a line + factions.top: + description: sort factions + factions.togglealliancechat: + description: toggle alliance chat on and off + factions.dontlosepoweroffline: + description: Don't lose power for being offline. + factions.ahome: + description: Ability to send players to their faction home. + factions.autoleavebypass: + description: Bypass autoleave. + factions.vault: + description: Access faction vault. + factions.setmaxvault: + description: Set a faction's max vaults. \ No newline at end of file diff --git a/common-master@c5eba833390/.gitignore b/common-master@c5eba833390/.gitignore new file mode 100644 index 0000000..ad7f541 --- /dev/null +++ b/common-master@c5eba833390/.gitignore @@ -0,0 +1,8 @@ + +\.idea/ + +target/classes/ + +target/ + +*.iml \ No newline at end of file diff --git a/common-master@c5eba833390/README.md b/common-master@c5eba833390/README.md new file mode 100644 index 0000000..91b5899 --- /dev/null +++ b/common-master@c5eba833390/README.md @@ -0,0 +1,4 @@ +# GTMCore +Link: https://circleci.com/gh/GrandTheftMinecart/GTMCore +
+Latest Artifact: https://github.com/GrandTheftMinecart/GTMCore/releases/latest \ No newline at end of file diff --git a/common-master@c5eba833390/pom.xml b/common-master@c5eba833390/pom.xml new file mode 100644 index 0000000..ba96ef0 --- /dev/null +++ b/common-master@c5eba833390/pom.xml @@ -0,0 +1,136 @@ + + + 4.0.0 + + net.grandtheftmc + common + 1.1.6 + Common + + + + nexus-release + http://nexus.grandtheftmc.net/content/repositories/releases + + + + + + nexus-release + Internal Releases + http://nexus.grandtheftmc.net/content/repositories/releases + + + nexus-snapshot + Internal Snapshots + http://nexus.grandtheftmc.net/content/repositories/snapshots + + + + + + 1 + Presidentx + + Owner + Developer + + + + + 2 + MrTeddeh + + Senior Developer + + + + + 3 + Tim + + Developer + + + + + 4 + ThatAbstractWolf + + Developer + + + + + + + redis.clients + jedis + LATEST + compile + + + + com.google.code.gson + gson + 2.8.0 + + + + com.google.guava + guava + 21.0 + + + + + UTF-8 + 1.8 + 1.8 + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.0.0 + + Common + + + + package + + shade + + + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.8 + true + + + default-deploy + deploy + + deploy + + + + + nexus + http://nexus.grandtheftmc.net/ + true + + + + + \ No newline at end of file diff --git a/common-master@c5eba833390/src/main/java/net/grandtheftmc/ServerType.java b/common-master@c5eba833390/src/main/java/net/grandtheftmc/ServerType.java new file mode 100644 index 0000000..50fc97a --- /dev/null +++ b/common-master@c5eba833390/src/main/java/net/grandtheftmc/ServerType.java @@ -0,0 +1,33 @@ +package net.grandtheftmc; + +/** + * Created by Luke Bingham on 19/08/2017. + */ +public enum ServerType { + HUB("hub", true), + GTM("gtm", true), + VICE("vice", true), + CREATIVE("creative", true), + + PROXY("proxy", false), + OPERATOR("operator", false), + + GLOBAL("global", false), + ; + + private final String serverName; + private final boolean playable; + + ServerType(String serverName, boolean playable) { + this.serverName = serverName; + this.playable = playable; + } + + public String getServerName() { + return serverName; + } + + public boolean isPlayable() { + return playable; + } +} diff --git a/common-master@c5eba833390/src/main/java/net/grandtheftmc/ServerTypeId.java b/common-master@c5eba833390/src/main/java/net/grandtheftmc/ServerTypeId.java new file mode 100644 index 0000000..928be90 --- /dev/null +++ b/common-master@c5eba833390/src/main/java/net/grandtheftmc/ServerTypeId.java @@ -0,0 +1,26 @@ +package net.grandtheftmc; + +/** + * Created by Luke Bingham on 19/08/2017. + */ +public class ServerTypeId { + private final ServerType serverType; + private final int id; + + public ServerTypeId(ServerType serverType, int id) { + this.serverType = serverType; + this.id = id; + } + + public ServerType getServerType() { + return serverType; + } + + public int getId() { + return id; + } + + public boolean isOperator() { + return serverType == ServerType.OPERATOR; + } +} diff --git a/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/JMessage.java b/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/JMessage.java new file mode 100644 index 0000000..a1f7358 --- /dev/null +++ b/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/JMessage.java @@ -0,0 +1,7 @@ +package net.grandtheftmc.jedis; + +/** + * Created by Luke Bingham on 19/08/2017. + */ +public interface JMessage { +} diff --git a/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/JMessageListener.java b/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/JMessageListener.java new file mode 100644 index 0000000..4d90c44 --- /dev/null +++ b/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/JMessageListener.java @@ -0,0 +1,10 @@ +package net.grandtheftmc.jedis; + +import net.grandtheftmc.ServerTypeId; + +/** + * Created by Luke Bingham on 19/08/2017. + */ +public interface JMessageListener { + void onReceive(ServerTypeId sender, T message); +} diff --git a/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/JMessageReader.java b/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/JMessageReader.java new file mode 100644 index 0000000..917f1f5 --- /dev/null +++ b/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/JMessageReader.java @@ -0,0 +1,88 @@ +package net.grandtheftmc.jedis; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import net.grandtheftmc.ServerType; +import net.grandtheftmc.ServerTypeId; +import redis.clients.jedis.JedisPubSub; + +import java.util.List; + +/** + * Created by Luke Bingham on 19/08/2017. + */ +public final class JMessageReader extends JedisPubSub { + + private final ServerTypeId serverTypeId; + private final Gson gson = new Gson(); + private final JsonParser jsonParser = new JsonParser(); + + public JMessageReader(ServerTypeId serverTypeId) { + this.serverTypeId = serverTypeId; + } + + @Override + public final void onMessage(String channel, String message) { + if (!isValid(message)) return; + + try { + JsonObject label = (JsonObject) jsonParser.parse(message); + String messageName = label.get("name").getAsString(); + int senderId = label.get("senderId").getAsInt(); + String senderType = label.get("senderType").getAsString(); + int recipientId = label.get("recipientId").getAsInt(); + String recipientType = label.get("recipientType").getAsString(); + + if(!"GLOBAL".equalsIgnoreCase(recipientType)) { + if(!this.serverTypeId.getServerType().name().equals(recipientType)) return; + if(recipientId != -1) if(this.serverTypeId.getId() != recipientId) return; + } +// if (recipient.equalsIgnoreCase("all") || recipient.equalsIgnoreCase(serverName)) { + Class messageClass = (Class) Class.forName(messageName); + JMessage msg = gson.fromJson(label.getAsJsonObject("content"), messageClass); + + List listenerList = JedisModule.listeners.get(messageClass); + if (listenerList != null) listenerList.forEach(c -> c.onReceive(new ServerTypeId(ServerType.valueOf(senderType), senderId), msg)); +// } + } + catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public final void onPMessage(String s, String s1, String s2) { + + } + + @Override + public final void onSubscribe(String s, int i) { + + } + + @Override + public final void onUnsubscribe(String s, int i) { + + } + + @Override + public final void onPUnsubscribe(String s, int i) { + + } + + @Override + public final void onPSubscribe(String s, int i) { + + } + + private boolean isValid(String str) { + try { + jsonParser.parse(str); + return true; + } + catch (Exception e) { + return false; + } + } +} diff --git a/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/JMessageWriter.java b/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/JMessageWriter.java new file mode 100644 index 0000000..42ef7cc --- /dev/null +++ b/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/JMessageWriter.java @@ -0,0 +1,59 @@ +package net.grandtheftmc.jedis; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import net.grandtheftmc.ServerType; +import net.grandtheftmc.ServerTypeId; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; + +/** + * Created by Luke Bingham on 19/08/2017. + */ +public final class JMessageWriter { + + private final ServerTypeId serverTypeId; + private final Gson gson = new Gson(); + private final JedisPool pool; + private final JedisChannel channel; + + public JMessageWriter(ServerTypeId serverTypeId, JedisPool pool, JedisChannel channel) { + this.serverTypeId = serverTypeId; + this.pool = pool; + this.channel = channel; + } + + public final void publishPacket(Object message, ServerTypeId recipient) { + JsonObject label = new JsonObject(); + label.addProperty("name", message.getClass().getName()); + label.addProperty("senderId", serverTypeId.getId()); + label.addProperty("senderType", serverTypeId.getServerType().name()); + label.addProperty("recipientId", recipient.getId()); + label.addProperty("recipientType", recipient.getServerType().name()); + label.add("content", gson.toJsonTree(message)); + + try (Jedis jedis = pool.getResource()) { + jedis.publish(channel.getChannel(), label.toString()); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + public final void publishPacket(Object message) { + JsonObject label = new JsonObject(); + label.addProperty("name", message.getClass().getName()); + label.addProperty("senderId", serverTypeId.getId()); + label.addProperty("senderType", serverTypeId.getServerType().name()); + label.addProperty("recipientId", -1); + label.addProperty("recipientType", ServerType.GLOBAL.name()); + label.add("content", gson.toJsonTree(message)); + + try (Jedis jedis = pool.getResource()) { + jedis.publish(channel.getChannel(), label.toString()); + } + catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/JedisChannel.java b/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/JedisChannel.java new file mode 100644 index 0000000..a2d2537 --- /dev/null +++ b/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/JedisChannel.java @@ -0,0 +1,22 @@ +package net.grandtheftmc.jedis; + +/** + * Created by Luke Bingham on 19/08/2017. + */ +public enum JedisChannel { + GLOBAL("global_network"), + SERVER_QUEUE("server_queue"), + DEV("dev"), + WATCHDAWG("watchdawg"), + ; + + private String channel; + + JedisChannel(String channel) { + this.channel = channel; + } + + public String getChannel() { + return channel; + } +} diff --git a/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/JedisManager.java b/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/JedisManager.java new file mode 100644 index 0000000..2bb370e --- /dev/null +++ b/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/JedisManager.java @@ -0,0 +1,30 @@ +package net.grandtheftmc.jedis; + +import net.grandtheftmc.ServerType; +import net.grandtheftmc.ServerTypeId; + +import java.util.HashMap; + +/** + * Created by Luke Bingham on 19/08/2017. + */ +public class JedisManager { + + private final HashMap jedisModules; + + public JedisManager() { + this.jedisModules = new HashMap(); + } + + public JedisModule getModule(JedisChannel channel) { + return this.jedisModules.getOrDefault(channel, null); + } + + public void initModule(ServerTypeId serverTypeId, JedisChannel channel, String vlan, int port, String password) { + this.jedisModules.putIfAbsent(channel, new JedisModule(serverTypeId, channel, vlan, port, password)); + } + + public HashMap getJedisModules() { + return this.jedisModules; + } +} diff --git a/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/JedisModule.java b/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/JedisModule.java new file mode 100644 index 0000000..50bce14 --- /dev/null +++ b/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/JedisModule.java @@ -0,0 +1,98 @@ +package net.grandtheftmc.jedis; + +import com.google.common.collect.Lists; +import com.google.gson.Gson; +import net.grandtheftmc.ServerType; +import net.grandtheftmc.ServerTypeId; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPoolConfig; + +import java.util.HashMap; +import java.util.List; + +/** + * Created by Luke Bingham on 19/08/2017. + */ +public class JedisModule { + private final Gson gson = new Gson(); + private JedisPool jedisPool; + private JMessageReader reader; + private JMessageWriter writer; + private final JedisChannel channel; + + protected static final HashMap, List> listeners; + + static { + listeners = new HashMap<>(); + } + + public JedisModule(ServerTypeId serverTypeId, JedisChannel channel, String vlan, int port, String password) { + this.channel = channel; + this.connect(serverTypeId, channel, vlan, port, password); + } + + public final void connect(ServerTypeId serverTypeId, JedisChannel channel, String vlan, int port, String password) { + this.jedisPool = new JedisPool(new JedisPoolConfig(), vlan, port, 5000, password); + + reader = new JMessageReader(serverTypeId); + writer = new JMessageWriter(serverTypeId, jedisPool, channel); + + new Thread(() -> { + try (Jedis j = getJedisPool().getResource()) { + j.subscribe(reader, channel.getChannel()); + } + catch (Exception e) { + e.printStackTrace(); + } + }).start(); + } + + /** + * This will send a message to the given server. + * + * @param message - The message a' server will receive. + * @param serverTypeId - Server to send the message to. + */ + public final void sendMessage(Object message, ServerTypeId serverTypeId) { + writer.publishPacket(message, serverTypeId); + } + + /** + * This will send a message to all servers including Proxy and Operator. + * + * @param message - The message all servers will receive. + */ + public final void sendMessage(Object message) { + writer.publishPacket(message); + } + + public final void disable() { + if(reader != null) { + if (reader.isSubscribed()) + reader.unsubscribe(); + } + + if(jedisPool != null) + jedisPool.destroy(); + } + + public final void disconnect() { + this.disable(); + } + + public final JedisPool getJedisPool() { + return jedisPool; + } + + public final void registerListener(Class msg, JMessageListener listener) { + if (listeners.containsKey(msg)) { + listeners.get(msg).add(listener); + } + else { + List list = Lists.newArrayList(); + list.add(listener); + listeners.put(msg, list); + } + } +} diff --git a/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/message/FindPlayerMessage.java b/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/message/FindPlayerMessage.java new file mode 100644 index 0000000..f391280 --- /dev/null +++ b/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/message/FindPlayerMessage.java @@ -0,0 +1,15 @@ +package net.grandtheftmc.jedis.message; + +import net.grandtheftmc.jedis.JMessage; + +import java.util.UUID; + +/** + * Created by Luke Bingham on 19/08/2017. + */ +public class FindPlayerMessage implements JMessage { + + public FindPlayerMessage() { + //TODO + } +} diff --git a/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/message/SendPlayerMessage.java b/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/message/SendPlayerMessage.java new file mode 100644 index 0000000..1420148 --- /dev/null +++ b/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/message/SendPlayerMessage.java @@ -0,0 +1,7 @@ +package net.grandtheftmc.jedis.message; + +/** + * Created by Luke Bingham on 20/08/2017. + */ +public class SendPlayerMessage { +} diff --git a/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/message/ServerJoinRequestMessage.java b/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/message/ServerJoinRequestMessage.java new file mode 100644 index 0000000..9f1f02a --- /dev/null +++ b/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/message/ServerJoinRequestMessage.java @@ -0,0 +1,28 @@ +package net.grandtheftmc.jedis.message; + +import net.grandtheftmc.ServerTypeId; +import net.grandtheftmc.jedis.JMessage; + +import java.util.UUID; + +/** + * Created by Luke Bingham on 20/08/2017. + */ +public class ServerJoinRequestMessage implements JMessage { + + private final UUID uniqueId; + private final ServerTypeId targetServer; + + public ServerJoinRequestMessage(UUID uniqueId, String rank, ServerTypeId targetServer) { + this.uniqueId = uniqueId; + this.targetServer = targetServer; + } + + public UUID getUniqueId() { + return uniqueId; + } + + public ServerTypeId getTargetServer() { + return targetServer; + } +} diff --git a/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/message/ServerJoinStatusMessage.java b/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/message/ServerJoinStatusMessage.java new file mode 100644 index 0000000..acbf94a --- /dev/null +++ b/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/message/ServerJoinStatusMessage.java @@ -0,0 +1,34 @@ +package net.grandtheftmc.jedis.message; + +import net.grandtheftmc.ServerTypeId; +import net.grandtheftmc.jedis.JMessage; + +import java.util.UUID; + +/** + * Created by Luke Bingham on 20/08/2017. + */ +public class ServerJoinStatusMessage implements JMessage { + + private final UUID uniqueId; + private final ServerTypeId targetServer; + + public ServerJoinStatusMessage(UUID uniqueId, String rank, ServerTypeId targetServer) { + this.uniqueId = uniqueId; + this.targetServer = targetServer; + } + + public UUID getUniqueId() { + return uniqueId; + } + + public ServerTypeId getTargetServer() { + return targetServer; + } + + public enum Status { + ERROR, + FULL, + ; + } +} diff --git a/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/message/ServerQueueMessage.java b/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/message/ServerQueueMessage.java new file mode 100644 index 0000000..07d500a --- /dev/null +++ b/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/message/ServerQueueMessage.java @@ -0,0 +1,35 @@ +package net.grandtheftmc.jedis.message; + +import net.grandtheftmc.ServerType; +import net.grandtheftmc.ServerTypeId; +import net.grandtheftmc.jedis.JMessage; + +import java.util.UUID; + +/** + * Created by Luke Bingham on 19/08/2017. + */ +public class ServerQueueMessage implements JMessage { + + private final UUID uniqueId; + private final String rank; + private final ServerTypeId targetServer; + + public ServerQueueMessage(UUID uniqueId, String rank, ServerTypeId targetServer) { + this.uniqueId = uniqueId; + this.rank = rank; + this.targetServer = targetServer; + } + + public UUID getUniqueId() { + return uniqueId; + } + + public String getRank() { + return rank; + } + + public ServerTypeId getTargetServer() { + return targetServer; + } +} diff --git a/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/message/ServerQueueNotifyMessage.java b/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/message/ServerQueueNotifyMessage.java new file mode 100644 index 0000000..2dab810 --- /dev/null +++ b/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/message/ServerQueueNotifyMessage.java @@ -0,0 +1,34 @@ +package net.grandtheftmc.jedis.message; + +import net.grandtheftmc.ServerTypeId; +import net.grandtheftmc.jedis.JMessage; + +import java.util.UUID; + +/** + * Created by Luke Bingham on 19/08/2017. + */ +public class ServerQueueNotifyMessage implements JMessage { + + private final UUID uniqueId; + private final ServerTypeId targetServer; + private final int possition; + + public ServerQueueNotifyMessage(UUID uniqueId, ServerTypeId targetServer, int possition) { + this.uniqueId = uniqueId; + this.targetServer = targetServer; + this.possition = possition; + } + + public UUID getUniqueId() { + return uniqueId; + } + + public ServerTypeId getTargetServer() { + return targetServer; + } + + public int getPossition() { + return possition; + } +} diff --git a/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/message/UserStateTransactionCheck.java b/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/message/UserStateTransactionCheck.java new file mode 100644 index 0000000..2661df9 --- /dev/null +++ b/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/message/UserStateTransactionCheck.java @@ -0,0 +1,34 @@ +package net.grandtheftmc.jedis.message; + +import java.util.UUID; + +import net.grandtheftmc.jedis.JMessage; + +public class UserStateTransactionCheck implements JMessage { + + /** The uuid of the user to check transactions for */ + private final UUID uuid; + + /** + * Construct a new UserStateTransactionCheck. + *

+ * This is forwarded to all servers and to force check for user state + * transactions for the given user. + *

+ * + * @param uuid - the uuid of the user to check transactions for + */ + public UserStateTransactionCheck(UUID uuid) { + this.uuid = uuid; + } + + /** + * Get the UUID of the user to check the user state transactions for. + * + * @return The UUID of the user to check the user state transactions in the + * database. + */ + public UUID getUUID() { + return uuid; + } +} diff --git a/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/message/VoteNotificationMessage.java b/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/message/VoteNotificationMessage.java new file mode 100644 index 0000000..4424f83 --- /dev/null +++ b/common-master@c5eba833390/src/main/java/net/grandtheftmc/jedis/message/VoteNotificationMessage.java @@ -0,0 +1,46 @@ +package net.grandtheftmc.jedis.message; + +import java.util.UUID; + +import net.grandtheftmc.jedis.JMessage; + +public class VoteNotificationMessage implements JMessage { + + /** The uuid of the user the vote notification is for */ + private final UUID uuid; + /** The message to pass along */ + private final String message; + + /** + * Construct a new VoteNotificationMessage. + *

+ * This is forwarded to all servers to let the user know that we have received their vote. + *

+ * + * @param uuid - the uuid of the user to notify + * @param message - the message to pass along + */ + public VoteNotificationMessage(UUID uuid, String message) { + this.uuid = uuid; + this.message = message; + } + + /** + * Get the UUID of the user that the vote notification is for. + * + * @return The UUID of the user that the vote notification is for. + */ + public UUID getUUID() { + return uuid; + } + + /** + * Get the message that should be passed along to this user. + * + * @return The message that should be displayed to the user. + */ + public String getMessage() { + return message; + } +} + diff --git a/common-master@c5eba833390/src/main/java/net/grandtheftmc/slack/Slack.java b/common-master@c5eba833390/src/main/java/net/grandtheftmc/slack/Slack.java new file mode 100644 index 0000000..954022f --- /dev/null +++ b/common-master@c5eba833390/src/main/java/net/grandtheftmc/slack/Slack.java @@ -0,0 +1,132 @@ +package net.grandtheftmc.slack; + +import com.google.gson.JsonObject; +import net.grandtheftmc.slack.attachment.SlackAttachment; +import net.grandtheftmc.slack.exception.SlackException; + +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.Proxy; +import java.net.URL; +import java.net.URLEncoder; + +/** + * Created by Luke Bingham on 05/09/2017. + */ +public class Slack { + + private static final String POST = "POST"; + private static final String PAYLOAD = "payload="; + private static final String UTF_8 = "UTF-8"; + + private final String service; + private final int timeout; + private final Proxy proxy; + + public Slack(String service) { + this(service, 5000); + } + + public Slack(String service, Proxy proxy) { + this(service, 5000, proxy); + } + + public Slack(String service, int timeout) { + this(service, timeout, Proxy.NO_PROXY); + } + + public Slack(String service, int timeout, Proxy proxy) { + this.timeout = timeout; + if (service == null) + throw new IllegalArgumentException("Missing WebHook URL Configuration @ SlackApi"); + + if (proxy == null) this.proxy = Proxy.NO_PROXY; + else this.proxy = proxy; + + this.service = service; + + } + + /** + * Prepare Message and send to Slack + */ + public static void send(SlackChannel channel, SlackHook hook, String... message) { + Slack api = new Slack(hook.getHook()); + StringBuilder msg = new StringBuilder(); + for(String str : message) msg.append(str).append("\n"); + api.call(new SlackMessage(channel.getChannelId(), hook.getName(), msg.toString())); + } + + /** + * Prepare Message and send to Slack + */ + public static void send(SlackChannel channel, SlackHook hook, SlackAttachment attachment, String... message) { + Slack api = new Slack(hook.getHook()); + StringBuilder msg = new StringBuilder(); + for(String str : message) msg.append(str).append("\n"); + api.call(new SlackMessage(channel.getChannelId(), hook.getName(), msg.toString()).addAttachments(attachment)); + } + + + + /** + * Prepare Message and send to Slack + */ + public static void send(SlackChannel channel, SlackHook hook, SlackAttachment attachment) { + Slack api = new Slack(hook.getHook()); + api.send(attachment.toJson()); + } + + /** + * Prepare Message and send to Slack + */ + public void call(SlackMessage message) { + if (message != null) { + this.send(message.prepare()); + } + } + + private String send(JsonObject message) { + HttpURLConnection connection = null; + try { + // Create connection + final URL url = new URL(this.service); + connection = (HttpURLConnection) url.openConnection(proxy); + connection.setRequestMethod(POST); + connection.setConnectTimeout(timeout); + connection.setUseCaches(false); + connection.setDoInput(true); + connection.setDoOutput(true); + + final String payload = PAYLOAD + URLEncoder.encode(message.toString(), UTF_8); + + // Send request + final DataOutputStream wr = new DataOutputStream(connection.getOutputStream()); + wr.writeBytes(payload); + wr.flush(); + wr.close(); + + // Get Response + final InputStream is = connection.getInputStream(); + final BufferedReader rd = new BufferedReader(new InputStreamReader(is)); + String line; + StringBuilder response = new StringBuilder(); + while ((line = rd.readLine()) != null) { + response.append(line); + response.append('\n'); + } + + rd.close(); + return response.toString(); + } catch (Exception e) { + throw new SlackException(e); + } finally { + if (connection != null) { + connection.disconnect(); + } + } + } +} diff --git a/common-master@c5eba833390/src/main/java/net/grandtheftmc/slack/SlackChannel.java b/common-master@c5eba833390/src/main/java/net/grandtheftmc/slack/SlackChannel.java new file mode 100644 index 0000000..b7f7c68 --- /dev/null +++ b/common-master@c5eba833390/src/main/java/net/grandtheftmc/slack/SlackChannel.java @@ -0,0 +1,27 @@ +package net.grandtheftmc.slack; + +/** + * Created by Luke Bingham on 29/08/2017. + */ +public enum SlackChannel { + + DEVELOP("#develop"), + DEVELOP_ALERTS("#develop_alerts"), + ENVIRONMENT("#environment"), + IMPORTANT("#important"), + PRODUCTION_ALERTS("#production_alerts"), + SENTRY("#sentry"), + TRELLO("#trello"), + + ; + + private String channelId; + + SlackChannel(String channelId) { + this.channelId = channelId; + } + + public String getChannelId() { + return channelId; + } +} diff --git a/common-master@c5eba833390/src/main/java/net/grandtheftmc/slack/SlackField.java b/common-master@c5eba833390/src/main/java/net/grandtheftmc/slack/SlackField.java new file mode 100644 index 0000000..8d29a5b --- /dev/null +++ b/common-master@c5eba833390/src/main/java/net/grandtheftmc/slack/SlackField.java @@ -0,0 +1,118 @@ +package net.grandtheftmc.slack; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Luke Bingham on 05/09/2017. + */ +public class SlackField { + + private static final String TITLE = "title"; + private static final String VALUE = "value"; + private static final String SHORT = "short"; + private static final String MRKDWN_IN = "mrkdwn_in"; + private static final String FIELD_ALLOWS_MARKDOWN_REGEX = "^(pretext|text|title|fields|fallback)$"; + + private List allowMarkdown = null; + private boolean shorten = false; + private String title = null; + private String value = null; + + public void addAllowedMarkdown(String field) { + if (this.allowMarkdown == null) { + this.allowMarkdown = new ArrayList(); + } + + if (field.matches(FIELD_ALLOWS_MARKDOWN_REGEX)) { + this.allowMarkdown.add(field); + } else { + throw new IllegalArgumentException( + field + " is not allowed. Allowed: pretext, text, title, fields and fallback"); + } + } + + public boolean isShorten() { + return shorten; + } + + private JsonArray prepareMarkdown() { + JsonArray data = new JsonArray(); + for (String item : this.allowMarkdown) { + data.add(new JsonPrimitive(item)); + } + + return data; + } + + public void setAllowedMarkdown(ArrayList allowMarkdown) { + if (allowMarkdown != null) { + this.allowMarkdown = allowMarkdown; + } + } + + public SlackField setShorten(boolean shorten) { + this.shorten = shorten; + return this; + } + + public SlackField setTitle(String title) { + this.title = title; + return this; + } + + public SlackField setValue(String value) { + this.value = value; + return this; + } + + public JsonObject toJson() { + final JsonObject data = new JsonObject(); + data.addProperty(TITLE, title); + data.addProperty(VALUE, value); + data.addProperty(SHORT, shorten); + if (allowMarkdown != null && allowMarkdown.size() > 0) { + data.add(MRKDWN_IN, prepareMarkdown()); + } + + return data; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final SlackField that = (SlackField) o; + + if (shorten != that.shorten) return false; + if (allowMarkdown != null ? !allowMarkdown.equals(that.allowMarkdown) : that.allowMarkdown != null) + return false; + if (title != null ? !title.equals(that.title) : that.title != null) return false; + return !(value != null ? !value.equals(that.value) : that.value != null); + + } + + @Override + public int hashCode() { + int result = allowMarkdown != null ? allowMarkdown.hashCode() : 0; + result = 31 * result + (shorten ? 1 : 0); + result = 31 * result + (title != null ? title.hashCode() : 0); + result = 31 * result + (value != null ? value.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "SlackField{" + + "allowMarkdown=" + allowMarkdown + + ", shorten=" + shorten + + ", title='" + title + '\'' + + ", value='" + value + '\'' + + '}'; + } +} diff --git a/common-master@c5eba833390/src/main/java/net/grandtheftmc/slack/SlackHook.java b/common-master@c5eba833390/src/main/java/net/grandtheftmc/slack/SlackHook.java new file mode 100644 index 0000000..8f2e2c3 --- /dev/null +++ b/common-master@c5eba833390/src/main/java/net/grandtheftmc/slack/SlackHook.java @@ -0,0 +1,26 @@ +package net.grandtheftmc.slack; + +/** + * Created by Luke Bingham on 29/08/2017. + */ +public enum SlackHook { + + MONTHLY_VOTES("Voters", "https://hooks.slack.com/services/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"), + SERVER_HEARTBEAT("Heartbeat", "https://hooks.slack.com/services/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"), + ; + + private final String name, hook; + + SlackHook(String name, String hook) { + this.name = name; + this.hook = hook; + } + + public String getName() { + return name; + } + + public String getHook() { + return hook; + } +} diff --git a/common-master@c5eba833390/src/main/java/net/grandtheftmc/slack/SlackMessage.java b/common-master@c5eba833390/src/main/java/net/grandtheftmc/slack/SlackMessage.java new file mode 100644 index 0000000..5a244f9 --- /dev/null +++ b/common-master@c5eba833390/src/main/java/net/grandtheftmc/slack/SlackMessage.java @@ -0,0 +1,218 @@ +package net.grandtheftmc.slack; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import net.grandtheftmc.slack.attachment.SlackAttachment; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Luke Bingham on 05/09/2017. + */ +public class SlackMessage { + + private static final String CHANNEL = "channel"; + private static final String USERNAME = "username"; + private static final String HTTP = "http"; + private static final String ICON_URL = "icon_url"; + private static final String ICON_EMOJI = "icon_emoji"; + private static final String UNFURL_MEDIA = "unfurl_media"; + private static final String UNFURL_LINKS = "unfurl_links"; + private static final String TEXT = "text"; + private static final String ATTACHMENTS = "attachments"; + + private List attach = new ArrayList(); + private String channel = null; + private String icon = null; + private JsonObject slackMessage = new JsonObject(); + + private String text = null; + private String username = null; + + private boolean unfurlMedia = false; + private boolean unfurlLinks = false; + + public SlackMessage() { + } + + public SlackMessage(String text) { + this(null, null, text); + } + + public SlackMessage(String username, String text) { + this(null, username, text); + } + + public SlackMessage(String channel, String username, String text) { + if (channel != null) { + this.channel = channel; + } + + if (username != null) { + this.username = username; + } + + this.text = text; + } + + public SlackMessage addAttachments(SlackAttachment attach) { + this.attach.add(attach); + + return this; + } + + /** + * Convert SlackMessage to JSON + * + * @return JsonObject + */ + public JsonObject prepare() { + if (channel != null) { + slackMessage.addProperty(CHANNEL, channel); + } + + if (username != null) { + slackMessage.addProperty(USERNAME, username); + } + + if (icon != null) { + if (icon.contains(HTTP)) { + slackMessage.addProperty(ICON_URL, icon); + } else { + slackMessage.addProperty(ICON_EMOJI, icon); + } + } + + slackMessage.addProperty(UNFURL_MEDIA, unfurlMedia); + slackMessage.addProperty(UNFURL_LINKS, unfurlLinks); + + if (text == null) { + throw new IllegalArgumentException( + "Missing Text field @ SlackMessage"); + } else { + slackMessage.addProperty(TEXT, text); + } + + if (!attach.isEmpty()) { + slackMessage.add(ATTACHMENTS, this.prepareAttach()); + } + + return slackMessage; + } + + private JsonArray prepareAttach() { + final JsonArray attachs = new JsonArray(); + for (SlackAttachment attach : this.attach) { + attachs.add(attach.toJson()); + } + + return attachs; + } + + public SlackMessage removeAttachment(int index) { + this.attach.remove(index); + + return this; + } + + public SlackMessage setAttachments(List attach) { + this.attach = attach; + + return this; + } + + public SlackMessage setChannel(String channel) { + if (channel != null) { + this.channel = channel; + } + + return this; + } + + /** + * See more icons in http://www.emoji-cheat-sheet.com/ + * + * @param icon + * Avatar + * @return SlackMessage + */ + public SlackMessage setIcon(String icon) { + if (icon != null) { + this.icon = icon; + } + + return this; + } + + public SlackMessage setText(String message) { + if (message != null) { + this.text = message; + } + + return this; + } + + public SlackMessage setUsername(String username) { + if (username != null) { + this.username = username; + } + + return this; + } + + public SlackMessage setUnfurlMedia(boolean unfurlMedia) { + this.unfurlMedia = unfurlMedia; + + return this; + } + + public SlackMessage setUnfurlLinks(boolean unfurlLinks) { + this.unfurlLinks = unfurlLinks; + + return this; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final SlackMessage that = (SlackMessage) o; + + if (unfurlMedia != that.unfurlMedia) return false; + if (unfurlLinks != that.unfurlLinks) return false; + if (attach != null ? !attach.equals(that.attach) : that.attach != null) return false; + if (channel != null ? !channel.equals(that.channel) : that.channel != null) return false; + if (icon != null ? !icon.equals(that.icon) : that.icon != null) return false; + if (text != null ? !text.equals(that.text) : that.text != null) return false; + return !(username != null ? !username.equals(that.username) : that.username != null); + + } + + @Override + public int hashCode() { + int result = attach != null ? attach.hashCode() : 0; + result = 31 * result + (channel != null ? channel.hashCode() : 0); + result = 31 * result + (icon != null ? icon.hashCode() : 0); + result = 31 * result + (text != null ? text.hashCode() : 0); + result = 31 * result + (username != null ? username.hashCode() : 0); + result = 31 * result + (unfurlMedia ? 1 : 0); + result = 31 * result + (unfurlLinks ? 1 : 0); + return result; + } + + @Override + public String toString() { + return "SlackMessage{" + + "attach=" + attach + + ", channel='" + channel + '\'' + + ", icon='" + icon + '\'' + + ", slackMessage=" + slackMessage + + ", text='" + text + '\'' + + ", username='" + username + '\'' + + ", unfurlMedia=" + unfurlMedia + + ", unfurlLinks=" + unfurlLinks + + '}'; + } +} diff --git a/common-master@c5eba833390/src/main/java/net/grandtheftmc/slack/action/SlackAction.java b/common-master@c5eba833390/src/main/java/net/grandtheftmc/slack/action/SlackAction.java new file mode 100644 index 0000000..4ddae04 --- /dev/null +++ b/common-master@c5eba833390/src/main/java/net/grandtheftmc/slack/action/SlackAction.java @@ -0,0 +1,91 @@ +package net.grandtheftmc.slack.action; + +import com.google.gson.JsonObject; + +/** + * Created by Luke Bingham on 05/09/2017. + */ +public class SlackAction { + private static final String NAME = "name"; + private static final String TEXT = "text"; + private static final String TYPE = "type"; + private static final String VALUE = "value"; + private static final String CONFIRM = "confirm"; + private static final String STYLE = "style"; + private static final String OPTIONS = "options"; + private static final String OPTION_GROUPS = "option_groups"; + private static final String DATA_SOURCE = "data_source"; + private static final String SELECTED_OPTIONS = "selected_options"; + private static final String MIN_QUERY_LENGTH = "min_query_length"; + + private String name; + private String text; + private SlackActionType type; + private String value; + private SlackActionStyle style; + + public SlackAction(String name, String text, SlackActionType type, String value) { + this.name = name; + this.text = text; + this.type = type; + this.value = value; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public SlackActionType getType() { + return type; + } + + public void setType(SlackActionType type) { + this.type = type; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public SlackActionStyle getStyle() { + return style; + } + + public void setStyle(SlackActionStyle style) { + this.style = style; + } + + public JsonObject toJson() { + final JsonObject data = new JsonObject(); + data.addProperty(NAME, name); + data.addProperty(TEXT, text); + + if (type != null) { + data.addProperty(TYPE, type.getCode()); + } + + data.addProperty(VALUE, value); + + if (style != null) { + data.addProperty(STYLE, style.getCode()); + } + + return data; + } +} diff --git a/common-master@c5eba833390/src/main/java/net/grandtheftmc/slack/action/SlackActionStyle.java b/common-master@c5eba833390/src/main/java/net/grandtheftmc/slack/action/SlackActionStyle.java new file mode 100644 index 0000000..b2fca25 --- /dev/null +++ b/common-master@c5eba833390/src/main/java/net/grandtheftmc/slack/action/SlackActionStyle.java @@ -0,0 +1,20 @@ +package net.grandtheftmc.slack.action; + +/** + * Created by Luke Bingham on 05/09/2017. + */ +public enum SlackActionStyle { + DEFAULT("default"), + PRIMARY("primary"), + DANGER("danger"); + + private String code; + + SlackActionStyle(String code) { + this.code = code; + } + + public String getCode() { + return code; + } +} diff --git a/common-master@c5eba833390/src/main/java/net/grandtheftmc/slack/action/SlackActionType.java b/common-master@c5eba833390/src/main/java/net/grandtheftmc/slack/action/SlackActionType.java new file mode 100644 index 0000000..b07e6f2 --- /dev/null +++ b/common-master@c5eba833390/src/main/java/net/grandtheftmc/slack/action/SlackActionType.java @@ -0,0 +1,19 @@ +package net.grandtheftmc.slack.action; + +/** + * Created by Luke Bingham on 05/09/2017. + */ +public enum SlackActionType { + BUTTON("button"), + SELECT("select"); + + private String code; + + SlackActionType(String code) { + this.code = code; + } + + public String getCode() { + return code; + } +} diff --git a/common-master@c5eba833390/src/main/java/net/grandtheftmc/slack/attachment/SlackAttachment.java b/common-master@c5eba833390/src/main/java/net/grandtheftmc/slack/attachment/SlackAttachment.java new file mode 100644 index 0000000..f4486c5 --- /dev/null +++ b/common-master@c5eba833390/src/main/java/net/grandtheftmc/slack/attachment/SlackAttachment.java @@ -0,0 +1,362 @@ +package net.grandtheftmc.slack.attachment; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import net.grandtheftmc.slack.SlackField; +import net.grandtheftmc.slack.action.SlackAction; + +/** + * Created by Luke Bingham on 05/09/2017. + */ +public class SlackAttachment { + + private static final String HEX_REGEX = "^([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$"; + private static final String FALLBACK = "fallback"; + private static final String CALLBACK_ID = "callback_id"; + private static final String TEXT = "text"; + private static final String PRETEXT = "pretext"; + private static final String COLOR = "color"; + private static final String FIELDS = "fields"; + private static final String AUTHOR_NAME = "author_name"; + private static final String AUTHOR_LINK = "author_link"; + private static final String AUTHOR_ICON = "author_icon"; + private static final String TITLE = "title"; + private static final String TITLE_LINK = "title_link"; + private static final String IMAGE_URL = "image_url"; + private static final String THUMB_URL = "thumb_url"; + private static final String MRKDWN_IN = "mrkdwn_in"; + private static final String ACTIONS = "actions"; + private static final String FOOTER = "footer"; + private static final String STAMP = "ts"; + + private String fallback; + private String callbackId; + private String text; + private String pretext; + private String color; + private String authorName; + private String authorLink; + private String authorIcon; + private String title; + private String titleLink; + private String imageUrl; + private String thumbUrl; + private Set markdownAttributes = new HashSet(); + private List fields = new ArrayList(); + private List actions = new ArrayList(); + private String footer; + + public SlackAttachment() { + } + + public SlackAttachment(String fallback) { + this.fallback = fallback; + } + + public SlackAttachment addFields(SlackField field) { + this.fields.add(field); + + return this; + } + + public SlackAttachment addAction(SlackAction action) { + this.actions.add(action); + + return this; + } + + public SlackAttachment addMarkdownAttribute(String attr) { + this.markdownAttributes.add(attr); + + return this; + } + + private boolean isHex(String pair) { + return pair.matches(HEX_REGEX); + } + + private JsonArray prepareFields() { + final JsonArray data = new JsonArray(); + for (SlackField field : fields) { + data.add(field.toJson()); + } + + return data; + } + + private JsonArray prepareActions() { + final JsonArray data = new JsonArray(); + for (SlackAction action : actions) { + data.add(action.toJson()); + } + + return data; + } + + public SlackAttachment removeAction(int index) { + this.actions.remove(index); + + return this; + } + + public SlackAttachment setFooter(String footer) { + this.footer = footer; + + return this; + } + + public SlackAttachment removeFields(int index) { + this.fields.remove(index); + + return this; + } + + private JsonArray prepareMarkdownAttributes() { + final JsonArray data = new JsonArray(); + for (String attr : markdownAttributes) { + data.add(new JsonPrimitive(attr)); + } + + return data; + } + + public SlackAttachment removeMarkdownAttribute(String attr) { + this.markdownAttributes.remove(attr); + + return this; + } + + public SlackAttachment setColor(String color) { + if (color != null) { + if (color.charAt(0) == '#') { + if (!isHex(color.substring(1))) { + throw new IllegalArgumentException("Invalid Hex Color @ SlackAttachment"); + } + } else if (!color.matches("^(good|warning|danger)$")) { + throw new IllegalArgumentException("Invalid PreDefined Color @ SlackAttachment"); + } + } + + this.color = color; + + return this; + } + + public SlackAttachment setFallback(String fallback) { + this.fallback = fallback; + + return this; + } + + public SlackAttachment setCallbackId(String callbackId) { + this.callbackId = callbackId; + + return this; + } + + public SlackAttachment setFields(List fields) { + this.fields = fields; + + return this; + } + + public SlackAttachment setPretext(String pretext) { + this.pretext = pretext; + + return this; + } + + public SlackAttachment setText(String text) { + this.text = text; + + return this; + } + + public SlackAttachment setAuthorName(String authorName) { + this.authorName = authorName; + + return this; + } + + public SlackAttachment setAuthorLink(String authorLink) { + this.authorLink = authorLink; + + return this; + } + + public SlackAttachment setAuthorIcon(String authorIcon) { + this.authorIcon = authorIcon; + + return this; + } + + public SlackAttachment setTitle(String title) { + this.title = title; + + return this; + } + + public SlackAttachment setTitleLink(String titleLink) { + this.titleLink = titleLink; + + return this; + } + + public SlackAttachment setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + + return this; + } + + public SlackAttachment setThumbUrl(String thumbUrl) { + this.thumbUrl = thumbUrl; + + return this; + } + + public JsonObject toJson() { + JsonObject data = new JsonObject(); + + if (fallback == null) { + throw new IllegalArgumentException("Missing Fallback @ SlackAttachment"); + } else { + data.addProperty(FALLBACK, fallback); + } + + if (text != null) { + data.addProperty(TEXT, text); + } + + if (pretext != null) { + data.addProperty(PRETEXT, pretext); + } + + if (color != null) { + data.addProperty(COLOR, color); + } + + if (authorName != null) { + data.addProperty(AUTHOR_NAME, authorName); + } + + if (authorLink != null) { + data.addProperty(AUTHOR_LINK, authorLink); + } + + if (authorIcon != null) { + data.addProperty(AUTHOR_ICON, authorIcon); + } + + if (title != null) { + data.addProperty(TITLE, title); + } + + if (titleLink != null) { + data.addProperty(TITLE_LINK, titleLink); + } + + if (imageUrl != null) { + data.addProperty(IMAGE_URL, imageUrl); + } + + if (thumbUrl != null) { + data.addProperty(THUMB_URL, thumbUrl); + } + + if (markdownAttributes != null) { + data.add(MRKDWN_IN, prepareMarkdownAttributes()); + } + + if (fields != null && fields.size() > 0) { + data.add(FIELDS, prepareFields()); + } + + if (actions != null && actions.size() > 0) { + data.add(ACTIONS, prepareActions()); + + if (callbackId == null) { + throw new IllegalArgumentException("Missing Callback ID @ SlackAttachment"); + } else { + data.addProperty(CALLBACK_ID, callbackId); + } + } + + if(footer != null) { + data.addProperty(FOOTER, footer); + data.addProperty(STAMP, System.currentTimeMillis()); + } + + return data; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + SlackAttachment that = (SlackAttachment) o; + + if (fallback != null ? !fallback.equals(that.fallback) : that.fallback != null) + return false; + if (text != null ? !text.equals(that.text) : that.text != null) + return false; + if (pretext != null ? !pretext.equals(that.pretext) : that.pretext != null) + return false; + if (color != null ? !color.equals(that.color) : that.color != null) + return false; + if (authorName != null ? !authorName.equals(that.authorName) : that.authorName != null) + return false; + if (authorLink != null ? !authorLink.equals(that.authorLink) : that.authorLink != null) + return false; + if (authorIcon != null ? !authorIcon.equals(that.authorIcon) : that.authorIcon != null) + return false; + if (title != null ? !title.equals(that.title) : that.title != null) + return false; + if (titleLink != null ? !titleLink.equals(that.titleLink) : that.titleLink != null) + return false; + if (imageUrl != null ? !imageUrl.equals(that.imageUrl) : that.imageUrl != null) + return false; + if (thumbUrl != null ? !thumbUrl.equals(that.thumbUrl) : that.thumbUrl != null) + return false; + if (markdownAttributes != null ? !markdownAttributes.equals(that.markdownAttributes) + : that.markdownAttributes != null) + return false; + return !(fields != null ? !fields.equals(that.fields) : that.fields != null); + + } + + @Override + public int hashCode() { + int result = fallback != null ? fallback.hashCode() : 0; + result = 31 * result + (text != null ? text.hashCode() : 0); + result = 31 * result + (pretext != null ? pretext.hashCode() : 0); + result = 31 * result + (color != null ? color.hashCode() : 0); + result = 31 * result + (authorName != null ? authorName.hashCode() : 0); + result = 31 * result + (authorLink != null ? authorLink.hashCode() : 0); + result = 31 * result + (authorIcon != null ? authorIcon.hashCode() : 0); + result = 31 * result + (title != null ? title.hashCode() : 0); + result = 31 * result + (titleLink != null ? titleLink.hashCode() : 0); + result = 31 * result + (imageUrl != null ? imageUrl.hashCode() : 0); + result = 31 * result + (thumbUrl != null ? thumbUrl.hashCode() : 0); + result = 31 * result + (markdownAttributes != null ? markdownAttributes.hashCode() : 0); + result = 31 * result + (fields != null ? fields.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "SlackAttachment{" + "fallback='" + fallback + '\'' + ", text='" + text + '\'' + ", pretext='" + pretext + + '\'' + ", color='" + color + '\'' + ", authorName='" + authorName + '\'' + ", authorLink='" + + authorLink + '\'' + ", authorIcon='" + authorIcon + '\'' + ", title='" + title + '\'' + + ", titleLink='" + titleLink + '\'' + ", imageUrl='" + imageUrl + '\'' + ", thumbUrl='" + thumbUrl + + '\'' + ", markdownAttributes=" + markdownAttributes + ", fields=" + fields + '}'; + } +} diff --git a/common-master@c5eba833390/src/main/java/net/grandtheftmc/slack/exception/SlackException.java b/common-master@c5eba833390/src/main/java/net/grandtheftmc/slack/exception/SlackException.java new file mode 100644 index 0000000..544c73a --- /dev/null +++ b/common-master@c5eba833390/src/main/java/net/grandtheftmc/slack/exception/SlackException.java @@ -0,0 +1,11 @@ +package net.grandtheftmc.slack.exception; + +/** + * Created by Luke Bingham on 05/09/2017. + */ +public class SlackException extends RuntimeException { + + public SlackException(Throwable cause) { + super(cause); + } +} diff --git a/core-master@6ef85bb745a/.gitignore b/core-master@6ef85bb745a/.gitignore new file mode 100644 index 0000000..b1935ec --- /dev/null +++ b/core-master@6ef85bb745a/.gitignore @@ -0,0 +1,102 @@ + +\.idea/ + +target/classes/ + +target/ + +*.iml + +/bin/ +/build/ + +##### Gradle ##### +.gradle +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache + +# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 +# gradle/wrapper/gradle-wrapper.properties + +##### Eclipse ##### +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders + +.project + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# PyDev specific (Python IDE for Eclipse) +*.pydevproject + +# CDT-specific (C/C++ Development Tooling) +.cproject + +# JDT-specific (Eclipse Java Development Tools) +.classpath + +# Java annotation processor (APT) +.factorypath + +# PDT-specific (PHP Development Tools) +.buildpath + +# sbteclipse plugin +.target + +# Tern plugin +.tern-project + +# TeXlipse plugin +.texlipse + +# STS (Spring Tool Suite) +.springBeans + +# Code Recommenders +.recommenders/ + +*.class + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear + + +##### IntelliJ ##### +*.iml +*.ipr +*.iws +.idea/ + +##### NetBeans ##### +/.nb-gradle/ + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +##### MacOS ##### +.DS_Store diff --git a/core-master@6ef85bb745a/README.md b/core-master@6ef85bb745a/README.md new file mode 100644 index 0000000..61ae224 --- /dev/null +++ b/core-master@6ef85bb745a/README.md @@ -0,0 +1,5 @@ +# GTMCore +Link: https://circleci.com/gh/GrandTheftMinecart/GTMCore +
+Latest Artifact: https://github.com/GrandTheftMinecart/GTMCore/releases/latest +-- \ No newline at end of file diff --git a/core-master@6ef85bb745a/pom.xml b/core-master@6ef85bb745a/pom.xml new file mode 100644 index 0000000..d27402e --- /dev/null +++ b/core-master@6ef85bb745a/pom.xml @@ -0,0 +1,271 @@ + + 4.0.0 + + net.grandtheftmc + core + + 2.3.10 + Core + + + + jitpack.io + https://jitpack.io + + + citizens-repo + http://repo.citizensnpcs.co/ + + + worldedit-repo + http://maven.sk89q.com/repo/ + + + dmulloy2-repo + http://repo.dmulloy2.net/nexus/repository/public/ + + + nexus-release + https://nexus.grandtheftmc.net/content/repositories/releases/ + + + bstats-repo + http://repo.bstats.org/content/repositories/releases/ + + + + + + nexus-release + Internal Releases + https://nexus.grandtheftmc.net/content/repositories/releases/ + + + nexus-snapshot + Internal Snapshots + https://nexus.grandtheftmc.net/content/repositories/snapshots/ + + + + + + net.citizensnpcs + citizensapi + 2.0.22 + provided + + + org.apache.poi + poi-ooxml + 3.15 + + + net.gpedro.integrations.slack + slack-webhook + 1.3.0 + + + com.neovisionaries + nv-websocket-client + 2.3 + + + org.json + json + 20131018 + compile + + + org.spigotmc.1.12 + spigot + 1.12.0 + provided + + + com.github.j0ach1mmall3 + JLib + 1.10.0 + provided + + + us.myles + viaversion + 1.0.4 + provided + + + + com.github.j0ach1mmall3 + UltimateCosmetics + 1.0.0 + provided + + + com.sk89q.worldedit + worldedit-bukkit + 6.1.5 + provided + + + com.github.vexsoftware + votifier + LATEST + provided + + + com.gmail.filoghost.holographicdisplays + HolographicDisplays + 1.0.0 + provided + + + com.earth2me + Essentials + 2.0.0 + provided + + + com.zaxxer + HikariCP + 2.6.0 + + + com.comphenix.protocol + ProtocolLib + LATEST + provided + + + redis.clients + jedis + 2.8.0 + jar + compile + + + org.apache.commons + commons-pool2 + 2.4.2 + + + net.grandtheftmc + common + 1.1.6 + + + net.buycraft + BuycraftX + 10.3.0 + provided + + + io.sentry + sentry + 1.5.2 + compile + + + de.oppermann.bastian.safetrade + safetrade + 1.0.14 + provided + + + com.squareup.okhttp3 + okhttp + 3.9.0 + provided + + + org.slf4j + slf4j-simple + 1.7.13 + + + org.slf4j + slf4j-api + 1.7.13 + + + + + UTF-8 + 1.8 + 1.8 + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.0.0 + + + + org.apache.poi.poi-ooxml + net.grandtheftmc.core.shaded.org.apache.poi.poi-ooxml + + + net.gpedro.integrations.slack.slack-webhook + net.grandtheftmc.core.shaded.net.gpedro.integrations.slack.slack-webhookl + + + redis.clients.jedis + net.grandtheftmc.core.shaded.redis.clients.jedis + + + org.apache.commons.pool + net.grandtheftmc.core.shaded.org.apache.commons.pool + + + com.neovisionaries.nv-websocket-client + net.grandtheftmc.core.shaded.com.neovisionaries.nv-websocket-client + + + redis.clients.util + net.grandtheftmc.core.shaded.redis.clients.util + + + Core + + + + package + + shade + + + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.8 + true + + + default-deploy + deploy + + deploy + + + + + nexus + http://nexus.grandtheftmc.net/ + true + + + + + \ No newline at end of file diff --git a/core-master@6ef85bb745a/setup/database_schema.txt b/core-master@6ef85bb745a/setup/database_schema.txt new file mode 100644 index 0000000..68c347b --- /dev/null +++ b/core-master@6ef85bb745a/setup/database_schema.txt @@ -0,0 +1,275 @@ +/***** +** Table Description: +** Represents user information. +** +** uuid is the uuid of the user +** name is the name of the user +** mutex is for mutual exclusion saves +** +** Reasoning for structure: +** PK is `uuid` , as there is a unique one per user. +** We add an index on name so we can do an efficient query for a name. +*****/ +CREATE TABLE IF NOT EXISTS user( +uuid BINARY(16) NOT NULL, +name VARCHAR(16) NOT NULL, +mutex TINYINT(1) NOT NULL DEFAULT 0, +PRIMARY KEY (uuid), +INDEX (name) +); + +/***** +** Table Description: +** Represents user cooldowns. +** +** uuid is the uuid of the user +** server_key is the id of the server +** id is the name of the cooldown +** endTime is the time that the cooldown will end. +** +** Reasoning for structure: +** PK is `uuid` and `id` since one player can have multiple `id`'s +** +*****/ +CREATE TABLE IF NOT EXISTS user_cooldown ( +uuid BINARY(16) NOT NULL, +server_key VARCHAR(10) NOT NULL, +id VARCHAR(32) NOT NULL, +endTime TIMESTAMP NOT NULL, +PRIMARY KEY (uuid, id)); +); + +/***** +** Table Description: +** Represents user profile information. +** +** uuid is the uuid of the user +** server_key is the id of the server +** rank is that users rank on the server +** +** Reasoning for structure: +** PK is `uuid, server_key` pair, as there can be a diff +** rank for a user on a diff server. +*****/ +CREATE TABLE IF NOT EXISTS user_profile( +uuid BINARY(16) NOT NULL, +server_key VARCHAR(10) NOT NULL, +rank VARCHAR(10) NOT NULL, +PRIMARY KEY (uuid, server_key), +FOREIGN KEY (uuid) REFERENCES user(uuid) ON DELETE CASCADE +); + +/***** +** Table Description: +** Represents user trial rank information. +** +** uuid is the uuid of the user +** server_key is the id of the server +** rank is that users trial rank on the server +** creation is when it was created +** expire_at is when the rank expires +** +** Reasoning for structure: +** PK is `uuid, server_key` pair, as there can be a diff +** rank for a user on a diff server. +*****/ +CREATE TABLE IF NOT EXISTS user_trial_rank( +uuid BINARY(16) NOT NULL, +server_key VARCHAR(10) NOT NULL, +rank VARCHAR(10) NOT NULL, +creation TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, +expire_at TIMESTAMP NOT NULL, +PRIMARY KEY (uuid, server_key), +FOREIGN KEY (uuid) REFERENCES user(uuid) ON DELETE CASCADE +); + +/***** +** Table Description: +** Represents user currency information. +** +** uuid is the uuid of the user +** server_key is the id of the server +** currency is the id of the currency +** amount is the amount of the currency +** +** Reasoning for structure: +** PK is `uuid, server_key, currency` tuple, as there can be a diff +** currency / server / uuid tuple. +*****/ +CREATE TABLE IF NOT EXISTS user_currency( +uuid BINARY(16) NOT NULL, +server_key VARCHAR(10) NOT NULL, +currency VARCHAR(16) NOT NULL, +amount INT NOT NULL, +PRIMARY KEY (uuid, server_key, currency), +FOREIGN KEY (uuid) REFERENCES user(uuid) ON DELETE CASCADE +); + +/***** +** Table Description: +** Represents user tag information. +** +** uuid is the uuid of the user +** server_key is the id of the server +** tag is the tag that they own +** enabled is whether its equipped +** +** Reasoning for structure: +** PK is `uuid, server_key, tag` tuple, as there can be a diff +** tags per server and per user. +*****/ +CREATE TABLE IF NOT EXISTS user_tag( +uuid BINARY(16) NOT NULL, +server_key VARCHAR(10) NOT NULL, +tag VARCHAR(16) NOT NULL, +enabled TINYINT(1) NOT NULL DEFAULT 0, +PRIMARY KEY (uuid, server_key, tag) +); + +/***** +** Table Description: +** Represents a log of currency transactions for users. +** +** uuid is the uuid of the user +** server_key is the id of the server +** currency is the id of the currency +** amount is the amount of the currency +** source is where the currency came from +** reason is optional data of what specifically the source is +** +** Reasoning for structure: +** PK is `id` as it's auto increment. +*****/ +CREATE TABLE IF NOT EXISTS log_currency_transaction( +id INT NOT NULL AUTO_INCREMENT, +uuid BINARY(16) NOT NULL, +server_key VARCHAR(10) NOT NULL, +currency VARCHAR(16) NOT NULL, +amount INT NOT NULL, +source VARCHAR(20) NOT NULL, +reason VARCHAR(40) NOT NULL DEFAULT "", +creation TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, +PRIMARY KEY (id) +); + +/***** +** Table Description: +** Represents user voting logs. +** +** uuid is the user that voted +** amount is the worth of their vote +** service_id is the service id that they voted on, from VoteSite.java +** +** Reasoning for structure: +** PK is the `id` field as this table logs all of the votes. +*****/ +CREATE TABLE IF NOT EXISTS log_user_vote( +id INT(10) unsigned NOT NULL AUTO_INCREMENT, +uuid BINARY(16) NOT NULL, +amount INT NOT NULL DEFAULT 1, +service_id TINYINT(1) NOT NULL, +creation TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, +PRIMARY KEY (id) +); + +/***** +** Table Description: +** Represents the tags that players have +** +** uuid is the user that the specific entry is for +** server_key is the server that it is for (global or gtm1 / vice1 etc) +** tag the display tag +** +** Reasoning for structure: +** have different entries for each column so global or server-specific can be specified +*****/ +CREATE TABLE IF NOT EXISTS user_tag( +uuid BINARY(16) NOT NULL, +server_key VARCHAR(10) NOT NULL, +tag VARCHAR(16) NOT NULL, +enabled TINYINT(1) NOT NULL DEFAULT 0, +PRIMARY KEY (uuid, server_key, tag) +); + +/***** +** Table Description: +** Represents the different npcs in the world. +** +** location is the location of the npc +** server_key is the server that it is for (global or gtm1 / vice1 etc) +** reference is the name of the class that the npc represents. +** +** Reasoning for structure: +** have different entries for each column so global or server-specific can be specified +*****/ +CREATE TABLE IF NOT EXISTS npc_record ( +location VARCHAR(255) NOT NULL, +reference VARCHAR(100) NOT NULL, +server_key VARCHAR(10) NOT NULL, +PRIMARY KEY (location) + +/***** +** Table Description: +** Represents the weapon skins that players have +** +** uuid is the user that the specific entry is for +** server_key is the server that it is for (global or gtm1 / vice1 etc) +** weapon_id the int id for the weapon +** skin_id is the int id for the skin +** +** Reasoning for structure: +** Have different entries for each column so global or server-specific can be specified +*****/ +CREATE TABLE IF NOT EXISTS user_weapon_skin( +uuid BINARY(16) NOT NULL, +server_key VARCHAR(10) NOT NULL, +weapon_id TINYINT NOT NULL, +skin_id TINYINT NOT NULL, +enabled TINYINT(1) DEFAULT 0, +PRIMARY KEY (uuid, server_key, weapon_id, skin_id) +); + +/***** +** Table Description: +** Represents the join info for the player. +** +** uuid is the user that the specific entry is for +** initial_server_address is the ip the user connected to for the network for the first time +** last_server_address is the ip the user connected to most recently +** join_date is when the user joined the server +** last_login is the when the user last logged in +** +** Reasoning for structure: +** Unique key is the uuid of the player, so it's an efficient lookup. +*****/ +CREATE TABLE IF NOT EXISTS user_join_info( +uuid BINARY(16) NOT NULL, +initial_server_address VARCHAR(30) NOT NULL, +last_server_address VARCHAR(30) NOT NULL, +join_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, +last_login TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, +PRIMARY KEY (uuid), +FOREIGN KEY (uuid) REFERENCES user(uuid) +); + +/***** +** Table Description: +** Represents user ammo information. +** +** uuid is the uuid of the user +** server_key is the id of the server +** ammo is the id of the ammo +** amount is the amount of the currency +** +** Reasoning for structure: +** PK is `uuid, server_key, ammo` tuple, as there can be a diff +** ammo / server / uuid tuple. +*****/ +CREATE TABLE IF NOT EXISTS user_ammo( +uuid BINARY(16) NOT NULL, +server_key VARCHAR(10) NOT NULL, +ammo VARCHAR(16) NOT NULL, +amount INT NOT NULL, +PRIMARY KEY (uuid, server_key, ammo), +FOREIGN KEY (uuid) REFERENCES user(uuid) ON DELETE CASCADE +); diff --git a/core-master@6ef85bb745a/setup/script/copy_house.py b/core-master@6ef85bb745a/setup/script/copy_house.py new file mode 100644 index 0000000..0cdd08a --- /dev/null +++ b/core-master@6ef85bb745a/setup/script/copy_house.py @@ -0,0 +1,172 @@ +#!/usr/bin/python + +# local imports + +# python modules +import MySQLdb +import string +import time + +DB_HOST = "localhost" +DB_USER = "root" +DB_PASS = "" +DB_NAME = "" +# number of queries per interval +MAX_QUERY_TICK = 10000000000 +# how long in seconds we sleep for +TICK_SLEEP = 1 + +FROM_SERVER_KEY = "GTM1" +TO_SERVER_KEY = "GTM2" + +QUERY_GET_HOUSES = ''' SELECT id, house_num, premium, currency, price FROM gtm_house WHERE server_key = %s; ''' +QUERY_GET_HOUSE_DATA = ''' SELECT hotspot_id, hotspot_type, data FROM gtm_house_data WHERE house_id = %s; ''' +QUERY_CREATE_HOUSE = ''' INSERT INTO gtm_house (house_num, server_key, premium, currency, price) VALUES (%s, %s, %s, %s, %s);''' +QUERY_CREATE_HOUSE_DATA = ''' INSERT INTO gtm_house_data (house_id, hotspot_type, data) VALUES (%s, %s, %s);''' + +# open MySQL connection +db = MySQLdb.connect(host=DB_HOST, user=DB_USER, passwd=DB_PASS, db=DB_NAME) +# grab cursor +cur = db.cursor() + +# print out variables +print("MAX_QUERY_TICK = " + str(MAX_QUERY_TICK)) +print("TICK_SLEEP = " + str(TICK_SLEEP)) +print("FROM_SERVER_KEY = " + str(FROM_SERVER_KEY)) +print("TO_SERVER_KEY = " + str(TO_SERVER_KEY)) +print("QUERY_GET_HOUSES = " + str(QUERY_GET_HOUSES)) +print("QUERY_GET_HOUSE_DATA = " + str(QUERY_GET_HOUSE_DATA)) +print("QUERY_CREATE_HOUSE = " + str(QUERY_CREATE_HOUSE)) +print("QUERY_CREATE_HOUSE_DATA = " + str(QUERY_CREATE_HOUSE_DATA)) + +def get_houses(server_key): + ''' + Get all the houses with the specified server key. + + Args: + server_key: The server key to get the houses for, i.e. "GTM1" + + Returns: + A list of tuples for the houses on the server key in the form + of (house_id, house_num, premium, currency, price). + ''' + data = (str(server_key)) + cur.execute(QUERY_GET_HOUSES, data) + + houses = [] + for tup in cur: + house_id = int(tup[0]) + house_num = int(tup[1]) + premium = bool(tup[2]) + currency = str(tup[3]) + price = int(tup[4]) + + houses.append((house_id, house_num, premium, currency, price)) + + return houses + +def get_house_data(house_id): + ''' + Get all the data regarding the house. + + Args: + house_id: The id of the house + + Returns: + A list of tuples for the house data in the form of (hotspot_id, hotspot_type, data). + ''' + data = (int(house_id)) + cur.execute(QUERY_GET_HOUSE_DATA, data) + + house_data = [] + for tup in cur: + hotspot_id = int(tup[0]) + hotspot_type = str(tup[1]) + data = str(tup[2]) + + house_data.append((hotspot_id, hotspot_type, data)) + + return house_data + +def create_house_entry(house_num, server_key, premium, currency, price): + ''' + Creates an entry in the 'gtm_house' table. + + Args: + house_num: The number of the house + server_key: The server key that this house is on + premium: Whether or not this is a premium house + currency: The currency involved for the purchase of this house + price: The amount of the currency involved for the purchase of this house + + Returns: + The generated house_id that is unique, if one was made. + ''' + data = (int(house_num), str(server_key), bool(premium), str(currency), int(price)) + cur.execute(QUERY_CREATE_HOUSE, data) + + # return the generated key + return cur.lastrowid + +def create_house_data_entry(house_id, hotspot_type, data): + ''' + Creates an entry in the 'gtm_house_data' table. + + Args: + house_id: The unique id of the house, generated by the database + hotspot_type: The type of the hotspot + data: The data associated with the hotspot + ''' + data = (int(house_id), str(hotspot_type), str(data)) + cur.execute(QUERY_CREATE_HOUSE_DATA, data) + +######### +# BELOW IS THE ACTUAL SCRIPT LOGIC +######### + +print('Running script...') +start_time = time.time() + +# limit the amount of queries to the database per interval +tick = 0 + +houses = get_houses(server_key=FROM_SERVER_KEY) +houses_created = 0 +house_data_found = 0 +house_data_created = 0 +for house_id, house_num, premium, currency, price in houses: + tick += 1 + + # create new house in new server + generated_house_id = create_house_entry(house_num=house_num, server_key=TO_SERVER_KEY, premium=premium, currency=currency, price=price) + if generated_house_id is not None and generated_house_id > 0: + houses_created += 1 + + # get house data from original house id + house_data = get_house_data(house_id=house_id) + if house_data is not None and len(house_data) > 0: + + house_data_found += len(house_data) + + for hotspot_id, hotspot_type, data in house_data: + create_house_data_entry(house_id=generated_house_id, hotspot_type=hotspot_type, data=data) + house_data_created += 1 + + if tick > MAX_QUERY_TICK: + tick = 0 + time.sleep(TICK_SLEEP) + break + +# commit query +db.commit() +cur.close() + +run_time = time.time() - start_time +print('Script is now complete! (' + str(run_time) + ' secs)') +print('Number of houses found: ' + str(len(houses))) +print('Number of houses created: ' + str(houses_created)) +print('Number of house data found: ' + str(house_data_found)) +print('Number of house data created: ' + str(house_data_created)) + +# close the connection +db.close() \ No newline at end of file diff --git a/core-master@6ef85bb745a/setup/script/data_mine.py b/core-master@6ef85bb745a/setup/script/data_mine.py new file mode 100644 index 0000000..f075d05 --- /dev/null +++ b/core-master@6ef85bb745a/setup/script/data_mine.py @@ -0,0 +1,141 @@ +#!/usr/bin/python + +# local imports + +# python modules +import MySQLdb +import time +import sys + +DB_HOST = "localhost" +DB_USER = "root" +DB_PASS = "" +DB_NAME = "" +QUERY = ''' SELECT backpackContents, name FROM gtm1; ''' +SELECT_COL = 'backpackContents' + +# open MySQL connection +db = MySQLdb.connect(host=DB_HOST, user=DB_USER, passwd=DB_PASS, db=DB_NAME) + +def get_largest_data(query, select_col): + ''' + Mine the data and determine the largest value for the given query. + + Args: + query: The query to run + select_col: The column to select + + Returns: + The largest data entry for the given query. + ''' + + largest = 0 + name = None + backpack_data = None + + # grab cursor + cur = db.cursor() + cur.execute(query) + + # commit query + db.commit() + + result = [] + for tup in cur: + x = tup[0] + + size_x = utf8len(str(x)) + if size_x >= largest: + largest = size_x + print(largest) + name = str(tup[1]) + backpackContents = str(x) + + temp = {} + temp[name] = backpackContents + result.append(temp) + + cur.close() + + return result + +def utf8len(s): + ''' + Get the length of a given string. + + Args: + s - the string in question + + Returns: + The length of the string . + ''' + return len(s.encode('utf-8')) + +def get_len_by_sys(s): + ''' + Get the length of a given string according to the sys module. + + Args: + s - the string in question + + Returns: + The length of the string. + ''' + return sys.getsizeof(s) + +def insert_data(name, backpack): + ''' + Insert data into a test column to see if it fits. + + Args: + name - the name of the user to insert fake data for + ''' + + largest = 0 + name = None + + # grab cursor + cur = db.cursor() + query = ''' SELECT uuid, backpackContents FROM gtm1 WHERE name=%s''' + data = [str(name)] + cur.execute(query, data) + + uuid = None + for tup in cur: + uuid = str(tup[0]) + + uuid = "0xDD" + + # grab cursor + cur = db.cursor() + query = ''' INSERT IGNORE INTO backpack_test (uuid, backpack) VALUES (%s, %s)''' + data = (uuid, backpack) + cur.execute(query, data) + + # commit query + db.commit() + cur.close() + + +######### +# BELOW IS THE ACTUAL SCRIPT LOGIC +######### + +print('Running script fix_house_data.py...' ) +print() +start_time = time.time() + +data_set = get_largest_data(query=QUERY, select_col=SELECT_COL) +#print(data_set) + +# for element in data_set: +# for k in element: +# print("k", k) +# insert_data(k, element[k]) + +run_time = time.time() - start_time + +print('Finished script in ' + str(run_time) + ' secs.') + +# close the connection +db.close() \ No newline at end of file diff --git a/core-master@6ef85bb745a/setup/script/fix_house_data.py b/core-master@6ef85bb745a/setup/script/fix_house_data.py new file mode 100644 index 0000000..d588b17 --- /dev/null +++ b/core-master@6ef85bb745a/setup/script/fix_house_data.py @@ -0,0 +1,213 @@ +#!/usr/bin/python + +# local imports + +# python modules +import MySQLdb +import time +import json + +DB_HOST = "localhost" +DB_USER = "root" +DB_PASS = "" +DB_NAME = "" + +# open MySQL connection +db = MySQLdb.connect(host=DB_HOST, user=DB_USER, passwd=DB_PASS, db=DB_NAME) + +# CREATE TABLE IF NOT EXISTS gtm_house ( +# id INT NOT NULL AUTO_INCREMENT, +# house_num INT NOT NULL, +# server_key VARCHAR(10) NOT NULL, +# premium TINYINT(1) NOT NULL DEFAULT 0, +# currency VARCHAR(10) NOT NULL, +# price INT NOT NULL, +# PRIMARY KEY (id), +# UNIQUE INDEX (house_num, server_key, premium) +# ); + +def get_premium_houses(): + ''' + Get all the premium houses that exist on the network. + + Returns: + A list of id where each id is the unique house id. + ''' + + # grab cursor + cur = db.cursor() + + query = ''' SELECT id FROM gtm_house WHERE premium=1 ORDER BY id DESC LIMIT 1000; ''' + cur.execute(query) + + # commit query + db.commit() + + result = [] + for tup in cur: + result.append(int(tup[0])) + + cur.close() + + return result + +# CREATE TABLE IF NOT EXISTS gtm_house_user ( +# house_id INT NOT NULL, +# uuid BINARY(16) NOT NULL, +# is_owner TINYINT(1) NOT NULL, +# PRIMARY KEY (house_id, uuid), +# INDEX(uuid), +# FOREIGN KEY (house_id) REFERENCES gtm_house(id) ON DELETE CASCADE +# ); + +def is_house_owned(house_id): + ''' + Get whether or not the house is owned by a player. + + Args: + house_id: The id of the house + + Return: + True of the house is owned by a player, False otherwise. + ''' + # grab cursor + cur = db.cursor() + + query = ''' SELECT COUNT(*) FROM gtm_house_user WHERE house_id=%s; ''' + data = (house_id) + cur.execute(query, [data]) + + # commit query + db.commit() + + num_users = 0 + for tup in cur: + num_users = int(tup[0]) + + cur.close() + + result = False + if num_users > 0: + result = True + + return result + +# CREATE TABLE IF NOT EXISTS gtm_house_data ( +# house_id INT NOT NULL, +# hotspot_id INT NOT NULL AUTO_INCREMENT, +# hotspot_type VARCHAR(5) NOT NULL, +# data BLOB DEFAULT NULL, +# PRIMARY KEY (hotspot_id), +# INDEX (house_id), +# FOREIGN KEY (house_id) REFERENCES gtm_house(id) ON DELETE CASCADE +# ); + +def get_house_data(house_id, hotspot_type): + ''' + Get the house data for the specified house id and the hotspot_type. + + Args: + house_id: The unique id for the house + hotspot_type: The type of hotspot data + + Returns: + A list of tuples in the form of (house_id, hotspot_id, hotspot_type, data). + ''' + # grab cursor + cur = db.cursor() + + query = ''' SELECT house_id, hotspot_id, hotspot_type, data FROM gtm_house_data WHERE house_id=%s AND hotspot_type=%s; ''' + data = (house_id, hotspot_type) + cur.execute(query, data) + + # commit query + db.commit() + + result = [] + for tup in cur: + result.append((int(tup[0]), int(tup[1]), str(tup[2]), str(tup[3]))) + + cur.close() + return result + +def update_house_data(house_id, hotspot_id, hotspot_type, data): + ''' + Updates the house data in the database. + + Args: + house_id: The id of the house + hotspot_id: The id of the hotspot + hotspot_type: The type of the hotspot + data: The data json object + ''' + # grab cursor + cur = db.cursor() + + query = ''' UPDATE gtm_house_data SET data=%s WHERE house_id=%s AND hotspot_id=%s AND hotspot_type=%s ''' + data = (str(data), int(house_id), int(hotspot_id), str(hotspot_type)) + cur.execute(query, data) + + # commit query + db.commit() + cur.close() + + +######### +# BELOW IS THE ACTUAL SCRIPT LOGIC +######### + +print('Running script fix_house_data.py...' ) +print() +start_time = time.time() + +# get all premium houses +premium_house_ids = get_premium_houses() +houses_changed = 0 +trash_data_changed = 0 +for house_id in premium_house_ids: + + # TODO re-enable + print('Running house_id #' + str(house_id)) + + # is the house owned + owned = is_house_owned(house_id=house_id) + + # has this data for this house been changed + changed = False + + if not owned: + + # get all TRASH data + trash_data_list = get_house_data(house_id=house_id, hotspot_type='TRASH') + if trash_data_list is not None and len(trash_data_list) > 0: + + # for each data + for hid, hotspot_id, hotspot_type, data in trash_data_list: + + # convert to json + json_data = json.loads(data) + if 'owned' in json_data and json_data['owned'] is True: + json_data['owned'] = False + + # convert back to string + new_data = json.dumps(json_data) + + # update new house data + update_house_data(house_id=hid, hotspot_id=hotspot_id, hotspot_type='TRASH', data=new_data) + + print('Changed owned trash for house_id #' + str(house_id)) + + # stats + trash_data_changed += 1 + if not changed: + changed = True + houses_changed += 1 + +run_time = time.time() - start_time +print('Number of initial premium houses = ' + str(len(premium_house_ids))) +print('Number of houses that were changed = ' + str(houses_changed)) +print('Number of data that were changed = ' + str(trash_data_changed)) +print('Finished script in ' + str(run_time) + ' secs.') + +# close the connection +db.close() \ No newline at end of file diff --git a/core-master@6ef85bb745a/setup/script/fix_user_data.py b/core-master@6ef85bb745a/setup/script/fix_user_data.py new file mode 100644 index 0000000..80b6ac7 --- /dev/null +++ b/core-master@6ef85bb745a/setup/script/fix_user_data.py @@ -0,0 +1,306 @@ +#!/usr/bin/python + +# local imports + +# python modules +import MySQLdb +import time +import json +import urllib2 +import base64 + +DB_HOST = "localhost" +DB_USER = "root" +DB_PASS = "" +DB_NAME = "" + +# open MySQL connection +db = MySQLdb.connect(host=DB_HOST, user=DB_USER, passwd=DB_PASS, db=DB_NAME) + +def request_api(username): + ''' + This will request the API server. + + Args: + username: The username to use to lookup the uuid. + + Returns: + The uuid for the user with the name username, otherwise None. + ''' + + api_url = "https://api.mojang.com/users/profiles/minecraft/{}".format(username) # This server can be pinged as many times as needed. + req = urllib2.Request(api_url) + try: + resp = urllib2.urlopen(req) + except urllib2.HTTPError as e: + if e.code == 404: + pass + # do something... + else: + pass + # ... + except urllib2.URLError as e: + pass + # Not an HTTP-specific error (e.g. connection refused) + # ... + else: + # 200 + body = resp.read() + + if body is not None and body is not '': + decoded_body = body.decode("utf-8") + api_load = json.loads(decoded_body) + + if 'id' in api_load: + return str(api_load['id']) + + return None + +def request_name(uuid): + ''' + This will request the names server. + + Args: + uuid: The uuid to use to get the name. + + Returns: + The last known name for the given uuid, if one exists, other None. + ''' + + name_url = "https://api.mojang.com/user/profiles/{}/names".format(uuid) # This server can be pinged as many times as needed. + + req = urllib2.Request(name_url) + try: + resp = urllib2.urlopen(req) + except urllib2.HTTPError as e: + if e.code == 404: + pass + # do something... + else: + pass + # ... + except urllib2.URLError as e: + pass + # Not an HTTP-specific error (e.g. connection refused) + # ... + else: + # 200 + body = resp.read() + + if body is not None and body is not '': + decoded_body = body.decode("utf-8") + name_load = json.loads(decoded_body) + + if len(name_load) > 0: + last_known_name = name_load[-1] + + if last_known_name is not None and 'name' in last_known_name: + return str(last_known_name['name']) + + return None + +# CREATE TABLE `user` ( +# `uuid` binary(16) NOT NULL, +# `name` varchar(16) NOT NULL, +# PRIMARY KEY (`uuid`), +# KEY `name` (`name`); + +def get_duplicate_users(): + ''' + Get a list of names where they have duplicate entries in the database. + + Returns: + A list of names where each name is a duplicate uuid, name pair in the database. + ''' + + # grab cursor + cur = db.cursor() + + query = ''' SELECT name, COUNT(*) FROM user GROUP BY name ORDER BY COUNT(*) DESC LIMIT 500; ''' + cur.execute(query) + + # commit query + db.commit() + + result = [] + for tup in cur: + name = str(tup[0]) + num = int(tup[1]) + + # only add to list those that have duplicates + if num > 1: + result.append(name) + + cur.close() + + return result + +def get_uuids(name): + ''' + Get a list of uuids for the given name. + + Returns: + A list of uuids for the given name. + ''' + + # grab cursor + cur = db.cursor() + + query = ''' SELECT HEX(uuid) FROM user WHERE name=%s; ''' + data = (name) + cur.execute(query, [data]) + + # commit query + db.commit() + + result = [] + for tup in cur: + uuid = str(tup[0]) + result.append(uuid) + + cur.close() + + return result + +def get_last_login(name): + ''' + Get last login information for this user. + + Args: + The name of the user to lookup. + + Returns: + TODO + ''' + + # grab cursor + cur = db.cursor() + + query = ''' SELECT uuid, lastname, last_login FROM users WHERE lastname=%s ORDER BY last_login DESC; ''' + data = (name) + cur.execute(query, [data]) + + # commit query + db.commit() + + result = [] + for tup in cur: + uuid = str(tup[0]) + lastname = str(tup[1]) + last_login = str(tup[2]) + + print(last_login) + + result.append((uuid, lastname, last_login)) + + cur.close() + + return result + +def update_name_for_user(uuid, name): + ''' + Updates the name record for the uuid. + + Args: + uuid: The uuid primary key that never changes + name: The name of the user to change for + ''' + + # grab cursor + cur = db.cursor() + + query = ''' UPDATE user SET name=%s WHERE uuid=UNHEX(%s); ''' + data = (str(name), str(uuid)) + cur.execute(query, data) + + # commit query + db.commit() + cur.close() + +def delete_user_record(uuid): + ''' + Deletes the user record from the database. + + Args: + uuid: The uuid primary key to delete. + ''' + + # grab cursor + cur = db.cursor() + + query = ''' DELETE FROM user WHERE uuid=UNHEX(%s); ''' + data = (str(uuid)) + cur.execute(query, [data]) + + # commit query + db.commit() + cur.close() + +######### +# BELOW IS THE ACTUAL SCRIPT LOGIC +######### + +print('Running script fix_user_data.py...' ) +print() +start_time = time.time() + +# get duplicate users +dup_users = get_duplicate_users() + +print('Found ' + str(len(dup_users)) + ' uuid/name pairs with duplicates.') + +# how many names were resolved by the mojang api +names_found = 0 +# how many names were not resolved by the mojang api +names_not_found = 0 +# how many user names were changed in the user table +user_names_changed = 0 + +# TODO remove +count = 0 +if dup_users is not None and len(dup_users) > 0: + for du in dup_users: + + # grab the uuids with this username + uuids = get_uuids(name=du) + if uuids is not None and len(uuids) > 0: + + for uid in uuids: + + # mojang api request for last known name + last_known_name = request_name(uuid=uid) + + # if we have a name for them + if last_known_name is not None: + print('Last known name for uuid=' + str(uid) + ' is ' + str(last_known_name)) + names_found = names_found + 1 + + update_name_for_user(uuid=uid, name=last_known_name) + user_names_changed = user_names_changed + 1 + + # else its an offline uuid + else: + print('Could not find last known name for uuid=' + str(uid)) + names_not_found = names_not_found + 1 + + delete_user_record(uuid=uid) + + count = count + 1 + if count > 50: + break + +# TEST CASES +#print(request_api(username='BlameStephen')) +#print(request_name(uuid='0bfd8917b6bf48088b12c59ec43e4260')) +#print(request_name(uuid='0FF3234F08D33344887FDB721202F9BB')) +#print(request_name(uuid='0BFD8917B6BF48088B12C59EC43E4260')) + +run_time = time.time() - start_time +print('Number of duplicate entries found = ' + str(len(dup_users))) +print('Number of names found = ' + str(names_found)) +print('Number of names NOT found = ' + str(names_not_found)) +print('Number of usernames changed = ' + str(user_names_changed)) +print('Finished script in ' + str(run_time) + ' secs.') + +# close the connection +db.close() \ No newline at end of file diff --git a/core-master@6ef85bb745a/setup/script/fix_user_table_foreign.py b/core-master@6ef85bb745a/setup/script/fix_user_table_foreign.py new file mode 100644 index 0000000..8b5439b --- /dev/null +++ b/core-master@6ef85bb745a/setup/script/fix_user_table_foreign.py @@ -0,0 +1,189 @@ +#!/usr/bin/python + +# local imports + +# python modules +import MySQLdb +import string +import time + +DB_HOST = "localhost" +DB_USER = "root" +DB_PASS = "" +DB_NAME = "" +# number of queries per interval +MAX_QUERY_TICK = 10000000 +# how long in seconds we sleep for +TICK_SLEEP = 1 + +QUERY_LARGE_SET = ''' SELECT HEX(uuid), name FROM gtm1; ''' +QUERY_SMALL_SET = ''' SELECT HEX(uuid), name FROM user; ''' +QUERY_FOREIGN_SET = ''' SELECT HEX(uuid) AS gu, G.name FROM gtm1 G WHERE G.uuid NOT IN (SELECT uuid FROM user);''' + +# open MySQL connection +db = MySQLdb.connect(host=DB_HOST, user=DB_USER, passwd=DB_PASS, db=DB_NAME) +# grab cursor +cur = db.cursor() + +# print out variables +print("MAX_QUERY_TICK = " + str(MAX_QUERY_TICK)) +print("TICK_SLEEP = " + str(TICK_SLEEP)) +print("QUERY_LARGE_SET = " + str(QUERY_LARGE_SET)) +print("QUERY_SMALL_SET = " + str(QUERY_SMALL_SET)) +print("QUERY_FOREIGN_SET = " + str(QUERY_FOREIGN_SET)) + +def get_foreign_users(): + ''' + Get all the users that exist in the gtm table but not in the user table. + + Return: + A list of pairs in the form of (uuid, name) for all the users. + ''' + + # grab cursor + #cur = db.cursor() + cur.execute(QUERY_FOREIGN_SET) + + users = [] + for tup in cur: + + uuid = str(tup[0]) + name = str(tup[1]) + + users.append((uuid, name)) + + # commit query + # db.commit() + # cur.close() + + return users + +def get_large_users(): + ''' + Get all the users known on the network for the specified gtm table. + + Return: + A list of pairs in the form of (uuid, name) for all the users. + ''' + + # grab cursor + #cur = db.cursor() + cur.execute(QUERY_LARGE_SET) + + users = [] + for tup in cur: + + uuid = str(tup[0]) + name = str(tup[1]) + + users.append((uuid, name)) + + # commit query + # db.commit() + # cur.close() + + return users + +def get_small_users(): + ''' + Get all the users known on the network for the user table. + + Return: + A list of users uuid for all the users. + ''' + + # grab cursor + #cur = db.cursor() + cur.execute(QUERY_SMALL_SET) + + users = [] + for tup in cur: + + uuid = str(tup[0]) + + users.append(uuid) + + # commit query + # db.commit() + # cur.close() + + return users + + +def create_user(uuid, name): + ''' + Create user information for the respective player. + + Args: + uuid: The uuid of the user + name: The name of the user + ''' + # grab cursor + # cur = db.cursor() + query = '''INSERT IGNORE INTO user VALUES (UNHEX(%s), %s) ON DUPLICATE KEY UPDATE name=VALUES(name);''' + data = (str(uuid), str(name)) + cur.execute(query, data) + + # commit query + # db.commit() + # cur.close() + +######### +# BELOW IS THE ACTUAL SCRIPT LOGIC +######### + +print('Running script...') +start_time = time.time() + +# limit the amount of queries to the database per interval +tick = 0 + +# get the large set of users (a list of tuples) +#large_users = get_large_users() + +# get the small set of users (a list of uuid) +#small_users = get_small_users() + +#creation_set = [] + +users_created = 0 + +# # for each user in gtm1 +# for uuid, name in large_users: +# tick += 1 + +# if uuid not in small_users: +# print('name', name) +# create_user(uuid=uuid, name=name) +# users_created += 1 + +# if tick > MAX_QUERY_TICK: +# tick = 0 +# time.sleep(TICK_SLEEP) + +foreign_users = get_foreign_users() + +# for each user in gtm1 +for uuid, name in foreign_users: + tick += 1 + + print('name', name) + create_user(uuid=uuid, name=name) + users_created += 1 + + if tick > MAX_QUERY_TICK: + tick = 0 + time.sleep(TICK_SLEEP) + +db.commit() +cur.close() + +# convert ranks + +run_time = time.time() - start_time +print('Script is now complete! (' + str(run_time) + ' secs)') +print('Number of users found in foreign set: ' + str(len(foreign_users))) +print('Number of users created: ' + str(users_created)) + +# close the connection +db.close() \ No newline at end of file diff --git a/core-master@6ef85bb745a/setup/script/mine_log.py b/core-master@6ef85bb745a/setup/script/mine_log.py new file mode 100644 index 0000000..5e07920 --- /dev/null +++ b/core-master@6ef85bb745a/setup/script/mine_log.py @@ -0,0 +1,259 @@ +#!/usr/bin/python + +# python modules +import json +import subprocess +import socket +import time +import datetime + +# pip modules +import requests + +FILE_NAME = '/var/log/auth.log' +USE_CURRENT_DATE = True + +SLACK_API_URL = 'https://hooks.slack.com/services/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' + +# maps fingerprint to name +FINGER_DICT = { + 'e3:a8:ef:d2:61:b1:13:8c:b0:e6:bc:aa:9c:3f:b0:90': 'Stephen', + '35:73:3c:fa:86:41:c2:28:e7:d2:4f:aa:38:62:6e:a5': 'Brad', + # brad macbook pro + 'dc:28:e9:c3:31:4b:7d:1b:fb:fe:c1:bb:5b:d9:d6:ab': 'Brad', + '1d:70:6b:a0:e4:89:ee:1f:63:4b:18:a4:92:07:e8:52': 'Mason', + # mason backup + '35:c9:a6:d4:06:e8:4a:fb:e4:a0:44:ec:36:bf:43:d6': 'Mason', + '33:ed:70:4e:02:3f:6f:a0:ff:e5:3c:f6:8f:67:fd:fb': 'Tim', + '8c:b8:40:b1:e9:ee:e8:7e:b2:d6:39:6f:24:5c:e3:f6': 'Jed', + '8b:ba:38:ff:e2:b1:28:b5:e1:6a:1c:24:8b:98:89:77': 'Liam', + '71:7f:fd:8b:cc:eb:db:98:98:62:3c:6a:06:8d:92:6f': 'Luke', + '47:cb:84:d1:6a:6e:94:a8:f7:b6:11:48:b5:72:8e:cf': 'Jesse', + # Jesse access + '76:c4:be:23:43:71:b4:d8:c8:3d:a3:a2:1b:bf:db:57': 'Jesse', + # Jesse backup + 'b7:1d:90:ac:25:20:c9:96:fb:3a:3c:9a:9e:8a:02:19': 'Jesse', +} + +# maps name to ip +NAME_DICT = { + 'Stephen': ['24.101.17.184', '24.112.212.17'], + 'Luke': ['90.240.15.159', '90.255.162.177', '90.255.175.1', '2.124.198.224'], + 'Mason': ['198.24.182.226', '24.253.105.169'], + 'Jed': ['150.143.79.210', '150.143.79.195'], + 'Brad': ['98.149.243.111'], + 'Tim': ['70.68.9.211'], + 'Jesse': ['95.97.205.201', '144.217.180.29', '162.208.95.194', '84.241.199.136', '139.162.217.42', '84.241.197.240', '12.217.236.130', '85.159.210.213'], +} + +class SlackAPI(object): + def __init__(self, api_url, headers, debug=False): + ''' + Args: + api_url: The URL for the API request + headers: The headers attached to this post request + debug: Boolean on whether we should print out debugging info + ''' + self.api_url = api_url + self.headers = headers + self.debug = debug + + def __str__(self): + ''' + Returns: + The string representation for this Message object. + ''' + return 'SlackAPI [api_url=' + str(self.api_url) + ', headers=' + str(self.headers) + ', debug=' + str(self.debug) + + def send_json(self, json_contents): + ''' + Send an arbitrary json object as a POST message to the specified URL. + + Args: + json: The dictionary representation that is being sent. + + Returns: + The response from the POST request, False if something happened. + ''' + try: + r = requests.post(self.api_url, data=json.dumps(json_contents), headers=self.headers) + print(r) + return r + except Exception as e: + print('Unknown exception occurred when trying to send ' + str(json) + ' for Message ' + str(self)) + print(e) + return False + + def send_message(self, contents, channel, username, icon_emoji): + ''' + Sends a POST request message with the given attributes. + + Args: + contents: The contents of the message as the 'text' field + channel: The channel to send the message + username: The username that is posting + icon_emoji: The emoji that the username has + + Returns: + The response from the POST request, False if something happened. + ''' + + # construct the JSON object + json_contents = {} + json_contents['text'] = contents + json_contents['channel'] = channel + json_contents['username'] = username + json_contents['icon_emoji'] = icon_emoji + + return self.send_json(json_contents) + +class Message(object): + def __init__(self): + + # initialize contents as a python dictionary + self.contents = {} + + # initialize attachments as a list + self.attachments = [] + + def add_attachment(self, data): + ''' + Adds the specified data as an attachment to the message. + + Args: + data: The data to add as an attachment + + Returns: + True if the attachment was added, False otherwise. + ''' + if type(data) is dict: + self.attachments.append(data) + return True + + return False + + def get_contents(self): + ''' + Get the contents of this message in terms of a Python dictionary. + + Returns: + The contents of this message. + ''' + c = self.contents + c['attachments'] = self.attachments + return c + +# Below is an example of how to use this module +# api_url = "https://hooks.slack.com/services/TOKEN" +# headers = {'content-type': 'application/json'} +# slack = SlackAPI(api_url=api_url, headers=headers, debug=True) +# slack.send_message(contents='Hello Slack!', channel='#general', username='TestAPIBot', icon_emoji=':smile:') + +# Mar 3 20:43:36 GTM-OVH-4 sshd[20268]: Accepted publickey for root from 198.24.182.226 port 53327 ssh2: RSA 35:c9:a6:d4:06:e8:4a:fb:e4:a0:44:ec:36:bf:43:d6 +# Mar 3 20:43:36 GTM-OVH-4 sshd[20268]: Accepted publickey for root from 198.24.182.226 port 53327 ssh2: RSA 35:c9:a6:d4:06:e8:4a:fb:e4:a0:44:ec:36:bf:43:d6 +# Mar 3 20:43:36 GTM-OVH-4 sshd[20268]: Accepted publickey for root from 198.24.182.226 port 53327 ssh2: RSA 35:c9:a6:d4:06:e8:4a:fb:e4:a0:44:ec:36:bf:43:d6 + +# maps ip to list of tuple (date_tuple) +UNKNOWN_LOGIN = {} +# maps unknown fingerprints to ips +UNKNOWN_FINGERPRINT = {} + +# grab the current time +current_time = datetime.date.today().strftime("%b %d") + +print('Running mine_log.py for ' + current_time) + +with open(FILE_NAME) as f: + lines = f.readlines() + + for line in lines: + + # strip new line away + #line = line.rstrip('\n') + line = " ".join(line.split()) + + if 'Accepted publickey for' in line: + + # split by space + parts = line.split(" ") + + # for i in range(0, len(parts)): + # print("index " + str(i) + " = " + str(parts[i])) + if parts is not None and len(parts) > 0: + date_str_full = str(parts[0]) + " " + str(parts[1]) + " " + str(parts[2]) + date_str_md = str(parts[0]) + " " + str(parts[1]) + user_str = str(parts[8]) + ip_str = str(parts[10]) + rsa_str = str(parts[15]) + + # if we want to use current date + if USE_CURRENT_DATE: + + # only parse lines from same date (month/day) + if current_time != date_str_md: + continue + + # have we seen this ip for this fingerprint + if rsa_str in FINGER_DICT: + name = FINGER_DICT[rsa_str] + + if name in NAME_DICT: + ip_list = NAME_DICT[name] + + if ip_str in ip_list: + pass + else: + # print(str(ip_str) + ' has logged in using ' + str(name) + '\'s RSA key!') + + result = None + if ip_str in UNKNOWN_LOGIN: + result = UNKNOWN_LOGIN[ip_str] + else: + result = [] + + data_tuple = (date_str_full, user_str, rsa_str, name) + result.append(data_tuple) + + UNKNOWN_LOGIN[ip_str] = result + else: + result = None + if ip_str in UNKNOWN_LOGIN: + result = UNKNOWN_LOGIN[ip_str] + else: + result = [] + + data_tuple = (date_str_full, user_str, rsa_str, name) + result.append(data_tuple) + + UNKNOWN_LOGIN[ip_str] = result + else: + # mark as UNKNOWN FINGERPRINT + UNKNOWN_FINGERPRINT[rsa_str] = ip_str + +local_ip = socket.gethostbyaddr(socket.gethostname()) +date = str(time.strftime("%c")) +SEND_MESSAGE = False + +contents = 'Box IP: ' + str(local_ip[0]) + ', Access Log for ' + str(date) + '\n' + +if len(UNKNOWN_LOGIN) > 0: + SEND_MESSAGE = True + + for key in UNKNOWN_LOGIN: + num_accesses = len(UNKNOWN_LOGIN[key]) + contents += 'Foreign IP (' + str(key) + ') x' + str(num_accesses) + ' conns using: ' + str(UNKNOWN_LOGIN[key][0][2]) + ' (' + str(UNKNOWN_LOGIN[key][0][3]) + ')' + contents += '\n' + +if len(UNKNOWN_FINGERPRINT) > 0: + SEND_MESSAGE = True + + contents += '\nThe following fingerprints are unknown: \n' + for key in UNKNOWN_FINGERPRINT: + contents += 'RSA (' + str(key) + ') with IP (' + str(UNKNOWN_FINGERPRINT[key]) + ')' + contents += '\n' + +if SEND_MESSAGE: + headers = {'content-type': 'application/json'} + slack = SlackAPI(api_url=SLACK_API_URL, headers=headers) + slack.send_message(contents=contents, channel='#important', username='Mine Log', icon_emoji=':closed_lock_with_key:') + diff --git a/core-master@6ef85bb745a/setup/script/python_script.sh b/core-master@6ef85bb745a/setup/script/python_script.sh new file mode 100644 index 0000000..f0c5d05 --- /dev/null +++ b/core-master@6ef85bb745a/setup/script/python_script.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# print debug messages +echo "Script is $@" + +cd "/minecraft" +# run python script +python "$@" \ No newline at end of file diff --git a/core-master@6ef85bb745a/setup/script/slack_api.py b/core-master@6ef85bb745a/setup/script/slack_api.py new file mode 100644 index 0000000..96c1094 --- /dev/null +++ b/core-master@6ef85bb745a/setup/script/slack_api.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python + +# python modules +import json +import subprocess + +# pip modules +import requests + +class SlackAPI(object): + def __init__(self, api_url, headers, debug=False): + ''' + Args: + api_url: The URL for the API request + headers: The headers attached to this post request + debug: Boolean on whether we should print out debugging info + ''' + self.api_url = api_url + self.headers = headers + self.debug = debug + + def __str__(self): + ''' + Returns: + The string representation for this Message object. + ''' + return 'SlackAPI [api_url=' + str(self.api_url) + ', headers=' + str(self.headers) + ', debug=' + str(self.debug) + + def send_json(self, json_contents): + ''' + Send an arbitrary json object as a POST message to the specified URL. + + Args: + json: The dictionary representation that is being sent. + + Returns: + The response from the POST request, False if something happened. + ''' + try: + r = requests.post(self.api_url, data=json.dumps(json_contents), headers=self.headers) + print(r) + return r + except Exception as e: + print('Unknown exception occurred when trying to send ' + str(json) + ' for Message ' + str(self)) + print(e) + return False + + def send_message(self, contents, channel, username, icon_emoji): + ''' + Sends a POST request message with the given attributes. + + Args: + contents: The contents of the message as the 'text' field + channel: The channel to send the message + username: The username that is posting + icon_emoji: The emoji that the username has + + Returns: + The response from the POST request, False if something happened. + ''' + + # construct the JSON object + json_contents = {} + json_contents['text'] = contents + json_contents['channel'] = channel + json_contents['username'] = username + json_contents['icon_emoji'] = icon_emoji + + return self.send_json(json_contents) + +class Message(object): + def __init__(self): + + # initialize contents as a python dictionary + self.contents = {} + + # initialize attachments as a list + self.attachments = [] + + def add_attachment(self, data): + ''' + Adds the specified data as an attachment to the message. + + Args: + data: The data to add as an attachment + + Returns: + True if the attachment was added, False otherwise. + ''' + if type(data) is dict: + self.attachments.append(data) + return True + + return False + + def get_contents(self): + ''' + Get the contents of this message in terms of a Python dictionary. + + Returns: + The contents of this message. + ''' + c = self.contents + c['attachments'] = self.attachments + return c + +# Below is an example of how to use this module +# api_url = "https://hooks.slack.com/services/TOKEN" +# headers = {'content-type': 'application/json'} +# slack = SlackAPI(api_url=api_url, headers=headers, debug=True) +# slack.send_message(contents='Hello Slack!', channel='#general', username='TestAPIBot', icon_emoji=':smile:') + diff --git a/core-master@6ef85bb745a/setup/script/stat_app.py b/core-master@6ef85bb745a/setup/script/stat_app.py new file mode 100644 index 0000000..2382ae3 --- /dev/null +++ b/core-master@6ef85bb745a/setup/script/stat_app.py @@ -0,0 +1,550 @@ +#!/usr/bin/python + +# local imports + +# python modules +import MySQLdb +import string +import time +import logging, logging.handlers +import os +import sys +import csv +import json +import slack_api + +# MySQL database creds +DB_HOST = "localhost" +DB_USER = "root" +DB_PASS = "" +DB_NAME = "bat" +# slack credentials +SLACK_API_URL = 'https://hooks.slack.com/services/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' +# The name of the network +NETWORK_NAME = 'Grand Theft Minecraft' +# the icon's url used in the bot that sends the response +ICON_URL = 'https://s3-us-west-2.amazonaws.com/slack-files2/avatars/2017-09-07/237267836001_e1d81f50852486fa452c_132.png' + +# slack hookup +SLACK_HEADERS = {'content-type': 'application/json'} +SLACK_SERVER = slack_api.SlackAPI(api_url=SLACK_API_URL, headers=SLACK_HEADERS) + +# set up the logger +LOG = logging.getLogger('stat_log') +LOG.setLevel(logging.DEBUG) +handler = logging.handlers.RotatingFileHandler("stats.log", backupCount=5) +handler.setFormatter(logging.Formatter('[%(asctime)s][%(levelname)s]: %(message)s')) +LOG.addHandler(handler) + +# open MySQL connection +db = MySQLdb.connect(host=DB_HOST, user=DB_USER, passwd=DB_PASS, db=DB_NAME) +gtmdb = MySQLdb.connect(host=DB_HOST, user=DB_USER, passwd=DB_PASS, db='users') +# grab cursor +cur = db.cursor() + +class StatApp(object): + + def __init__(self, file_name='network_stats.csv'): + + # internal data, generated by collect() + self.data = [] + self.dict_data = {} + self.file_name = file_name + + # the internal data folder for stats + self.internal_folder = '/minecraft/stats' + # the file directory + name, ex: /home/cache.txt used for caching data + self.cache_dir_and_file = self.internal_folder + '/cache.txt' + + # make sure the folder exists if it doesn't + if not os.path.exists(self.internal_folder): + os.makedirs(self.internal_folder) + + def collect(self): + ''' + Collects the stats that this app should handle. + ''' + + # collect the stats + default = self.collect_default() + spec = self.collect_specific() + if spec is None: + spec = [] + + self.data = default + spec + + # create the dict representation of this data + for k,v in self.data: + self.dict_data[k] = v + + # try: + # # optional call-back for after the data is collected + # self.on_collect() + # except Exception as e: + # err_msg = 'Error occurred in on_collect(). ' + str(e) + # print(err_msg) + # LOG.error(err_msg) + + + def collect_default(self): + ''' + Collects the default stats, like number of unique players. + + Returns: + A list of tuples, in the form of (category, value), as the default stats + we are collecting. + ''' + + # we'll store results in here + result = [] + + # grab default stats and add to result + result.append(("Total Unique Players", get_total_unique_players())) + result.append(("Active Users (1 day)", get_num_players_last_x_days(1))) + result.append(("Active Users (7 days)", get_num_players_last_x_days(7))) + result.append(("Active Users (30 days)", get_num_players_last_x_days(30))) + result.append(("New Users (1 day)", get_num_players_joined_x_days(1))) + result.append(("New Users (7 days)", get_num_players_joined_x_days(7))) + result.append(("New Users (30 days)", get_num_players_joined_x_days(30))) + + return result + + def collect_specific(self): + ''' + Collects the specific stats, different for each network. + + Returns: + A list of tuples, in the form of (category, value), as the stats + we are collecting. + ''' + + # we'll store results in here + result = [] + + # NOTE: this should be implemented for specific projects. + result.append(("Votes (1 day)", get_num_votes_x_days(1))) + result.append(("Votes (7 days)", get_num_votes_x_days(7))) + result.append(("Votes (30 days)", get_num_votes_x_days(30))) + + return result + + def save_to_csv(self): + ''' + Saves this object to the csv file. + ''' + + # if there is data to save + if self.data is not None and len(self.data) > 0: + + # sort into columns / values + columns = [] + values = [] + + columns.append('Time') + #values.append(str(time.ctime(time.time()))) + values.append(str(time.strftime('%Y-%b-%d'))) + columns.append('Day') + #values.append(str(time.ctime(time.time()))) + values.append(str(time.strftime('%A'))) + + for k,v in self.data: + columns.append(k) + values.append(v) + + # write to csv, generates headers if file doesn't exist + write_row_csv(self.internal_folder + '/' + str(self.file_name), columns, values) + + def save_to_file(self): + ''' + Writes the specified internal data of this factory to a file in the form of JSON. + ''' + + # if there is data to save + if self.data is not None and len(self.data) > 0: + + # build a dictionary of key/value + cache = {} + for k,v in self.data: + cache[k] = v + + # add the timestamp + cache['Time'] = str(time.ctime(time.time())) + + with open(self.internal_folder + '/cache.txt', 'wb') as outfile: + json.dump(cache, outfile) + + def notify_slack(self): + ''' + Send a message to slack about this object. + ''' + + # create a message + message = slack_api.Message() + + # add attachments + attachments = self.get_attachments() + if attachments is not None and len(attachments) > 0: + for a in attachments: + message.add_attachment(a) + + message_data = message.get_contents() + message_data['channel'] = '#important' + message_data['username'] = NETWORK_NAME + message_data['icon_emoji'] = ':bar_chart:' + + # send message to Slack + if SLACK_SERVER is not None: + SLACK_SERVER.send_json(message_data) + + def get_attachments(self): + ''' + Get the attachments for a message that are being sent to Slack. + + Returns: + A list of attachments that are to be added to the slack message. + ''' + + result = [] + + # get the default attachments and add to result + default = self.get_def_attachments() + if default is not None and len(default) > 0: + result = result + default + + # get specific attachments and add to result + specific = self.get_spec_attachments() + if specific is not None and len(specific) > 0: + result = result + specific + + return result + + def get_def_attachments(self): + ''' + Get the default attachments that are to be sent to Slack in the message. + + Returns: + A list of attachments, in the form of a dict, to be added the Slack message. + ''' + + total_unique_players = self.dict_data["Total Unique Players"] + active_user_1 = self.dict_data["Active Users (1 day)"] + active_user_7 = self.dict_data["Active Users (7 days)"] + active_user_30 = self.dict_data["Active Users (30 days)"] + new_user_1 = self.dict_data["New Users (1 day)"] + new_user_7 = self.dict_data["New Users (7 days)"] + new_user_30 = self.dict_data["New Users (30 days)"] + vote_1 = self.dict_data["Votes (1 day)"] + vote_7 = self.dict_data["Votes (7 days)"] + vote_30 = self.dict_data["Votes (30 days)"] + + old_data = None + # if cached stats file exists + if os.path.isfile(self.cache_dir_and_file): + with open(self.cache_dir_and_file) as data_file: + old_data = json.load(data_file) + + # these will be mutated if we have cached results from previous running of script + active_user_line1 = str(active_user_1) + new_user_line1 = str(new_user_1) + active_user_line7 = str(active_user_7) + new_user_line7 = str(new_user_7) + active_user_line30 = str(active_user_30) + new_user_line30 = str(new_user_30) + vote_line1 = str(vote_1) + vote_line7 = str(vote_7) + vote_line30 = str(vote_30) + + # if cached old_data, change the line data + if old_data is not None: + prev_active1 = int(old_data['Active Users (1 day)']) + prev_new1 = int(old_data['New Users (1 day)']) + prev_active7 = int(old_data['Active Users (7 days)']) + prev_new7 = int(old_data['New Users (7 days)']) + prev_active30 = int(old_data['Active Users (30 days)']) + prev_new30 = int(old_data['New Users (30 days)']) + prev_vote1 = int(old_data['Votes (1 day)']) + prev_vote7 = int(old_data['Votes (7 days)']) + prev_vote30 = int(old_data['Votes (30 days)']) + + # calculate change, expressed in % + active_change1 = "{0:.2f}".format(get_state_of_change(prev_active1, active_user_1)) + new_change1 = "{0:.2f}".format(get_state_of_change(prev_new1, new_user_1)) + active_change7 = "{0:.2f}".format(get_state_of_change(prev_active7, active_user_7)) + new_change7 = "{0:.2f}".format(get_state_of_change(prev_new7, new_user_7)) + active_change30 = "{0:.2f}".format(get_state_of_change(prev_active30, active_user_30)) + new_change30 = "{0:.2f}".format(get_state_of_change(prev_new30, new_user_30)) + vote_change1 = "{0:.2f}".format(get_state_of_change(prev_vote1, vote_1)) + vote_change7 = "{0:.2f}".format(get_state_of_change(prev_vote7, vote_7)) + vote_change30 = "{0:.2f}".format(get_state_of_change(prev_vote30, vote_30)) + + # active_change1 = int(round(get_state_of_change(prev_active1, active_user_1))) + # new_change1 = int(round(get_state_of_change(prev_new1, new_user_1))) + # active_change7 = int(round(get_state_of_change(prev_active7, active_user_7))) + # new_change7 = int(round(get_state_of_change(prev_new7, new_user_7))) + # active_change30 = int(round(get_state_of_change(prev_active30, active_user_30))) + # new_change30 = int(round(get_state_of_change(prev_new30, new_user_30))) + + active_user_line1 = str(active_user_1) + ' (' + str(active_change1) + '%)' + new_user_line1 = str(new_user_1) + ' (' + str(new_change1) + '%)' + active_user_line7 = str(active_user_7) + ' (' + str(active_change7) + '%)' + new_user_line7 = str(new_user_7) + ' (' + str(new_change7) + '%)' + active_user_line30 = str(active_user_30) + ' (' + str(active_change30) + '%)' + new_user_line30 = str(new_user_30) + ' (' + str(new_change30) + '%)' + vote_line1 = str(vote_1) + ' (' + str(vote_change1) + '%)' + vote_line7 = str(vote_7) + ' (' + str(vote_change7) + '%)' + vote_line30 = str(vote_30) + ' (' + str(vote_change30) + '%)' + + contents = {} + contents['title'] = 'User Report' + contents['color'] = 'good' + + # build the fields + fields = [] + f1 = {} + f1['title'] = 'Active (Last 7 days)' + f1['value'] = active_user_line7 + f1['short'] = True + f2 = {} + f2['title'] = 'Active (Last 30 days)' + f2['value'] = active_user_line30 + f2['short'] = True + f3 = {} + f3['title'] = 'New (Last 7 days)' + f3['value'] = new_user_line7 + f3['short'] = True + f4 = {} + f4['title'] = 'New (Last 30 days)' + f4['value'] = new_user_line30 + f4['short'] = True + f5 = {} + f5['title'] = 'Votes (Last 7 days)' + f5['value'] = vote_line7 + f5['short'] = True + f6 = {} + f6['title'] = 'Votes (Last 30 days)' + f6['value'] = vote_line30 + f6['short'] = True + f7 = {} + f7['title'] = 'Total Users' + f7['value'] = int(total_unique_players) + f7['short'] = True + + fields.append(f1) + fields.append(f2) + fields.append(f3) + fields.append(f4) + fields.append(f5) + fields.append(f6) + fields.append(f7) + contents['fields'] = fields + + if type(contents) is dict: + # general footer + contents['footer'] = str(NETWORK_NAME) + contents['footer_icon'] = str(ICON_URL) + # attach the timestamp + contents['ts'] = int(time.time()) + + result = [] + result.append(contents) + + return result + + def get_spec_attachments(self): + ''' + Optional implementation to get specific stats attachments to be sent to Slack. + + Returns: + A list of attachments, in the form of a dict, to add to the message to be sent to Slack. + ''' + pass + +def write_row_csv(fname, headers, data_row): + ''' + Writes the data to a csv file. + + Args: + fname: absolute name of the file, with directory + headers: list of strings representing the column headings + data_row: the data entry to write, as a list + ''' + + # if no file, generate headings + if not os.path.isfile(fname): + cw = csv.writer(open(fname, 'wb')) + cw.writerow(headers) + + # open csv writer with the append feature + cw = csv.writer(open(fname, 'ab')) + + # write the row + cw.writerow(data_row) + +def get_total_unique_players(): + ''' + Gets the total amount of players that have ever logged in. + ''' + query = '''SELECT COUNT(*) FROM BAT_players''' + cur.execute(query) + + count = 0 + for tup in cur: + count = int(tup[0]) + + # commit query + # db.commit() + + return count + +def get_num_players_last_x_days(day): + ''' + Args: + day - the amount of days to look back + + Gets the number of players that last logged on in the past day days. + ''' + query = '''SELECT COUNT(*) FROM BAT_players WHERE lastlogin >= (CURDATE() - INTERVAL %s DAY);''' + data = (day) + cur.execute(query, [data]) + + count = 0 + for tup in cur: + count = int(tup[0]) + + # # commit query + # db.commit() + + return count + +def get_num_players_joined_x_days(day): + ''' + Args: + day - the amount of days to look back + + Gets the number of players that joined the server in the past day days. + ''' + + cur = db.cursor() + query = '''SELECT COUNT(*) FROM BAT_players WHERE firstlogin >= (CURDATE() - INTERVAL %s DAY);''' + data = (day) + cur.execute(query, [data]) + + count = 0 + for tup in cur: + count = int(tup[0]) + + # commit query + # db.commit() + + return count + +def get_num_votes_x_days(day): + ''' + Args: + day - the amount of days to look back + + Gets the number of players that joined the server in the past day days. + ''' + + # grab cursor + cur = gtmdb.cursor() + query = '''SELECT COUNT(*) FROM log_user_vote WHERE creation >= (CURDATE() - INTERVAL %s DAY);''' + data = (day) + cur.execute(query, [data]) + + count = 0 + for tup in cur: + count = int(tup[0]) + + # commit query + # db.commit() + + return count + +def get_state_of_change(prev, new): + ''' + Calculates the percent of change from the previous to the new. + + Ex: If prev=50, and new=100, the state of change is (100-50)/50 * 100 = 100% + + Returns: + The percent state of change, so times 100. + ''' + + diff = int(new - prev) + change = 0 + if prev > 0: + change = float(diff) / float(prev) + + return change * 100.0 + +######### +# BELOW IS THE ACTUAL SCRIPT LOGIC +######### + +def command_help(): + print('You run this script by using: ') + print('- python stat_app.py run') + print('\nYou run and publish results to slack by: ') + print('- python stat_app.py publish') + print('\nYou can display test information, without writing it to files: ') + print('- python stat_app.py test') + +def command_test(): + print('Running script in test mode...') + LOG.debug('Running script in test mode...') + + # construct a new stats object + stat_obj = StatApp() + + # collect the stats information, and cache it inside the object + stat_obj.collect() + + if stat_obj.data is not None and len(stat_obj.data) > 0: + for k,v in stat_obj.data: + print(str(k) + ' -> ' + str(v)) + +def command_run(slack_post=False): + print('Running script in execute mode, slack_post=' + str(slack_post)) + LOG.debug('Running script in execute mode, slack_post=' + str(slack_post)) + + # construct a new stats object + stat_obj = StatApp() + + # collect the stats information, and cache it inside the object + stat_obj.collect() + LOG.debug('Data collected: ' + str(stat_obj.dict_data)) + + # write to csv + stat_obj.save_to_csv() + + if slack_post == True: + stat_obj.notify_slack() + + # save to file, we can use to retrieve previous day's information + stat_obj.save_to_file() + + print('Script has finished running. Look in ' + str(stat_obj.internal_folder)) + LOG.debug('Script has finished running. Look in ' + str(stat_obj.internal_folder)) + +if __name__ == '__main__': + + # execute from command line + if len(sys.argv) > 1: + command = str(sys.argv[1]).lower() + + if command == 'help': + command_help() + elif command == 'test': + command_test() + elif command == 'run': + command_run(slack_post=False) + elif command == 'publish': + command_run(slack_post=True) + +# commit query +db.commit() +cur.close() + +# close the connection +db.close() \ No newline at end of file diff --git a/core-master@6ef85bb745a/setup/script/transpose_gang.py b/core-master@6ef85bb745a/setup/script/transpose_gang.py new file mode 100644 index 0000000..e49c7db --- /dev/null +++ b/core-master@6ef85bb745a/setup/script/transpose_gang.py @@ -0,0 +1,383 @@ +#!/usr/bin/python + +# local imports + +# python modules +import MySQLdb +import string +import time + +DB_HOST = "localhost" +DB_USER = "root" +DB_PASS = "" +DB_NAME = "" +# number of queries per interval +MAX_QUERY_TICK = 10000000 +# how long in seconds we sleep for +TICK_SLEEP = 1 + +SERVER_KEY = "GTM0" +QUERY_GET_GANGS = '''SELECT name, leader, leaderName, description, maxMembers FROM gtm0_gangs;''' +QUERY_GET_GANG_RELATIONS = '''SELECT gang1, gang2, relation FROM gtm0_gangs_relations;''' +QUERY_GET_USER_GANG = '''SELECT uuid, gang, gangRank FROM gtm0 WHERE gang IS NOT NULL;''' + + +# open MySQL connection +db = MySQLdb.connect(host=DB_HOST, user=DB_USER, passwd=DB_PASS, db=DB_NAME) +# grab cursor +cur = db.cursor() + +# print out variables +print("MAX_QUERY_TICK = " + str(MAX_QUERY_TICK)) +print("TICK_SLEEP = " + str(TICK_SLEEP)) +print("SERVER_KEY = " + str(SERVER_KEY)) +print("QUERY_GET_GANGS = " + str(QUERY_GET_GANGS)) +print("QUERY_GET_GANG_RELATIONS = " + str(QUERY_GET_GANG_RELATIONS)) +print("QUERY_GET_USER_GANG = " + str(QUERY_GET_USER_GANG)) + +# CREATE TABLE IF NOT EXISTS gtm_gang( +# id INT NOT NULL AUTO_INCREMENT, +# server_key VARCHAR(10) NOT NULL, +# name VARCHAR(36) NOT NULL, +# owner BINARY(16) NOT NULL, +# description VARCHAR(255) NOT NULL, +# max_members INT(11) NOT NULL, +# PRIMARY KEY (id), +# INDEX (server_key), +# INDEX (name) +# ); + +# represents a gang +class Gang(object): + def __init__(self): + # id of the gang + self.id = -1 + # the server that this gang is for + self.server_key = None + # name of the gang + self.name = None + # uuid of the owner of the gang + self.owner = None + # description of the gang + self.description = None + # max members this gang can hold + self.max_members = 0 + + def __str__(self): + return 'id=' + str(self.id) + ", server_key=" + str(self.server_key) + ", name=" + str(self.name) + ", owner=" + str(self.owner) + ", description=" + str(self.description) + ", max_members=" + str(self.max_members) + +# CREATE TABLE IF NOT EXISTS gtm_gang_member( +# gang_id INT NOT NULL, +# uuid BINARY(16) NOT NULL, +# role SMALLINT(6) DEFAULT 1, +# PRIMARY KEY (gang_id, uuid), +# FOREIGN KEY (gang_id) REFERENCES gtm_gang(id) ON DELETE CASCADE +# ); + +# represents a gang member +class GangMember(object): + def __init__(self): + # the id of the gang + self.gang_id = -1 + # the name of the gang + self.gang_name = None + # uuid of the member + self.uuid = None + # role of the member + self.role = None + + def __str__(self): + return "gang_id=" + str(self.gang_id) + ", gang_name=" + str(self.gang_name) + ",uuid=" + str(self.uuid) + ", role=" + str(self.role) + +# CREATE TABLE IF NOT EXISTS gtm_gang_relation( +# gang_id INT NOT NULL, +# other_id INT NOT NULL, +# relation VARCHAR(10), +# PRIMARY KEY (gang_id, other_id), +# FOREIGN KEY (gang_id) REFERENCES gtm_gang(id) ON DELETE CASCADE, +# FOREIGN KEY (other_id) REFERENCES gtm_gang(id) ON DELETE CASCADE +# ); + +def get_gangs(): + ''' + Get all the gangs that belong in the specified table. + + Returns: + A list of dictionary objects that represent a gang. + ''' + + # # grab cursor + # cur = db.cursor() + cur.execute(QUERY_GET_GANGS) + + gangs = [] + for tup in cur: + g = Gang() + g.server_key = str(SERVER_KEY) + g.name = str(tup[0]) + g.owner = string.replace(str(tup[1]), "-", "") + g.description = str(tup[3]) + g.max_members = int(tup[4]) + gangs.append(g) + + # # commit query + # db.commit() + # cur.close() + + return gangs + +def create_gang(gang): + ''' + Create the new representation of the gang in the new table. + + Args: + gang: The gang object to create. + ''' + # # grab cursor + # cur = db.cursor() + query = '''INSERT INTO gtm_gang (server_key, name, owner, description, max_members) VALUES (%s, %s, UNHEX(%s), %s, %s);''' + data = (str(gang.server_key), str(gang.name), str(gang.owner), str(gang.description), int(gang.max_members)) + cur.execute(query, data) + + # # commit query + # db.commit() + # cur.close() + +def create_gang_member(gang_member): + ''' + Create the gang member representation in the database. + + Args: + gang_member: The member object to create + ''' + + # get the role of the member + rank = gang_member.role + # determine the role to change it to + role = 1 + + if rank is not None: + rank = str(rank).lower() + + if rank == 'member': + role = 1 + elif rank == 'trusted': + role = 2 + elif rank == 'coleader': + role = 5 + elif rank == 'leader': + role = 6 + + # # grab cursor + # cur = db.cursor() + query = '''INSERT INTO gtm_gang_member (gang_id, uuid, role) VALUES (%s, UNHEX(%s), %s);''' + data = (int(gang_member.gang_id), str(gang_member.uuid), int(role)) + cur.execute(query, data) + + # # commit query + # db.commit() + # cur.close() + +def create_gang_relation(gang1_id, gang2_id, relation): + ''' + Create the gang relation in the database. + + Args: + gang1_id: The id of the first gang + gang2_id: The id of the second gang + relation: The relationship they share + ''' + + # # grab cursor + # cur = db.cursor() + query = '''INSERT INTO gtm_gang_relation (gang_id, other_id, relation) VALUES (%s, %s, %s);''' + data = (int(gang1_id), int(gang2_id), str(relation)) + cur.execute(query, data) + + # # commit query + # db.commit() + # cur.close() + +def get_relations(): + ''' + Get a list of relation objects that need parsed. + + Returns: + A relation objects that need parsed, in the form of a tuple (gang1, gang2, relation). + ''' + + # # grab cursor + # cur = db.cursor() + cur.execute(QUERY_GET_GANG_RELATIONS) + + relations = [] + for tup in cur: + gang1 = str(tup[0]) + gang2 = str(tup[1]) + relation = str(tup[2]) + + relations.append((gang1, gang2, relation)) + + # # commit query + # db.commit() + # cur.close() + + return relations + +def get_users(): + ''' + Get a list of users and their respective gang member information. + + Returns: + A list of GangMember objects where each one represents information about a member of a gang. + ''' + + # # grab cursor + # cur = db.cursor() + cur.execute(QUERY_GET_USER_GANG) + + users = [] + for tup in cur: + gm = GangMember() + gm.uuid = string.replace(str(tup[0]), "-", "") + #print('gm.uuid', gm.uuid) + gm.gang_name = str(tup[1]) + #print('gm.gang_name', gm.gang_name) + gm.role = str(tup[2]) + #print('gm.role', gm.role) + users.append(gm) + + # # commit query + # db.commit() + # cur.close() + + return users + +def find_gang_id(server_key, gang_name): + ''' + Find the id of a gang by their gang name. + + Args: + server_key: The server key for the gang + name: The name of the gang to find + + Returns: + The id of the gang, if one exists, otherwise None. + ''' + + # # grab cursor + # cur = db.cursor() + query = ''' SELECT id FROM gtm_gang WHERE server_key=%s AND name=%s;''' + data = (str(server_key), str(gang_name)) + cur.execute(query, data) + + gang_id = None + for tup in cur: + if len(tup) > 0: + gang_id = int(tup[0]) + + # # commit query + # db.commit() + # cur.close() + + return gang_id + + +######### +# BELOW IS THE ACTUAL SCRIPT LOGIC +######### + +print('Running script...') +start_time = time.time() + +# limit the amount of queries to the database per interval +tick = 0 + +# get all the gangs in old tables +gangs = get_gangs() +gangs_created = 0 +for gang in gangs: + tick += 1 + # create relation in new table + try: + create_gang(gang) + gangs_created += 1 + except Exception as e: + print(e) + + if tick > MAX_QUERY_TICK: + tick = 0 + time.sleep(TICK_SLEEP) + + +# get all the old relations +relations = get_relations() +relations_created = 0 +for rel in relations: + tick += 1 + (gang1, gang2, relation) = rel + + # only do valid gangs + gang1_id = find_gang_id(SERVER_KEY, gang1) + if gang1_id is not None: + + gang2_id = find_gang_id(SERVER_KEY, gang2) + if gang2_id is not None: + try: + print("#" + str(relations_created) + " - Creating gang relation " + str(rel)) + # create relation in new table + create_gang_relation(gang1_id, gang2_id, relation) + relations_created += 1 + except Exception as e: + print(e) + + if tick > MAX_QUERY_TICK: + tick = 0 + time.sleep(TICK_SLEEP) + +# get all users in the old table +gang_members = get_users() +gang_members_created = 0 + +tick = 0 +for gm in gang_members: + tick += 1 + + # find the gang_id with the given name + gang_id = find_gang_id(SERVER_KEY, gm.gang_name) + if gang_id is not None: + gm.gang_id = gang_id + + try: + print("#" + str(gang_members_created) + " - creating gang member=" + str(gm)) + + # create new gang member + create_gang_member(gm) + gang_members_created += 1 + except Exception as e: + print(e) + + if tick > MAX_QUERY_TICK: + tick = 0 + time.sleep(TICK_SLEEP) + +# for unt in# print("failed to " + str(unt)) +# print(str(len(untranferred)) + " gang members were not found gang for") untranferred: + +# commit query +db.commit() +cur.close() + +run_time = time.time() - start_time +print('Script is now complete! (' + str(run_time) + ' secs)') +print('Number of gangs found: ' + str(len(gangs))) +print('Number of gangs transposed: ' + str(gangs_created)) +print() +print('Number of relations found: ' + str(len(relations))) +print('Number of relations transposed: ' + str(relations_created)) +print() +print('Number of gang members found: ' + str(len(gang_members))) +print('Number of gang members transposed: ' + str(gang_members_created)) + +# close the connection +db.close() \ No newline at end of file diff --git a/core-master@6ef85bb745a/setup/script/transpose_house.py b/core-master@6ef85bb745a/setup/script/transpose_house.py new file mode 100644 index 0000000..30077c3 --- /dev/null +++ b/core-master@6ef85bb745a/setup/script/transpose_house.py @@ -0,0 +1,232 @@ +#!/usr/bin/python + +# local imports + +# python modules +import MySQLdb +import string +import time + +DB_HOST = "localhost" +DB_USER = "root" +DB_PASS = "" +DB_NAME = "" +# number of queries per interval +MAX_QUERY_TICK = 1000000000 +# how long in seconds we sleep for +TICK_SLEEP = 1 + +SERVER_KEY = "GTM0" +QUERY_GET_REG_HOUSES = ''' SELECT uuid, houseId FROM gtm0_houses; ''' +QUERY_GET_REG_CHESTS = '''SELECT uuid, houseId, chestId, contents FROM gtm0_houses_chests; ''' + +# open MySQL connection +db = MySQLdb.connect(host=DB_HOST, user=DB_USER, passwd=DB_PASS, db=DB_NAME) +# grab cursor +cur = db.cursor() + +# print out variables +print("MAX_QUERY_TICK = " + str(MAX_QUERY_TICK)) +print("TICK_SLEEP = " + str(TICK_SLEEP)) +print("SERVER_KEY = " + str(SERVER_KEY)) +print("QUERY_GET_REG_HOUSES = " + str(QUERY_GET_REG_HOUSES)) +print("QUERY_GET_REG_CHESTS = " + str(QUERY_GET_REG_CHESTS)) + +def get_regular_houses(): + ''' + Get all the regular houses known on the network. + + Return: + A list of pairs in the form of (uuid, house_num) for all the regular houses. + ''' + + # # grab cursor + # cur = db.cursor() + cur.execute(QUERY_GET_REG_HOUSES) + + houses = [] + for tup in cur: + + uuid = string.replace(str(tup[0]), "-", "") + house_num = int(tup[1]) + + houses.append((uuid, house_num)) + + # commit query + # db.commit() + # cur.close() + + return houses + +def get_regular_chests(): + ''' + Get all the regular chests information on the network. + + Return: + A list of tuples in the form of (uuid, house_num, chest_id, contents) + that represent data for a chest. + ''' + + # # grab cursor + # cur = db.cursor() + cur.execute(QUERY_GET_REG_CHESTS) + + chests = [] + for tup in cur: + uuid = string.replace(str(tup[0]), "-", "") + house_num = int(tup[1]) + chest_id = int(tup[2]) + contents = str(tup[3]) + + chests.append((uuid, house_num, chest_id, contents)) + + # # commit query + # db.commit() + # cur.close() + + return chests + +def find_house_id(house_num, server_key, premium): + ''' + Find the id of the house that was generated by the database. + + Args: + house_num: The number of the house + server_key: The key of server that this house is for + premium: Whether or not this is a premium house + + Return: + A list of tuples in the form of (uuid, house_num, chest_id, contents) + that represent data for a chest. + ''' + + # grab cursor + # cur = db.cursor() + query = '''SELECT id FROM gtm_house WHERE house_num=%s AND server_key=%s AND premium=%s ''' + data = (int(house_num), str(server_key), bool(premium)) + cur.execute(query, data) + + house_id = None + for tup in cur: + if len(tup) > 0: + house_id = int(tup[0]) + + # # commit query + # db.commit() + # cur.close() + + return house_id + +# CREATE TABLE IF NOT EXISTS gtm_house_chest ( +# house_id INT NOT NULL, +# uuid BINARY(16) NOT NULL, +# chest_id INT NOT NULL, +# content BLOB DEFAULT NULL, +# PRIMARY KEY (house_id, uuid), +# INDEX(uuid), +# FOREIGN KEY (house_id) REFERENCES gtm_house(id) ON DELETE CASCADE +# ); + +def create_house_chest(house_id, uuid, chest_id, content): + ''' + Create chest information for the respective house. + + Args: + house_id: The id of the house + uuid: The uuid of the user for the respective house + chest_id: The id of the chest + content: The contents of the chest + ''' + # # grab cursor + # cur = db.cursor() + query = '''INSERT INTO gtm_house_chest (house_id, uuid, chest_id, content) VALUES (%s, UNHEX(%s), %s, %s);''' + data = (int(house_id), str(uuid), int(chest_id), str(content)) + cur.execute(query, data) + + # # commit query + # db.commit() + # cur.close() + +def create_house_user(house_id, uuid, is_owner): + ''' + Create a new house user record in the database for the specified house. + + Args: + house_id: The id of the house + uuid: The uuid of the user for the house + is_owner: Whether the user owns the house + ''' + + # # grab cursor + # cur = db.cursor() + + query = ''' INSERT INTO gtm_house_user (house_id, uuid, is_owner) VALUES (%s, UNHEX(%s), %s); ''' + data = (int(house_id), str(uuid), bool(is_owner)) + cur.execute(query, data) + + # # commit query + # db.commit() + # cur.close() + +######### +# BELOW IS THE ACTUAL SCRIPT LOGIC +######### + +print('Running script...') +start_time = time.time() + +# limit the amount of queries to the database per interval +tick = 0 + +houses = get_regular_houses() +houses_created = 0 +for uuid, house_num in houses: + tick += 1 + + # find generated house id + house_id = find_house_id(house_num=house_num, server_key=SERVER_KEY, premium=0) + if house_id is not None: + + # create the user in the house relation + create_house_user(house_id=house_id, uuid=uuid, is_owner=True) + houses_created += 1 + + if tick > MAX_QUERY_TICK: + tick = 0 + time.sleep(TICK_SLEEP) + +# get all the houses in old tables +chests = get_regular_chests() +chests_created = 0 +for uuid, house_num, chest_id, contents in chests: + tick += 1 + + # find generated house id + house_id = find_house_id(house_num=house_num, server_key=SERVER_KEY, premium=0) + if house_id is not None: + + try: + # create house data in new table + create_house_chest(house_id=house_id, uuid=uuid, chest_id=chest_id, content=contents) + chests_created += 1 + except Exception as e: + print(e) + print('Error for house_id=' + str(house_id) + ', uuid=' + str(uuid) + ', chest_id=' + str(chest_id)) + + if tick > MAX_QUERY_TICK: + tick = 0 + time.sleep(TICK_SLEEP) + +# commit query +db.commit() +cur.close() + +run_time = time.time() - start_time +print('Script is now complete! (' + str(run_time) + ' secs)') +print('Number of houses found: ' + str(len(houses))) +print('Number of houses transposed: ' + str(houses_created)) +print('Number of chests found: ' + str(len(chests))) +print('Number of chests transposed: ' + str(chests_created)) + +# close the connection +db.close() \ No newline at end of file diff --git a/core-master@6ef85bb745a/setup/script/transpose_house_yml.py b/core-master@6ef85bb745a/setup/script/transpose_house_yml.py new file mode 100644 index 0000000..926efa9 --- /dev/null +++ b/core-master@6ef85bb745a/setup/script/transpose_house_yml.py @@ -0,0 +1,333 @@ +#!/usr/bin/python + +# local imports + +# python modules +import yaml +import MySQLdb +import string +import time +import json + +DB_HOST = "localhost" +DB_USER = "root" +DB_PASS = "" +DB_NAME = "" +# number of queries per interval +MAX_QUERY_TICK = 10000000 +# how long in seconds we sleep for +TICK_SLEEP = 1 + +SERVER_KEY = "GTM0" +# mutated by script +PREMIUM = True + +# print out variables +print("MAX_QUERY_TICK = " + str(MAX_QUERY_TICK)) +print("TICK_SLEEP = " + str(TICK_SLEEP)) +print("SERVER_KEY = " + str(SERVER_KEY)) + +# open MySQL connection +db = MySQLdb.connect(host=DB_HOST, user=DB_USER, passwd=DB_PASS, db=DB_NAME) + +# CREATE TABLE IF NOT EXISTS gtm_house ( +# id INT NOT NULL AUTO_INCREMENT, +# house_num INT NOT NULL, +# server_key VARCHAR(10) NOT NULL, +# premium TINYINT(1) NOT NULL DEFAULT 0, +# currency VARCHAR(10) NOT NULL, +# price INT NOT NULL, +# PRIMARY KEY (id), +# UNIQUE INDEX (house_num, server_key, premium) +# ); + +def create_house(house_num, server_key, premium, currency, price): + ''' + Create the new representation of the house in the new table. + + Args: + house_num: The number id of the house + server_key: The server key, i.e. gtm1 + premium: Whether or not this is a premium house + currency: The currency for purchases + price: The cost of the purchase + + Return: + The id of the house that was just created. + ''' + + # grab cursor + cur = db.cursor() + + query = ''' INSERT INTO gtm_house (house_num, server_key, premium, currency, price) VALUES (%s, %s, %s, %s, %s); ''' + data = (int(house_num), str(server_key), bool(premium), str(currency), int(price)) + cur.execute(query, data) + + # commit query + db.commit() + + generated_house_id = cur.lastrowid + cur.close() + + return generated_house_id + +# CREATE TABLE IF NOT EXISTS gtm_house_data ( +# house_id INT NOT NULL, +# hotspot_id INT NOT NULL AUTO_INCREMENT, +# hotspot_type VARCHAR(5) NOT NULL, +# data BLOB DEFAULT NULL, +# PRIMARY KEY (hotspot_id), +# INDEX (house_id), +# FOREIGN KEY (house_id) REFERENCES gtm_house(id) ON DELETE CASCADE +# ); + +def create_house_data(house_id, hotspot_type, data): + ''' + Create a new house data record in the database for the given house. + + Args: + house_id: The id of the house + hotspot_type: The type of the hotspot + data: The data representation for the hotspot + ''' + + # grab cursor + cur = db.cursor() + + query = ''' INSERT INTO gtm_house_data (house_id, hotspot_type, data) VALUES (%s, %s, %s); ''' + data = (int(house_id), str(hotspot_type), str(data)) + cur.execute(query, data) + + # commit query + db.commit() + cur.close() + +# CREATE TABLE IF NOT EXISTS gtm_house_user ( +# house_id INT NOT NULL, +# uuid BINARY(16) NOT NULL, +# is_owner TINYINT(1) NOT NULL, +# PRIMARY KEY (house_id, uuid), +# INDEX(uuid), +# FOREIGN KEY (house_id) REFERENCES gtm_house(id) ON DELETE CASCADE +# ); + +def create_house_user(house_id, uuid, is_owner): + ''' + Create a new house user record in the database for the specified house. + + Args: + house_id: The id of the house + uuid: The uuid of the user for the house + is_owner: Whether the user owns the house + ''' + + # grab cursor + cur = db.cursor() + + query = ''' INSERT INTO gtm_house_user (house_id, uuid, is_owner) VALUES (%s, UNHEX(%s), %s); ''' + data = (int(house_id), str(uuid), bool(is_owner)) + cur.execute(query, data) + + # commit query + db.commit() + cur.close() + +def run_script(file_name): + ''' + Run the tranpose of the house script. + + Args: + file_name: The name of the file to read from. + ''' + + num_houses = 0 + houses_created = 0 + + # lets get a list of keys that we know about + with open(file_name, 'r') as stream: + try: + + # get the data + data = yaml.load(stream) + num_houses = len(data) + + for house_num in data: + + print('Running house #' + str(house_num)) + + # get the dict for the house data + house_data = data[house_num] + currency = None + price = None + owner = None + + # if 'blocks' not in house_data: + # continue + + if 'permits' in house_data: + price = int(house_data['permits']) + currency = "PERMIT" + elif 'price' in house_data: + price = int(house_data['price']) + currency = "MONEY" + + if 'owner' in house_data: + owner = string.replace(str(house_data['owner']), "-", "") + + # create the generic house data + generated_house_id = int(create_house(house_num=int(house_num), server_key=str(SERVER_KEY), premium=bool(PREMIUM), currency=currency, price=price)) + + # if valid generated house + if generated_house_id is not None and generated_house_id > 0: + + houses_created += 1 + + # if valid owner, add as a user + if owner is not None: + create_house_user(house_id=generated_house_id, uuid=owner, is_owner=True) + + # parse the guests of this house + if 'guests' in house_data: + for guest in house_data['guests']: + guest_uuid = string.replace(str(guest), "-", "") + create_house_user(house_id=generated_house_id, uuid=guest_uuid, is_owner=False) + + # parse the chests of this house + if 'chests' in house_data: + chest_data = house_data['chests'] + + # for each chest + for chest_id in chest_data: + + # a chest can have multiple locations + chest_loc1 = None + chest_loc2 = None + if 'loc1' in chest_data[chest_id]: + chest_loc1 = str(chest_data[chest_id]['loc1']) + if 'loc2' in chest_data[chest_id]: + chest_loc2 = str(chest_data[chest_id]['loc2']) + + # build the json for this object + chest_json = {} + chest_json['id'] = int(chest_id) + if chest_loc1 is not None: + chest_json['loc1'] = str(chest_loc1) + if chest_loc2 is not None: + chest_json['loc2'] = str(chest_loc2) + + # create chest entry + create_house_data(house_id=generated_house_id, hotspot_type="CHEST", data=str(json.dumps(chest_json))) + + if 'doors' in house_data: + door_data = house_data['doors'] + + for door_id in door_data: + + loc = None + insideLoc = None + outsideLoc = None + if 'location' in door_data[door_id]: + loc = str(door_data[door_id]['location']) + if 'insideLocation' in door_data[door_id]: + insideLoc = str(door_data[door_id]['insideLocation']) + if 'outsideLocation' in door_data[door_id]: + outsideLoc = str(door_data[door_id]['outsideLocation']) + + # build the json for this object + door_json = {} + door_json['id'] = int(door_id) + if loc is not None: + door_json['location'] = str(loc) + if insideLoc is not None: + door_json['insideLocation'] = str(insideLoc) + if outsideLoc is not None: + door_json['outsideLocation'] = str(outsideLoc) + + # create chest entry + create_house_data(house_id=generated_house_id, hotspot_type="DOOR", data=str(json.dumps(door_json))) + + if 'signs' in house_data: + sign_data = house_data['signs'] + + for sign_loc in sign_data: + sign_json = {} + sign_json['loc'] = str(sign_loc) + + # create sign entry + create_house_data(house_id=generated_house_id, hotspot_type="SIGN", data=str(json.dumps(sign_json))) + + if 'blocks' in house_data: + block_data = house_data['blocks'] + + for block_loc in block_data: + + block_info = None + if 'default' in block_data[block_loc]: + block_info = str(block_data[block_loc]['default']) + + # build the json for this object + block_json = {} + block_json['loc'] = str(block_loc) + if block_info is not None: + block_json['block_data'] = str(block_info) + + # create trashcan entry + create_house_data(house_id=generated_house_id, hotspot_type="BLOCK", data=str(json.dumps(block_json))) + + if 'trashcans' in house_data: + trash_data = house_data['trashcans'] + + for trashcan_id in trash_data: + + loc = None + owned = None + if 'loc' in trash_data[trashcan_id]: + loc = str(trash_data[trashcan_id]['loc']) + if 'owned' in trash_data[trashcan_id]: + owned = bool(trash_data[trashcan_id]['owned']) + + # build the json for this object + trash_json = {} + trash_json['id'] = int(trashcan_id) + if loc is not None: + trash_json['loc'] = str(loc) + if owned is not None: + trash_json['owned'] = bool(owned) + + # create trashcan entry + create_house_data(house_id=generated_house_id, hotspot_type="TRASH", data=str(json.dumps(trash_json))) + + else: + print('Unknown error occurred when trying to transpose data for id=' + str(house_num) + " and data=" + str(house_data)) + break + + except yaml.YAMLError as exc: + print(exc) + + print('Initial amount of houses: ' + str(num_houses)) + print('Number of houses transposed: ' + str(houses_created)) + + + +######### +# BELOW IS THE ACTUAL SCRIPT LOGIC +######### + +print('Running script for both houses.yml and premiumHouses.yml.' ) +print() +start_time = time.time() + +print('Running houses.yml...') +PREMIUM = False +run_script('houses.yml') +run_time = time.time() - start_time +print('Finished script for houses.yml in ' + str(run_time) + ' secs.') + +print('Running premiumHouses.yml...') +PREMIUM = True +run_script('premiumHouses.yml') +run_time = time.time() - start_time +print('Finished script for premiumHouses.yml in ' + str(run_time) + ' secs.') + +# close the connection +db.close() \ No newline at end of file diff --git a/core-master@6ef85bb745a/setup/script/transpose_user.py b/core-master@6ef85bb745a/setup/script/transpose_user.py new file mode 100644 index 0000000..b359216 --- /dev/null +++ b/core-master@6ef85bb745a/setup/script/transpose_user.py @@ -0,0 +1,115 @@ +#!/usr/bin/python + +# local imports + +# python modules +import MySQLdb +import string +import time + +DB_HOST = "localhost" +DB_USER = "root" +DB_PASS = "" +DB_NAME = "" +# number of queries per interval +MAX_QUERY_TICK = 10000000 +# how long in seconds we sleep for +TICK_SLEEP = 1 + +QUERY_GET_USERS = ''' SELECT uuid, lastname FROM users; ''' + +# open MySQL connection +db = MySQLdb.connect(host=DB_HOST, user=DB_USER, passwd=DB_PASS, db=DB_NAME) +# grab cursor +cur = db.cursor() + +# print out variables +print("MAX_QUERY_TICK = " + str(MAX_QUERY_TICK)) +print("TICK_SLEEP = " + str(TICK_SLEEP)) +print("QUERY_GET_USERS = " + str(QUERY_GET_USERS)) + +def get_users(): + ''' + Get all the users known on the network. + + Return: + A list of pairs in the form of (uuid, name) for all the users. + ''' + + # grab cursor + #cur = db.cursor() + cur.execute(QUERY_GET_USERS) + + users = [] + for tup in cur: + + uuid = string.replace(str(tup[0]), "-", "") + name = str(tup[1]) + + users.append((uuid, name)) + + # commit query + # db.commit() + # cur.close() + + return users + +# CREATE TABLE IF NOT EXISTS user( +# uuid BINARY(16) NOT NULL, +# name VARCHAR(16) NOT NULL, +# PRIMARY KEY (uuid), +# INDEX (name) +# ); + +def create_user(uuid, name): + ''' + Create user information for the respective player. + + Args: + uuid: The uuid of the user + name: The name of the user + ''' + # grab cursor + # cur = db.cursor() + query = '''INSERT IGNORE INTO user VALUES (UNHEX(%s), %s);''' + data = (str(uuid), str(name)) + cur.execute(query, data) + + # commit query + # db.commit() + # cur.close() + +######### +# BELOW IS THE ACTUAL SCRIPT LOGIC +######### + +print('Running script...') +start_time = time.time() + +# limit the amount of queries to the database per interval +tick = 0 + +users = get_users() +users_created = 0 +for uuid, name in users: + tick += 1 + + create_user(uuid=uuid, name=name) + users_created += 1 + + if tick > MAX_QUERY_TICK: + tick = 0 + time.sleep(TICK_SLEEP) + +db.commit() +cur.close() + +# convert ranks + +run_time = time.time() - start_time +print('Script is now complete! (' + str(run_time) + ' secs)') +print('Number of users found: ' + str(len(users))) +print('Number of users transposed: ' + str(users_created)) + +# close the connection +db.close() \ No newline at end of file diff --git a/core-master@6ef85bb745a/setup/script/transpose_user_ammo.py b/core-master@6ef85bb745a/setup/script/transpose_user_ammo.py new file mode 100644 index 0000000..757b7d5 --- /dev/null +++ b/core-master@6ef85bb745a/setup/script/transpose_user_ammo.py @@ -0,0 +1,155 @@ +#!/usr/bin/python + +# local imports + +# python modules +import MySQLdb +import string +import time + +DB_HOST = "localhost" +DB_USER = "root" +DB_PASS = "" +DB_NAME = "" +# number of queries per interval +MAX_QUERY_TICK = 10000000 +# how long in seconds we sleep for +TICK_SLEEP = 1 + +QUERY_GET_AMMO_GTM1 = ''' SELECT uuid, pistol, smg, shotgun, assault_rifle, mg, sniper, rocket, minigun FROM gtm1; ''' +QUERY_GET_AMMO_GTM2 = ''' SELECT uuid, pistol, smg, shotgun, assault_rifle, mg, sniper, rocket, minigun FROM gtm2; ''' +QUERY_GET_AMMO_GTM3 = ''' SELECT uuid, pistol, smg, shotgun, assault_rifle, mg, sniper, rocket, minigun FROM gtm3; ''' +QUERY_GET_AMMO_GTM4 = ''' SELECT uuid, pistol, smg, shotgun, assault_rifle, mg, sniper, rocket, minigun FROM gtm4; ''' +QUERY_GET_AMMO_GTM5 = ''' SELECT uuid, pistol, smg, shotgun, assault_rifle, mg, sniper, rocket, minigun FROM gtm5; ''' +QUERY_GET_AMMO_GTM6 = ''' SELECT uuid, pistol, smg, shotgun, assault_rifle, mg, sniper, rocket, minigun FROM gtm6; ''' +AMMO_QUERIES = [("GTM1", QUERY_GET_AMMO_GTM1), ("GTM2", QUERY_GET_AMMO_GTM2), ("GTM3", QUERY_GET_AMMO_GTM3), ("GTM4", QUERY_GET_AMMO_GTM4), ("GTM5", QUERY_GET_AMMO_GTM5), ("GTM6", QUERY_GET_AMMO_GTM6)] + + +# open MySQL connection +db = MySQLdb.connect(host=DB_HOST, user=DB_USER, passwd=DB_PASS, db=DB_NAME) +# grab cursor +cur = db.cursor() + +# print out variables +print("MAX_QUERY_TICK = " + str(MAX_QUERY_TICK)) +print("TICK_SLEEP = " + str(TICK_SLEEP)) +print("QUERY_GET_AMMO_GTM1 = " + str(QUERY_GET_AMMO_GTM1)) +print("QUERY_GET_AMMO_GTM2 = " + str(QUERY_GET_AMMO_GTM2)) +print("QUERY_GET_AMMO_GTM3 = " + str(QUERY_GET_AMMO_GTM3)) +print("QUERY_GET_AMMO_GTM4 = " + str(QUERY_GET_AMMO_GTM4)) +print("QUERY_GET_AMMO_GTM5 = " + str(QUERY_GET_AMMO_GTM5)) +print("QUERY_GET_AMMO_GTM6 = " + str(QUERY_GET_AMMO_GTM6)) + +def get_ammo(query): + ''' + Get all the ammo. + + Return: + A list of tuples in the form of (uuid, pistol, smg, shotgun, assault_rifle, mg, sniper, rocket, minigun) for all the users. + ''' + + # grab cursor + #cur = db.cursor() + cur.execute(query) + + user_ammo = [] + for tup in cur: + + uuid = string.replace(str(tup[0]), "-", "") + pistol = int(tup[1]) + smg = int(tup[2]) + shotgun = int(tup[3]) + assault_rifle = int(tup[4]) + mg = int(tup[5]) + sniper = int(tup[6]) + rocket = int(tup[7]) + minigun = int(tup[8]) + + user_ammo.append((uuid, pistol, smg, shotgun, assault_rifle, mg, sniper, rocket, minigun)) + + # commit query + # db.commit() + # cur.close() + + return user_ammo + +# CREATE TABLE IF NOT EXISTS user_ammo( +# uuid BINARY(16) NOT NULL, +# server_key VARCHAR(10) NOT NULL, +# ammo VARCHAR(16) NOT NULL, +# amount INT NOT NULL, +# PRIMARY KEY (uuid, server_key, ammo), +# FOREIGN KEY (uuid) REFERENCES user(uuid) ON DELETE CASCADE +# ); + +def create_user_ammo(uuid, server_key, ammo, amount): + ''' + Create user ammo information for the user. + + Args: + uuid: The uuid of the user + server_key: The server that this ammo is for + ammo: The ammo to store + amount: The amount of ammo to store + ''' + # grab cursor + # cur = db.cursor() + query = '''INSERT IGNORE INTO user_ammo VALUES (UNHEX(%s), %s, %s, %s);''' + data = (str(uuid), str(server_key), str(ammo), int(amount)) + cur.execute(query, data) + + # commit query + # db.commit() + # cur.close() + +######### +# BELOW IS THE ACTUAL SCRIPT LOGIC +######### + +print('Running script...') +start_time = time.time() + +# limit the amount of queries to the database per interval +tick = 0 + +num_ammo_records = 0 +num_ammo_records_created = 0 +for ammo_query in AMMO_QUERIES: + server_key, query = ammo_query + + ammo_record = get_ammo(query) + num_ammo_records += len(ammo_record) + for uuid, pistol, smg, shotgun, assault_rifle, mg, sniper, rocket, minigun in ammo_record: + tick += 1 + + create_user_ammo(uuid=uuid, server_key=str(server_key), ammo="PISTOL", amount=pistol) + num_ammo_records_created += 1 + create_user_ammo(uuid=uuid, server_key=str(server_key), ammo="SMG", amount=smg) + num_ammo_records_created += 1 + create_user_ammo(uuid=uuid, server_key=str(server_key), ammo="SHOTGUN", amount=shotgun) + num_ammo_records_created += 1 + create_user_ammo(uuid=uuid, server_key=str(server_key), ammo="ASSAULT_RIFLE", amount=assault_rifle) + num_ammo_records_created += 1 + create_user_ammo(uuid=uuid, server_key=str(server_key), ammo="MG", amount=mg) + num_ammo_records_created += 1 + create_user_ammo(uuid=uuid, server_key=str(server_key), ammo="SNIPER", amount=sniper) + num_ammo_records_created += 1 + create_user_ammo(uuid=uuid, server_key=str(server_key), ammo="ROCKET", amount=rocket) + num_ammo_records_created += 1 + create_user_ammo(uuid=uuid, server_key=str(server_key), ammo="MINIGUN", amount=minigun) + num_ammo_records_created += 1 + + if tick > MAX_QUERY_TICK: + tick = 0 + time.sleep(TICK_SLEEP) + +db.commit() +cur.close() + +run_time = time.time() - start_time +print('Script is now complete! (' + str(run_time) + ' secs)') +print('Number of user ammo records found: ' + str(num_ammo_records)) +print('Number of user ammo records transposed: ' + str(num_ammo_records_created)) + +# close the connection +db.close() \ No newline at end of file diff --git a/core-master@6ef85bb745a/setup/script/transpose_user_currency.py b/core-master@6ef85bb745a/setup/script/transpose_user_currency.py new file mode 100644 index 0000000..7d368f0 --- /dev/null +++ b/core-master@6ef85bb745a/setup/script/transpose_user_currency.py @@ -0,0 +1,180 @@ +#!/usr/bin/python + +# local imports + +# python modules +import MySQLdb +import string +import time + +DB_HOST = "localhost" +DB_USER = "root" +DB_PASS = "" +DB_NAME = "" +# number of queries per interval +MAX_QUERY_TICK = 10000000 +# how long in seconds we sleep for +TICK_SLEEP = 1 + +QUERY_GET_GLOBAL_CURR = ''' SELECT uuid, crowbars, tokens FROM users; ''' + +QUERY_GET_CURR_GTM1 = ''' SELECT uuid, money, permits FROM gtm1; ''' +QUERY_GET_CURR_GTM2 = ''' SELECT uuid, money, permits FROM gtm2; ''' +QUERY_GET_CURR_GTM3 = ''' SELECT uuid, money, permits FROM gtm3; ''' +QUERY_GET_CURR_GTM4 = ''' SELECT uuid, money, permits FROM gtm4; ''' +QUERY_GET_CURR_GTM5 = ''' SELECT uuid, money, permits FROM gtm5; ''' +QUERY_GET_CURR_GTM6 = ''' SELECT uuid, money, permits FROM gtm6; ''' +CURR_QUERIES = [("GTM1", QUERY_GET_CURR_GTM1), ("GTM2", QUERY_GET_CURR_GTM2), ("GTM3", QUERY_GET_CURR_GTM3), ("GTM4", QUERY_GET_CURR_GTM4), ("GTM5", QUERY_GET_CURR_GTM5), ("GTM6", QUERY_GET_CURR_GTM6)] + + +# open MySQL connection +db = MySQLdb.connect(host=DB_HOST, user=DB_USER, passwd=DB_PASS, db=DB_NAME) +# grab cursor +cur = db.cursor() + +# print out variables +print("MAX_QUERY_TICK = " + str(MAX_QUERY_TICK)) +print("TICK_SLEEP = " + str(TICK_SLEEP)) +print("QUERY_GET_GLOBAL_CURR = " + str(QUERY_GET_GLOBAL_CURR)) + +def get_global_currencies(): + ''' + Get all the user currencies known on the network. + + This will return multiple tuples per user. + + Return: + A list of tuples in the form of (uuid, crowbars, tokens) for all the users. + ''' + + # grab cursor + #cur = db.cursor() + cur.execute(QUERY_GET_GLOBAL_CURR) + + user_currencies = [] + for tup in cur: + + uuid = string.replace(str(tup[0]), "-", "") + crowbars = int(tup[1]) + tokens = int(tup[2]) + + user_currencies.append((uuid, crowbars, tokens)) + + # commit query + # db.commit() + # cur.close() + + return user_currencies + +def get_local_currencies(query): + ''' + Get all the local user currencies. + + Return: + A list of tuples in the form of (uuid, money, permits) for all the users. + ''' + + # grab cursor + #cur = db.cursor() + cur.execute(query) + + user_currencies = [] + for tup in cur: + + uuid = string.replace(str(tup[0]), "-", "") + money = int(tup[1]) + permits = int(tup[2]) + + user_currencies.append((uuid, money, permits)) + + # commit query + # db.commit() + # cur.close() + + return user_currencies + +# CREATE TABLE IF NOT EXISTS user_currency( +# uuid BINARY(16) NOT NULL, +# server_key VARCHAR(10) NOT NULL, +# currency VARCHAR(16) NOT NULL, +# amount INT NOT NULL, +# PRIMARY KEY (uuid, server_key), +# FOREIGN KEY (uuid) REFERENCES user(uuid) ON DELETE CASCADE +# ); + +def create_user_currency(uuid, server_key, currency, amount): + ''' + Create user currency information for the respective player. + + Args: + uuid: The uuid of the user + server_key: The server that this currency is for, or GLOBAL + currency: The currency to store + amount: The amount of currency to store + ''' + # grab cursor + # cur = db.cursor() + query = '''INSERT IGNORE INTO user_currency VALUES (UNHEX(%s), %s, %s, %s);''' + data = (str(uuid), str(server_key), str(currency), int(amount)) + cur.execute(query, data) + + # commit query + # db.commit() + # cur.close() + +######### +# BELOW IS THE ACTUAL SCRIPT LOGIC +######### + +print('Running script...') +start_time = time.time() + +# limit the amount of queries to the database per interval +tick = 0 + +global_currencies = get_global_currencies() +global_currencies_created = 0 +for uuid, crowbars, tokens in global_currencies: + tick += 1 + + create_user_currency(uuid=uuid, server_key="GLOBAL", currency="CROWBAR", amount=crowbars) + global_currencies_created += 1 + create_user_currency(uuid=uuid, server_key="GLOBAL", currency="TOKEN", amount=tokens) + global_currencies_created += 1 + + if tick > MAX_QUERY_TICK: + tick = 0 + time.sleep(TICK_SLEEP) + +num_local_currencies = 0 +num_local_currencies_created = 0 +for curr_query in CURR_QUERIES: + server_key, query = curr_query + + local_currencies = get_local_currencies(query) + num_local_currencies += len(local_currencies) + for uuid, money, permits in local_currencies: + tick += 1 + + create_user_currency(uuid=uuid, server_key=str(server_key), currency="MONEY", amount=money) + num_local_currencies_created += 1 + create_user_currency(uuid=uuid, server_key=str(server_key), currency="PERMIT", amount=permits) + num_local_currencies_created += 1 + + if tick > MAX_QUERY_TICK: + tick = 0 + time.sleep(TICK_SLEEP) + +db.commit() +cur.close() + +run_time = time.time() - start_time +print('Script is now complete! (' + str(run_time) + ' secs)') +print('Number of global user currencies found: ' + str(len(global_currencies))) +print('Number of global user currencies transposed: ' + str(global_currencies_created)) +print() +print('Number of local user currencies found: ' + str(num_local_currencies)) +print('Number of local user currencies transposed: ' + str(num_local_currencies_created)) + +# close the connection +db.close() \ No newline at end of file diff --git a/core-master@6ef85bb745a/setup/script/transpose_user_rank.py b/core-master@6ef85bb745a/setup/script/transpose_user_rank.py new file mode 100644 index 0000000..4b27830 --- /dev/null +++ b/core-master@6ef85bb745a/setup/script/transpose_user_rank.py @@ -0,0 +1,163 @@ +#!/usr/bin/python + +# local imports + +# python modules +import MySQLdb +import string +import time +import datetime + +DB_HOST = "localhost" +DB_USER = "root" +DB_PASS = "" +DB_NAME = "" +# number of queries per interval +MAX_QUERY_TICK = 10000000 +# how long in seconds we sleep for +TICK_SLEEP = 1 + +QUERY_GET_USER_RANKS = ''' SELECT uuid, userrank, trialRank, trialRankExpiry FROM users; ''' + +# open MySQL connection +db = MySQLdb.connect(host=DB_HOST, user=DB_USER, passwd=DB_PASS, db=DB_NAME) +# grab cursor +cur = db.cursor() + +# print out variables +print("MAX_QUERY_TICK = " + str(MAX_QUERY_TICK)) +print("TICK_SLEEP = " + str(TICK_SLEEP)) +print("QUERY_GET_USER_RANKS = " + str(QUERY_GET_USER_RANKS)) + +def get_user_ranks(): + ''' + Get all the user ranks known on the network. + + Return: + A list of pairs in the form of (uuid, rank) for all the users. + ''' + + # grab cursor + #cur = db.cursor() + cur.execute(QUERY_GET_USER_RANKS) + + ranks = [] + for tup in cur: + + uuid = string.replace(str(tup[0]), "-", "") + rank = str(tup[1]) + trial_rank = tup[2] + trial_rank_expire = long(tup[3]) + + ranks.append((uuid, rank, trial_rank, trial_rank_expire)) + + # commit query + # db.commit() + # cur.close() + + return ranks + +# CREATE TABLE IF NOT EXISTS user_profile( +# uuid BINARY(16) NOT NULL, +# server_key VARCHAR(10) NOT NULL, +# rank VARCHAR(10) NOT NULL, +# PRIMARY KEY (uuid, server_key), +# FOREIGN KEY (uuid) REFERENCES user(uuid) ON DELETE CASCADE +# ); + +def create_user_profile(uuid, server_key, rank): + ''' + Create user profile information for the respective player. + + Args: + uuid: The uuid of the user + server_key: The key of the server + rank: The user's rank for that server + ''' + # grab cursor + # cur = db.cursor() + query = '''INSERT IGNORE INTO user_profile VALUES (UNHEX(%s), %s, %s);''' + data = (str(uuid), str(server_key), str(rank)) + cur.execute(query, data) + + # commit query + # db.commit() + # cur.close() + +# CREATE TABLE IF NOT EXISTS user_trial_rank( +# uuid BINARY(16) NOT NULL, +# server_key VARCHAR(10) NOT NULL, +# rank VARCHAR(10) NOT NULL, +# creation TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, +# expire_at TIMESTAMP NOT NULL, +# PRIMARY KEY (uuid, server_key), +# FOREIGN KEY (uuid) REFERENCES user(uuid) ON DELETE CASCADE +# ); + +def create_user_trial_rank(uuid, server_key, rank, expire_at): + ''' + Create user trial rank information for the respective player. + + Args: + uuid: The uuid of the user + server_key: The key of the server + rank: The user's rank for that server + expire_at: When this rank expires + ''' + #print('expire_at', expire_at) + # convert from epoch time "1516038023138" (in msecs) to secs + expire_secs = expire_at // 1000 + #print('expire_secs', expire_secs) + # convert to time object (takes secs) + expire = datetime.datetime.fromtimestamp(expire_secs) + #print('expire', expire) + + # grab cursor + # cur = db.cursor() + query = '''INSERT IGNORE INTO user_trial_rank (uuid, server_key, rank, expire_at) VALUES (UNHEX(%s), %s, %s, %s);''' + data = (str(uuid), str(server_key), str(rank), expire) + cur.execute(query, data) + + # commit query + # db.commit() + # cur.close() + +######### +# BELOW IS THE ACTUAL SCRIPT LOGIC +######### + +print('Running script...') +start_time = time.time() + +# limit the amount of queries to the database per interval +tick = 0 + +ranks = get_user_ranks() +ranks_created = 0 +trial_ranks_created = 0 +for uuid, rank, trial_rank, trial_rank_expire in ranks: + tick += 1 + + # create the user rank + create_user_profile(uuid=uuid, server_key="GLOBAL", rank=rank) + ranks_created += 1 + + if trial_rank is not None: + create_user_trial_rank(uuid=uuid, server_key="GLOBAL", rank=trial_rank, expire_at=trial_rank_expire) + trial_ranks_created += 1 + + if tick > MAX_QUERY_TICK: + tick = 0 + time.sleep(TICK_SLEEP) + +db.commit() +cur.close() + +run_time = time.time() - start_time +print('Script is now complete! (' + str(run_time) + ' secs)') +print('Number of users ranks found: ' + str(len(ranks))) +print('Number of users ranks transposed: ' + str(ranks_created)) +print('Number of users trial ranks transposed: ' + str(trial_ranks_created)) + +# close the connection +db.close() \ No newline at end of file diff --git a/core-master@6ef85bb745a/setup/script/transpose_user_uuid.py b/core-master@6ef85bb745a/setup/script/transpose_user_uuid.py new file mode 100644 index 0000000..74e68da --- /dev/null +++ b/core-master@6ef85bb745a/setup/script/transpose_user_uuid.py @@ -0,0 +1,141 @@ +#!/usr/bin/python + +# local imports + +# python modules +import MySQLdb +import string +import time +import sys + +DB_HOST = "localhost" +DB_USER = "root" +DB_PASS = "" +DB_NAME = "" +# number of queries per interval +MAX_QUERY_TICK = 10000000 +# how long in seconds we sleep for +TICK_SLEEP = 1 + +QUERY_GET_OLD_UUID_GTM1 = ''' SELECT uuid FROM gtm1; ''' +QUERY_GET_OLD_UUID_GTM2 = ''' SELECT uuid FROM gtm2; ''' +QUERY_GET_OLD_UUID_GTM3 = ''' SELECT uuid FROM gtm3; ''' +QUERY_GET_OLD_UUID_GTM4 = ''' SELECT uuid FROM gtm4; ''' +QUERY_GET_OLD_UUID_GTM5 = ''' SELECT uuid FROM gtm5; ''' +QUERY_GET_OLD_UUID_GTM6 = ''' SELECT uuid FROM gtm6; ''' +GET_UUID_QUERIES = [("GTM1", QUERY_GET_OLD_UUID_GTM1), ("GTM2", QUERY_GET_OLD_UUID_GTM2), ("GTM3", QUERY_GET_OLD_UUID_GTM3), ("GTM4", QUERY_GET_OLD_UUID_GTM4), ("GTM5", QUERY_GET_OLD_UUID_GTM5), ("GTM6", QUERY_GET_OLD_UUID_GTM6)] + +QUERY_UPDATE_UUID_GTM1 = ''' UPDATE gtm1 SET new_uuid=UNHEX(%s) WHERE uuid=%s; ''' +QUERY_UPDATE_UUID_GTM2 = ''' UPDATE gtm2 SET new_uuid=UNHEX(%s) WHERE uuid=%s; ''' +QUERY_UPDATE_UUID_GTM3 = ''' UPDATE gtm3 SET new_uuid=UNHEX(%s) WHERE uuid=%s; ''' +QUERY_UPDATE_UUID_GTM4 = ''' UPDATE gtm4 SET new_uuid=UNHEX(%s) WHERE uuid=%s; ''' +QUERY_UPDATE_UUID_GTM5 = ''' UPDATE gtm5 SET new_uuid=UNHEX(%s) WHERE uuid=%s; ''' +QUERY_UPDATE_UUID_GTM6 = ''' UPDATE gtm6 SET new_uuid=UNHEX(%s) WHERE uuid=%s; ''' +UPDATE_UUID_QUERIES = {} +UPDATE_UUID_QUERIES['GTM1'] = QUERY_UPDATE_UUID_GTM1 +UPDATE_UUID_QUERIES['GTM2'] = QUERY_UPDATE_UUID_GTM2 +UPDATE_UUID_QUERIES['GTM3'] = QUERY_UPDATE_UUID_GTM3 +UPDATE_UUID_QUERIES['GTM4'] = QUERY_UPDATE_UUID_GTM4 +UPDATE_UUID_QUERIES['GTM5'] = QUERY_UPDATE_UUID_GTM5 +UPDATE_UUID_QUERIES['GTM6'] = QUERY_UPDATE_UUID_GTM6 + +# open MySQL connection +db = MySQLdb.connect(host=DB_HOST, user=DB_USER, passwd=DB_PASS, db=DB_NAME) +# grab cursor +cur = db.cursor() + +# print out variables +print("MAX_QUERY_TICK = " + str(MAX_QUERY_TICK)) +print("TICK_SLEEP = " + str(TICK_SLEEP)) +print("QUERY_GET_OLD_UUID_GTM1 = " + str(QUERY_GET_OLD_UUID_GTM1)) +print("QUERY_GET_OLD_UUID_GTM2 = " + str(QUERY_GET_OLD_UUID_GTM2)) +print("QUERY_GET_OLD_UUID_GTM3 = " + str(QUERY_GET_OLD_UUID_GTM3)) +print("QUERY_GET_OLD_UUID_GTM4 = " + str(QUERY_GET_OLD_UUID_GTM4)) +print("QUERY_GET_OLD_UUID_GTM5 = " + str(QUERY_GET_OLD_UUID_GTM5)) +print("QUERY_GET_OLD_UUID_GTM6 = " + str(QUERY_GET_OLD_UUID_GTM6)) + +def get_old_uuid(query): + ''' + Get all the old uuids. + + Return: + A list of tuples in the form of (old_uuid, new_uuid). + ''' + + # grab cursor + #cur = db.cursor() + cur.execute(query) + + uuid_list = [] + for tup in cur: + + old_uuid = str(tup[0]) + new_uuid = string.replace(str(tup[0]), "-", "") + + uuid_list.append((old_uuid, new_uuid)) + + # commit query + # db.commit() + # cur.close() + + return uuid_list + +def create_uuid(old_uuid, new_uuid, query): + ''' + Create newly formatted uuid. + + Args: + old_uuid: The old uuid, with hyphens. + new_uuid: The new uuid, without hyphens. + query: The query to use + ''' + + # grab cursor + # cur = db.cursor() + data = (str(new_uuid), str(old_uuid)) + cur.execute(query, data) + + # commit query + # db.commit() + # cur.close() + +######### +# BELOW IS THE ACTUAL SCRIPT LOGIC +######### + +print('Running script...') +start_time = time.time() + +# limit the amount of queries to the database per interval +tick = 0 + +num_uuid_records = 0 +num_uuid_records_created = 0 +for get_uuid_query in GET_UUID_QUERIES: + server_key, query = get_uuid_query + + uuid_list = get_old_uuid(query) + num_uuid_records += len(uuid_list) + for old_uuid, new_uuid in uuid_list: + tick += 1 + + # TODO test remove + print("old_uuid", old_uuid) + + create_uuid(old_uuid=old_uuid, new_uuid=new_uuid, query=UPDATE_UUID_QUERIES[server_key]) + num_uuid_records_created += 1 + + if tick > MAX_QUERY_TICK: + tick = 0 + time.sleep(TICK_SLEEP) + +db.commit() +cur.close() + +run_time = time.time() - start_time +print('Script is now complete! (' + str(run_time) + ' secs)') +print('Number of user uuids found: ' + str(num_uuid_records)) +print('Number of user ammo records transposed: ' + str(num_uuid_records_created)) + +# close the connection +db.close() \ No newline at end of file diff --git a/core-master@6ef85bb745a/setup/script/transpose_vice_cheatcode.py b/core-master@6ef85bb745a/setup/script/transpose_vice_cheatcode.py new file mode 100644 index 0000000..72bc954 --- /dev/null +++ b/core-master@6ef85bb745a/setup/script/transpose_vice_cheatcode.py @@ -0,0 +1,112 @@ +#!/usr/bin/python + +# local imports + +# python modules +import MySQLdb +import string +import time + +DB_HOST = "localhost" +DB_USER = "root" +DB_PASS = "" +DB_NAME = "" +# number of queries per interval +MAX_QUERY_TICK = 10000000 +# how long in seconds we sleep for +TICK_SLEEP = 1 + +QUERY_GET_USER_DATA = ''' SELECT uuid, cheatcodes FROM vice1 WHERE cheatcodes IS NOT NULL; ''' +#QUERY_GET_USER_DATA = ''' SELECT uuid, cheatcodes FROM vice1 WHERE cheatcodes IS NOT NULL AND name='Micatchu'; ''' +QUERY_UPDATE_USER_DATA = ''' UPDATE vice2 SET cheatcodes = %s WHERE uuid = %s AND cheatcodes IS NULL; ''' +#QUERY_UPDATE_USER_DATA = ''' UPDATE vice2 SET cheatcodes = %s WHERE uuid = %s; ''' + +# open MySQL connection +db = MySQLdb.connect(host=DB_HOST, user=DB_USER, passwd=DB_PASS, db=DB_NAME) +# grab cursor +cur = db.cursor() + +# print out variables +print("MAX_QUERY_TICK = " + str(MAX_QUERY_TICK)) +print("TICK_SLEEP = " + str(TICK_SLEEP)) +print("QUERY_GET_USER_DATA = " + str(QUERY_GET_USER_DATA)) +print("QUERY_UPDATE_USER_DATA = " + str(QUERY_UPDATE_USER_DATA)) + +def get_user_data(): + ''' + Get all the user data known on the network. + + Return: + A list of pairs in the form of (uuid, cheatcode) for all the users. + ''' + + # execute the query + cur.execute(QUERY_GET_USER_DATA) + + users = [] + for tup in cur: + + uuid = str(tup[0]) + cheatcodes = str(tup[1]) + + users.append((uuid, cheatcodes)) + + # commit query + # db.commit() + # cur.close() + + return users + +def update_user_data(uuid, cheatcodes): + ''' + Update user information for the respective user. + + Args: + uuid: The uuid of the user + cheatcodes: The cheatcodes for the user + ''' + # grab cursor + # cur = db.cursor() + data = (str(cheatcodes), str(uuid)) + cur.execute(QUERY_UPDATE_USER_DATA, data) + + # commit query + # db.commit() + # cur.close() + +######### +# BELOW IS THE ACTUAL SCRIPT LOGIC +######### + +print('Running script...') +start_time = time.time() + +# limit the amount of queries to the database per interval +tick = 0 + +users = get_user_data() +users_modified = 0 +for uuid, cheatcodes in users: + tick += 1 + + print(uuid) + print(cheatcodes) + update_user_data(uuid=uuid, cheatcodes=cheatcodes) + users_modified += 1 + + if tick > MAX_QUERY_TICK: + tick = 0 + time.sleep(TICK_SLEEP) + +db.commit() +cur.close() + +# convert ranks + +run_time = time.time() - start_time +print('Script is now complete! (' + str(run_time) + ' secs)') +print('Number of vice cheatcode user data found: ' + str(len(users))) +print('Number of vice cheatcode user data transposed: ' + str(users_modified)) + +# close the connection +db.close() \ No newline at end of file diff --git a/core-master@6ef85bb745a/setup/script/vote_sync.py b/core-master@6ef85bb745a/setup/script/vote_sync.py new file mode 100644 index 0000000..014c091 --- /dev/null +++ b/core-master@6ef85bb745a/setup/script/vote_sync.py @@ -0,0 +1,95 @@ +#!/usr/bin/python + +# local imports + +# python modules +import MySQLdb +import time +import json + +DB_HOST = "localhost" +DB_USER = "root" +DB_PASS = "" +DB_NAME = "" + +QUERY_GET_THIS_MONTHS_VOTES = ''' SELECT HEX(LUV.uuid), COUNT(*) FROM log_user_vote LUV WHERE YEAR(LUV.creation) = YEAR(CURRENT_DATE()) AND MONTH(LUV.creation) = MONTH(CURRENT_DATE()) GROUP by LUV.uuid ORDER BY COUNT(*); ''' +QUERY_RESET_USER_VOTE = ''' UPDATE votes SET monthlyVotes = 0; ''' +QUERY_UPDATE_USER_VOTE = ''' UPDATE votes SET monthlyVotes = %s WHERE uuid = %s; ''' + +# open MySQL connection +db = MySQLdb.connect(host=DB_HOST, user=DB_USER, passwd=DB_PASS, db=DB_NAME) +# grab cursor +cur = db.cursor() + +def get_this_months_votes(): + ''' + Get all the votes, and the respective amount for this month. + + Returns: + A list of tuples in the form of (uuid, num_votes) for each voter. + Note: uuid is in form of 795FA12992B943E8B408BADB830CEB0B + ''' + cur.execute(QUERY_GET_THIS_MONTHS_VOTES) + + result = [] + for tup in cur: + uuid = str(tup[0]) + num_votes = int(tup[1]) + result.append((uuid, num_votes)) + + return result + +def reset_user_votes(): + ''' + Resets all users votes for the votes table, in the monthlyVotes column. + ''' + cur.execute(QUERY_RESET_USER_VOTE) + +def update_vote(uuid, num_votes): + ''' + Updates the vote tally for the specified user. + + Args: + uuid: The uuid for the user in the form of 0ff3234f-08d3-3344-887f-db721202f9bb + num_votes: The number of votes for that user + ''' + data = (int(num_votes), str(uuid)) + cur.execute(QUERY_UPDATE_USER_VOTE, data) + +######### +# BELOW IS THE ACTUAL SCRIPT LOGIC +######### + +print('Running script vote_sync.py...' ) +print() +start_time = time.time() + +votes_month = get_this_months_votes() +num_users_updated = 0 +vote_tallied = 0 +if votes_month is not None and len(votes_month): + + # reset user votes + reset_user_votes() + + # for each user + for uuid, num_votes in votes_month: + lower_uuid = str(uuid).lower() + + # 8 4 4 4 12 + formatted_uuid = str(lower_uuid[0:8]) + '-' + str(lower_uuid[8:12]) + '-' + str(lower_uuid[12:16]) + '-' + str(lower_uuid[16:20]) + '-' + str(lower_uuid[20:32]) + + update_vote(uuid=formatted_uuid, num_votes=num_votes) + vote_tallied += num_votes + num_users_updated += 1 + +# commit query +db.commit() + +run_time = time.time() - start_time +print('Number of users updated = ' + str(num_users_updated)) +print('Number of votes tallied = ' + str(vote_tallied)) +print('Finished script in ' + str(run_time) + ' secs.') + +# close the connection +db.close() \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/Core.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/Core.java new file mode 100644 index 0000000..ee0357e --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/Core.java @@ -0,0 +1,1318 @@ +package net.grandtheftmc.core; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.logging.Level; + +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.bukkit.Bukkit; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; + +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.ProtocolManager; +import com.j0ach1mmall3.ultimatecosmetics.Main; +import com.sk89q.worldedit.bukkit.WorldEditPlugin; + +import io.sentry.SentryClient; +import net.buycraft.plugin.bukkit.BuycraftPlugin; +import net.buycraft.plugin.internal.okhttp3.OkHttpClient; +import net.grandtheftmc.ServerTypeId; +import net.grandtheftmc.core.achivements.AchievementCommand; +import net.grandtheftmc.core.alert.AlertManager; +import net.grandtheftmc.core.announcer.Announcer; +import net.grandtheftmc.core.announcer.AnnouncerCommand; +import net.grandtheftmc.core.anticheat.Anticheat; +import net.grandtheftmc.core.casino.coins.CoinManager; +import net.grandtheftmc.core.commands.BucksCommand; +import net.grandtheftmc.core.commands.BungeeCommand; +import net.grandtheftmc.core.commands.ChatFilterCommand; +import net.grandtheftmc.core.commands.ClearChatCommand; +import net.grandtheftmc.core.commands.ConfigCommand; +import net.grandtheftmc.core.commands.CooldownCommand; +import net.grandtheftmc.core.commands.CouponCreditsCommand; +import net.grandtheftmc.core.commands.CrateCommand; +import net.grandtheftmc.core.commands.CrowbarCommand; +import net.grandtheftmc.core.commands.DiscordCommand; +import net.grandtheftmc.core.commands.EditModeCommand; +import net.grandtheftmc.core.commands.EventTagCommand; +import net.grandtheftmc.core.commands.FacebookCommand; +import net.grandtheftmc.core.commands.ForumRankCommand; +import net.grandtheftmc.core.commands.GlobalMuteCommand; +import net.grandtheftmc.core.commands.IgnoreCommand; +import net.grandtheftmc.core.commands.InfoCommand; +import net.grandtheftmc.core.commands.ListCommand; +import net.grandtheftmc.core.commands.MaxPlayersCommand; +import net.grandtheftmc.core.commands.MessageCommand; +import net.grandtheftmc.core.commands.OpenMenuCommand; +import net.grandtheftmc.core.commands.PlaytimeCommand; +import net.grandtheftmc.core.commands.PrefsCommand; +import net.grandtheftmc.core.commands.RankCommand; +import net.grandtheftmc.core.commands.ReplyCommand; +import net.grandtheftmc.core.commands.RewardsCommand; +import net.grandtheftmc.core.commands.RulesCommand; +import net.grandtheftmc.core.commands.SaveCommand; +import net.grandtheftmc.core.commands.ServerCommand; +import net.grandtheftmc.core.commands.SocialSpyCommand; +import net.grandtheftmc.core.commands.SpankCommand; +import net.grandtheftmc.core.commands.StoreCommand; +import net.grandtheftmc.core.commands.TokensCommand; +import net.grandtheftmc.core.commands.TradeCommand; +import net.grandtheftmc.core.commands.TrialCommand; +import net.grandtheftmc.core.commands.TwitterCommand; +import net.grandtheftmc.core.commands.VotestreakCommand; +import net.grandtheftmc.core.commands.WhitelistCommand; +import net.grandtheftmc.core.currency.Currency; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.database.dao.MutexDAO; +import net.grandtheftmc.core.database.dao.ServerStatsDAO; +import net.grandtheftmc.core.editmode.BlockChange; +import net.grandtheftmc.core.editmode.BreakBlock; +import net.grandtheftmc.core.editmode.Craft; +import net.grandtheftmc.core.editmode.HangingBreak; +import net.grandtheftmc.core.editmode.Liquid; +import net.grandtheftmc.core.editmode.PlaceBlock; +import net.grandtheftmc.core.editmode.WorldManager; +import net.grandtheftmc.core.event.EventCommand; +import net.grandtheftmc.core.events.ServerSaveEvent; +import net.grandtheftmc.core.handlers.chat.ChatManager; +import net.grandtheftmc.core.inventory.CoreMenuHandler; +import net.grandtheftmc.core.leaderboards.LeaderBoardManager; +import net.grandtheftmc.core.listeners.Chat; +import net.grandtheftmc.core.listeners.ChunkLoad; +import net.grandtheftmc.core.listeners.CommandListener; +import net.grandtheftmc.core.listeners.Damage; +import net.grandtheftmc.core.listeners.HopperComponent; +import net.grandtheftmc.core.listeners.HungerChange; +import net.grandtheftmc.core.listeners.InventoryClick; +import net.grandtheftmc.core.listeners.Join; +import net.grandtheftmc.core.listeners.Leave; +import net.grandtheftmc.core.listeners.Login; +import net.grandtheftmc.core.listeners.Move; +import net.grandtheftmc.core.listeners.PetListener; +import net.grandtheftmc.core.listeners.PlaywireRecieve; +import net.grandtheftmc.core.listeners.Save; +import net.grandtheftmc.core.listeners.SignChange; +import net.grandtheftmc.core.listeners.SwapHandItems; +import net.grandtheftmc.core.listeners.Teleport; +import net.grandtheftmc.core.listeners.UserStateTransactionListener; +import net.grandtheftmc.core.listeners.WeatherChange; +import net.grandtheftmc.core.menus.MenuListener; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.nametags.NametagCommand; +import net.grandtheftmc.core.nametags.NametagManager; +import net.grandtheftmc.core.npc.NPCManager; +import net.grandtheftmc.core.perms.PermsManager; +import net.grandtheftmc.core.playwire.PlaywireManager; +import net.grandtheftmc.core.redis.RedisFactory; +import net.grandtheftmc.core.redis.RedisManager; +import net.grandtheftmc.core.redis.listener.QueueListener; +import net.grandtheftmc.core.redis.listener.UserStateTransactionCheckListener; +import net.grandtheftmc.core.redis.listener.VoteNotificationListener; +import net.grandtheftmc.core.resourcepack.ResourcePackManager; +import net.grandtheftmc.core.servers.ServerManager; +import net.grandtheftmc.core.servers.ServerPingListener; +import net.grandtheftmc.core.servers.ServerType; +import net.grandtheftmc.core.stat.StatFactory; +import net.grandtheftmc.core.task.common.AntiAFK; +import net.grandtheftmc.core.task.common.BossBarTask; +import net.grandtheftmc.core.trading.TradeManager; +import net.grandtheftmc.core.tutorials.Help; +import net.grandtheftmc.core.tutorials.NextCommand; +import net.grandtheftmc.core.tutorials.TutorialCommand; +import net.grandtheftmc.core.tutorials.TutorialManager; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserDAO; +import net.grandtheftmc.core.users.UserManager; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.voting.VoteCommand; +import net.grandtheftmc.core.voting.VoteManager; +import net.grandtheftmc.core.voting.crates.CrateManager; +import net.grandtheftmc.core.voting.crates.listeners.CrateNearbyListener; +import net.grandtheftmc.core.voting.crates.listeners.CrateOpenListener; +import net.grandtheftmc.core.whitelist.WhitelistManager; +import net.grandtheftmc.jedis.JedisChannel; +import net.grandtheftmc.jedis.JedisManager; +import net.grandtheftmc.jedis.message.ServerQueueNotifyMessage; +import net.grandtheftmc.jedis.message.UserStateTransactionCheck; +import net.grandtheftmc.jedis.message.VoteNotificationMessage; + +public class Core extends JavaPlugin { + + // test commit + + public static final String GTM_VERSION = "2.4"; + public static final String VICE_VERSION = "2"; + public static final String CREATIVE_VERSION = "1.0"; + +// public static MySQL sql; + private static Core instance; + private WorldEditPlugin worldEdit; + private Main uc; + private ProtocolManager manager; + + private Settings settings; + + private ServerManager serverManager; + private UserManager userManager; + private PermsManager permsManager; + private NPCManager npcManager; + private WhitelistManager whitelistManager; + private VoteManager voteManager; + private Announcer announcer; + private TutorialManager tutorialManager; + private LeaderBoardManager leaderBoardManager; + private NametagManager nametagManager; + private CrateManager crateManager; + private AntiAFK antiAFK; + private WorldManager worldManager; +// private MySQLAsyncQueue mySQLAsyncQueue; + private BukkitTask mysqlAsyncTask; + private MenuManager menuManager; + private PlaywireManager playwireManager; + private CoinManager coinManager; + private static BuycraftPlugin bp; + private ChatManager chatManager; + public static ResourcePackManager resourcePackManager; + private TradeManager tradeManager; + private static JedisManager jedisManager; + private SentryClient sentryClient; + private AlertManager alertManager; + private CoreMenuHandler coreMenuHandler; + /** The boss bar task handler */ + private BossBarTask bossBarTask; + private static boolean enabled; + + private boolean restarting = false; + + private static final OkHttpClient okHttpClient = new OkHttpClient(); + + public static Core getInstance() { + return instance; + } + + public void setRestarting(boolean restarting) { + this.restarting = restarting; + } + + public boolean isRestarting(){ + return this.restarting; + } + + // public static MySQL getSQL() { +// return sql; +// } + + public static CoinManager getCoinManager() { + return Core.getInstance().coinManager; + } + + public static WorldEditPlugin getWorldEdit() { + return Core.getInstance().worldEdit; + } + + public static Main getUltimateCosmetics() { + return Core.getInstance().uc; + } + + public static ServerManager getServerManager() { + return Core.getInstance().serverManager; + } + + /** + * @deprecated Please just reference the singleton, {@link UserManager#getInstance()}. + */ + @Deprecated + public static UserManager getUserManager() { + return Core.getInstance().userManager; + } + + public static PermsManager getPermsManager() { + return Core.getInstance().permsManager; + } + + public static WhitelistManager getWhitelistManager() { + return Core.getInstance().whitelistManager; + } + + public static VoteManager getVoteManager() { + return Core.getInstance().voteManager; + } + + public static Announcer getAnnouncer() { + return Core.getInstance().announcer; + } + + public static Settings getSettings() { + return Core.getInstance().settings; + } + + public static OkHttpClient getOkHttpClient() { + return Core.getInstance().okHttpClient; + } + + public static TutorialManager getTutorialManager() { + return Core.getInstance().tutorialManager; + } + + public static NametagManager getNametagManager() { + return Core.getInstance().nametagManager; + } + + public static CrateManager getCrateManager() { + return Core.getInstance().crateManager; + } + + public static ProtocolManager getProtocolLib() { + return Core.getInstance().manager; + } + + public static AntiAFK getAntiAFK() { + return Core.getInstance().antiAFK; + } + + public static WorldManager getWorldManager() { + return Core.getInstance().worldManager; + } + + public static NPCManager getNPCManager() { + return Core.getInstance().npcManager; + } + + public static String name() { + return Core.getInstance().settings.name(); + } + +// public static MySQLAsyncQueue getMySQLAsyncQueue() { +// return Core.getInstance().mySQLAsyncQueue; +// } + + public static JedisManager getJedisManager() { + return jedisManager; + } + + public static void setJedisManager(JedisManager jmanager) { + jedisManager = jmanager; + } + + public SentryClient getSentryClient() { + return sentryClient; + } + + public static TradeManager getTradeManager() { + return Core.getInstance().tradeManager; + } + + public AlertManager getAlertManager() { + return alertManager; + } + + + public static void log(String s) { + Core.getInstance().getLogger().log(Level.INFO, s); + } + + public static void error(String s) { + Core.getInstance().getLogger().log(Level.SEVERE, s); + } + + public static boolean isCoreEnabled() { + return enabled; + } + + @Override + public void onEnable() { + + Bukkit.setWhitelist(false); + instance = this; + PluginManager plm = Bukkit.getPluginManager(); + + this.settings = new Settings(); + + this.manager = ProtocolLibrary.getProtocolManager(); + this.worldEdit = plm.getPlugin("WorldEdit") == null ? null : (WorldEditPlugin) plm.getPlugin("WorldEdit"); + this.uc = plm.getPlugin("UltimateCosmetics") == null ? null : (Main) plm.getPlugin("UltimateCosmetics"); + if (this.uc == null) { + Core.error("UltimateCosmetics not found. Disabling Cosmetics"); + this.settings.setLoadCosmetics(false); + } + this.load(); + bp = (BuycraftPlugin) Bukkit.getPluginManager().getPlugin("BuycraftX"); + this.worldManager = new WorldManager(); + this.serverManager = new ServerManager(); + this.userManager = UserManager.getInstance(); + this.permsManager = new PermsManager(); + this.whitelistManager = new WhitelistManager(); + this.voteManager = new VoteManager(this); + this.announcer = new Announcer(); + //this.playwireManager = new PlaywireManager().onEnable(this); + this.tutorialManager = new TutorialManager(); + this.leaderBoardManager = new LeaderBoardManager(); + this.nametagManager = new NametagManager(); + this.tradeManager = new TradeManager().onEnable(this); + this.crateManager = new CrateManager().onEnable(this); + this.coreMenuHandler = new CoreMenuHandler(this); + this.npcManager = new NPCManager().onEnable(this); + this.alertManager = new AlertManager().onEnable(this); + this.coinManager = new CoinManager().onEnable(this); + this.registerCommands(); + this.registerListeners(); + getServer().getMessenger().registerOutgoingPluginChannel(Core.getInstance(), "BungeeCord"); + +// EnjinCore.init(); + + ServerUtil.runTaskAsync(() -> { + String server = this.settings.getRedisConfig().getString("server"); + String password = this.settings.getRedisConfig().getString("password"); + int port = this.settings.getRedisConfig().getInt("port"); + + jedisManager = new JedisManager(); + + // init the module for the SERVER_QUEUE channel + jedisManager.initModule(new ServerTypeId(net.grandtheftmc.ServerType.valueOf(this.settings.getType().name().toUpperCase()), this.settings.getNumber()), JedisChannel.SERVER_QUEUE, server, port, password); + // init the module for the GLOBAL channel + jedisManager.initModule(new ServerTypeId(net.grandtheftmc.ServerType.valueOf(this.settings.getType().name().toUpperCase()), this.settings.getNumber()), JedisChannel.GLOBAL, server, port, password); + + // register listeners for redis payloads + Core.getJedisManager().getModule(JedisChannel.SERVER_QUEUE).registerListener(ServerQueueNotifyMessage.class, new QueueListener()); + Core.getJedisManager().getModule(JedisChannel.GLOBAL).registerListener(UserStateTransactionCheck.class, new UserStateTransactionCheckListener()); + Core.getJedisManager().getModule(JedisChannel.GLOBAL).registerListener(VoteNotificationMessage.class, new VoteNotificationListener()); + }); + + // register stat factory + StatFactory.init(this); + // TODO should probably only register this on hubs + StatFactory.getInstance().registerClientConnectionStat(getProtocolLib()); + +// this.sentryClient = Sentry.init("https://b92c7a1d7aa543d281784f682acd1679:297e39e8e563441498073d28479297be@sentry.io/210918"); +// this.sentryClient.setServerName(this.settings.getType().name() + "-" + this.settings.getNumber()); +// this.sentryClient +// try { +// Method setupUncaughtExc = this.sentryClient.getClass().getDeclaredMethod("setupUncaughtExceptionHandler"); +// setupUncaughtExc.setAccessible(true); +// setupUncaughtExc.invoke(this.sentryClient); +// } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { +// e.printStackTrace(); +// } +// System.out.println(this.sentryClient.toString()); +// +// Sentry.capture("This is the first capture test"); + + //Removed temp +// if(name().equalsIgnoreCase("gtm1")) { +// ScheduledExecutorService daily = Executors.newScheduledThreadPool(1); +// Long midnight = LocalDateTime.now().until(LocalDate.now().plusDays(1).atStartOfDay(), ChronoUnit.MINUTES); +// daily.scheduleAtFixedRate(new SaveDailyStatsRunnable(), midnight, TimeUnit.DAYS.toMinutes(1), TimeUnit.MINUTES); +// } + + new Anticheat(this); + BossBarTask bossBarTask = new BossBarTask(); + + // setup currencies + for (Currency currency : Currency.values()){ + + if (settings.isMainNetwork()){ + + // main network has some global currencies + switch(currency){ + case TOKEN: + case CROWBAR: + case COUPON_CREDIT: + case VOTE_TOKEN: + log("Setting " + currency.getId() + " as a GLOBAL currency."); + currency.setServerKey("GLOBAL"); + break; + case MONEY: + case PERMIT: + log("Setting " + currency.getId() + " as a SERVER currency."); + currency.setServerKey(name().toUpperCase()); + break; + } + } + else{ + + // sister network all currencies are server only + switch(currency){ + case TOKEN: + case CROWBAR: + case MONEY: + case PERMIT: + log("Setting " + currency.getId() + " as a SERVER currency."); + currency.setServerKey(name().toUpperCase()); + break; + } + } + } + + // setup ranks + for (UserRank ur : UserRank.values()){ + + if (settings.isMainNetwork()){ + switch(ur){ + default: + log("Setting " + ur.getName() + " as a GLOBAL rank."); + ur.setServerKey("GLOBAL"); + break; + } + } + else{ + switch(ur){ + case ADMIN: + case BUILDER: + case DEV: + case HELPOP: + case MANAGER: + case MOD: + case OWNER: + case SRMOD: + case YOUTUBER: + case BUILDTEAM: + log("Setting " + ur.getName() + " as a GLOBAL rank."); + ur.setServerKey("GLOBAL"); + break; + default: + log("Setting " + ur.getName() + " as a SERVER rank."); + ur.setServerKey(Core.name().toUpperCase()); + break; + } + } + } + + // remove all expired trial ranks + try (Connection conn = BaseDatabase.getInstance().getConnection()){ + UserDAO.removeAllExpiredTrialRanks(conn); + } + catch(Exception e){ + e.printStackTrace(); + } + + //Enable core. + enabled = true; + } + + @Override + public void onDisable() { + //Disable core. + enabled = false; + + Bukkit.setWhitelist(true); + Bukkit.getScheduler().cancelTasks(this); + this.save(true); + + for (JedisChannel channel : jedisManager.getJedisModules().keySet()) { + jedisManager.getModule(channel).disconnect(); + } + + //Components + if (this.announcer != null) this.announcer.onDisable(this); + if (this.worldManager != null) this.worldManager.onDisable(this); + if (this.chatManager != null) this.chatManager.onDisable(this); + if (this.leaderBoardManager != null) this.leaderBoardManager.onDisable(this); + if (this.menuManager != null) this.menuManager.onDisable(this); + if (this.nametagManager != null) this.nametagManager.onDisable(this); + if (this.permsManager != null) this.permsManager.onDisable(this); + if (resourcePackManager != null) resourcePackManager.onDisable(this); + if (this.antiAFK != null) this.antiAFK.onDisable(this); + if (this.tutorialManager != null) this.tutorialManager.onDisable(this); + if (this.crateManager != null) this.crateManager.onDisable(this); + if (this.voteManager != null) this.voteManager.onDisable(this); + if (this.whitelistManager != null) this.whitelistManager.onDisable(this); + if (this.alertManager != null) this.alertManager.onDisable(this); + if (this.npcManager !=null) this.npcManager.onDisable(this); + + for(Player player : Bukkit.getOnlinePlayers()) { + + // grab the user + User user = UserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + if (user != null && user.isLocked()){ + try (Connection conn = BaseDatabase.getInstance().getConnection()){ + + // save the user + user.onSave(conn); + + // update stats + ServerStatsDAO.updatePlaytimeAndFirstlogin(conn, player, user); + + // set mutex to false + MutexDAO.setUserMutex(conn, user.getUUID(), false); + } + catch(Exception e){ + e.printStackTrace(); + } + } + } + shutdownRedis(); + + // TODO test remove + System.out.println("[Core] Shutting down MySQL DB pool..."); + + // shutdown mysql connection pool + BaseDatabase.getInstance().close(); +// Sentry.close(); +// this.sentryClient.closeConnection(); + } + + private void registerListeners() { + PluginManager pm = Bukkit.getPluginManager(); + pm.registerEvents(new Join(), this); + pm.registerEvents(new Leave(), this); + pm.registerEvents(new Login(this), this); + pm.registerEvents(new Move(), this); + pm.registerEvents(new PetListener(), this); + pm.registerEvents(new SignChange(), this); + pm.registerEvents(new MenuListener(), this); + pm.registerEvents(new HungerChange(), this); + pm.registerEvents(new WeatherChange(), this); + if (!Core.getWorldManager().getEditModeWorlds().isEmpty()) { + pm.registerEvents(new BlockChange(), this); + pm.registerEvents(new BreakBlock(), this); + pm.registerEvents(new PlaceBlock(), this); + pm.registerEvents(new Liquid(), this); + } + if (!Core.getSettings().canCraft()) { + pm.registerEvents(new Craft(), this); + } + if (!Core.getWorldManager().getEditModeWorlds().isEmpty() || !Core.getSettings().canInteractInventory()) { + pm.registerEvents(new InventoryClick(), this); + } + pm.registerEvents(new ChunkLoad(), this); + pm.registerEvents(new Chat(), this); + pm.registerEvents(new Teleport(), this); + pm.registerEvents(new CommandListener(), this); + pm.registerEvents(new HangingBreak(), this); + pm.registerEvents(new net.grandtheftmc.core.editmode.Damage(), this); + pm.registerEvents(new net.grandtheftmc.core.editmode.Interact(), this); + pm.registerEvents(new net.grandtheftmc.core.editmode.InventoryClick(), this); + pm.registerEvents(new ServerPingListener(), this); + pm.registerEvents(new SwapHandItems(), this); + pm.registerEvents(new Save(), this); + pm.registerEvents(new CrateOpenListener(), this); + + if (pm.getPlugin("NuVotifier") != null || pm.getPlugin("Votifier") != null) { + if (!settings.isSister()) pm.registerEvents(this.voteManager, this); + } + + pm.registerEvents(menuManager = new MenuManager(), this); + pm.registerEvents(new Damage(), this); + pm.registerEvents(new CrateNearbyListener(), this); + pm.registerEvents(new HopperComponent(), this); + pm.registerEvents(new PlaywireRecieve(), this); + pm.registerEvents(new UserStateTransactionListener(this), this); + this.getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord"); + } + + private void registerCommands() { + this.getCommand("config").setExecutor(new ConfigCommand()); + new EditModeCommand(); + this.getCommand("rank").setExecutor(new RankCommand()); + this.getCommand("bucks").setExecutor(new BucksCommand()); + this.getCommand("tokens").setExecutor(new TokensCommand()); + this.getCommand("whitelist").setExecutor(new WhitelistCommand()); + this.getCommand("announcer").setExecutor(new AnnouncerCommand()); + this.getCommand("message").setExecutor(new MessageCommand()); + this.getCommand("reply").setExecutor(new ReplyCommand()); + + if (!Core.getSettings().isSister()) { + this.getCommand("vote").setExecutor(new VoteCommand()); + this.getCommand("votestreak").setExecutor(new VotestreakCommand()); + } + + this.getCommand("tutorial").setExecutor(new TutorialCommand()); + this.getCommand("next").setExecutor(new NextCommand()); + this.getCommand("socialspy").setExecutor(new SocialSpyCommand()); +// this.getCommand("cosmetic").setExecutor(new CosmeticCommand()); + this.getCommand("nametag").setExecutor(new NametagCommand()); +// this.getCommand("petdata").setExecutor(new PetDataCommand()); + this.getCommand("prefs").setExecutor(new PrefsCommand()); + this.getCommand("rewards").setExecutor(new RewardsCommand()); + this.getCommand("ignore").setExecutor(new IgnoreCommand()); + this.getCommand("list").setExecutor(new ListCommand()); + this.getCommand("clearchat").setExecutor(new ClearChatCommand()); + this.getCommand("globalmute").setExecutor(new GlobalMuteCommand()); + this.getCommand("rules").setExecutor(new RulesCommand()); + this.getCommand("save").setExecutor(new SaveCommand()); + this.getCommand("playtime").setExecutor(new PlaytimeCommand()); + this.getCommand("info").setExecutor(new InfoCommand()); + this.getCommand("achievement").setExecutor(new AchievementCommand()); + this.getCommand("crowbar").setExecutor(new CrowbarCommand()); + this.getCommand("crate").setExecutor(new CrateCommand()); + this.getCommand("maxplayers").setExecutor(new MaxPlayersCommand()); + this.getCommand("chatfilter").setExecutor(new ChatFilterCommand()); + this.getCommand("forumrank").setExecutor(new ForumRankCommand()); + this.getCommand("store").setExecutor(new StoreCommand()); + this.getCommand("event").setExecutor(new EventCommand(this)); + new DiscordCommand(); + new FacebookCommand(); + new TwitterCommand(); + new SpankCommand(); + new ServerCommand(); + new CooldownCommand(); + new CouponCreditsCommand(); + new BungeeCommand(); + new TradeCommand(); + new OpenMenuCommand(); + new TrialCommand(); + new EventTagCommand(); + } + + private void load() { + this.getServer().getScheduler().scheduleSyncRepeatingTask(this, () -> { + Bukkit.getPluginManager().callEvent(new ServerSaveEvent()); + this.getLogger().info("ServerSaveEvent check"); + }, 18000L, 18000L); + this.settings.setCoreConfig(Utils.loadConfig("core")); + this.settings.setMySQLConfig(Utils.loadConfigFromMaster("mysql")); + this.settings.setServersConfig(Utils.loadConfig("servers")); + this.settings.setJoinSignsConfig(Utils.loadConfig("joinSigns")); + this.settings.setPermsConfig(Utils.loadConfig("perms")); + this.settings.setWhitelistConfig(Utils.loadConfig("whitelist")); + this.settings.setAnnouncerConfig(Utils.loadConfig("announcer")); + this.settings.setVotingConfig(Utils.loadConfig("voting")); + this.settings.setTokenShopConfig(Utils.loadConfig("tokenshop")); + this.settings.setTutorialsConfig(Utils.loadConfig("tutorials")); + this.settings.setLeaderBoardsConfig(Utils.loadConfig("leaderBoards")); + this.settings.setSocialSpyConfig(Utils.loadConfig("socialSpy")); + this.settings.setWorldsConfig(Utils.loadConfig("worlds")); + this.settings.setRewardsConfig(Utils.loadConfig("rewards")); + this.settings.setRulesConfig(Utils.loadConfig("rules")); + this.settings.setNametagsConfig(Utils.loadConfigFromMaster("nametags")); + this.settings.setHelpConfig(Utils.loadConfig("help")); + this.settings.setCratesConfig(Utils.loadConfig("crates")); + this.settings.setCrateRewardsConfig(Utils.loadConfig("craterewards")); + this.settings.setRedisConfig(Utils.loadConfig("redis")); + Utils.setMaxPlayers(this.settings.getCoreConfig().getInt("maxplayers")); + YamlConfiguration c = this.settings.getCoreConfig(); + + // New entries to support sister network. + this.settings.setSister(c.getBoolean("sister")); + this.settings.setNetworkName(c.getString("networkName")); + this.settings.setNetworkShortName(c.getString("networkShortName")); + this.settings.setNetworkIP(c.getString("networkIP")); + this.settings.setWebsiteLink(c.getString("websiteLink")); + this.settings.setStoreLink(c.getString("websiteStoreLink")); + this.settings.setServer_GTM_name(c.getString("server_GTA_name")); + this.settings.setServer_GTM_shortName(c.getString("server_GTA_shortName")); + + this.settings.setType(ServerType.getType(c.getString("serverType"))); + if (c.get("serverNumber") == null) this.settings.setNumber(0); + else this.settings.setNumber(c.getInt("serverNumber")); + if (c.getString("rankToJoin") != null) + this.settings.setRankToJoin(UserRank.getUserRankOrNull(c.getString("rankToJoin"))); + + this.loadMySQL(); + this.loadMenus(); + Help.loadHelpData(); + antiAFK = new AntiAFK(); + this.chatManager = new ChatManager(Utils.loadConfig("chatsettings")); + +// mySQLAsyncQueue = new MySQLAsyncQueue(); +// mysqlAsyncTask = Bukkit.getScheduler().runTaskTimerAsynchronously(this, mySQLAsyncQueue, 0L, 20L); + + loadRedis(); + } + + public void reload() { + +// mySQLAsyncQueue.run(); +// mysqlAsyncTask.cancel(); + + // TODO remove legacy code + BaseDatabase.getInstance().close(); + //sql.closeConnection(); + + shutdownRedis(); + + this.load(); + this.serverManager.loadJoinSigns(); + this.permsManager.loadPerms(); + this.whitelistManager.load(); + this.announcer.loadAnnouncements(); + this.announcer.startSchedule(); + + if (!settings.isSister()) { + this.voteManager.startSchedule(); + this.voteManager.loadLinksAndRewards(); + this.voteManager.loadTokenShop(); + } + + this.tutorialManager.load(); + this.leaderBoardManager.loadLeaderBoards(); + this.nametagManager.loadNametags(); + this.crateManager.load(); + this.crateManager.loadRewards(); + } + + public void save(boolean shutdown) { + this.serverManager.saveJoinSigns(shutdown); + this.permsManager.savePerms(shutdown); + this.whitelistManager.save(shutdown); + this.announcer.saveAnnouncements(shutdown); + this.tutorialManager.save(shutdown); + this.leaderBoardManager.saveLeaderBoards(shutdown); + this.crateManager.save(shutdown); + + if (!settings.isSister()) { + this.voteManager.save(shutdown); + } + } + + + private void loadRedis() { + String server = this.settings.getRedisConfig().getString("server"); + String password = this.settings.getRedisConfig().getString("password"); + int port = this.settings.getRedisConfig().getInt("port"); + Core.log("Attempting to connect to redis server (" + server + ":" + port + ")(pass=" + password + ")..."); + + Bukkit.getScheduler().runTaskAsynchronously(this, () -> { + +// Core.log("Initialising Redis connection pool..."); +// new RedisFactory(server, password, port, () -> { +// +// Core.log("Initialising Redis listener..."); +// new RedisListener(); +// }); + + + }); + + /* //THIS WORKS + + try { + jedis = new Jedis(server, port); + jedis.auth(password); + jedis.ping(); + getLogger().info("Connected to Redis server successfully."); + + redisManager = new RedisManager(); + + Bukkit.getScheduler().runTaskAsynchronously(this, () -> { + new RedisListener(); + }); + + getLogger().info("Redis listener registered."); + } catch (Exception e) { + getLogger().warning("Failed to connect to redis! Redis support is disabled."); + }*/ + + + + /* + +FutureTask task = new FutureTask(new Callable() { + public JedisPool call() + throws Exception { + //JedisPoolConfig config = new JedisPoolConfig(); + //config.setMaxTotal(8); + return new JedisPool(server, port); + //return new JedisPool(config, server, port, 0, password); + } + }); + + Bukkit.getScheduler().runTaskAsynchronously(this, task); + + try { + Core.log("Creating Jedis pool..."); + ClassLoader prev = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(Core.class.getClassLoader()); + this.pool = task.get(); + Thread.currentThread().setContextClassLoader(prev); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException("Unable to create Redis pool", e); + } + + + try (Jedis rsc = pool.getResource()) { + Core.log("Pinging Redis..."); + rsc.auth(password); + rsc.ping(); + // If that worked + getLogger().log(Level.INFO, "Successfully connected to Redis."); + + redisManager = new RedisManager(); + new RedisListener(); + } catch (JedisConnectionException e) { + pool.destroy(); + pool = null; + athrow e; + }*/ + } + + private void shutdownRedis() { + if (RedisManager.redisEnabled()) { + RedisFactory.getPool().close(); + } + } + + private void loadMySQL() { + + // initialize sql with settings from config.yml (in mysql) column + YamlConfiguration c = this.settings.getMySQLConfig(); + + // TODO remove, as it's the old way of starting the sql settings + this.settings.setHost(c.getString("mysql.host")); + this.settings.setPort(c.getString("mysql.port")); + this.settings.setDatabase(c.getString("mysql.database")); + this.settings.setUser(c.getString("mysql.user")); + this.settings.setPassword(c.getString("mysql.password")); + +// sql = new MySQL(this.settings.getHost(), this.settings.getPort(), this.settings.getDatabase(), this.settings.getUser(), +// this.settings.getPassword()); +// sql.openConnection(); + + // two connection system for compatibility purposes + BaseDatabase.getInstance().init(c, "mysql"); + // TEST + try (Connection conn = BaseDatabase.getInstance().getConnection()){ + System.out.println("[Core] BaseDatabase grabbing connection..."); + try (ResultSet result = conn.prepareStatement("SELECT 1").executeQuery()){ + // empty on purpose + System.out.println("[Core] BaseDatabase works!"); + } + } + catch(Exception e){ + e.printStackTrace(); + } + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("ALTER TABLE users " + + "ADD COLUMN `country` VARCHAR(32) NOT NULL DEFAULT 'NONE'," + + "ADD COLUMN `language` VARCHAR(8) NOT NULL DEFAULT 'NONE';")) { + + statement.execute(); + } + } catch (SQLException e) { +// e.printStackTrace(); Ignore + } + + new BukkitRunnable() { + @Override + public void run() { +// if (!Core.this.settings.loadCosmetics()) return; +// try (ResultSet rs = Core.sql.query("select * from cosmetics LIMIT 1;")) { +// ResultSetMetaData metaData = rs.getMetaData(); +// List columns = new ArrayList<>(); +// for (int i = 3; i <= metaData.getColumnCount(); i++) +// columns.add(metaData.getColumnName(i).toLowerCase()); +// for (CosmeticType type : CosmeticType.values()) { +// if (!columns.contains(type.toString().toLowerCase())) +// Core.sql.update("alter table cosmetics add column `" + type.toString().toLowerCase() + "` BOOLEAN not null default 0;"); +// if (!columns.contains("last:" + type.toString().toLowerCase())) +// Core.sql.update("alter table cosmetics add column `last:" + type.toString().toLowerCase() + "` VARCHAR(255);"); +// } +// for (Cosmetic c : Cosmetic.values()) { +// if (!columns.contains(c.getDBName())) { +// Core.sql.update("alter table cosmetics add column `" + c.getDBName() + "` BOOLEAN not null default 0;"); +// } +// } +// rs.close(); +// } catch (SQLException e) { +// Core.error("Error while altering Cosmetics table: "); +// e.printStackTrace(); +// } +// try (ResultSet rs = Core.sql.query("select * from nametags LIMIT 1;")) { +// ResultSetMetaData metaData = rs.getMetaData(); +// List columns = new ArrayList<>(); +// for (int i = 3; i <= metaData.getColumnCount(); i++) +// columns.add(metaData.getColumnName(i).toLowerCase()); +// Core.getNametagManager().getNametags().stream().filter(tag -> !columns.contains(tag.getName().toLowerCase())).forEach(tag -> Core.sql.update("alter table nametags add column " + tag.getName() + " BOOLEAN not null default 0;")); +// rs.close(); +// } catch (SQLException e) { +// Core.error("Error while altering Nametags table:"); +// e.printStackTrace(); +// } + } + }.runTaskAsynchronously(this); + } + + private void loadMenus() { + if (!Core.getSettings().isSister()) { + MenuManager.addMenu("vote", 54, "&e&lVoting Menu"); + } + MenuManager.addMenu("tokenshop", 54, "&e&lToken Shop"); + MenuManager.addMenu("buyshopitem", 54, "&e&lBuy Token Shop Item"); + MenuManager.addMenu("serverwarper", 54, "&e&lServer Warper"); + MenuManager.addMenu("gtmservers", 54, "&e&l" + Core.getSettings().getServer_GTM_shortName() + " Server Warper"); + MenuManager.addMenu("cosmetics", 54, "&6&lCosmetics"); + MenuManager.addMenu("buycosmetic", 54, "&6&lBuy Cosmetic"); + MenuManager.addMenu("nametags", 54, "&a&lNametags"); + MenuManager.addMenu("applynametag", 54, "&a&lApply Nametag"); + MenuManager.addMenu("buynametag", 54, "&a&lBuy Nametag"); + MenuManager.addMenu("chooseeventtag", 54, "&6&lChoose Event Tag"); + MenuManager.addMenu("prefs", 54, "&5&lPreferences"); + MenuManager.addMenu("rewards", 54, "&a&lRewards"); + MenuManager.addMenu("confirmcratereward", 54, "&e&lConfirm Accepting Reward"); + MenuManager.addMenu("confirmexpensivecrate", 54, "&e&lConfirm Opening Crate"); + MenuManager.addMenu("hubservers", 54, "&e&lHub Server Warper"); + MenuManager.addMenu("topvoters", 54, "&a&lTop Voters"); + MenuManager.addMenu("freecoupons", 54, "&a&lStore Coupons"); + + if (!Core.getSettings().isSister()) { + MenuManager.addMenu("topvoters", 54, "&a&lTop Voters"); + } + +// ServerType st = this.settings.getType(); +// for (CosmeticType type : CosmeticType.values()) +// if (type.isEnabled(st)) +// MenuManager.addMenu(type.toString().toLowerCase(), 54, type.getColoredDisplayName()); +// if (CosmeticType.BANNER.isEnabled(st)) +// MenuManager.addMenu("bannervariant", 54, CosmeticType.BANNER.getColoredDisplayName() + " Hat or Cape"); +// if (CosmeticType.BLOCK.isEnabled(st)) +// MenuManager.addMenu("blockvariant", 54, "&2&lBalloon or Block Pet"); +// if (CosmeticType.PARTICLE.isEnabled(st)) +// MenuManager.addMenu("particleshape", 54, CosmeticType.PARTICLE.getColoredDisplayName() + " Shape"); +// if (CosmeticType.PET.isEnabled(st)) { +// MenuManager.addMenu("petdata", 54, CosmeticType.PET.getColoredDisplayName() + " Data"); +// } + } + + public static BuycraftPlugin getBuycraftX() { + return bp; + } + public String getBuycraftSecret() { + return "74d7d741ff781080376cee2bd09635098a7b966e"; + } + + private static LinkedList getPastDataFromExcel(String fileName) throws IOException{ + FileInputStream excelFile = null; + try { + excelFile = new FileInputStream(new File(fileName)); + }catch (FileNotFoundException e) { + XSSFWorkbook workbook = new XSSFWorkbook(); + File f = new File(fileName); + f.createNewFile(); + FileOutputStream outputStream = new FileOutputStream(f); + workbook.write(outputStream); + workbook.close(); + return getPastDataFromExcel(fileName); + } + + XSSFWorkbook workbook = new XSSFWorkbook(excelFile); + XSSFSheet sheet = workbook.getSheet("Stats")==null ? workbook.createSheet("Stats") : workbook.getSheet("Stats"); + Iterator iterator = sheet.iterator(); + LinkedList pastData = new LinkedList(); + + while (iterator.hasNext()) { + Row currentRow = iterator.next(); + Iterator cellIterator = currentRow.iterator(); + StringBuilder sb = new StringBuilder(); + while (cellIterator.hasNext()) { + Cell currentCell = cellIterator.next(); + if (currentCell.getCellTypeEnum() == CellType.STRING) { + sb.append(currentCell.getStringCellValue() + "-"); + } else if (currentCell.getCellTypeEnum() == CellType.NUMERIC) { + sb.append(currentCell.getNumericCellValue() + "-"); + } + } + sb.deleteCharAt(sb.length()-1); + pastData.add(sb.toString()); + } + return pastData; + } + + public static void saveDataToExcel(String fileName, LinkedList pastData) throws IOException{ + int rowNum = 0; + FileInputStream excelFile = new FileInputStream(new File(fileName)); + XSSFWorkbook workbook = new XSSFWorkbook(excelFile); + XSSFSheet sheet = workbook.getSheet("Stats")==null ? workbook.createSheet("Stats") : workbook.getSheet("Stats"); + for(String entry : pastData) { + Row row = sheet.createRow(rowNum++); + int colNum = 0; + for (String s : entry.split("-")) { + Cell cell = row.createCell(colNum++); + cell.setCellValue(s); + } + } + + try { + FileOutputStream outputStream = new FileOutputStream(new File("stats.xlsx")); + workbook.write(outputStream); + workbook.close(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } + + /** + * Get the boss bar task that belongs to this Core plugin. + * + * @return The boss bar task handler. + */ + public BossBarTask getBossBarTask() { + return bossBarTask; + } + + +// public static class SaveDailyStatsRunnable implements Runnable { +// +// @Override +// public void run(){ +// new BukkitRunnable() { +// @Override +// public void run() { +// try { +// saveDailyStats(); +// Calendar calendar = Calendar.getInstance(); +// int day = calendar.get(Calendar.DAY_OF_WEEK); +// if(day == Calendar.MONDAY) { +// saveWeeklyStats(); +// } +// } catch (IOException | SQLException e) { +// e.printStackTrace(); +// } +// } +// }.runTaskAsynchronously(Core.getInstance()); +// +// } +// +// private void saveWeeklyStats() throws IOException, SQLException{ +// +// LinkedList pastData = getPastDataFromExcel("stats-weekly.xlsx"); +// +// double totalLogins = 0, totalNewPlayers = 0, totalNewPlayersLoginAgain = 0, totalPlayersPlayedBoth = 0, totalPlayersPlayedVice = 0, totalPlayersPlayedGTM = 0; +// ResultSet set = sql.prepareStatement("SELECT * FROM server_stats").executeQuery(); +// while(set.next()) { +// totalLogins++; +// long firstLogin = set.getLong("firstLogin"); +// long weeklyLogin = set.getLong("weeklyLoginTime"); +// if(System.currentTimeMillis() - firstLogin <= 1000*60*60*24*7) { +// totalNewPlayers++; +// if(weeklyLogin!=0 && weeklyLogin!=firstLogin) +// totalNewPlayersLoginAgain++; +// } +// String playedServers = set.getString("playedServers")!=null ? set.getString("playedServers").toLowerCase() : ""; +// if(playedServers.contains("vice") && playedServers.contains("gtm")) { +// totalPlayersPlayedBoth++; +// continue; +// } +// if(playedServers.contains("vice")) { +// totalPlayersPlayedVice++; +// } +// if(playedServers.contains("gtm")) { +// totalPlayersPlayedGTM++; +// } +// +// } +// pastData.add(new Date().toGMTString() + "-" + totalNewPlayersLoginAgain + "-" + totalPlayersPlayedBoth + "-" + totalPlayersPlayedVice + "-" + totalPlayersPlayedGTM + "-" + totalNewPlayers + "-" + totalLogins); +// +// saveDataToExcel("stats-weekly.xlsx", pastData); +// +// double avgLogins = 0, avgNewPlayers = 0, avgNewPlayersLoginAgain = 0, avgPlayersPlayedBoth = 0, avgPlayersPlayedVice = 0, avgPlayersPlayedGTM = 0; +// int maxSize = (pastData.size() > 4 ? 4 : pastData.size()); +// Collections.reverse(pastData); +// for(int i = 0; i fields = new ArrayList<>(); +// +// SlackField f1 = new SlackField(); +// f1.setTitle("New Players Who Logged In >1 Times (Last 7 days)"); +// f1.setValue(df.format(totalNewPlayersLoginAgain/totalNewPlayers*100) + "% (4 Week Average: " + df.format(avgNewPlayersLoginAgain/avgNewPlayers*100) + "%)"); +// f1.setShorten(false); +// fields.add(f1); +// +// SlackField f2 = new SlackField(); +// f2.setTitle("Players Who Logged Into JUST Vice (Last 7 days)"); +// f2.setValue(df.format(totalPlayersPlayedVice/totalLogins*100) + "% (4 Week Average: " + df.format(avgPlayersPlayedVice/avgLogins*100) + "%)"); +// f2.setShorten(false); +// fields.add(f2); +// +// SlackField f3 = new SlackField(); +// f3.setTitle("Players Who Logged Into JUST GTM (Last 7 days)"); +// f3.setValue(df.format(totalPlayersPlayedGTM/totalLogins*100) + "% (4 Week Average: " + df.format(avgPlayersPlayedGTM/avgLogins*100) + "%)");; +// f3.setShorten(false); +// fields.add(f3); +// +// SlackField f4 = new SlackField(); +// f4.setTitle("Players Who Logged Into BOTH Vice and GTM (Last 7 days)"); +// f4.setValue(df.format(totalPlayersPlayedBoth/totalLogins*100) + "% (4 Week Average: " + df.format(avgPlayersPlayedBoth/avgLogins*100) + "%)"); +// f4.setShorten(false); +// fields.add(f4); +// +// attachment.setFields(fields); +// msg.setAttachments(Arrays.asList(attachment)); +// msg.setText(" "); +// api.call(msg); +// +// sql.prepareStatement("update server_stats set playedServers = NULL;").executeUpdate(); +// sql.prepareStatement("update server_stats set weeklyLoginTime = " + System.currentTimeMillis() + ";").executeUpdate(); +// +// } +// +// private void saveDailyStats() throws IOException, SQLException{ +// +// for(Player p: Bukkit.getOnlinePlayers()) { +// User u = Core.getUserManager().getLoadedUser(p.getUniqueId()); +// long playTime = System.currentTimeMillis() - u.getLoginTime() + u.getDailyPlayTime(); +// PreparedStatement stmt = Core.sql.prepareStatement("UPDATE server_stats set dailyPlayTime=" + playTime + ", firstLogin=" + p.getFirstPlayed() + " WHERE uuid='" + p.getUniqueId() + "';"); +// stmt.execute(); +// u.setDailyPlayTime(0); +// u.setLoginTime(System.currentTimeMillis()); +// } +// +// LinkedList pastData = getPastDataFromExcel("stats.xlsx"); +// +// double dailyTotalLogins = 0, dailyPlaytime = 0, dailyNewPlayers = 0, dailyPlaytimeRanked = 0, dailyLoginsRanked = 0, dailyLoginsDefault = 0, dailyPlaytimeDefault = 0; +// ResultSet set = sql.prepareStatement("SELECT * FROM server_stats").executeQuery(); +// while(set.next()) { +// String uuid = set.getString("uuid"); +// if((System.currentTimeMillis() - set.getLong("firstLogin")<=1000*60*60*24)) +// dailyNewPlayers++; +// if(System.currentTimeMillis() - set.getLong("dailyLoginTime")<=1000*60*60*24) { +// dailyTotalLogins++; +// long playtime = set.getLong("dailyPlayTime"); +// dailyPlaytime += playtime; +// ResultSet rank = sql.prepareStatement("SELECT * FROM users where UUID='" + uuid + "';").executeQuery(); +// if(rank.next()) { +// UserRank userRank = UserRank.getUserRank(rank.getString("userrank")); +// if(userRank==UserRank.DEFAULT) { +// dailyLoginsDefault++; +// dailyPlaytimeDefault += playtime; +// } +// else { +// dailyLoginsRanked++; +// dailyPlaytimeRanked += playtime; +// } +// } +// } +// } +// set = sql.prepareStatement("SELECT * FROM users;").executeQuery(); +// +// double totalPlayers = 0; +// if(set.last()) +// totalPlayers = set.getRow(); +// +// dailyPlaytime /= dailyTotalLogins; +// dailyPlaytime /= 1000.0 * 60.0;//minutes +// +// dailyPlaytimeDefault /= dailyLoginsDefault; +// dailyPlaytimeDefault /= 1000.0 * 60.0; +// +// dailyPlaytimeRanked /= dailyLoginsRanked; +// dailyPlaytimeRanked /= 1000.0 * 60.0; +// +// pastData.add(new Date().toGMTString() + "-" + dailyTotalLogins + "-" + dailyNewPlayers + "-" + dailyPlaytime + "-" + dailyPlaytimeRanked + "-" + dailyPlaytimeDefault); +// //pastData.add(new Date().toGMTString() + "-" + cNewPlayers + "-" + cActivePlayers); +// +// saveDataToExcel("stats.xlsx", pastData); +// +// double avgNewPlayers = 0, avgActivePlayers = 0, avgPlayTime = 0, avgPlayTimeRanked = 0, avgPlayTimeDefault = 0; +// int maxSize = (pastData.size() > 7 ? 7 : pastData.size()); +// Collections.reverse(pastData); +// for(int i = 0; i fields = new ArrayList<>(); +// +// SlackField f1 = new SlackField(); +// f1.setTitle("Active Players (Last 24 hrs)"); +// f1.setValue(dailyTotalLogins + " (" + df.format((dailyTotalLogins-avgActivePlayers)/avgActivePlayers*100) + "% Change compared to 7 day average)"); +// f1.setShorten(false); +// fields.add(f1); +// +// SlackField f2 = new SlackField(); +// f2.setTitle("New Players (Last 24 hrs)"); +// f2.setValue(dailyNewPlayers + " (" + df.format((dailyNewPlayers-avgNewPlayers)/avgNewPlayers*100) + "% Change compared to 7 day average)"); +// f2.setShorten(false); +// fields.add(f2); +// +// SlackField f3 = new SlackField(); +// f3.setTitle("Average Playtime (Last 24 hrs)"); +// f3.setValue(df.format(dailyPlaytime) + "min (" + df.format((dailyPlaytime-avgPlayTime)/avgPlayTime*100) + "% Change compared to 7 day average)"); +// f3.setShorten(false); +// fields.add(f3); +// +// SlackField f4 = new SlackField(); +// f4.setTitle("Average Playtime for Ranked Users (Last 24 hrs)"); +// f4.setValue(df.format(dailyPlaytimeRanked) + "min (" + df.format((dailyPlaytimeRanked-avgPlayTimeRanked)/avgPlayTimeRanked*100) + "% Change compared to 7 day average)"); +// f4.setShorten(false); +// fields.add(f4); +// +// SlackField f5 = new SlackField(); +// f5.setTitle("Average Playtime for Default Users (Last 24 hrs)"); +// f5.setValue(df.format(dailyPlaytimeDefault) + "min (" + df.format((dailyPlaytimeDefault-avgPlayTimeDefault)/avgPlayTimeDefault*100) + "% Change compared to 7 day average)"); +// f5.setShorten(false); +// fields.add(f5); +// +// +// SlackField f6 = new SlackField(); +// f6.setTitle("Total Players"); +// f6.setValue(totalPlayers + ""); +// f6.setShorten(false); +// fields.add(f6); +// +// attachment.setFields(fields); +// msg.setAttachments(Arrays.asList(attachment)); +// msg.setText(" "); +// api.call(msg); +// +// sql.prepareStatement("update server_stats set dailyPlayTime = 0;").executeUpdate(); +// sql.prepareStatement("update server_stats set dailyLoginTime = " + System.currentTimeMillis() + ";").executeUpdate(); +// +// } +// } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/Lang.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/Lang.java new file mode 100644 index 0000000..4a4ef98 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/Lang.java @@ -0,0 +1,116 @@ +package net.grandtheftmc.core; + +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.Utils; + +public enum Lang { + + NOPERM("&cYou don't have permission to execute this command!"), + CHRISTMAS("&a&lC&c&lH&a&lR&c&lI&a&lS&c&lT&a&lM&c&lA&a&lS&8&l> "), + NOTPLAYER("&cYou are not a player!"), + MSG(" &a&lMSG&8&l> "), + TRADE(" &2&lTRADE&8&l> "), + BUCKS(" &a&lBUCKS&8&l> "), + BUCKS_ADD(" &a&lBUCKS&8&l> &a&l+&a $&l"), + BUCKS_TAKE(" &a&lBUCKS&8&l> &c&l-&c $&l"), + TOKENS(" &e&lTOKENS&8&l> "), + TOKENS_ADD(" &e&lTOKENS&8&l> &e&l+ "), + TOKENS_TAKE(" &e&lTOKENS&8&l> &c&l- "), + MONEY(" &3&lMONEY&8&l> "), + MONEY_ADD(" &3&lMONEY&8&l> &a&l+&a $&l"), + MONEY_TAKE(" &3&lMONEY&8&l> &c&l-&c $&l"), + CROWBARS(" &9&lCROWBARS&8&l> "), + CROWBARS_ADD(" &9&lCROWBARS&8&l> &9&l+ "), + CROWBARS_TAKE(" &9&lCROWBARS&8&l> &c&l- "), + ATM(" &3&lATM&8&l> "), + BANK(" &3&lBANK&8&l> "), + BANK_ADD("&3&lBANK&8&l> &a&l+&a $&l"), + BANK_TAKE("&3&lBANK&8&l> &c&l-&c $&l"), + AMMO(" &c&lAMMO&8&l> "), + AMMO_ADD(" &c&lAMMO&8&l> &a&l+ "), + AMMO_TAKE(" &c&lAMMO&8&l> &c&l- "), + GTM(" &7&l" + Core.getSettings().getServer_GTM_shortName() + "&8&l> "), + CHEAT_CODES(" &2&lCHEATCODE&8&l> "), + PREFS(" &5&lPREFS&8&l> "), + AMMUNATION(" &9&lAMMU&4&lNATION&8&l> "), + WANTED(" &c&lWANTED&8&l> "), + TAXI(" &e&lTAXI&8&l> "), + WARP(" &e&lWARP&8&l> "), + SHOP(" &a&lSHOP&8&l> "), + TRASH_CAN(" &7&lTRASH CAN&8&l> "), + HEY(" &c&lHEY&8&l> "), + COMBATTAG(" &7&lCOMBATTAG&8&l> "), + GUARDPETS(" &c&lGUARD PETS&8&l> "), + BOUNTIES(" &5&lBOUNTIES&8&l> "), + VOTE(" &e&lVOTE&8&l> "), + TOKEN_SHOP(" &e&lTOKEN SHOP&8&l> "), + CRATES(" &6&lCRATES&8&l> "), + KITS(" &b&lKITS&8&l> "), + GAMEITEMS(" &a&lGAMEITEMS&8&l> "), + RANKUP(" &a&lRANKUP&8&l> "), + RANKS(" &a&lRANKS&8&l> "), + JOBS(" &3&lJOBS&8&l> "), + COP_MODE(" &3&lCOP MODE&8&l> "), + COPS(" &3&lCOPS&8&l> "), + COP(" &3&lCOP&8&l> "), + POLICE(" &3&lPOLICE&8&l> "), + BRIBE(" &3&lBRIBE&8&l> "), + HITMAN_MODE(" &8&lHITMAN MODE> "), + JAIL(" &c&lJAIL&8&l> "), + GPS(" &7&lGPS&8&l> "), + HOUSES(" &3&lHOUSES&8&l> "), + TUTORIALS(" &2&lTUTORIALS&8&l> "), + GANGS(" &a&lGANGS&8&l> "), + GANGCHAT(" &a&lGANGCHAT&8&l> "), + LOOTCRATES(" &e&lLOOTCRATES&8&l> "), + GLIDERS(" &c&lGLIDERS&8&l> "), + HUB("&6&lHUB&8&l> "), + SOCIALSPY(" &c&lSOCIALSPY&8&l> "), + VANISH(" &c&lVANISH&8&l> "), + SS(" &c&lSS&8&l> "), + SERVERS(" &6&lSERVERS&8&l> "), + COSMETICS(" &6&lCOSMETICS&8&l> "), + NAMETAGS(" &e&lNAMETAGS&8&l> "), + REWARDS(" &a&lREWARDS&8&l> "), + VEHICLES(" &4&lVEHICLES&8&l> "), + DEATH(" &c&lDEATH&8&l> "), + HEAD_AUCTION(" &e&lHEAD AUCTION&8&l> "), + ARMOR_UPGRADE(" &b&lARMOR UPGRADE&8&l> "), + ANTIAURA(" &c&lANTIAURA&8&l> "), + SAVE(" &c&lSAVE&8&l> "), + ACHIEVEMENT(" &c&lACHIEVEMENTS&8&l> "), + GTW(" &e&lGTW&8&l> "), + DRUGS(" &e&lDRUGS&8&L> "), + LOTTERY(" &e&lLOTTERY&8&l> "), + ANTISPAM(" &c&lANTISPAM&8&l> "), + ANTIAD(" &c&lANTIADVERT&8&l> "), + VICE(" &d&lVICE&8&l> "), + DISCORD(" &5&lDISCORD&8&l> "), + FACEBOOK(" &1&lFACEBOOK&8&l> "), + TWITTER(" &3&lTWITTER&8&l> "), + SPANK(" &d&lS&a&lP&e&lA&9&lN&b&lK&8&l>&7 "), + QUEUE(" &e&lQUEUE&8&l> "), + ALERTS(" &c&lALERTS&8&l>&7 "), + CASINO(" &9&lCASINO&8&l>&7 "), + ANTICHEAT(" " + C.RED + C.BOLD + "WATCHDAWG" + C.DARK_GRAY + C.BOLD + ">" + C.RESET + " "), + ; + + private final String s; + + Lang(String s) { + this.s = s; + } + + public String s() { + return Utils.f(this.s); + } + + @Override + public String toString() { + return Utils.f(this.s); + } + + public String f(String s) { + return Utils.f(this.s + s); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/Settings.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/Settings.java new file mode 100644 index 0000000..73e506e --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/Settings.java @@ -0,0 +1,592 @@ +package net.grandtheftmc.core; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.GameMode; +import org.bukkit.configuration.file.YamlConfiguration; + +import net.grandtheftmc.core.servers.ServerType; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.Utils; + +public class Settings { + + private final List stopHungerChange = new ArrayList<>(); + private final List stopWeatherChange = new ArrayList<>(); + private final List stopChunkLoad = new ArrayList<>(); + private boolean stopLoadDefaultWorld; + private boolean deletePlayerDatFiles; + private GameMode defaultGameMode = GameMode.ADVENTURE; + private boolean joinLeaveMessagesEnabled; + private boolean useTeleportFix = true; + private boolean loadCosmetics; + private boolean serverWarperEnabled = true; + private boolean statsMenuEnabled = true; + private boolean useAnnouncer; + private boolean tokenShopEnabled; + private boolean canCraft; + private boolean canOpenChests; + private boolean canInteractInventory; + private boolean petsVulnerable; + private int maxPlayers = 300; + + private int number; + private ServerType type; + private UserRank rankToJoin; + + /** Whether or not this is the main Grand Theft Minecart network */ + private boolean sister = false; + + private String networkName = "Unknown", + networkShortName = "Unknown", + networkIP = "unknown.com", + websiteLink = "unknown.com", + storeLink = "store.unknown.com", + server_GTM_name = "null", + server_GTM_shortName = "null"; + + private String host = "error"; + private String port = "error"; + private String database = "error"; + private String user = "error"; + private String password = "error"; + + private YamlConfiguration coreConfig; + private YamlConfiguration mysqlConfig; + private YamlConfiguration serversConfig; + private YamlConfiguration joinSignsConfig; + private YamlConfiguration permsConfig; + private YamlConfiguration whitelistConfig; + private YamlConfiguration announcerConfig; + private YamlConfiguration votingConfig; + private YamlConfiguration tokenShopConfig; + private YamlConfiguration tutorialsConfig; + private YamlConfiguration leaderBoardsConfig; + private YamlConfiguration socialSpyConfig; + private YamlConfiguration worldsConfig; + private YamlConfiguration rewardsConfig; + private YamlConfiguration rulesConfig; + private YamlConfiguration nametagsConfig; + private YamlConfiguration helpConfig; + private YamlConfiguration cratesConfig; + private YamlConfiguration crateRewardsConfig; + private YamlConfiguration redisConfig; + + public boolean useEditMode() { + return true; + } + + public boolean isUseEditMode() { + return true; + } + + public void setUseEditMode(boolean useEditMode) { + } + + public boolean stopHungerChange(String world) { + return this.stopHungerChange.contains(world); + } + + public void setStopHungerChange(String world) { + if (!this.stopHungerChange.contains(world)) + this.stopHungerChange.add(world); + } + + public void removeStopHungerChange(String world) { + this.stopHungerChange.remove(world); + } + + public boolean stopWeatherChange(String world) { + return this.stopWeatherChange.contains(world); + } + + public void setStopWeatherChange(String world) { + if (!this.stopWeatherChange.contains(world)) + this.stopWeatherChange.add(world); + } + + public void removeStopWeatherChange(String world) { + this.stopWeatherChange.remove(world); + } + + public boolean stopChunkLoad(String world) { + return this.stopChunkLoad.contains(world); + } + + public void setStopChunkLoad(String world) { + if (!this.stopChunkLoad.contains(world)) + this.stopChunkLoad.add(world); + } + + public void removeStopChunkLoad(String world) { + this.stopChunkLoad.remove(world); + } + + public GameMode getDefaultGameMode() { + return this.defaultGameMode == null ? GameMode.ADVENTURE : this.defaultGameMode; + } + + public void setDefaultGameMode(GameMode g) { + this.defaultGameMode = g; + } + + public boolean getJoinLeaveMessagesEnabled() { + return this.joinLeaveMessagesEnabled; + } + + public void setJoinLeaveMessagesEnabled(boolean b) { + this.joinLeaveMessagesEnabled = b; + } + + public boolean getUseTeleportFix() { + return this.useTeleportFix; + } + + public void setUseTeleportFix(boolean b) { + this.useTeleportFix = b; + } + + public int getNumber() { + return this.number; + } + + public void setNumber(int number) { + this.number = number; + } + + public ServerType getType() { + return this.type; + } + + public void setType(ServerType type) { + this.type = type; + } + + public String getDisplayName() { + return Utils.f(this.type.getDisplayName() + " &a&l" + this.number); + } + + public String name() { + return this.type.getName() + this.number; + } + + public String getHost() { + return this.host; + } + + public void setHost(String host) { + this.host = host; + } + + public String getPort() { + return this.port; + } + + public void setPort(String port) { + this.port = port; + } + + public String getDatabase() { + return this.database; + } + + public void setDatabase(String database) { + this.database = database; + } + + public String getUser() { + return this.user; + } + + public void setUser(String user) { + this.user = user; + } + + public String getPassword() { + return this.password; + } + + public void setPassword(String password) { + this.password = password; + } + + public YamlConfiguration getCoreConfig() { + return this.coreConfig; + } + + public void setCoreConfig(YamlConfiguration c) { + this.coreConfig = c; + } + + public YamlConfiguration getRedisConfig() { + return this.redisConfig; + } + + public void setRedisConfig(YamlConfiguration c) { + this.redisConfig = c; + } + + public YamlConfiguration getMySQLConfig() { + return this.mysqlConfig; + } + + public void setMySQLConfig(YamlConfiguration c) { + this.mysqlConfig = c; + } + + public YamlConfiguration getServersConfig() { + return this.serversConfig; + } + + public void setServersConfig(YamlConfiguration c) { + this.serversConfig = c; + } + + public YamlConfiguration getJoinSignsConfig() { + return this.joinSignsConfig; + } + + public void setJoinSignsConfig(YamlConfiguration c) { + this.joinSignsConfig = c; + } + + public YamlConfiguration getPermsConfig() { + return this.permsConfig; + } + + public void setPermsConfig(YamlConfiguration c) { + this.permsConfig = c; + } + + public YamlConfiguration getWhitelistConfig() { + return this.whitelistConfig; + } + + public void setWhitelistConfig(YamlConfiguration c) { + this.whitelistConfig = c; + } + + public boolean stopLoadDefaultWorld() { + return this.stopLoadDefaultWorld; + } + + public void setStopLoadDefaultWorld(boolean b) { + this.stopLoadDefaultWorld = b; + } + + public boolean deletePlayerDatFiles() { + return this.deletePlayerDatFiles; + } + + public void setDeletePlayerDatFiles(boolean b) { + this.deletePlayerDatFiles = b; + } + + /* + * public boolean loadUserKits() { return loadUserKits; } + * + * public void setLoadUserKits(boolean loadUserKits) { this.loadUserKits = + * loadUserKits; } + * + * public boolean loadUserStats() { return loadUserStats; } + * + * public void setLoadUserStats(boolean loadUserStats) { this.loadUserStats + * = loadUserStats; } + */ + + public boolean serverWarperEnabled() { + return this.serverWarperEnabled; + } + + public void setServerWarperEnabled(boolean b) { + this.serverWarperEnabled = b; + } + + public YamlConfiguration getAnnouncerConfig() { + return this.announcerConfig; + } + + public void setAnnouncerConfig(YamlConfiguration announcerConfig) { + this.announcerConfig = announcerConfig; + } + + public boolean useAnnouncer() { + return this.useAnnouncer; + } + + public void setUseAnnouncer(boolean useAnnouncer) { + this.useAnnouncer = useAnnouncer; + } + + public YamlConfiguration getVotingConfig() { + return this.votingConfig; + } + + public void setVotingConfig(YamlConfiguration votingConfig) { + this.votingConfig = votingConfig; + } + + public boolean statsMenuEnabled() { + return this.statsMenuEnabled; + } + + public void setStatsMenuEnabled(boolean statsMenuEnabled) { + this.statsMenuEnabled = statsMenuEnabled; + } + + public boolean isTokenShopEnabled() { + return this.tokenShopEnabled; + } + + public void setTokenShopEnabled(boolean tokenShopEnabled) { + this.tokenShopEnabled = tokenShopEnabled; + } + + public YamlConfiguration getTokenShopConfig() { + return this.tokenShopConfig; + } + + public void setTokenShopConfig(YamlConfiguration tokenShopConfig) { + this.tokenShopConfig = tokenShopConfig; + } + + public YamlConfiguration getTutorialsConfig() { + return this.tutorialsConfig; + } + + public void setTutorialsConfig(YamlConfiguration tutorialsConfig) { + this.tutorialsConfig = tutorialsConfig; + } + + public boolean canCraft() { + return this.canCraft; + } + + public void setCanCraft(boolean canCraft) { + this.canCraft = canCraft; + } + + public boolean canOpenChests() { + return this.canOpenChests; + } + + public void setCanOpenChests(boolean canOpenChests) { + this.canOpenChests = canOpenChests; + } + + public boolean canInteractInventory() { + return this.canInteractInventory; + } + + public void setCanInteractInventory(boolean canInteractInventory) { + this.canInteractInventory = canInteractInventory; + } + + public YamlConfiguration getLeaderBoardsConfig() { + return this.leaderBoardsConfig; + } + + public void setLeaderBoardsConfig(YamlConfiguration leaderBoardsConfig) { + this.leaderBoardsConfig = leaderBoardsConfig; + } + + public boolean useHolographicDisplays() { + return Bukkit.getPluginManager().isPluginEnabled("HolographicDisplays"); + } + + public YamlConfiguration getSocialSpyConfig() { + return this.socialSpyConfig; + } + + public void setSocialSpyConfig(YamlConfiguration socialSpyConfig) { + this.socialSpyConfig = socialSpyConfig; + } + + public UserRank getRankToJoin() { + return this.rankToJoin; + } + + public void setRankToJoin(UserRank rankToJoin) { + this.rankToJoin = rankToJoin; + } + + public boolean isSister() { + return sister; + } + + public void setSister(boolean sister) { + this.sister = sister; + } + + public String getNetworkName() { + return networkName; + } + + public void setNetworkName(String networkName) { + this.networkName = ChatColor.translateAlternateColorCodes('&', networkName); + } + + public String getNetworkShortName() { + return networkShortName; + } + + public void setNetworkShortName(String networkShortName) { + this.networkShortName = ChatColor.translateAlternateColorCodes('&', networkShortName); + } + + public String getNetworkIP() { + return networkIP; + } + + public void setNetworkIP(String networkIP) { + this.networkIP = networkIP; + } + + public String getWebsiteLink() { + return websiteLink; + } + + public void setWebsiteLink(String websiteLink) { + this.websiteLink = websiteLink; + } + + public String getStoreLink() { + return storeLink; + } + + public void setStoreLink(String storeLink) { + this.storeLink = storeLink; + } + + public String getServer_GTM_name() { + return server_GTM_name; + } + + public void setServer_GTM_name(String server_GTM_name) { + this.server_GTM_name = ChatColor.translateAlternateColorCodes('&', server_GTM_name); + } + + public String getServer_GTM_shortName() { + return server_GTM_shortName; + } + + public void setServer_GTM_shortName(String server_GTM_shortName) { + this.server_GTM_shortName = ChatColor.translateAlternateColorCodes('&', server_GTM_shortName); + } + +// public void setServer_GTM_longName(String server_GTM_longName) { +// this.server_GTM_longName = server_GTM_longName; +// } +// +// public String getServer_GTM_longName() { +// return server_GTM_longName; +// } + + public boolean needRankToJoin() { + return this.rankToJoin != null; + } + + public YamlConfiguration getWorldsConfig() { + return this.worldsConfig; + } + + public void setWorldsConfig(YamlConfiguration worldsConfig) { + this.worldsConfig = worldsConfig; + } + + public boolean loadCosmetics() { + return this.loadCosmetics; + } + + public void setLoadCosmetics(boolean b) { + this.loadCosmetics = b; + } + + public boolean isPetsVulnerable() { + return this.petsVulnerable; + } + + public void setPetsVulnerable(boolean petsVulnerable) { + this.petsVulnerable = petsVulnerable; + } + + public YamlConfiguration getRewardsConfig() { + return this.rewardsConfig; + } + + public void setRewardsConfig(YamlConfiguration rewardsConfig) { + this.rewardsConfig = rewardsConfig; + } + + public YamlConfiguration getRulesConfig() { + return this.rulesConfig; + } + + public void setRulesConfig(YamlConfiguration rulesConfig) { + this.rulesConfig = rulesConfig; + } + + public YamlConfiguration getNametagsConfig() { + return this.nametagsConfig; + } + + public void setNametagsConfig(YamlConfiguration nametagsConfig) { + this.nametagsConfig = nametagsConfig; + } + + public YamlConfiguration getHelpConfig() { + return this.helpConfig; + } + + public void setHelpConfig(YamlConfiguration c) { + this.helpConfig = c; + } + + public YamlConfiguration getCratesConfig() { + return this.cratesConfig; + } + + public void setCratesConfig(YamlConfiguration c) { + this.cratesConfig = c; + } + + public YamlConfiguration getCrateRewardsConfig() { + return this.crateRewardsConfig; + } + + public void setCrateRewardsConfig(YamlConfiguration c) { + this.crateRewardsConfig = c; + } + + public int getMaxPlayers() { + return this.maxPlayers; + } + + public void setMaxPlayers(int maxPlayers) { + this.maxPlayers = maxPlayers; + } + + /** + * Whether or not this is the main grand theft minecart network. + *

+ * Note: This is really only used to flag this as the Main or Sister network. + *

+ * + * @return {@code true} if this is the main network, {@code false} otherwise. + */ + public boolean isMainNetwork() { + return !sister; + } + + /** + * Set whether or not this is the main grand theft minecart network. + * + * @param isMainNetwork - {@code true} if this is the main network, {@code false} if it's the sister network. + */ + public void setMainNetwork(boolean isMainNetwork) { + this.sister = !isMainNetwork; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/Utils.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/Utils.java new file mode 100644 index 0000000..8c46bf6 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/Utils.java @@ -0,0 +1,1068 @@ +package net.grandtheftmc.core; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; +import java.text.NumberFormat; +import java.time.LocalDate; +import java.time.Month; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Random; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Color; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.WorldCreator; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.BlockState; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Creature; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.LeatherArmorMeta; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.plugin.Plugin; +import org.bukkit.potion.PotionEffect; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolManager; +import com.comphenix.protocol.events.ListenerPriority; +import com.comphenix.protocol.events.PacketAdapter; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; +import com.j0ach1mmall3.jlib.inventory.CustomEnchantment; +import com.j0ach1mmall3.jlib.methods.ReflectionAPI; +import com.j0ach1mmall3.jlib.player.JLibPlayer; + +import net.grandtheftmc.core.boards.Board; +import net.grandtheftmc.core.boards.BoardType; +import net.grandtheftmc.core.database.dao.LogDAO; +import net.grandtheftmc.core.database.dao.ServerInfoDAO; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserDAO; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.DefaultFontInfo; +import net.grandtheftmc.core.util.TimeFormatter; +import net.grandtheftmc.core.util.Title; + +public final class Utils { + private static final Random RANDOM = new Random(); + private static final List DEBUGGERS = Arrays.asList("Presidentx", "j0ach1mmall3", "Duci13", "KwonShiYun"); + private static final Class BLOCK_POSITION_CLASS = ReflectionAPI.getNmsClass("BlockPosition"); + private static final Class TILE_ENTITY_CHEST_CLASS = ReflectionAPI.getNmsClass("TileEntityChest"); + private static final Class PACKET_PLAY_OUT_BLOCK_ACTION_CLASS = ReflectionAPI.getNmsClass("PacketPlayOutBlockAction"); + private static final Class BLOCK_CLASS = ReflectionAPI.getNmsClass("Block"); + private static final Enchantment GLOW; + + static { + CustomEnchantment customEnchantment = new CustomEnchantment("GTMCore_Glow", new ArrayList<>(), null, 0, 1); + customEnchantment.register(); + GLOW = customEnchantment.getEnchantment(); + } + + private Utils() { + } + + public static boolean isInteger(String s) { + try { + Integer.parseInt(s); + } catch (NumberFormatException e) { + return false; + } + return true; + } + + public static boolean returnTrue() { + return true; + } + + public static Random getRandom() { + return RANDOM; + } + + public static void broadcast(String string) { + Bukkit.broadcastMessage(f(string)); + } + + public static void broadcastExcept(Player player, String string) { + Bukkit.getOnlinePlayers().stream().filter(p -> !p.equals(player)).forEach(p -> p.sendMessage(Utils.f(string))); + } + + public static void m(int i) { + b(String.valueOf(i)); + } + + public static void b(String string) { + DEBUGGERS.stream().map(Bukkit::getPlayer).filter(p -> p != null).forEach(p -> p.sendMessage(string)); + Core.log(string); + } + + /** + * @param player The player whose line of sight we will use + * @param targetLocation The target location that is converted to a vector to form an angle with line of sight + * @return angle between entity's line of sight and the target vector + */ + public static double getAngleBetweenVectors(Player player, Location targetLocation) { + Vector lineOfSight = player.getEyeLocation().toVector(); + Vector target = targetLocation.toVector(); + target.setY(0); + lineOfSight.setY(0); + return lineOfSight.angle(target); + } + + public static List blocksFromTwoPoints(Location loc1, Location loc2) { + if (loc1 == null || loc2 == null) return null; + List blocks = new ArrayList<>(); + + int topBlockX = loc1.getBlockX() < loc2.getBlockX() ? loc2.getBlockX() : loc1.getBlockX(); + int bottomBlockX = loc1.getBlockX() > loc2.getBlockX() ? loc2.getBlockX() : loc1.getBlockX(); + + int topBlockY = loc1.getBlockY() < loc2.getBlockY() ? loc2.getBlockY() : loc1.getBlockY(); + int bottomBlockY = loc1.getBlockY() > loc2.getBlockY() ? loc2.getBlockY() : loc1.getBlockY(); + + int topBlockZ = loc1.getBlockZ() < loc2.getBlockZ() ? loc2.getBlockZ() : loc1.getBlockZ(); + int bottomBlockZ = loc1.getBlockZ() > loc2.getBlockZ() ? loc2.getBlockZ() : loc1.getBlockZ(); + + for (int x = bottomBlockX; x <= topBlockX; x++) { + for (int z = bottomBlockZ; z <= topBlockZ; z++) { + for (int y = bottomBlockY; y <= topBlockY; y++) { + blocks.add(loc1.getWorld().getBlockAt(x, y, z)); + } + } + } + + return blocks; + } + + public static Location getCenterOfBlock(Location loc) { + return loc.add(0.5, 0, 0.5); + } + + public static Location getCenterOfTwoBlocks(Location loc1, Location loc2) { + loc1 = getCenterOfBlock(loc1); + loc2 = getCenterOfBlock(loc2); + return new Location(loc1.getWorld(), (loc1.getX() + loc2.getX()) / 2, loc1.getY(), (loc1.getZ() + loc2.getZ()) / 2); + } + + public static Block getSecondHalfChest(Block block) { + Optional possibleChest = Stream.of(BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST).map(block::getRelative).filter(b -> b.getType() == Material.CHEST || b.getType() == Material.TRAPPED_CHEST).findFirst(); + return possibleChest.isPresent() ? possibleChest.get() : null; + } + + public static void playDoorAnimation(Location location, boolean open) { + playDoorAnimation(location.getBlock().getState(), open); + } + + public static void playDoorAnimation(Player player, Location location, boolean open) { + playDoorAnimation(player, location.getBlock().getState(), open); + } + + public static void playDoorAnimation(BlockState state, boolean open) { + Bukkit.getOnlinePlayers().forEach(p -> playDoorAnimation(p, state, open)); + } + + @SuppressWarnings("deprecation") + public static void playDoorAnimation(Player player, BlockState state, boolean open) { + byte data = state.getRawData(); + byte b = data < 4 ? open ? (byte) (data + 4) : data : open ? data : (byte) (data - 4); + player.sendBlockChange(state.getLocation(), Material.IRON_DOOR_BLOCK, b); + } + + public static void playIronDoorAnimation(Player player, Location loc, boolean open) { + // TODO + } + + public static boolean putItemInInventoryRandomly(Inventory inv, ItemStack item) { + List list = new ArrayList<>(); + for (int i = 0; i < inv.getSize(); i++) { + if (inv.getItem(i) == null) list.add(i); + } + + if (list.isEmpty()) return false; + int i = list.get(RANDOM.nextInt(list.size())); + inv.setItem(i, item); + return true; + } + + public static String f(String string) { + return ChatColor.translateAlternateColorCodes('&', string); + } + + public static String fColor(String string) { + for (Character c : new Character[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}) { + if (string.contains("&" + c)) string = string.replace("&" + c, ChatColor.getByChar(c).toString()); + } + + return string; + } + + public static net.md_5.bungee.api.ChatColor getLastColor(String string) { + net.md_5.bungee.api.ChatColor chatColor = null; + for (Character c : new Character[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}) { + if (string.contains("&" + c)) { + chatColor = net.md_5.bungee.api.ChatColor.getByChar(c); + } + } + return chatColor; + } + + public static String deFormat(String string) { + return string.replace(ChatColor.COLOR_CHAR, '&'); + } + + public static String[] f(String[] array) { + if (array == null) return null; + for (int i = 0; i < array.length; i++) { + array[i] = Utils.f(array[i]); + } + + return array; + } + + public static String[] deFormat(String[] array) { + if (array == null) return null; + for (int i = 0; i < array.length; i++) { + array[i] = Utils.deFormat(array[i]); + } + + return array; + } + + public static Location blockLocationFromString(String string) { + if (string == null) return null; + String[] coords = string.split(","); + if (coords.length != 4) return null; + World world = Bukkit.getWorld(coords[0]); + if (world == null) return null; + int x; + int y; + int z; + try { + x = Integer.parseInt(coords[1]); + y = Integer.parseInt(coords[2]); + z = Integer.parseInt(coords[3]); + } catch (NumberFormatException e) { + return null; + } + + return new Location(world, x, y, z); + + } + + public static double round(double value) { + return new BigDecimal(value).setScale(2, RoundingMode.HALF_UP).doubleValue(); + } + + public static float round(float value) { + return new BigDecimal(value).setScale(2, RoundingMode.HALF_UP).floatValue(); + } + + public static String blockLocationToString(Location loc) { + if (loc == null) return null; + return loc.getWorld().getName() + ',' + loc.getBlockX() + ',' + loc.getBlockY() + ',' + loc.getBlockZ(); + } + + public static Location teleportLocationFromString(String string) { + if (string == null) return null; + String[] coords = string.split(","); + if (coords.length != 6) return null; + World world = Bukkit.getWorld(coords[0]); + double x; + double y; + double z; + float pitch; + float yaw; + try { + x = round(Double.parseDouble(coords[1])); + y = round(Double.parseDouble(coords[2])); + z = round(Double.parseDouble(coords[3])); + pitch = round(Float.parseFloat(coords[4])); + yaw = round(Float.parseFloat(coords[5])); + } catch (NumberFormatException e) { + return null; + } + + Location location = new Location(world, x, y, z); + location.setPitch(pitch); + location.setYaw(yaw); + return location; + } + + public static String teleportLocationToString(Location loc) { + if (loc == null) return null; + return loc.getWorld().getName() + ',' + round(loc.getX()) + ',' + round(loc.getY()) + ',' + round(loc.getZ()) + ',' + round(loc.getPitch()) + ',' + round(loc.getYaw()); + } + + public static void giveLobbyItems(Player player) { + if (player == null) return; + player.setHealth(20); + player.setMaxHealth(20); + player.setFoodLevel(20); + player.setGameMode(GameMode.SURVIVAL); + PlayerInventory inv = player.getInventory(); + inv.clear(); + player.getInventory().setHeldItemSlot(4); + + inv.setItem(0, createItem(Material.COMPASS, "&e&lServer Warper &7&lRight Click")); + inv.setItem(4, createItem(Material.ENDER_CHEST, "&6&lCosmetics &7&lRight Click")); + // inv.setItem(6, createItem(Material.NETHER_STAR, "&d&lStats &7&lRight Click")); + inv.setItem(7, createItem(Material.EXP_BOTTLE, "&a&lRewards &7&lRight Click")); + inv.setItem(8, createItem(Material.REDSTONE_COMPARATOR, "&5&lPreferences &7&lRight Click")); + + player.getActivePotionEffects().clear(); + inv.setArmorContents(null); + player.updateInventory(); + + } + + public static void sendLobbyJoinMessage(Player p, User user) { + p.sendMessage(new String[]{"", "", "", "", "", "", "", "", ""}); + String[] header = Core.getAnnouncer().getHeader(); + if (header != null && header.length > 0) ; + p.sendMessage(f(Core.getAnnouncer().getHeader())); + p.sendMessage(new String[]{"", + Utils.fc("Welcome, " + user.getColoredName(p) + "&r to the &7&l" + Core.getSettings().getNetworkShortName() + " &6&lHub&r!"), + Utils.fc("&e&l&oGTA in Minecraft!"), "", Utils.fc("&e&lSTORE &r&n" + Core.getSettings().getStoreLink()), + Utils.fc("&a&lSITE &r&n" + Core.getSettings().getWebsiteLink()), "", Utils.fc("&7Use the &eserver warper&7 to play!")}); + String[] footer = Core.getAnnouncer().getFooter(); + if (footer != null && footer.length > 0) ; + p.sendMessage(f(Core.getAnnouncer().getFooter())); + } + + public static void setInvisible(Player player, boolean b) { + Bukkit.getOnlinePlayers().stream().filter(p -> !Objects.equals(player, p)).forEach(p -> { + if (b) + p.hidePlayer(player); + else + p.showPlayer(player); + }); + } + + public static List f(List lore) { + return lore.stream().map(Utils::f).collect(Collectors.toList()); + } + + public static ItemStack createItem(Material material, String name, int amnt, String... lore) { + return createItem(material, name, toList(lore), amnt); + } + + public static ItemStack createItem(Material material, String name, List lore, int amnt) { + ItemStack item = new ItemStack(material); + if (amnt > 0) + item.setAmount(amnt); + if (name != null || lore != null) { + ItemMeta meta = item.getItemMeta(); + if (name != null) + meta.setDisplayName(Utils.f(name)); + if (lore != null) + meta.setLore(f(lore)); + item.setItemMeta(meta); + } + return item; + } + + public static ItemStack createItem(Material material, int durability, String name, String... lore) { + return createItem(material, durability, name, toList(lore)); + } + + public static ItemStack createItem(Material material, int durability, String name, List lore) { + ItemStack item = new ItemStack(material); + if (durability > 0) + item.setDurability((short) durability); + if (name != null || lore != null) { + ItemMeta meta = item.getItemMeta(); + if (name != null) + meta.setDisplayName(Utils.f(name)); + if (lore != null) + meta.setLore(f(lore)); + item.setItemMeta(meta); + } + return item; + } + + public static ItemStack createItem(Material material, int durability, String name, int amnt, String... lore) { + return createItem(material, durability, name, toList(lore), amnt); + } + + public static ItemStack createItem(Material material, int durability, String name, List lore, int amnt) { + ItemStack item = new ItemStack(material); + if (amnt > 0) + item.setAmount(amnt); + if (durability > 0) + item.setDurability((short) durability); + if (name != null || lore != null) { + ItemMeta meta = item.getItemMeta(); + if (name != null) + meta.setDisplayName(Utils.f(name)); + if (lore != null) + meta.setLore(f(lore)); + item.setItemMeta(meta); + } + return item; + } + + public static ItemStack createItem(Material material, String name, String... lore) { + return createItem(material, name, toList(lore)); + } + + public static ItemStack createItem(Material material, String name, List lore) { + ItemStack item = new ItemStack(material); + + if (name != null || lore != null) { + ItemMeta meta = item.getItemMeta(); + if (name != null) + meta.setDisplayName(Utils.f(name)); + if (lore != null) + meta.setLore(f(lore)); + item.setItemMeta(meta); + } + return item; + } + + public static ItemStack createItem(Material material, String name) { + ItemStack item = new ItemStack(material); + if (name != null) { + ItemMeta meta = item.getItemMeta(); + if (name != null) + meta.setDisplayName(Utils.f(name)); + item.setItemMeta(meta); + } + return item; + } + + public static ItemStack createItem(Material material, int durability, String name) { + ItemStack item = new ItemStack(material); + if (durability > 0) + item.setDurability((short) durability); + if (name != null) { + ItemMeta meta = item.getItemMeta(); + if (name != null) + meta.setDisplayName(Utils.f(name)); + item.setItemMeta(meta); + } + return item; + } + + public static ItemStack setArmorColor(ItemStack item, int red, int green, int blue) { + return setArmorColor(item, Color.fromRGB(red, green, blue)); + } + + public static ItemStack setArmorColor(ItemStack item, Color color) { + if (!(item.getItemMeta() instanceof LeatherArmorMeta)) + return item; + LeatherArmorMeta meta = (LeatherArmorMeta) item.getItemMeta(); + meta.setColor(color); + item.setItemMeta(meta); + return item; + } + + public static ItemStack setSkullOwner(ItemStack item, String owner) { + item.setDurability((short) 3); + SkullMeta meta = (SkullMeta) item.getItemMeta(); + meta.setOwner(owner); + item.setItemMeta(meta); + return item; + } + + public static void hidePlayersTo(Player player) { + Bukkit.getOnlinePlayers().stream().filter(p -> !Objects.equals(p, player)).forEach(player::hidePlayer); + } + + public static void showPlayersTo(Player player) { + Bukkit.getOnlinePlayers().stream().filter(p -> !Objects.equals(p, player)).forEach(player::showPlayer); + } + + public static void sendTitle(Player player, Title title) { + sendTitle(player, title.getTitle(), title.getSubtitle(), title.getFadeIn(), title.getStay(), + title.getFadeOut()); + } + + public static void sendTitle(Title title) { + sendTitle(title.getTitle(), title.getSubtitle(), title.getFadeIn(), title.getStay(), title.getFadeOut()); + } + + public static void sendTitle(String title, String subTitle, int fadeIn, int stay, int fadeOut) { + for (Player p : Bukkit.getOnlinePlayers()) + sendTitle(p, title, subTitle, fadeIn, stay, fadeOut); + } + + public static void sendTitle(Player player, String title, String subtitle, int fadeIn, int stay, int fadeOut) { + new JLibPlayer(player).sendTitle(fadeIn, fadeOut, stay, Utils.f(title)); + if (subtitle != null) + new JLibPlayer(player).sendSubTitle(fadeIn, fadeOut, stay, Utils.f(subtitle)); + } + + public static void sendActionBar(Player pl, String msg) { + //new JLibPlayer(pl).sendActionBar(msg); + Utils.sendActionBar(pl, msg); + } + + public static void sendActionBar(String msg) { +// for (Player p : Bukkit.getOnlinePlayers()) +// sendActionBar(p, msg); + Utils.sendActionBar(msg); + } + + public static void updateHubScoreboard(Player player, User user) { + String rank = "No Rank"; + if (user.isSpecial()) + rank = user.getUserRank().getColoredNameBold(); + Board board = new Board("lobby", Core.getSettings().getType().getScoreboardHeader(), BoardType.KEY_VALUE); + board.addValue("a", "Bucks", String.valueOf(user.getBucks())); + board.addValue("e", "Tokens", String.valueOf(user.getTokens())); + board.addValue("6", "Rank", rank); + board.addValue("6", "Server IP", user.getServerJoinAddress() != null ? user.getServerJoinAddress() : Core.getSettings().getNetworkIP()); + board.updateFor(player, user); + } + + public static List toList(String[] array) { + List ls = new ArrayList<>(); + if (array == null) + return ls; + Collections.addAll(ls, array); + return ls; + } + + public static ItemStack[] toArray(List list) { + ItemStack[] items = new ItemStack[list.size()]; + for (int i = 0; i < list.size(); i++) + items[i] = list.get(i); + return items; + } + + public static String[] stringsToArray(List list) { + if (list == null) + return null; + String[] l = new String[list.size()]; + l = list.toArray(l); + return l; + } + + public static boolean calculateChance(double i) { + return ThreadLocalRandom.current().nextDouble(101) <= i; + } + + public static void sendToServer(Player player, String server) { + Core.getServerManager().sendToServer(player, server); + } + + public static void stopEntityTracking(Player player) { + player.getLocation().getWorld().getLivingEntities().stream().filter(e -> e instanceof Creature).forEach(e -> { + Creature c = (Creature) e; + if (c.getTarget() instanceof Player && c.getTarget().equals(player)) + c.setTarget(null); + }); + } + + public static void setFlyMode(Player player, boolean b) { + player.setAllowFlight(b); + player.setFlying(b); + } + + public static Location randomLocation(Location location, double d) { + double x = location.getX() + (RANDOM.nextDouble() * d) - (d / 2); + double z = location.getZ() + (RANDOM.nextDouble() * d) - (d / 2); + return new Location(location.getWorld(), x, location.getY(), z, location.getYaw(), location.getPitch()); + } + + public static int randomNumber(int start, int end) { + return RANDOM.nextInt(end - start + 1) + start; + } + + public static int randomNumber(int end) { + return RANDOM.nextInt(end + 1); + } + + public static void copyWorld(String name) { + try { + Core.log("Copying world " + "/home/mcservers/development/master/maps/" + name + " to " + Bukkit.getWorldContainer().getCanonicalPath() + '/' + name); + File source = new File("/home/mcservers/development/master/maps/" + name); + File dest = new File(name); + Files.delete(dest.toPath()); + Files.copy(source.toPath(), dest.toPath(), StandardCopyOption.REPLACE_EXISTING); + Core.log("Finished copying world " + name); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static World loadWorld(String name) { + copyWorld(name); + World world = Bukkit.getWorld(name); + if (world == null) { + WorldCreator creator = new WorldCreator(name); + creator.environment(World.Environment.NORMAL); + world = creator.createWorld(); + } + return world; + } + + public static YamlConfiguration loadConfigFile(File file) { + YamlConfiguration c = new YamlConfiguration(); + try { + if (!file.exists()) + file.createNewFile(); + c.load(file); + } catch (IOException | InvalidConfigurationException e1) { + e1.printStackTrace(); + } + return c; + } + + public static YamlConfiguration loadConfig(String src) { + return loadConfigFile(new File(src + ".yml")); + } + + public static YamlConfiguration loadConfigFromMaps(String src) { + return loadConfigFile(new File("/home/mcservers/development/master/maps/" + src + ".yml")); + } + + public static YamlConfiguration loadConfigFromMaster(String src) { + return loadConfigFile(new File("/home/mcservers/development/master/" + src + ".yml")); + } + + public static YamlConfiguration loadConfigFromPlugin(String src, String plugin) { + try { + return loadConfigFile(new File(Bukkit.getWorldContainer().getCanonicalPath() + '/' + plugin, src + ".yml")); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + public static void saveConfigFile(YamlConfiguration c, File file) { + try { + if (!file.exists()) + file.createNewFile(); + c.save(file); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static void saveConfig(YamlConfiguration c, String src) { + saveConfigFile(c, new File(src + ".yml")); + } + + public static void deletePlayerDatFiles(String world) { + File file = new File(Bukkit.getWorldContainer() + "/" + world + "/playerdata"); + if (file.isDirectory()) + for (File f : file.listFiles()) + f.delete(); + } + + public static void kaching(Player player) { + player.playSound(player.getLocation(), Sound.BLOCK_WOODEN_DOOR_CLOSE, 2, 1); + UUID uuid = player.getUniqueId(); + new BukkitRunnable() { + @Override + public void run() { + Player player = Bukkit.getPlayer(uuid); + if (player != null) + player.playSound(player.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 0.3F, 1); + + } + }.runTaskLater(Core.getInstance(), 5); + + } + + public static String timeInMillisToText(Long millis) { + return timeInSecondsToText(millis / 1000); + } + + + public static String formatMoney(double money) { + return NumberFormat.getCurrencyInstance(Locale.US).format(money > 1000000 ? (money / 1000000) : money) + (money > 1000000 ? " mil" : ""); + } + + public static String numberFormat(int num) { + return NumberFormat.getCurrencyInstance(Locale.US).format(num); + } + + public static String numberFormat(double num) { + return NumberFormat.getCurrencyInstance(Locale.US).format(num); + } + + public static int getAmountInInv(Player player, ItemStack stack) { + int amnt = 0; + Inventory inventory = player.getInventory(); + for (ItemStack item : inventory.getContents()) { + if (item != null && item.isSimilar(stack)) + amnt += item.getAmount(); + } + return amnt; + } + + public static boolean giveItems(Player player, ItemStack... items) { + Map hm = player.getInventory().addItem(items); + if (hm.isEmpty()) + return false; + World w = player.getWorld(); + Location loc = player.getLocation(); + for (ItemStack item : hm.values()) + w.dropItemNaturally(loc, item); + return true; + } + + public static void takeItems(Player player, int amount, ItemStack stack) { + int toRemove = amount; + Inventory inventory = player.getInventory(); + for (int i = 0; i < inventory.getSize(); i++) { + ItemStack item = inventory.getItem(i); + if (item != null && item.isSimilar(stack)) { + if (toRemove >= item.getAmount()) { + toRemove -= item.getAmount(); + inventory.setItem(i, null); + } else { + item.setAmount(item.getAmount() - toRemove); + return; + } + + } + } + } + + public static String fc(String s) { + s = Utils.f(s); + int messagePxSize = 0; + boolean previousCode = false; + boolean isBold = false; + + for (char c : s.toCharArray()) { + if (c == '§') { + previousCode = true; + } else if (previousCode) { + previousCode = false; + isBold = c == 'l' || c == 'L'; + } else { + DefaultFontInfo dFI = DefaultFontInfo.getDefaultFontInfo(c); + messagePxSize += isBold ? dFI.getBoldLength() : dFI.getLength(); + messagePxSize++; + } + } + + int halvedMessageSize = messagePxSize / 2; + int toCompensate = 154 - halvedMessageSize; + int spaceLength = DefaultFontInfo.SPACE.getLength() + 1; + int compensated = 0; + StringBuilder sb = new StringBuilder(); + while (compensated < toCompensate) { + sb.append(' '); + compensated += spaceLength; + } + return sb + s; + } + + public static String[] fc(String[] array) { + if (array == null) + return null; + String[] a = new String[array.length]; + for (int i = 0; i < array.length; i++) + a[i] = Utils.fc(array[i]); + return a; + } + + public static Map sort(Map unsortMap) { + List> list = new LinkedList<>(unsortMap.entrySet()); + Collections.sort(list, (o1, o2) -> o1.getValue().compareTo(o2.getValue())); + Map sortedMap = new LinkedHashMap<>(); + for (Map.Entry entry : list) + sortedMap.put(entry.getKey(), entry.getValue()); + return sortedMap; + } + + public static void clearPotionEffects(Player player) { + for (PotionEffect e : player.getActivePotionEffects()) + player.removePotionEffect(e.getType()); + } + + public static String getCardinalDirection(Location location) { + double rotation = location.getYaw() % 360; + if (rotation < 0) + rotation += 360.0; + if (rotation >= 0 && rotation < 22.5) + return "S"; + else if (rotation >= 22.5 && rotation < 67.5) + return "SW"; + else if (rotation >= 67.5 && rotation < 112.5) + return "W"; + else if (rotation >= 112.5 && rotation < 157.5) + return "NW"; + else if (rotation >= 157.5 && rotation < 202.5) + return "N"; + else if (rotation >= 202.5 && rotation < 247.5) + return "NE"; + else if (rotation >= 247.5 && rotation < 292.5) + return "E"; + else if (rotation >= 292.5 && rotation < 337.5) + return "SE"; + else if (rotation >= 337.5 && rotation < 360.0) + return "S"; + return null; + + } + + public static Location getInFrontOf(Location location) { + String s = getCardinalDirection(location); + switch (s) { + case "N": + return location.add(0, 0, -2); + case "NE": + return location.add(2, 0, -2); + case "E": + return location.add(2, 0, 0); + case "SE": + return location.add(2, 0, 2); + case "S": + return location.add(0, 0, 2); + case "SW": + return location.add(-2, 0, 2); + case "W": + return location.add(-2, 0, 0); + case "NW": + return location.add(-2, 0, -2); + default: + return location; + } + } + + public static void playChestAnimation(Location loc, boolean open) { + Bukkit.getOnlinePlayers().forEach(p -> playChestAnimation(p, loc, open)); + } + + public static void playChestAnimation(Player player, Location loc, boolean open) { + try { + Object world = ReflectionAPI.getHandle((Object) loc.getWorld()); + Object position = BLOCK_POSITION_CLASS.getConstructor(double.class, double.class, double.class).newInstance(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + Object tileChest = world.getClass().getMethod("getTileEntity", BLOCK_POSITION_CLASS).invoke(world, position); + Object packet = PACKET_PLAY_OUT_BLOCK_ACTION_CLASS.getConstructor(BLOCK_POSITION_CLASS, BLOCK_CLASS, int.class, int.class).newInstance(position, tileChest.getClass().getMethod("getBlock").invoke(tileChest), 1, open ? 1 : 0); + ReflectionAPI.sendPacket(player, packet); + } catch (Exception e) { + Core.error("An error occured while playing a chest animation"); + e.printStackTrace(); + } + } + + public static ItemStack addGlow(ItemStack item) { + item.addUnsafeEnchantment(GLOW, 1); + return item; + } + + public static void insertLogLater(UUID uuid, String name, String action, String type, String reward, double amount, double price) { + new BukkitRunnable() { + @Override + public void run() { + Utils.insertLog(uuid, name, action, type, reward, amount, price); + } + }.runTaskAsynchronously(Core.getInstance()); + } + + public static void insertLog(UUID uuid, String name, String action, String type, String reward, double amount, double price) { + boolean result = LogDAO.insertLog(uuid, name, action, type, reward, amount, price); + if(!result) Core.error("Error while logging uuid " + uuid + " name " + name + " action " + action + " reward " + reward + " amount " + amount + " price " + price); + +// try (PreparedStatement st = Core.sql.prepareStatement("insert into logs(uuid, name, action, type, reward, amount, price, server) values (?,?,?,?,?,?,?,?);")) { +// st.setString(1, uuid.toString()); +// st.setString(2, name); +// st.setString(3, action); +// st.setString(4, type); +// st.setString(5, reward); +// st.setDouble(6, amount); +// st.setDouble(7, price); +// st.setString(8, Core.name()); +// st.execute(); +// st.close(); +// } catch (SQLException e) { +// Core.error("Error while logging uuid " + uuid + " name " + name + " action " + action + " reward " + reward + " amount " + amount + " price " + price); +// } + } + + public static Collection getOfflineStaff() { +// Collection staff = new ArrayList<>(); +// try (ResultSet resultSet = Core.getSQL().query("SELECT lastname FROM users WHERE userrank IN ( 'HELPOP', 'MOD', 'ADMIN', 'DEV' );")) { +// while (resultSet.next()) { +// staff.add(resultSet.getString("lastname")); +// } +// resultSet.close(); +// } catch (Exception exception) { +// +// } +// return staff; + return ServerInfoDAO.getOnlineStaff(); + } + + public static TimeFormatter timeFormatter(TimeUnit timeUnit, Long time) { + return new TimeFormatter(timeUnit, time); + } + + public static boolean isBanned(String uuid) { +// try (ResultSet rs = Core.sql.query("select * from BAT_ban where UUID='" + uuid + "';")) { +// if (rs.next()) { +// if (rs.getBoolean("ban_state")) { +// rs.close(); +// return true; +// } +// } +// rs.close(); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// return false; + return UserDAO.isUserBanned(uuid); + } + + /** + * Apply these item flags to ItemStack + * + * @param itemStack - the ItemStack to apply these flags to + * @param flags - the flags to apply + **/ + public static void applyItemFlags(ItemStack itemStack, ItemFlag... flags) { + ItemMeta itemMeta = itemStack.getItemMeta(); + + itemMeta.setUnbreakable(true); + itemMeta.addItemFlags(flags); + + itemMeta.addItemFlags(flags); + itemStack.setItemMeta(itemMeta); + } + + /** + * Clone ItemStack, apply flags and return new copy. + * + * @param itemStack the ItemStack to apply these flags to + * @param flags the flags to apply + * @return cloned ItemStack with itemflags + **/ + public static ItemStack addItemFlags(ItemStack itemStack, ItemFlag... flags) { + ItemStack stack = itemStack.clone(); + ItemMeta itemMeta = stack.getItemMeta(); + + itemMeta.setUnbreakable(true); + itemMeta.addItemFlags(flags); + + itemMeta.addItemFlags(flags); + stack.setItemMeta(itemMeta); + return stack; + } + + public static Month getMonth() { + Date date = new Date(); + LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); + return localDate.getMonth(); + } + + public static int getDay() { + Date date = new Date(); + LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); + return localDate.getDayOfMonth(); + } + + public static void setMaxPlayers(int maxPlayers) { + String bukkitversion = Bukkit.getServer().getClass().getPackage() + .getName().substring(23); + Object playerlist = null; + try { + playerlist = Class.forName("org.bukkit.craftbukkit." + bukkitversion + ".CraftServer") + .getDeclaredMethod("getHandle", null).invoke(Bukkit.getServer(), null); + Field maxplayers = playerlist.getClass().getSuperclass() + .getDeclaredField("maxPlayers"); + maxplayers.setAccessible(true); + maxplayers.set(playerlist, maxPlayers); + } catch (IllegalAccessException | InvocationTargetException | + NoSuchMethodException | + ClassNotFoundException | + NoSuchFieldException exception) { + exception.printStackTrace(); + } + Core.getSettings().setMaxPlayers(maxPlayers); + Core.getSettings().getCoreConfig().set("maxplayers", maxPlayers); + Utils.saveConfig(Core.getSettings().getCoreConfig(), "core"); + } + + public static void startEnchantmentShineRemover(ProtocolManager lib, Plugin owner){ + lib.addPacketListener(new PacketAdapter(owner, ListenerPriority.NORMAL, PacketType.Play.Server.ENTITY_EQUIPMENT, PacketType.Play.Server.WINDOW_ITEMS){ + @Override + public void onPacketSending(PacketEvent event){ + PacketContainer packet = event.getPacket(); + if(packet.getType()==PacketType.Play.Server.ENTITY_EQUIPMENT){ + removeEnchantments(packet.getItemModifier().read(0)); + } + else if(packet.getType()==PacketType.Play.Server.WINDOW_ITEMS){ + for(ItemStack is : packet.getItemArrayModifier().read(0)){ + if(is!=null) + removeEnchantments(is); + } + } + } + }); + } + + private static void removeEnchantments(ItemStack stack) { + if(stack==null) + return; + Object[] copy = stack.getEnchantments().keySet().toArray(); + + for (Object enchantment : copy) { + stack.removeEnchantment((Enchantment) enchantment); + } + } + + public static String timeInSecondsToText(long timer) { + return timeInSecondsToText(timer, C.WHITE, C.WHITE, C.WHITE); + } + + public static String timeInSecondsToText(long timer, String numberColor, String textColor, String splitterColor) { + StringBuilder sb = new StringBuilder(); + List units = Arrays.asList(TimeUnit.values()); + Collections.reverse(units); + int counter = 0; + for(TimeUnit u : units) { + if (counter >= 2) + break; + long time = u.convert(timer, TimeUnit.SECONDS); + if (time >= 1) { + sb.append(numberColor + time + textColor + " " + (time == 1 ? u.toString().toLowerCase().substring(0, u.toString().length()-1) : u.toString().toLowerCase()) + splitterColor + (counter == 1 ? "" : ", ")); + counter++; + timer -= TimeUnit.SECONDS.convert(time, u); + } + } + return sb.toString(); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/achivements/Achievement.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/achivements/Achievement.java new file mode 100644 index 0000000..1055416 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/achivements/Achievement.java @@ -0,0 +1,72 @@ +package net.grandtheftmc.core.achivements; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.Utils; + +import java.util.Optional; + +public enum Achievement { + + Hobo("Hobo", "&7&lHobo", "&7Join " + Core.getSettings().getServer_GTM_shortName() + " for the first time!", "&7&l"), + CRIMINAL("Criminal", "&e&lCriminal", "&7Rankup to CRIMINAL!", "&e&l"), + HOMIE("Homie", "&e&lHomie", "&7Rankup to &e&lHOMIE&7!", "&e&l"), + THUG("Thug", "&e&lThug", "&7Rankup to &e&lTHUG&7!", "&e&l"), + GANGSTER("Gangster", "&a&lGangster", "&7Rankup to &e&lGANGSTER&7!", "&a&l"), + MUGGER("Mugger", "&e&lMugger", "&7Rankup to &e&lMUGGER&7!", "&e&l"), + HUNTER("Hunter", "&e&lHunter", "&7Rankup to &e&lHUNTER&7!", "&e&l"), + DEALER("Dealer", "&e&lDealer", "&7Rankup to &e&lDEALER&7!", "&e&l"), + PIMP("Pimp", "&d&lPimp", "&7Rankup to &d&lPIMP&7!", "&d&l"), + MOBSTER("Mobster", "&e&lMobster", "&7Rankup to &e&lMOBSTER&7!", "&e&l"), + GODFATHER("Godfather", "&e&lGodfather", "&7Rankup to &1&lGODFATHER&7!", "&e&l"), + GTM_God(Core.getSettings().getServer_GTM_shortName() + "God", "&4&l" + Core.getSettings().getServer_GTM_name() + " God", "&7Have &a1000 &7or more hours total playtime!", "&4&l"), + Psychopath("Psychopath", "&c&lPsychopath", "&7Have &a10000 &7or more total kills", "&c&l"), + Witness("Witness", "&e&lWitness", "&7Witness &4&lPresidentx &7online!", "&e&l"), + Memelord("Memelord", "&e&lMemelord", "&7Own the rare Haramabe pet!", "&e&l"); + + private String shortName; + private String title; + private String description; + private String color; + + Achievement(String shortName, String title, String description, String color) { + this.shortName = shortName; + this.title = title; + this.description = description; + this.color = color; + } + + public static Optional getAchivement(String search) { + search = search.toLowerCase(); + for(Achievement achievement : Achievement.values()) { + if(achievement.getShortName().toLowerCase().contains(search) || achievement.getTitle().toLowerCase().contains(search)) { + return Optional.ofNullable(achievement); + } + } + return Optional.empty(); + } + + public static Optional getAchivementExact(String search) { + for (Achievement achievement : Achievement.values()) { + if (achievement.getShortName().equalsIgnoreCase(search) || achievement.getTitle().equalsIgnoreCase(search)) { + return Optional.ofNullable(achievement); + } + } + return Optional.empty(); + } + + public String getShortName() { + return this.shortName; + } + + public String getTitle() { + return this.title; + } + + public String getDescription() { + return this.description; + } + + public String getColor() { + return Utils.f(color); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/achivements/AchievementCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/achivements/AchievementCommand.java new file mode 100644 index 0000000..4c2d9b7 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/achivements/AchievementCommand.java @@ -0,0 +1,138 @@ +package net.grandtheftmc.core.achivements; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import org.apache.commons.lang.StringUtils; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.Collection; + +public class AchievementCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (args.length == 0) { + s.sendMessage(Lang.ACHIEVEMENT.f("&7&lAchievements Help")); + s.sendMessage(Utils.f("&a/achievement &7locked List all Achievements that are still locked")); + s.sendMessage(Utils.f("&a/achievement &7unlocked List all Achievements you have unlocked")); + s.sendMessage(Utils.f("&a/achievement &7shown List your current shown Achievement")); + s.sendMessage(Utils.f("&a/achievement &7setshown &a &7Set your shown achievement")); + return true; + } + String string; + switch (args[0].toLowerCase()) { + case "locked": { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.toString()); + return true; + } + Player player = (Player) s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + Collection achievements = new ArrayList<>(); + for (Achievement achievement : Achievement.values()) { + if (user.getUnlockedAchievements().contains(achievement)) continue; + achievements.add(achievement.getColor() + achievement.getShortName() + " &7- " + achievement.getDescription()); + } + string = StringUtils.join(achievements, " \n"); + player.sendMessage(Utils.f("&aLocked achievements: \n" + string)); + return true; + } + case "unlocked": { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.toString()); + return true; + } + Player player = (Player) s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + Collection t = new ArrayList<>(); + user.getUnlockedAchievements().forEach(achievement -> t.add(achievement.getTitle())); + string = StringUtils.join(t, "&7, &a"); + player.sendMessage(Utils.f("&7Unlocked achievements: &a" + string)); + return true; + } + case "shown": { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.toString()); + return true; + } + Player player = (Player) s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + player.sendMessage(Lang.ACHIEVEMENT.f("&7Shown Achievement: &a" + user.getShownAchievement().getTitle())); + return true; + } + case "setshown": { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.toString()); + return true; + } + Player player = (Player) s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (args.length != 2) { + player.sendMessage(Utils.f("&aUsage: &7/achievement &asetshown [achievement]")); + return true; + } + if (Achievement.getAchivement(args[1]).isPresent()) { + Achievement achievement = Achievement.getAchivement(args[1]).get(); + if (!user.getUnlockedAchievements().contains(achievement)) { + player.sendMessage(Lang.ACHIEVEMENT.f("&cYou have not unlocked that Achievement yet!")); + } else { + user.setShownAchievement(Achievement.getAchivement(args[1]).get()); + player.sendMessage(Utils.f("&7Your shown Achievement has been set to &a" + achievement.getTitle() + "&7!")); + user.updateNameTag(player); + } + } else { + player.sendMessage(Lang.ACHIEVEMENT.f("&cAchievement not found!")); + } + return true; + } + case "give": + if (s instanceof Player) { + Player player = (Player) s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (!user.isRank(UserRank.ADMIN)) { + player.sendMessage(Lang.NOPERM.s()); + return true; + } + } + if (args.length != 3) { + s.sendMessage(Utils.f("&aUsage: &7/achievement give [player] [achievement]")); + return true; + } + if (Bukkit.getPlayer(args[1]) != null) { + Player target = Bukkit.getPlayer(args[1]); + User targetUser = Core.getUserManager().getLoadedUser(target.getUniqueId()); + if (Achievement.getAchivement(args[2]).isPresent()) { + Achievement achievement = Achievement.getAchivement(args[2]).get(); + if (targetUser.hasAchievement(achievement)) { + s.sendMessage(Lang.ACHIEVEMENT.f("&7Player already has achievement &a" + achievement.getShortName())); + } else { + targetUser.addAchievement(achievement); + s.sendMessage(Lang.ACHIEVEMENT.f("&7Achievement &a" + + achievement.getShortName() + " &7given to &a" + target.getName())); + } + } else { + s.sendMessage(Lang.ACHIEVEMENT.f("&cAchievement not found!")); + } + } else { + s.sendMessage(Lang.ACHIEVEMENT.f("&cPlayer not found!")); + } + return true; + default: + s.sendMessage(Lang.ACHIEVEMENT.f("&7&lAchievements Help")); + s.sendMessage(Utils.f("&a/achievement &7locked - List all Achievements that are still locked")); + s.sendMessage(Utils.f("&a/achievement &7unlocked - List all Achievements you have unlocked")); + s.sendMessage(Utils.f("&a/achievement &7shown - List your current shown Achievement")); + s.sendMessage(Utils.f("&a/achievement &7setshown &a &7- Set your shown achievement")); + return true; + } + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/Alert.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/Alert.java new file mode 100644 index 0000000..599cc75 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/Alert.java @@ -0,0 +1,117 @@ +package net.grandtheftmc.core.alert; + +import net.grandtheftmc.core.alert.type.AlertShowType; +import net.grandtheftmc.core.alert.type.AlertType; + +import java.sql.Timestamp; + +/** + * Created by Luke Bingham on 10/09/2017. + */ +public interface Alert { + + int getUniqueIdentifier(); + void setUniqueIdentifier(int id); + + /** + * Get the player who created this Alert. + * + * @return + */ + String getPlayer(); + + /** + * Set the player who created this Alert. + * + * @param name + */ + void setPlayer(String name); + + /** + * Get the name of the Alert. + * + * @return + */ + String getName(); + + /** + * Get the Alert description. + * If POLL, This will be the 'question'. + * + * @return + */ + String getDescription(); + + /** + * Get the Alert description. + * If POLL, This will be the 'question'. + * + * @param desc + */ + void setDescription(String desc); + + /** + * Get the url of the image shown on the map. + * + * @return + */ + String getImageUrl(); + + /** + * Get the ShowType of this Alert. + * + * @return + */ + AlertShowType getShowType(); + + /** + * Get the AlertType of this specific Alert. + * + * @return + */ + AlertType getAlertType(); + + /** + * Get the Link that the Alert shows when interacted with. + * + * @return + */ + String getLink(); + + /** + * This Timestamp is when the Alert has or should begin. + * + * @return + */ + Timestamp getStart(); + + /** + * This Timestamp is when the Alert will end. + * + * @return + */ + Timestamp getEnd(); + + /** + * Is the Alert disabled or not started yet. + * + * @return + */ + boolean isDisabled(); + + /** + * Is the current time greater than the ending Timestamp. + * + * @return + */ + boolean hasExpired(); + + /** + * Has the Alert started? + * + * @return + */ + boolean hasStarted(); + + boolean isInProgress(); +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/AlertCreateStage.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/AlertCreateStage.java new file mode 100644 index 0000000..df42885 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/AlertCreateStage.java @@ -0,0 +1,9 @@ +package net.grandtheftmc.core.alert; + +/** + * Created by Luke Bingham on 11/09/2017. + */ +public enum AlertCreateStage { + NAME, DESC, IMAGE, LINK, + ; +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/AlertEntry.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/AlertEntry.java new file mode 100644 index 0000000..10141a8 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/AlertEntry.java @@ -0,0 +1,190 @@ +package net.grandtheftmc.core.alert; + +import net.grandtheftmc.core.alert.type.AlertShowType; +import net.grandtheftmc.core.alert.type.AlertType; + +import java.sql.Timestamp; + +/** + * Created by Luke Bingham on 10/09/2017. + */ +public class AlertEntry implements Alert { + + private int uniqueId; + private final String name, imageUrl; + private final AlertShowType showType; + private final AlertType alertType; + private final Timestamp start, end; + + private boolean disabled; + private String link, player, description = "none"; + private String addon; + + public AlertEntry(String name, String imageUrl, AlertShowType showType, AlertType alertType, Timestamp start, Timestamp end, boolean disabled) { + this.name = name; + this.imageUrl = imageUrl; + this.showType = showType; + this.alertType = alertType; + this.start = start; + this.end = end; + this.disabled = disabled; + } + + public AlertEntry(String name, String imageUrl, AlertShowType showType, AlertType alertType, String link, Timestamp start, Timestamp end, boolean disabled) { + this(name, imageUrl, showType, alertType, start, end, disabled); + this.link = link; + } + + @Override + public int getUniqueIdentifier() { + return this.uniqueId; + } + + @Override + public void setUniqueIdentifier(int id) { + this.uniqueId = id; + } + + /** + * Get the player who created this Alert. + * + * @return + */ + @Override + public String getPlayer() { + return this.player; + } + + /** + * Set the player who created this Alert. + * + * @param name + * @return + */ + @Override + public void setPlayer(String name) { + this.player = name; + } + + /** + * Get the name of the Alert. + * + * @return + */ + @Override + public String getName() { + return this.name; + } + + /** + * Get the Alert description. + * If POLL, This will be the 'question'. + * + * @return + */ + @Override + public String getDescription() { + return this.description; + } + + /** + * Get the Alert description. + * If POLL, This will be the 'question'. + * + * @param desc + */ + @Override + public void setDescription(String desc) { + this.description = desc; + } + + /** + * Get the url of the image shown on the map. + * + * @return + */ + @Override + public String getImageUrl() { + return this.imageUrl; + } + + /** + * Get the ShowType of this Alert. + * + * @return + */ + @Override + public AlertShowType getShowType() { + return this.showType; + } + + /** + * Get the AlertType of this specific Alert. + * + * @return + */ + @Override + public AlertType getAlertType() { + return this.alertType; + } + + /** + * Get the Link that the Alert shows when interacted with. + * + * @return + */ + @Override + public String getLink() { + return this.link; + } + + /** + * This Timestamp is when the Alert has or should begin. + * + * @return + */ + @Override + public Timestamp getStart() { + return this.start; + } + + /** + * This Timestamp is when the Alert will end. + * + * @return + */ + @Override + public Timestamp getEnd() { + return this.end; + } + + /** + * Is the Alert disabled or not started yet. + * + * @return + */ + @Override + public boolean isDisabled() { + return this.disabled; + } + + /** + * Is the current time greater than the ending Timestamp. + * + * @return + */ + @Override + public boolean hasExpired() { + return System.currentTimeMillis() > this.end.getTime(); + } + + @Override + public boolean hasStarted() { + return System.currentTimeMillis() >= this.start.getTime(); + } + + @Override + public boolean isInProgress() { + return !hasExpired() && hasStarted(); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/AlertManager.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/AlertManager.java new file mode 100644 index 0000000..9a2fafa --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/AlertManager.java @@ -0,0 +1,160 @@ +package net.grandtheftmc.core.alert; + +import com.google.common.collect.Lists; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.alert.command.AlertCommand; +import net.grandtheftmc.core.alert.type.AlertShowType; +import net.grandtheftmc.core.alert.type.AlertType; +import net.grandtheftmc.core.database.dao.AlertsDAO; +import net.grandtheftmc.core.util.Callback; +import net.grandtheftmc.core.util.Component; +import net.grandtheftmc.core.util.ServerUtil; +import org.bukkit.entity.Player; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Collectors; + +/** + * Created by Luke Bingham on 10/09/2017. + */ +public class AlertManager implements Component { + + private final List alerts; + private final List polls; +// private final MySQL mySQL; + + public AlertManager() { +// this.mySQL = mySQL; + this.alerts = Lists.newArrayList(); + this.polls = Lists.newArrayList(); + new AlertCommand(Core.getInstance(), this); + } + + @Override + public final AlertManager onEnable(Core plugin) { + this.reload(this::log); + return this; + } + + @Override + public final AlertManager onDisable(Core plugin) { + if(this.alerts != null && !this.alerts.isEmpty()) + this.alerts.clear(); + + return this; + } + + public List getAlerts() { + return this.alerts; + } + + public List getAvailableAlerts() { + return this.alerts.stream().filter(Alert::isInProgress).collect(Collectors.toList()); + } + + public Optional getAvailableAlertById(int id) { + return this.alerts.stream().filter(a -> a.isInProgress() && a.getUniqueIdentifier() == id).findFirst(); + } + + public Optional getAlertById(int id) { + return this.alerts.stream().filter(a -> a.getUniqueIdentifier() == id).findFirst(); + } + + public Optional getAlertById(String image) { + return this.alerts.stream().filter(a -> a.getImageUrl().equals(image)).findFirst(); + } + + public final AlertManager reload(Callback callback) { + this.alerts.clear(); + this.polls.clear(); + + ServerUtil.runTaskAsync(() -> { + createTable(); + + Optional[]> optional = AlertsDAO.fetchAllAlerts(); + if(!optional.isPresent()) return; + this.alerts.addAll(optional.get()[0]); + this.polls.addAll(optional.get()[1]); + + callback.call(true); + }); + + return this; + } + + private void createTable() { +// String query = "CREATE TABLE IF NOT EXISTS `alerts` " + +// "(" + +// "`id` int NOT NULL AUTO_INCREMENT," + +// "`name` varchar(255) NOT NULL," + +// "`description` varchar(255) DEFAULT 'none'," + +// "`image` varchar(255)," + +// "`link` varchar(255)," + +// "`showType` varchar(32) NOT NULL," + +// "`type` varchar(32) NOT NULL," + +// "`disabled` varchar(6)," + +// "`start` timestamp NOT NULL," + +// "`end` timestamp NOT NULL," + +// "`player` varchar(32) NOT NULL," + +// "`addon` longtext," + +// "PRIMARY KEY (`id`)" + +// ");"; +// PreparedStatement statement = this.mySQL.prepareStatement(query); +// statement.execute(); +// statement.close(); + AlertsDAO.createAlertsTable(); + +// String query2 = "CREATE TABLE IF NOT EXISTS `alert_users` " + +// "(" + +// "`uuid` varchar(36) NOT NULL," + +// "`id` int NOT NULL," + +// "`complete` varchar(6) NOT NULL," + +// "`input` longtext" + +// ");"; +// PreparedStatement statement2 = this.mySQL.prepareStatement(query2); +// statement2.execute(); +// statement2.close(); + AlertsDAO.createAlertUserTable(); + } + + public void insertAlert(Alert alert, Callback callback) { + if(alert.getAlertType() == AlertType.POLL) return; + ServerUtil.runTaskAsync(() -> callback.call(AlertsDAO.insertAlert(alert))); + } + + public void updateAlert(Alert alert, Callback callback) { + if(alert.getAlertType() == AlertType.POLL) return; + + ServerUtil.runTaskAsync(() -> callback.call(AlertsDAO.updateAlert(alert))); + } + + public void alertShown(Player player, Alert alert, Callback callback) { + if(player == null) return; + if(alert == null) return; + if(alert.getAlertType() == AlertType.POLL) return; + if(alert.getShowType() == AlertShowType.REPEAT) return; + + ServerUtil.runTaskAsync(() -> callback.call(AlertsDAO.insertAlertUser(player, alert))); + } + + public void deleteAlert(Player player, Alert alert, Callback callback) { + if(player == null || alert == null) { + callback.call(false); + return; + } + + ServerUtil.runTaskAsync(() -> callback.call(AlertsDAO.deleteAlert(alert))); + } + + /** + * This is ran on no thread, handle that yourself! + * + * @param uuid + * @param callback + */ + public void getAvailableAlertsForPlayer(UUID uuid, Callback> callback) { + callback.call(AlertsDAO.fetchAlertsForPlayer(this, uuid).orElse(Lists.newArrayList())); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/command/AlertCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/command/AlertCommand.java new file mode 100644 index 0000000..e44f9e2 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/command/AlertCommand.java @@ -0,0 +1,73 @@ +package net.grandtheftmc.core.alert.command; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.alert.Alert; +import net.grandtheftmc.core.alert.AlertEntry; +import net.grandtheftmc.core.alert.AlertManager; +import net.grandtheftmc.core.alert.type.AlertShowType; +import net.grandtheftmc.core.alert.type.AlertType; +import net.grandtheftmc.core.alert.ui.AlertsMenu; +import net.grandtheftmc.core.commands.CoreCommand; +import net.grandtheftmc.core.commands.RankedCommand; +import net.grandtheftmc.core.users.UserRank; +import org.bukkit.entity.Player; + +import java.sql.Timestamp; + +/** + * Created by Luke Bingham on 10/09/2017. + */ +public class AlertCommand extends CoreCommand implements RankedCommand { + + private final Core core; + private final AlertManager alertManager; + + /** + * Construct a new command. + */ + public AlertCommand(Core core, AlertManager alertManager) { + super( + "alerts", + "View all Alerts or create a new one." + ); + this.core = core; + this.alertManager = alertManager; + } + + /** + * This method is fired when the command is executed. + * + * @param sender sender type of the command + * @param args command arguments + */ + @Override + public void execute(Player sender, String[] args) { + if(args.length >= 1) { + if(args[0].equalsIgnoreCase("reload")) { + long start = System.currentTimeMillis(); + this.alertManager.reload(obj -> { + if (obj) { + sender.sendMessage(Lang.ALERTS.f("Successfully reloaded. (" + (System.currentTimeMillis() - start) + "ms)")); + } else { + sender.sendMessage(Lang.ALERTS.f("An error occurred while reloading!")); + } + }); + return; + } + } + + new AlertsMenu(this.alertManager).openInventory(sender); + } + + /** + * Get the required rank to use said command. + * + * @return UserRank + */ + @Override + public UserRank requiredRank() { + return UserRank.ADMIN; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/component/AlertCreateHandler.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/component/AlertCreateHandler.java new file mode 100644 index 0000000..fb59008 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/component/AlertCreateHandler.java @@ -0,0 +1,38 @@ +package net.grandtheftmc.core.alert.component; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.alert.AlertCreateStage; +import net.grandtheftmc.core.alert.ui.AlertCreationMenu; +import net.grandtheftmc.core.util.Component; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.AsyncPlayerChatEvent; + +/** + * Created by Luke Bingham on 11/09/2017. + */ +public class AlertCreateHandler implements Component { + + private final String user; + private final AlertCreateStage stage; + private final AlertCreationMenu menu; + + public AlertCreateHandler(String user, AlertCreateStage stage, AlertCreationMenu menu) { + this.user = user; + this.stage = stage; + this.menu = menu; + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onChat(AsyncPlayerChatEvent event) { + if(!event.getPlayer().getName().equals(user)) return; + event.setCancelled(true); + + if(stage == AlertCreateStage.NAME) menu.setName(event.getMessage()); + if(stage == AlertCreateStage.DESC) menu.setDescription(event.getMessage()); + if(stage == AlertCreateStage.IMAGE) menu.setImageUrl(event.getMessage()); + if(stage == AlertCreateStage.LINK) menu.setLink(event.getMessage()); + + menu.refresh(); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/type/AlertShowType.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/type/AlertShowType.java new file mode 100644 index 0000000..96d6247 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/type/AlertShowType.java @@ -0,0 +1,16 @@ +package net.grandtheftmc.core.alert.type; + +/** + * Created by Luke Bingham on 10/09/2017. + */ +public enum AlertShowType { + ONCE, + REPEAT, + ; + + public AlertShowType next() { + if(this == ONCE) return REPEAT; + if(this == REPEAT) return ONCE; + return ONCE; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/type/AlertType.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/type/AlertType.java new file mode 100644 index 0000000..75e07f9 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/type/AlertType.java @@ -0,0 +1,28 @@ +package net.grandtheftmc.core.alert.type; + +/** + * Created by Luke Bingham on 10/09/2017. + */ +public enum AlertType { + NEWS(true), + SALE(false), + + POLL(false), + ; + + private final boolean enabled; + + AlertType(boolean enabled) { + this.enabled = enabled; + } + + public boolean isEnabled() { + return this.enabled; + } + + public AlertType next() { + if(this == NEWS) return SALE; + if(this == SALE) return NEWS; + return NEWS; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/ui/AlertCreationMenu.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/ui/AlertCreationMenu.java new file mode 100644 index 0000000..942bcf8 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/ui/AlertCreationMenu.java @@ -0,0 +1,276 @@ +package net.grandtheftmc.core.alert.ui; + +import com.google.common.collect.Lists; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.alert.Alert; +import net.grandtheftmc.core.alert.AlertCreateStage; +import net.grandtheftmc.core.alert.AlertEntry; +import net.grandtheftmc.core.alert.AlertManager; +import net.grandtheftmc.core.alert.component.AlertCreateHandler; +import net.grandtheftmc.core.alert.type.AlertShowType; +import net.grandtheftmc.core.alert.type.AlertType; +import net.grandtheftmc.core.inventory.CoreMenu; +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import net.grandtheftmc.core.inventory.button.ClickableItem; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.factory.ItemFactory; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.ItemFlag; + +import java.sql.Timestamp; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +/** + * Created by Luke Bingham on 11/09/2017. + */ +public class AlertCreationMenu extends CoreMenu { + + private final AlertManager alertManager; + private final Player user; + + private boolean newEntry = true; + + private String name = "none", imageUrl = "none"; + private AlertShowType showType = AlertShowType.ONCE; + private AlertType alertType = AlertType.NEWS; + private long startTime = -1, expireTime = -1; + private boolean disabled = true; + private String link = "none", playerName = "none", description = "none"; + + private AlertCreateHandler handler = null; + + /** + * Construct a new Menu. + */ + public AlertCreationMenu(AlertManager alertManager, Player player) { + super( + 6, + "Alert Setup Wizard", + CoreMenuFlag.RESET_CURSOR_ON_OPEN + ); + this.alertManager = alertManager; + this.user = player; + + this.playerName = player.getName(); + this.startTime = System.currentTimeMillis(); + this.expireTime = System.currentTimeMillis(); + refresh(); + } + + /** + * Construct a new Menu. + */ + public AlertCreationMenu(AlertManager alertManager, String name, String imageUrl, String link, String description, AlertShowType showType, AlertType type, long startTime, long expireTime, boolean disabled, Player player) { + super( + 6, + "Alert Setup Wizard", + CoreMenuFlag.RESET_CURSOR_ON_OPEN + ); + this.alertManager = alertManager; + this.user = player; + this.name = name; + this.imageUrl = imageUrl; + this.link = link; + this.description = description; + this.showType = showType; + this.alertType = type; + this.startTime = startTime; + this.expireTime = expireTime; + this.disabled = disabled; + + this.newEntry = false; + + this.playerName = player.getName(); + this.startTime = System.currentTimeMillis(); + this.expireTime = System.currentTimeMillis(); + refresh(); + } + + public void refresh() { + if(this.handler != null) { + HandlerList.unregisterAll(this.handler); + this.handler = null; + } + + addItem(new ClickableItem(10, new ItemFactory(Material.NAME_TAG).setName("Name").setLore(C.GREEN + this.name).build(), (player, clickType) -> { + player.closeInventory(); + player.sendMessage(Lang.ALERTS.f("Enter a name for the Alert.")); + Bukkit.getPluginManager().registerEvents(this.handler = new AlertCreateHandler(player.getName(), AlertCreateStage.NAME, this), Core.getInstance()); + })); + + addItem(new ClickableItem(12, new ItemFactory(Material.BOOK).setName("Description").setLore(getDescription()).build(), (player, clickType) -> { + player.closeInventory(); + player.sendMessage(Lang.ALERTS.f("Enter a description for the Alert. (split with '~ln')")); + Bukkit.getPluginManager().registerEvents(this.handler = new AlertCreateHandler(player.getName(), AlertCreateStage.DESC, this), Core.getInstance()); + })); + + addItem(new ClickableItem(14, new ItemFactory(Material.PAINTING).setName("Image URL").setLore(C.GREEN + this.imageUrl).build(), (player, clickType) -> { + player.closeInventory(); + player.sendMessage(Lang.ALERTS.f("Enter a Image URL for the Alert.")); + Bukkit.getPluginManager().registerEvents(this.handler = new AlertCreateHandler(player.getName(), AlertCreateStage.IMAGE, this), Core.getInstance()); + })); + + addItem(new ClickableItem(16, new ItemFactory(Material.COMPASS).setName("Redirect Link").setLore(C.GREEN + this.link).build(), (player, clickType) -> { + player.closeInventory(); + player.sendMessage(Lang.ALERTS.f("Enter a redirect link for the Alert.")); + Bukkit.getPluginManager().registerEvents(this.handler = new AlertCreateHandler(player.getName(), AlertCreateStage.LINK, this), Core.getInstance()); + })); + + addItem(new ClickableItem(20, new ItemFactory(Material.SIGN).setName("Alert Type").setLore(C.GREEN + this.alertType.name(), " ", C.GRAY + "Click to change").build(), (player, clickType) -> { + this.alertType = this.alertType.next(); + refresh(); + })); + + addItem(new ClickableItem(22, new ItemFactory(this.showType == AlertShowType.ONCE ? Material.REDSTONE : Material.REDSTONE_COMPARATOR).setName("Show Type").setLore(C.GREEN + this.showType.name(), " ", C.GRAY + "Click to change").build(), (player, clickType) -> { + this.showType = this.showType.next(); + refresh(); + })); + + addItem(new ClickableItem(24, new ItemFactory(this.disabled ? Material.MAGMA_CREAM : Material.SLIME_BALL).setName("Disabled").setLore("" + (this.disabled ? C.RED : C.GREEN) + this.disabled, " ", C.GRAY + "Click to change").build(), (player, clickType) -> { + this.disabled = !this.disabled; + refresh(); + })); + + addItem(new ClickableItem(38, new ItemFactory(Material.WATCH).setName("Start").setLore(C.GRAY + new Timestamp(this.startTime).toString()).build(), (player, clickType) -> { + new AlertTimeEditor(this, false, user); + })); + + addItem(new ClickableItem(42, new ItemFactory(Material.WATCH).setName("Expire").setLore(C.GRAY + new Timestamp(this.expireTime).toString()).build(), (player, clickType) -> { + new AlertTimeEditor(this, true, user); + })); + + addItem(new ClickableItem(49, createAlertItem().build(), (player, clickType) -> refresh())); + + if(!name.equals("none") && !imageUrl.equals("none") && !link.equals("none") && !playerName.equals("none") && !description.equals("none")) { + if (newEntry) { + addItem(new ClickableItem(53, new ItemFactory(Material.ARROW).setName(C.GREEN + "Finish").build(), (player, clickType) -> { + long s = System.currentTimeMillis(); + AlertEntry alert = new AlertEntry(name, imageUrl, showType, alertType, link, new Timestamp(this.startTime), new Timestamp(this.expireTime), disabled); + alert.setDescription(description); + alert.setPlayer(playerName); + player.closeInventory(); + alertManager.insertAlert(alert, obj -> { + if (obj) { + player.sendMessage(Lang.ALERTS.f("New Alert entry has been added! (" + (System.currentTimeMillis() - s) + "ms)")); + } else { + player.sendMessage(Lang.ALERTS.f("An error occurred while adding entry!")); + } + }); + })); + } + else { + addItem(new ClickableItem(53, new ItemFactory(Material.ARROW).setName(C.GREEN + "Finish").build(), (player, clickType) -> { + long s = System.currentTimeMillis(); + AlertEntry alert = new AlertEntry(name, imageUrl, showType, alertType, link, new Timestamp(this.startTime), new Timestamp(this.expireTime), disabled); + alert.setDescription(description); + alert.setPlayer(playerName); + player.closeInventory(); + alertManager.updateAlert(alert, obj -> { + if (obj) { + player.sendMessage(Lang.ALERTS.f("Alert " + alert.getUniqueIdentifier() + " has been updated! (" + (System.currentTimeMillis() - s) + "ms)")); + } else { + player.sendMessage(Lang.ALERTS.f("An error occurred while updating entry!")); + } + }); + })); + } + } + + if(!newEntry) { + addItem(new ClickableItem(45, new ItemFactory(Material.FERMENTED_SPIDER_EYE).setName(C.RED + "Delete Alert").build(), (player, clickType) -> { + Optional optional = this.alertManager.getAlertById(this.imageUrl); + long s = System.currentTimeMillis(); + optional.ifPresent(alert -> this.alertManager.deleteAlert(player, alert, obj -> { + if (obj) { + player.sendMessage(Lang.ALERTS.f("Alert #" + alert.getUniqueIdentifier() + " has deleted! (" + (System.currentTimeMillis() - s) + "ms)")); + } else { + player.sendMessage(Lang.ALERTS.f("An error occurred while deleting entry!")); + } + new AlertsMenu(this.alertManager).openInventory(player); + })); + })); + } + + openInventory(user); + } + + public void setName(String name) { + this.name = name; + } + + public void setDescription(String description) { + this.description = description; + } + + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + } + + public void setLink(String link) { + this.link = link; + } + + public void addTime(boolean expire, long add) { + if(expire) this.expireTime += add; + else this.startTime += add; + } + + public void takeTime(boolean expire, long take) { + if(expire) this.expireTime -= take; + else this.startTime -= take; + } + + public long getTime(boolean expire) { + return expire ? this.expireTime : this.startTime; + } + + private ItemFactory createAlertItem() { + byte data = 14; + + if(!name.equals("none") && !imageUrl.equals("none") && !link.equals("none") && !playerName.equals("none") && !description.equals("none")) + data = 5; + + ItemFactory factory = new ItemFactory(Material.STAINED_CLAY, data); + factory.setName(this.getNameByByte(name, data)); + List lore = Lists.newArrayList(); + lore.addAll(this.getDescription()); + lore.addAll(Arrays.asList(" ", C.GRAY + "Status" + C.WHITE + ": " + (disabled ? C.RED + "Disabled" : C.GREEN + "Enabled"), " ")); + lore.addAll(Arrays.asList( + C.WHITE + "Start", " " + C.GRAY + new Timestamp(this.startTime).toString(), + " ", + C.WHITE + "Expire", " " + C.GRAY + new Timestamp(this.expireTime).toString(), + " ", + C.WHITE + "Created by", " " + C.GRAY + playerName + )); + factory.setLore(lore); + factory.addFlags(ItemFlag.HIDE_ATTRIBUTES); + return factory; + } + + private String getNameByByte(String name, byte data) { + if(data == 5) return C.GREEN + C.BOLD + name; + if(data == 14) return C.RED + C.BOLD + name; + return C.YELLOW + C.BOLD + name; + } + + private List getDescription() { + if(description.equalsIgnoreCase("none")) + return Collections.singletonList(" "); + + List desc = Lists.newArrayList(); + for(String line : description.split("~ln")) { + desc.add(C.DARK_GRAY + line); + } + desc.add(" "); + + return desc; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/ui/AlertTimeEditor.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/ui/AlertTimeEditor.java new file mode 100644 index 0000000..77fbed4 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/ui/AlertTimeEditor.java @@ -0,0 +1,94 @@ +package net.grandtheftmc.core.alert.ui; + +import net.grandtheftmc.core.inventory.CoreMenu; +import net.grandtheftmc.core.inventory.button.ClickableItem; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.factory.ItemFactory; +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import java.sql.Timestamp; + +/** + * Created by Luke Bingham on 12/09/2017. + */ +public class AlertTimeEditor extends CoreMenu { + + private final AlertCreationMenu menu; + private final Player user; + + private int days = 0; + private int hours = 0; + private int minutes = 0; + private int seconds = 0; + + /** + * Construct a new Menu. + */ + public AlertTimeEditor(AlertCreationMenu menu, boolean s, Player user) { + super(6, s ? "Alert Expire Time" : "Alert Start Time"); + this.menu = menu; + this.user = user; + + update(s); + } + + protected void update(boolean expire) { + addItem(new ClickableItem(10, new ItemFactory(Material.LONG_GRASS, (byte) 2).setName(C.GREEN + "+1 Day").build(), (player, clickType) -> { + this.days += 1; + menu.addTime(expire, 86400000); + update(expire); + })); + addItem(new ClickableItem(11, new ItemFactory(Material.DOUBLE_PLANT).setName(days + " Days").build(), (player, clickType) -> {})); + addItem(new ClickableItem(12, new ItemFactory(Material.HOPPER).setName(C.RED + "-1 Day").build(), (player, clickType) -> { + this.days -= 1; + menu.takeTime(expire, 86400000); + update(expire); + })); + + addItem(new ClickableItem(14, new ItemFactory(Material.LONG_GRASS, (byte) 2).setName(C.GREEN + "+1 Hour").build(), (player, clickType) -> { + this.hours += 1; + menu.addTime(expire, 3600000); + update(expire); + })); + addItem(new ClickableItem(15, new ItemFactory(Material.DOUBLE_PLANT).setName(hours + " Hours").build(), (player, clickType) -> {})); + addItem(new ClickableItem(16, new ItemFactory(Material.HOPPER).setName(C.RED + "-1 Hour").build(), (player, clickType) -> { + this.hours -= 1; + menu.takeTime(expire, 3600000); + update(expire); + })); + + addItem(new ClickableItem(28, new ItemFactory(Material.LONG_GRASS, (byte) 2).setName(C.GREEN + "+1 Minute").build(), (player, clickType) -> { + this.minutes += 1; + menu.addTime(expire, 60000); + update(expire); + })); + addItem(new ClickableItem(29, new ItemFactory(Material.DOUBLE_PLANT).setName(minutes + " Minutes").build(), (player, clickType) -> {})); + addItem(new ClickableItem(30, new ItemFactory(Material.HOPPER).setName(C.RED + "-1 Minute").build(), (player, clickType) -> { + this.minutes -= 1; + menu.takeTime(expire, 60000); + update(expire); + })); + + addItem(new ClickableItem(32, new ItemFactory(Material.LONG_GRASS, (byte) 2).setName(C.GREEN + "+1 Second").build(), (player, clickType) -> { + this.seconds += 1; + menu.addTime(expire, 1000); + update(expire); + })); + addItem(new ClickableItem(33, new ItemFactory(Material.DOUBLE_PLANT).setName(seconds + " Seconds").build(), (player, clickType) -> {})); + addItem(new ClickableItem(34, new ItemFactory(Material.HOPPER).setName(C.RED + "-1 Second").build(), (player, clickType) -> { + this.seconds -= 1; + menu.takeTime(expire, 1000); + update(expire); + })); + + addItem(new ClickableItem(49, new ItemFactory(Material.WATCH).setName(new Timestamp(menu.getTime(expire)).toString()).build(), (player, clickType) -> update(expire))); + + addItem(new ClickableItem(44, new ItemFactory(Material.ARROW).setName(C.RED + "Back").build(), (player, clickType) -> { + player.closeInventory(); + menu.refresh(); + })); + + this.openInventory(user); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/ui/AlertsMenu.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/ui/AlertsMenu.java new file mode 100644 index 0000000..63834b6 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/alert/ui/AlertsMenu.java @@ -0,0 +1,134 @@ +package net.grandtheftmc.core.alert.ui; + +import com.google.common.collect.Lists; +import net.grandtheftmc.core.alert.Alert; +import net.grandtheftmc.core.alert.AlertManager; +import net.grandtheftmc.core.inventory.CoreMenu; +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import net.grandtheftmc.core.inventory.button.ClickableItem; +import net.grandtheftmc.core.inventory.button.MenuItem; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.factory.ItemFactory; +import org.bukkit.Material; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * Created by Luke Bingham on 10/09/2017. + */ +public class AlertsMenu extends CoreMenu { + + /** + * Construct a new Menu. + */ + public AlertsMenu(AlertManager alertManager) { + this(1, alertManager); + } + + private AlertsMenu(int page, AlertManager alertManager) { + super( + 6, + "Alerts (page " + page + ")", + CoreMenuFlag.RESET_CURSOR_ON_OPEN + ); + + /** + * SOLID_RED = Disabled. + * SOLID_YELLOW = Expired. + * SOLID_GREEN = Active. + */ + +// for(int slot : super.getEdgeSlots(super.getRows())) +// super.addItem(new MenuItem(slot, new ItemFactory(Material.STAINED_GLASS_PANE, (byte) 7).setName(" ").build(), false)); + + addItem(new ClickableItem(49, new ItemFactory(Material.BOOK_AND_QUILL).setName(C.AQUA + "Create Alert").build(), (player, clickType) -> { + player.closeInventory(); + new AlertCreationMenu(alertManager, player); + })); + + int[] middle = {10,11,12,13,14,15,16, 19,20,21,22,23,24,25, 28,29,30,31,32,33,34}; + int perPage = middle.length, pages = 1, x = alertManager.getAlerts().size(), z = 0; + if(x / perPage > 0) pages = x / perPage; + if(x % perPage > 0) pages += 1; + if(page > pages) return; + for(int i = ((page * perPage) - perPage); i < (page * perPage); i += 1) { + if(i >= x) { + //Fill in the blank spaces. +// for(int j = z; j < perPage; j += 1) { +// addItem(null); +// } + break; + } + Alert alert = alertManager.getAlerts().get(i); + addItem(new ClickableItem(middle[z++], createAlertItem(alert).build(), (player, clickType) -> { + player.sendMessage("#" + alert.getUniqueIdentifier()); + new AlertCreationMenu(alertManager, alert.getName(), alert.getImageUrl(), alert.getLink(), alert.getDescription(), alert.getShowType(), alert.getAlertType(), alert.getStart().getTime(), alert.getEnd().getTime(), alert.isDisabled(), player).openInventory(player); + })); + } + + if (page < pages) { + addItem(new ClickableItem(52, new ItemStack(Material.ARROW), (player, clickType) -> new AlertsMenu(page + 1, alertManager).openInventory(player))); + } + + if (page > 1) { + addItem(new ClickableItem(46, new ItemStack(Material.ARROW), (player, clickType) -> new AlertsMenu(page - 1, alertManager).openInventory(player))); + } + } + + private ItemFactory createAlertItem(Alert alert) { + byte data = 5; + String status = ""; + if(alert.isInProgress()) { + data = 5; + status = C.GREEN + "Active"; + } + if(alert.hasExpired()) { + data = 4; + status = C.YELLOW + "Expired"; + } + if(alert.isDisabled()) { + data = 14; + status = C.RED + "Disabled"; + } + ItemFactory factory = new ItemFactory(Material.STAINED_CLAY, data); + factory.setName(this.getNameByByte(alert.getName(), data)); + List lore = Lists.newArrayList(); + lore.addAll(this.getDescription(alert)); + lore.addAll(Arrays.asList(" ", C.GRAY + "Status" + C.WHITE + ": " + status, " ")); + lore.addAll(Arrays.asList( + C.WHITE + (alert.hasStarted() ? "Started at" : (alert.hasExpired() ? "Started at" : "Starts at")), " " + C.GRAY + alert.getStart().toString(), + " ", + C.WHITE + (alert.hasExpired() ? "Expired" : "Expires at"), " " + C.GRAY + alert.getEnd().toString(), + " ", + C.WHITE + "Created by", " " + C.GRAY + alert.getPlayer(), + " ", + C.WHITE + "Shift " + C.GRAY + "&" + C.WHITE + " Right Click " + C.GRAY + "to edit" + )); + factory.setLore(lore); + factory.addFlags(ItemFlag.HIDE_ATTRIBUTES); + return factory; + } + + private String getNameByByte(String name, byte data) { + if(data == 5) return C.GREEN + C.BOLD + name; + if(data == 14) return C.RED + C.BOLD + name; + return C.YELLOW + C.BOLD + name; + } + + public List getDescription(Alert alert) { + if(alert.getDescription().equalsIgnoreCase("none")) + return Collections.singletonList(" "); + + List desc = Lists.newArrayList(); + for(String line : alert.getDescription().split("~ln")) { + desc.add(C.DARK_GRAY + line); + } + desc.add(" "); + + return desc; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/animation/Animation.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/animation/Animation.java new file mode 100644 index 0000000..39d1241 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/animation/Animation.java @@ -0,0 +1,19 @@ +package net.grandtheftmc.core.animation; + +import net.grandtheftmc.core.animation.step.AStep; + +public interface Animation { + + AStep[] getSteps(); + + boolean isAsynchronous(); + + void addStep(AStep step); + + void start(); + + /** + * This method will stop all animations. + */ + void stop(); +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/animation/CoreAnimation.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/animation/CoreAnimation.java new file mode 100644 index 0000000..2281d55 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/animation/CoreAnimation.java @@ -0,0 +1,93 @@ +package net.grandtheftmc.core.animation; + +import com.avaje.ebeaninternal.server.el.ElSetValue; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.animation.event.AnimationFinishEvent; +import net.grandtheftmc.core.animation.step.AStep; +import org.bukkit.Bukkit; +import org.bukkit.scheduler.BukkitRunnable; + +public class CoreAnimation implements Animation { + + private final AStep[] aSteps; + private final boolean async; + + private int size = 0, current = 0; + private BukkitRunnable task = null; + + /** + * Construct a new Animation. + * + * @param steps + */ + public CoreAnimation(boolean async, AStep... steps) { + this.async = async; + this.aSteps = steps; + this.size = steps.length; + } + + /** + * Construct a new Animation. + */ + public CoreAnimation(boolean async, int steps) { + this.async = async; + this.aSteps = new AStep[steps]; + } + + @Override + public AStep[] getSteps() { + return this.aSteps; + } + + @Override + public boolean isAsynchronous() { + return this.async; + } + + @Override + public void addStep(AStep step) { + this.aSteps[this.size++] = step; + } + + @Override + public void start() { + if(this.task != null) return; + + this.task = new BukkitRunnable() { + private long ticks = 0; + @Override public void run() { + AStep step = aSteps[current]; + if(ticks >= step.getEndingTime()) { + if(current >= (aSteps.length - 1)) { + ticks = 0; + stop(); + + AnimationFinishEvent event = new AnimationFinishEvent(CoreAnimation.this); + Bukkit.getPluginManager().callEvent(event); + return; + } + + step.getEnd().end(); + aSteps[current++].getStart().start(); + } + } + }; + + if(this.async) this.task.runTaskTimerAsynchronously(Core.getInstance(), 0L, 1L); + else this.task.runTaskTimer(Core.getInstance(), 0L, 1L); + } + + /** + * This method will stop all animations. + */ + @Override + public void stop() { + if(this.task == null) return; + this.task.cancel(); + + this.aSteps[this.current].getEnd().end(); + current = 0; + + this.task = null; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/animation/event/AnimationFinishEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/animation/event/AnimationFinishEvent.java new file mode 100644 index 0000000..c3957b1 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/animation/event/AnimationFinishEvent.java @@ -0,0 +1,18 @@ +package net.grandtheftmc.core.animation.event; + +import net.grandtheftmc.core.animation.Animation; +import net.grandtheftmc.core.events.CoreEvent; + +public class AnimationFinishEvent extends CoreEvent { + + private final Animation animation; + + public AnimationFinishEvent(Animation animation) { + super(false); + this.animation = animation; + } + + public Animation getAnimation() { + return this.animation; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/animation/step/AStep.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/animation/step/AStep.java new file mode 100644 index 0000000..013a564 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/animation/step/AStep.java @@ -0,0 +1,32 @@ +package net.grandtheftmc.core.animation.step; + +public class AStep { + + private final long endingTime; + private final AStepStart start; + private final AStepEnd end; + + /** + * Construct a new Animation Step. + * + * @param start - Starting action + * @param end - Ending action + */ + public AStep(long endingTime, AStepStart start, AStepEnd end) { + this.endingTime = endingTime; + this.start = start; + this.end = end; + } + + public long getEndingTime() { + return this.endingTime; + } + + public AStepStart getStart() { + return this.start; + } + + public AStepEnd getEnd() { + return this.end; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/animation/step/AStepEnd.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/animation/step/AStepEnd.java new file mode 100644 index 0000000..0a1dcc3 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/animation/step/AStepEnd.java @@ -0,0 +1,9 @@ +package net.grandtheftmc.core.animation.step; + +public interface AStepEnd { + + /** + * This will run when the AnimationStep ends. + */ + void end(); +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/animation/step/AStepStart.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/animation/step/AStepStart.java new file mode 100644 index 0000000..7d6ce65 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/animation/step/AStepStart.java @@ -0,0 +1,9 @@ +package net.grandtheftmc.core.animation.step; + +public interface AStepStart { + + /** + * This will run when the AnimationStep first starts. + */ + void start(); +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/announcer/Announcement.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/announcer/Announcement.java new file mode 100644 index 0000000..7bdbc68 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/announcer/Announcement.java @@ -0,0 +1,29 @@ +package net.grandtheftmc.core.announcer; + +public class Announcement { + + private int id; + private String[] lines; + + public Announcement(int id, String[] lines) { + this.id = id; + this.lines = lines; + } + + public int getId() { + return this.id; + } + + public void setId(int id) { + this.id = id; + } + + public String[] getLines() { + return this.lines.clone(); + } + + public void setLines(String[] lines) { + this.lines = lines; + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/announcer/Announcer.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/announcer/Announcer.java new file mode 100644 index 0000000..f14ade7 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/announcer/Announcer.java @@ -0,0 +1,185 @@ +package net.grandtheftmc.core.announcer; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.users.Pref; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserManager; +import net.grandtheftmc.core.util.Component; +import net.grandtheftmc.core.util.Utils; + +public class Announcer implements Component { + + private List announcements = new ArrayList<>(); + private int delay = 60; + private boolean random = true; + private String[] header = new String[] { "Header: error" }; + private String[] footer = new String[] { "Footer: error" }; + private int taskId = -1; + private int id = -1; + + public Announcer() { + this.loadAnnouncements(); + this.startSchedule(); + } + + @Override + public Announcer onDisable(Core plugin) { + this.announcements.clear(); + return this; + } + + public void loadAnnouncements() { + YamlConfiguration c = Core.getSettings().getAnnouncerConfig(); + this.announcements = new ArrayList<>(); + try { + Core.getSettings().setUseAnnouncer(c.getBoolean("enable")); + this.delay = c.getInt("delay"); + this.random = c.getBoolean("random"); + this.header = Utils.stringsToArray(c.getStringList("header")); + this.footer = Utils.stringsToArray(c.getStringList("footer")); + int i = 0; + if (c.get("announcements") != null) + for (String key : c.getConfigurationSection("announcements").getKeys(false)) { + String[] array = Utils.stringsToArray(c.getStringList("announcements." + key)); + if (array != null) { + this.announcements.add(new Announcement(i, array)); + i++; + } + } + } + catch (Exception e) { + Core.log("An error has occured while launching the announcer: "); + e.printStackTrace(); + } + } + + public void saveAnnouncements(boolean shutdown) { + YamlConfiguration c = Core.getSettings().getAnnouncerConfig(); + + c.set("enable", Core.getSettings().useAnnouncer()); + c.set("delay", this.delay); + c.set("random", this.random); + c.set("header", this.header); + c.set("footer", this.footer); + int i = 0; + if (c.getConfigurationSection("announcements") != null) + for (String key : c.getConfigurationSection("announcements").getKeys(false)) + c.set(key, null); + for (Announcement an : this.announcements) { + c.set("announcements." + i, an.getLines()); + i++; + } + + Utils.saveConfig(c, "announcer"); + } + + public void startSchedule() { + if (!Core.getSettings().useAnnouncer()) + return; + if (this.taskId != -1) + Bukkit.getScheduler().cancelTask(this.taskId); + + this.taskId = new BukkitRunnable() { + @Override + public void run() { + Announcer.this.broadcastAnnouncement(); + } + + }.runTaskTimer(Core.getInstance(), this.delay * 20L, this.delay * 20L).getTaskId(); + } + + private void broadcastAnnouncement() { + Announcement an = this.pickAnnouncement(); + if (an == null) + return; + String[] header = Utils.f(this.header); + String[] lines = Utils.fc(an.getLines()); + String[] footer = Utils.f(this.footer); + for (Player player : Bukkit.getOnlinePlayers()) { + + User user = UserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + if (user != null) { + + if (!user.getPref(Pref.ANNOUNCEMENTS) || user.isInTutorial()) + continue; + if (header != null) + player.sendMessage(header); + player.sendMessage(lines); + if (footer != null) + player.sendMessage(footer); + } + } + } + + private Announcement pickAnnouncement() { + if (this.announcements.isEmpty()) + return null; + if (this.random) + return this.announcements.get(Utils.getRandom().nextInt(this.announcements.size())); + this.id += 1; + if (this.id >= this.announcements.size()) + this.id = 0; + return this.announcements.get(this.id); + } + + public Announcement addAnnouncement(String[] lines) { + Announcement an = new Announcement(this.getUnusedId(), lines); + this.announcements.add(an); + return an; + } + + public void removeAnnouncement(int id) { + Announcement an = this.getAnnouncement(id); + if (an != null) + this.announcements.remove(id); + } + + private int getUnusedId() { + for (int i = 0;; i++) + if (this.getAnnouncement(this.id) == null) + return i; + } + + public Announcement getAnnouncement(int id) { + for (Announcement an : this.announcements) + if (an.getId() == id) + return an; + return null; + } + + public String[] getHeader() { + return this.header; + } + + public String[] getFooter() { + return this.footer; + } + + public List getAnnouncements() { + return this.announcements; + } + + public int getTaskId() { + return this.taskId; + } + + public void setTaskId(int taskId) { + this.taskId = taskId; + } + + public int getId() { + return this.id; + } + + public void setId(int id) { + this.id = id; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/announcer/AnnouncerCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/announcer/AnnouncerCommand.java new file mode 100644 index 0000000..2cb396c --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/announcer/AnnouncerCommand.java @@ -0,0 +1,134 @@ +package net.grandtheftmc.core.announcer; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.Utils; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.List; + +public class AnnouncerCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (!s.isOp()) { + s.sendMessage(Utils.f("&cYou do not have permission to execute this command!")); + return true; + } + if (args.length == 0) { + s.sendMessage(Utils.f("&a/announcer add ")); + s.sendMessage(Utils.f("&a/announcer remove ")); + s.sendMessage(Utils.f("&a/announcer reload")); + s.sendMessage(Utils.f("&a/announcer save")); + s.sendMessage(Utils.f("&a/announcer show ")); + s.sendMessage(Utils.f("&a/announcer list")); + s.sendMessage(Utils.f("&a/announcer test ")); + s.sendMessage(Utils.f("&a/announcer say ")); + return true; + } + switch (args[0].toLowerCase()) { + case "add": { + if (args.length < 2) { + s.sendMessage(Utils.f("&c/announcer add ")); + return true; + } + String text = args[1]; + for (int i = 2; i < args.length; i++) + text = text + ' ' + args[i]; + String[] lines = text.split("#"); + Announcement an = Core.getAnnouncer().addAnnouncement(lines); + s.sendMessage(Utils.f("&7An announcement with ID &a" + an.getId() + " was created!")); + + return true; + } + case "remove": + if (args.length < 2) { + s.sendMessage(Utils.f("/announcer remove ")); + return true; + } + try { + int id = Integer.parseInt(args[1]); + if (Core.getAnnouncer().getAnnouncement(id) == null) { + s.sendMessage(Utils.f("&cThat announcement does not exist!")); + return true; + } + s.sendMessage(Utils.f("&7An announcement with ID &a" + id + " was created!")); + Core.getAnnouncer().removeAnnouncement(id); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f("&cThat is not an ID!")); + } + return true; + case "reload": + Core.getSettings().setAnnouncerConfig(Utils.loadConfig("announcer")); + Core.getAnnouncer().loadAnnouncements(); + Core.getAnnouncer().startSchedule(); + s.sendMessage(Utils.f("&7The announcer config was reloaded!")); + return true; + case "save": + Core.getAnnouncer().saveAnnouncements(false); + s.sendMessage(Utils.f("&7The announcer config was saved!")); + return true; + case "show": { + if (args.length < 2) { + s.sendMessage(Utils.f("&c/announcer show ")); + return true; + } + int id; + try { + id = Integer.parseInt(args[1]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f("&cThe ID must be a number!")); + return true; + } + Announcer a = Core.getAnnouncer(); + Announcement an = a.getAnnouncement(id); + s.sendMessage(Utils.f(a.getHeader())); + s.sendMessage(Utils.fc(an.getLines())); + s.sendMessage(Utils.f(a.getFooter())); + return true; + + } + case "list": + Announcer a = Core.getAnnouncer(); + List ann = a.getAnnouncements(); + if (ann.isEmpty()) { + s.sendMessage(Utils.f("&aThere are no announcements!")); + return true; + } + String st = "&aAnnouncements&7: &a" + ann.get(0).getId(); + for (int i = 1; i < ann.size(); i++) + st = st + "&7, &a" + ann.get(i).getId(); + s.sendMessage(Utils.f(st)); + return true; + case "test": { + if (args.length < 2) { + s.sendMessage(Utils.f("&c/announcer test ")); + return true; + } + String text = args[1]; + for (int i = 2; i < args.length; i++) + text = text + ' ' + args[i]; + s.sendMessage(Utils.fc(text)); + return true; + } + case "say": + if (args.length < 2) { + s.sendMessage(Utils.f("&c/announcer say ")); + return true; + } + String text = args[1]; + for (int i = 2; i < args.length; i++) + text = text + ' ' + args[i]; + Utils.broadcast(text); + return true; + default: + s.sendMessage(Utils.f("/announcer add ")); + s.sendMessage(Utils.f("/announcer remove ")); + s.sendMessage(Utils.f("/announcer list")); + return true; + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/Anticheat.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/Anticheat.java new file mode 100644 index 0000000..65ded92 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/Anticheat.java @@ -0,0 +1,101 @@ +package net.grandtheftmc.core.anticheat; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.ProtocolManager; +import com.comphenix.protocol.events.ListenerPriority; +import com.comphenix.protocol.events.PacketAdapter; +import com.comphenix.protocol.events.PacketEvent; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.anticheat.check.CheckManager; +import net.grandtheftmc.core.anticheat.component.AnticheatComponent; +import net.grandtheftmc.core.anticheat.data.ClientData; +import net.grandtheftmc.core.anticheat.data.ClientHandler; +import net.grandtheftmc.core.anticheat.inspect.InspectCommand; +import net.grandtheftmc.core.anticheat.report.ReportManager; +import net.grandtheftmc.core.anticheat.trigger.MovementTrigger; +import net.grandtheftmc.core.util.C; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; + +public class Anticheat { + + private static final String NAME = "WatchDawg"; + + private final ClientHandler clientHandler; + private final CheckManager checkManager; + + public Anticheat(Core core) { + this.checkManager = new CheckManager(); + new AnticheatComponent(core, this); + ReportManager reportManager = new ReportManager(core, this); + this.clientHandler = new ClientHandler(this, reportManager); + new InspectCommand(); + + ProtocolManager manager = ProtocolLibrary.getProtocolManager(); + + manager.addPacketListener(new PacketAdapter(core, ListenerPriority.NORMAL, PacketType.Play.Client.FLYING) { + public void onPacketReceiving(PacketEvent event) { + if(event.getPlayer().getGameMode() == GameMode.CREATIVE || event.getPlayer().getGameMode() == GameMode.SPECTATOR) return; + if (clientHandler.getClientData(event.getPlayer()) == null) return; + + if (event.getPacketType().equals(PacketType.Play.Client.FLYING)) { + ClientData data = getClientHandler().getClientData(event.getPlayer()); + MovementTrigger trigger = new MovementTrigger(data, null, null, true); + data.addToEventQueue(trigger); + } + } + }); + +// manager.addPacketListener(new PacketAdapter(core, ListenerPriority.NORMAL, PacketType.Play.Client.ARM_ANIMATION) { +// public void onPacketReceiving(PacketEvent event) { +// if(clientHandler.getClientData(event.getPlayer()) == null) return; +// +// if (event.getPacketType().equals(PacketType.Play.Client.ARM_ANIMATION)) { +// ClientData checkPlayer = clientHandler.getClientData(event.getPlayer()); +// CombatTrigger trigger = new CombatTrigger(checkPlayer, null, CombatTrigger.FightAction.SWING); +// checkPlayer.addToEventQueue(trigger); +// } +// } +// }); +// +// manager.addPacketListener(new PacketAdapter(core, ListenerPriority.NORMAL, PacketType.Play.Client.USE_ENTITY) { +// public void onPacketReceiving(PacketEvent event) { +// if(clientHandler.getClientData(event.getPlayer()) == null) return; +// +// if (event.getPacketType().equals(PacketType.Play.Client.USE_ENTITY)) { +// Player targetEntity = null; +// int entityId = event.getPacket().getIntegers().getValues().get(0); +// +// for (Entity e : event.getPlayer().getWorld().getEntities()) { +// if (e.getEntityId() == entityId) { +// if (e instanceof Player) targetEntity = (Player) e; +// else targetEntity = null; +// } +// } +// +// if (targetEntity != null) { +// ClientData checkPlayer = clientHandler.getClientData(event.getPlayer()); +// ClientData targetPlayer = clientHandler.getClientData(targetEntity); +// if (Math.abs(checkPlayer.lastSwingTime - System.currentTimeMillis()) < 100) { +// CombatTrigger trigger = new CombatTrigger(checkPlayer, targetPlayer, CombatTrigger.FightAction.HIT); +// checkPlayer.addToEventQueue(trigger); +// } +// } +// } +// } +// }); + } + + public ClientHandler getClientHandler() { + return clientHandler; + } + + public CheckManager getCheckManager() { + return checkManager; + } + + public static void log(String log) { + Bukkit.getConsoleSender().sendMessage(C.GOLD + NAME + C.AQUA + " " + log); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/Severity.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/Severity.java new file mode 100644 index 0000000..90994d2 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/Severity.java @@ -0,0 +1,7 @@ +package net.grandtheftmc.core.anticheat; + +public enum Severity { + + LOW, MEDIUM, HIGH; + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/check/CheatType.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/check/CheatType.java new file mode 100644 index 0000000..0c9dc45 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/check/CheatType.java @@ -0,0 +1,63 @@ +package net.grandtheftmc.core.anticheat.check; + +public class CheatType { + + private final int identifier; + private final String name; + private final TriggerType triggerType; + private final Type type; + + public CheatType(int identifier, String name, TriggerType triggerType, Type type) { + this.identifier = identifier; + this.name = name; + this.triggerType = triggerType; + this.type = type; + } + + public int getIdentifier() { + return identifier; + } + + public String getName() { + return name; + } + + public Type getType() { + return type; + } + + public TriggerType getTriggerType() { + return triggerType; + } + + private static interface ITriggerType {} + + public static class Movement implements ITriggerType { + public static final CheatType FLIGHT = new CheatType(1, "Flight", TriggerType.MOVEMENT, Type.FLIGHT); + public static final CheatType SPEED = new CheatType(2, "Speed", TriggerType.MOVEMENT, Type.SPEED); + public static final CheatType JESUS = new CheatType(3, "Jesus", TriggerType.MOVEMENT, Type.JESUS); + } + + public static class Combat implements ITriggerType { + + } + + public enum TriggerType { + MOVEMENT, + COMBAT, + ; + } + + public enum Type { + FLIGHT(Movement.class), + SPEED(Movement.class), + JESUS(Movement.class), + ; + + private Class trigger; + + Type(Class trigger) { + this.trigger = trigger; + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/check/Check.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/check/Check.java new file mode 100644 index 0000000..b74fa0f --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/check/Check.java @@ -0,0 +1,20 @@ +package net.grandtheftmc.core.anticheat.check; + +import net.grandtheftmc.core.anticheat.trigger.Trigger; + +public class Check { + + protected String name; + + public Check(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public double analyse(Trigger trigger) { + return 0D; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/check/CheckManager.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/check/CheckManager.java new file mode 100644 index 0000000..11ca4e9 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/check/CheckManager.java @@ -0,0 +1,43 @@ +package net.grandtheftmc.core.anticheat.check; + +import com.google.common.collect.Lists; +import net.grandtheftmc.core.anticheat.check.movement.SpeedCheck; +import net.grandtheftmc.core.anticheat.check.movement.VelocityCheck; +import net.grandtheftmc.core.anticheat.trigger.Trigger; + +import java.util.List; + +public class CheckManager { + + private final List checks = Lists.newArrayList(); + + public CheckManager() { + + //Movement + this.checks.add(new SpeedCheck()); + this.checks.add(new VelocityCheck()); + + //Combat +// this.checks.add(new KillAuraCheck()); +// this.checks.add(new FrequencyCheck()); +// this.checks.add(new ImprobableCheck()); +// this.checks.add(new NoSwingCheck()); +// this.checks.add(new ReachCheck()); +// this.checks.add(new SwingCheck()); + } + + public List getChecks() { + return checks; + } + + public double check(Trigger trigger) { + double lvl = 0D; + for(Check check : this.checks) { + double violation = check.analyse(trigger); + if(violation > 0) { + lvl += violation; + } + } + return lvl; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/check/movement/SpeedCheck.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/check/movement/SpeedCheck.java new file mode 100644 index 0000000..f2c84fe --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/check/movement/SpeedCheck.java @@ -0,0 +1,211 @@ +package net.grandtheftmc.core.anticheat.check.movement; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.anticheat.Severity; +import net.grandtheftmc.core.anticheat.check.CheatType; +import net.grandtheftmc.core.anticheat.check.Check; +import net.grandtheftmc.core.anticheat.data.ClientData; +import net.grandtheftmc.core.anticheat.event.MovementCheatEvent; +import net.grandtheftmc.core.anticheat.trigger.MovementTrigger; +import net.grandtheftmc.core.anticheat.trigger.Trigger; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +public class SpeedCheck extends Check { + + public SpeedCheck() { + super("Speed"); + } + + public double getMaxSpeed(MovementTrigger trigger) { + double speed = 0.30D;//0.29D + //SPRINT 0.561208202072919 1.3x faster + //SNEAK 0.12951234466191863 0.3x faster + //SPDI 0.5180519387595268 1.2x faster + //SPDII 0.6044049676671079 1.4x faster + + if (trigger.getData().getPlayer().getWalkSpeed() > 0.2F) + speed *= (trigger.getData().getPlayer().getWalkSpeed() * 5); + + for (PotionEffect potionEffect : trigger.getData().getPlayer().getActivePotionEffects()) { + if (potionEffect.getType().equals(PotionEffectType.SPEED)) { + int amp = potionEffect.getAmplifier() + 1; + speed = (speed * (1.3 * amp)); + + //Speed potions >4 tend to false positive; give an extra bit of running speed + if (amp > 3) speed *= 1.8; + } + } + + if (trigger.isSneaking()) speed *= 0.3; + + //Players under blocks can rapidly press space to achieve very fast speeds + for (int x = -2; x < 2; x++) { + for (int z = -2; z < 2; z++) { + Location plo = trigger.getTo().clone().add(x, 2.55, z); + + if (!plo.getBlock().getType().equals(Material.AIR)) { + speed *= 3; + } + } + } + + boolean d = false; + for (int x = -2; x < 2; x++) { + for (int z = -2; z < 2; z++) { + Location plo = trigger.getTo().clone().add(x, -1, z); + + if (plo.getBlock().getType().equals(Material.ICE)) { + d = true; + speed *= 3; + } + } + } + + for (int x = -2; x < 2; x++) { + for (int z = -2; z < 2; z++) { + Location plo = trigger.getTo().clone().add(x, -2, z); + + if (!d) { + if (plo.getBlock().getType().equals(Material.ICE)) { + speed *= 3; + } + } + } + } + + if (trigger.getData().justJumped) { + if (trigger.getData().jumpTicks == 0) + speed *= 1.45; + + trigger.getData().justJumped = false; + } + + //Sprint-jumping values + double jumpVals[] = {2.11, 1.64, 1.57, 1.51, 1.43}; + if (trigger.getData().jumpTicks > 0) { + if (trigger.getData().jumpTicks <= 3) { + speed *= jumpVals[trigger.getData().jumpTicks + 1]; + } + } + + //Account for server-side velocities + double xV = Math.abs(trigger.getxV()); + double zV = Math.abs(trigger.getzV()); + + double sD = ((xV + zV) / 0.44); + if (sD > 0) speed += speed * sD; + + return speed; + } + + @Override + public double analyse(Trigger trigger) { + double vL = 0; + + if (trigger instanceof MovementTrigger) { + ClientData data = trigger.getData(); + + if (data.sLastPacketTime == 0) + data.sLastPacketTime = trigger.getTimeCreated(); + + double lag = Math.abs(data.sLastPacketTime - trigger.getTimeCreated()); + data.sLastPacketTime = trigger.getTimeCreated(); + + if (!((MovementTrigger) trigger).isFlying()) { + + //If the player teleported, can fly, or is in a vehicle, don't flag them and reset their locations + if ((Math.abs(trigger.getData().timeSinceLastTeleport - System.currentTimeMillis()) < 2000) || data.getPlayer().getAllowFlight() || data.getPlayer().getVehicle() != null) { + data.xBefore = ((MovementTrigger) trigger).getTo().getX(); + data.zBefore = ((MovementTrigger) trigger).getTo().getZ(); + data.xCurrent = data.xBefore; + data.zCurrent = data.zBefore; + } else { + data.xBefore = data.xCurrent; + data.xCurrent = ((MovementTrigger) trigger).getTo().getX(); + data.zBefore = data.zCurrent; + data.zCurrent = ((MovementTrigger) trigger).getTo().getZ(); + + + double sLag = lag / 2; + if (sLag < 50 && sLag > 0) sLag = 50; + + //Depending on how long they haven't sent a packet, add the theoretical max speed the player could go at that moment to a buffer + //(Not sending packets for 1 second is lag, allow them to move ~6 or so blocks) + if (Math.abs(data.xBefore - data.xCurrent) > 0) + data.maxDistanceBufferX += (sLag / 50) * this.getMaxSpeed((MovementTrigger) trigger); + + if (Math.abs(data.zBefore - data.zCurrent) > 0) + data.maxDistanceBufferZ += (sLag / 50) * this.getMaxSpeed((MovementTrigger) trigger); + + //If the player isn't currently spamming packets to catch up on lag + if (lag > 0) { + data.maxDistanceBufferX -= Math.abs(data.xBefore - data.xCurrent); + data.maxDistanceBufferZ -= Math.abs(data.zBefore - data.zCurrent); + + //TODO: This is kinda exploitable; the player can go faster to go get allowed to go further for a longer distance... + //If the player is going slower than the maximum speed, subtracting from the buffer isnt an issue, so lower the buffer so that they can't speed up a lot after racking up a buffer + // if(Math.abs(player.xBefore - player.xCurrent) < this.getMaxSpeed((MovementEvent) e)) { + data.maxDistanceBufferX *= 0.95; + // } + // if(Math.abs(player.zBefore - player.zCurrent) < this.getMaxSpeed((MovementEvent) e)) { + data.maxDistanceBufferZ *= 0.95; + // } + + //The player shouldn't be able to teleport more than 200 blocks... or go an insane speed for a long-er amount of time. Lower it drastically... + //The player would have to lag for ~40 seconds to get this amount of buffer, or an attempt to bypass, which neither are possible in vanilla + if (data.maxDistanceBufferX > 200) data.maxDistanceBufferX *= 0.1; + if (data.maxDistanceBufferZ > 200) data.maxDistanceBufferZ *= 0.1; + + //When the buffer is lower than 0 (faster speed than average) + if (data.maxDistanceBufferX < -0.1) { + data.sBuffer += 10; + data.maxDistanceBufferX = -0.1; + + if (data.sBuffer > 30) { + data.sBuffer = 30; + vL += 1; + + MovementCheatEvent event = new MovementCheatEvent<>(data, CheatType.Movement.SPEED, this.getMaxSpeed((MovementTrigger) trigger)); + Bukkit.getPluginManager().callEvent(event); + if(event.isCancelled()) return vL; + + data.setDetectedHack(CheatType.Movement.SPEED); + data.setDetectedHackAttribute("X"); + data.setDetectedHackBanMessage("SPEED_X"); + data.lastSeverity = Severity.MEDIUM; + return vL; + } + } + + if (data.maxDistanceBufferZ < -0.1) { + data.sBuffer += 10; + data.maxDistanceBufferZ = -0.1; + + if (data.sBuffer > 30) { + data.sBuffer = 30; + vL += 1; + + MovementCheatEvent event = new MovementCheatEvent<>(data, CheatType.Movement.SPEED, this.getMaxSpeed((MovementTrigger) trigger)); + Bukkit.getPluginManager().callEvent(event); + if(event.isCancelled()) return vL; + + data.setDetectedHack(CheatType.Movement.SPEED); + data.setDetectedHackAttribute("Z"); + data.setDetectedHackBanMessage("SPEED_Z"); + data.lastSeverity = Severity.MEDIUM; + return vL; + } + } + + } + } + } + } + + return vL; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/check/movement/VelocityCheck.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/check/movement/VelocityCheck.java new file mode 100644 index 0000000..df1ab70 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/check/movement/VelocityCheck.java @@ -0,0 +1,147 @@ +package net.grandtheftmc.core.anticheat.check.movement; + +import net.grandtheftmc.core.anticheat.Severity; +import net.grandtheftmc.core.anticheat.check.CheatType; +import net.grandtheftmc.core.anticheat.check.Check; +import net.grandtheftmc.core.anticheat.data.ClientData; +import net.grandtheftmc.core.anticheat.event.MovementCheatEvent; +import net.grandtheftmc.core.anticheat.trigger.MovementTrigger; +import net.grandtheftmc.core.anticheat.trigger.Trigger; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +public class VelocityCheck extends Check { + + public VelocityCheck() { + super("Velocity"); + } + + @Override + public double analyse(Trigger trigger) { + double vL = 0; + + if (trigger instanceof MovementTrigger) { + MovementTrigger mTrigger = (MovementTrigger) trigger; + + if (!mTrigger.isFlying()) { + ClientData data = trigger.getData(); + + double dif = Math.abs(mTrigger.getyV() - mTrigger.getyD()); + if (dif > 0.8) { + + if (!data.getPlayer().getAllowFlight()) { + if (Math.abs(data.timeSinceLastTeleport - System.currentTimeMillis()) > 2000) { + //Lagging players + jump boost == false positives... + boolean jumpBoost = false; + for (PotionEffect potionEffect : trigger.getData().getPlayer().getActivePotionEffects()) { + if (potionEffect.getType().equals(PotionEffectType.JUMP)) { + jumpBoost = true; + } + } + + //TODO: Recreate the check to NOT false positive, but still have lag compensation + if (!jumpBoost) { + //If the player should be falling, and the player isn't going down, flag them after a while + if (mTrigger.getyD() == 0.0D) { + data.hovertime += 1; + } else { + if (data.hovertime >= 0) {//TODO > + data.hovertime -= 1; + } + } + + if (data.hovertime > 15) { + data.hovertime = 5; + vL += 3; + + data.setDetectedHack(CheatType.Movement.FLIGHT); + data.setDetectedHackAttribute("Hover"); + data.lastSeverity = Severity.LOW; + return vL; + } + + + if (mTrigger.getyD() > 0) { + data.vBuffer += 1; + + if (mTrigger.getyD() > 0.8) { + data.vBuffer += 3; + } + + //Stairs seem to not register with bukkit very well; exempt them if they're around stairs by 0.5 blocks + boolean check = true; + for (double xC = -0.5; xC < 0.5; xC += 0.1) { + for (double zC = -0.5; zC < 0.5; zC += 0.1) { + String block = data.getPlayer().getLocation().clone().add(xC, -1, zC).getBlock().getType().name(); + + if (block.contains("STAIR") || block.contains("STEP")) { + check = false; + data.hovertime = 0; + data.vBuffer = 0; + } + } + } + + if (check) { + if (data.vBuffer > 5) { + data.vBuffer = 5; + vL += 6; + + Block block = data.getPlayer().getLocation().clone().add(0, -0.5, 0).getBlock(); + if (block.getType() == Material.STATIONARY_LAVA + || block.getType() == Material.LAVA + || block.getType() == Material.STATIONARY_WATER + || block.getType() == Material.WATER) { + MovementCheatEvent event = new MovementCheatEvent(data, CheatType.Movement.JESUS); + Bukkit.getPluginManager().callEvent(event); + if(event.isCancelled()) return vL; + + data.setDetectedHack(CheatType.Movement.JESUS); + data.setDetectedHackBanMessage("WATER_WALK"); + data.setDetectedHackAttribute("*"); + data.lastSeverity = Severity.MEDIUM; + return vL; + } else { + if (mTrigger.isOnground()) { + MovementCheatEvent event = new MovementCheatEvent(data, CheatType.Movement.FLIGHT); + Bukkit.getPluginManager().callEvent(event); + if(event.isCancelled()) return vL; + + data.setDetectedHack(CheatType.Movement.FLIGHT); + data.setDetectedHackBanMessage("FLY_STEP"); + data.setDetectedHackAttribute("*"); + data.lastSeverity = Severity.MEDIUM; + return vL; + } else { + MovementCheatEvent event = new MovementCheatEvent(data, CheatType.Movement.FLIGHT); + Bukkit.getPluginManager().callEvent(event); + if(event.isCancelled()) return vL; + + data.setDetectedHack(CheatType.Movement.FLIGHT); + data.setDetectedHackBanMessage("FLY"); + data.setDetectedHackAttribute("*"); + data.lastSeverity = Severity.MEDIUM; + return vL; + } + } + } + } + } + } + } + } + } else { + if (data.vBuffer > 0) { + data.vBuffer -= 1; + } + } + } + } + + return vL; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/component/AnticheatComponent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/component/AnticheatComponent.java new file mode 100644 index 0000000..05f8a94 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/component/AnticheatComponent.java @@ -0,0 +1,76 @@ +package net.grandtheftmc.core.anticheat.component; + +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerMoveEvent; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.anticheat.Anticheat; +import net.grandtheftmc.core.anticheat.data.ClientData; +import net.grandtheftmc.core.anticheat.trigger.MovementTrigger; +import net.grandtheftmc.core.util.Component; +import net.grandtheftmc.core.util.ServerUtil; + +public class AnticheatComponent implements Component { + + private final Anticheat anticheat; + + public AnticheatComponent(Core core, Anticheat anticheat) { + this.anticheat = anticheat; + Bukkit.getPluginManager().registerEvents(this, core); + } + + @EventHandler(ignoreCancelled = true) + protected final void onPlayerMove(PlayerMoveEvent event) { + if(event.getPlayer().getGameMode() == GameMode.CREATIVE || event.getPlayer().getGameMode() == GameMode.SPECTATOR) return; + if (event.getFrom().getX() == event.getTo().getX() && event.getFrom().getZ() == event.getTo().getZ() && event.getFrom().getY() == event.getTo().getY()) return; + + ClientData data = anticheat.getClientHandler().getClientData(event.getPlayer()); + if (data == null) return; + + ServerUtil.runTaskAsync(() -> { + + // due another check just in case it takes too long to run + if (data != null){ + MovementTrigger trigger = new MovementTrigger(data, event.getFrom(), event.getTo(), false); + data.addToEventQueue(trigger); + data.readQueue(); + } + }); + } + + @EventHandler + protected final void onPlayerJoin(PlayerJoinEvent event) { +// Anticheat.getInstance().getClientHandler().addClientData(event.getPlayer()); + } + +// @EventHandler +// protected final void onUse(PlayerInteractEvent event) { +// if(event.getAction() == Action.RIGHT_CLICK_AIR) { +// ClientData data = Anticheat.getInstance().getClientHandler().getClientData(event.getPlayer()); +// CombatTrigger trigger = new CombatTrigger(data, null, CombatTrigger.FightAction.RIGHT_CLICK); +// data.addToEventQueue(trigger); +// data.readQueue(); +// } +// +// else if(event.getAction() == Action.LEFT_CLICK_AIR) { +// ClientData data = Anticheat.getInstance().getClientHandler().getClientData(event.getPlayer()); +// CombatTrigger trigger = new CombatTrigger(data, null, CombatTrigger.FightAction.LEFT_CLICK); +// data.addToEventQueue(trigger); +// data.readQueue(); +// } +// } +// +// @EventHandler +// protected final void onHit(EntityDamageByEntityEvent e) { +// if (!(e.getDamager() instanceof Player)) return; +// +// ClientData playerData = Anticheat.getInstance().getClientHandler().getClientData((Player) e.getDamager()); +// ClientData targetData = e.getEntity() instanceof Player ? Anticheat.getInstance().getClientHandler().getClientData((Player) e.getEntity()) : null; +// CombatTrigger trigger = new CombatTrigger(playerData, targetData, CombatTrigger.FightAction.BUKKIT_HIT); +// playerData.addToEventQueue(trigger); +// playerData.readQueue(); +// } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/data/ClientData.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/data/ClientData.java new file mode 100644 index 0000000..d0cc720 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/data/ClientData.java @@ -0,0 +1,387 @@ +package net.grandtheftmc.core.anticheat.data; + +import com.google.common.collect.Maps; +import net.grandtheftmc.core.anticheat.Anticheat; +import net.grandtheftmc.core.anticheat.Severity; +import net.grandtheftmc.core.anticheat.check.CheatType; +import net.grandtheftmc.core.anticheat.trigger.MovementTrigger; +import net.grandtheftmc.core.anticheat.trigger.Trigger; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer; +import org.bukkit.entity.Player; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class ClientData { + + public Map queuedEvents = new ConcurrentHashMap<>(); + public HashMap countEvent = Maps.newHashMap(); + + private CheatType detectedHack = null; + private String detectedHackAttribute; + private String detectedHackBanMessage; + public Severity lastSeverity; + + + private int CPS; + private int Hits; + private int Misses; + private double lastReachDistance; + + public double vL; + public double autoBanVL; + + private final Player player; + private final Anticheat anticheat; + + public ClientData(Player player, Anticheat anticheat) { + this.player = player; + this.anticheat = anticheat; + } + + public Player getPlayer() { + return this.player; + } + + private double lastViolationTime; + public double lastAttackTime; + + public void readQueue() { + int maxChecks = 100; + + if (Math.abs(System.currentTimeMillis() - lastAttackTime) > 2000) { + this.Hits = 0; + this.Misses = 0; + } + + double newVL = 0.0D; + + + for (Trigger trigger : this.queuedEvents.keySet()) { + if (maxChecks < 0) break; + maxChecks -= 1; + +// if (trigger instanceof CombatTrigger) { +// if (((CombatTrigger) trigger).getAction().equals(CombatTrigger.FightAction.HIT)) { +// this.lastAttackTime = trigger.getTimeCreated(); +// this.Hits += 1; +// if (this.Misses > 0) { +// this.Misses -= 1; +// } +// } +// +// if (((CombatTrigger) trigger).getAction().equals(CombatTrigger.FightAction.SWING)) { +// this.Misses += 1; +// } +// } + + double vL = this.anticheat.getCheckManager().check(trigger); + if (vL > 0) newVL += vL; + + this.queuedEvents.remove(trigger); + } + + if (newVL == 0.0D) { + if (Math.abs(lastViolationTime - System.currentTimeMillis()) > 1500) + this.vL *= 0.99D; + + if (Math.abs(lastViolationTime - System.currentTimeMillis()) > 2500) + this.autoBanVL *= 0.8D; + } else { + lastViolationTime = System.currentTimeMillis(); + this.vL += newVL; + } + + double maxVL = 20;/*Aeron.getAPI().getConfig().getDoubleValue("core.MaxVL");*/ + if (this.vL > maxVL) { + this.anticheat.getClientHandler().notifyCheck(this); + this.vL = maxVL / 2; + } + +// double maxAutoBanVL = Aeron.getAPI().getConfig().getDoubleValue("AutoBan.MaxVL"); +// if (this.autoBanVL > maxAutoBanVL) { +// this.autoBanVL = 0; +// if (Aeron.getAPI().getConfig().getBooleanValue("AutoBan.Enabled")) { +// if (!autoBanning) { +// int delay = Aeron.getAPI().getConfig().getIntegerValue("AutoBan.Delay"); +// this.autoBanTime = System.currentTimeMillis() + (delay * 1000); +// this.autoBanning = true; +// api.getPlayerDataHandler().notifyAutoBan(this); +// } +// } else { +// api.getPlayerDataHandler().notifyAdminsCustom(this.getPlayer().getName() + " would have been auto-banned."); +// } +// } + } + + public double autoBanTime = -1; + public boolean autoBanning; + + public void addToEventQueue(Trigger trigger) { + if (trigger instanceof MovementTrigger) { + MovementTrigger mTrigger = (MovementTrigger) trigger; + + this.addEvent(mTrigger); + +// if(!mTrigger.isFlying()) { +// if(this.autoBanning) { +// if(System.currentTimeMillis() > this.autoBanTime) { +// if(this.autoBanTime != -1) { +// String banReason = Aeron.getAPI().getConfig().getStringValue("AutoBan.BanMessage").replace("&", "�").replace("%reason%", this.getDetectedHackBanMessage()); +// Timestamp curTime = new Timestamp(new Date().getTime()); +// Aeron.getAPI().getPlayerDataHandler().notifyAdminsCustom("�8[�l�cSloth�8] �c" + this.getPlayer().getName() + " �6has been banned."); +// Aeron.getAPI().getLogger().log("autobans.log", curTime + ": " + this.getPlayer().getName() + " should have been automatically banned. (" + this.getDetectedHackBanMessage() + ")", true); +// Aeron.getAPI().getPlugin().getServer().dispatchCommand(Aeron.getAPI().getPlugin().getServer().getConsoleSender(), "ban " + this.getPlayer().getName() + " " + banReason); +// autoBanning = false; +// this.autoBanTime = -1; +// } +// } +// } +// } + } + this.queuedEvents.put(trigger, false); + } + + private MovementTrigger[] recording = new MovementTrigger[30]; + + public double lastSwingTime; + public double lastEnderpearlTime; + private ClientData lastTarget; + public double timeSinceLastTeleport; + public double lastRightClickTime; + public int clicks; + public int cpsPackets; + public double reachBuffer; + public float aimbotLastCamera; + public float aimbotBuffer; + public int aimbotHits; + public Location aimbotPreviousTargetLocation; + public int aimbotVL; + public double swingBuffer; + public double swingLastCamera; + public double noSwingLastSwingTime; + public int aimbotDetections; + public int swingVL; + public double aimbotDelta; + public double xSpeed; + public double zSpeed; + public double lastX, lastY, lastZ; + public World lastWorld; + public float lastYaw; + public float lastPitch; + public double improbableLastBukkitHitTime; + public double improbableLastDifference; + public double improbableLastFullDifference; + public int jumpTicks; + public boolean justJumped; + public double xBefore; + public double zBefore; + public double xCurrent; + public double zCurrent; + public double sLastPacketTime; + public double maxDistanceBufferX; + public double maxDistanceBufferZ; + public int sBuffer; + public int hovertime; + public int vBuffer; + + public double lastDifficulty; + + public boolean difficultyChanged; + + public int morepacketsPackets; + + public double lastPacketTime; + + public double mpDelay; + + + public void addEvent(MovementTrigger e) { + if (!e.isFlying()) { + boolean needsShifted = true; + for (int i = 0; i < recording.length; i++) { + if (recording[i] == null) { + recording[i] = e; + needsShifted = false; + break; + } + } + + if (needsShifted) { + for (int i = 0; i < recording.length; i++) { + if (i != recording.length - 1) { + recording[i] = recording[i + 1]; + } else { + recording[i] = e; + } + } + } + } + } + + public int getPing() { + return ((CraftPlayer) this.getPlayer().getPlayer()).getHandle().ping; + } + + public Map getQueuedEvents() { + return queuedEvents; + } + + public void setQueuedEvents(Map queuedEvents) { + this.queuedEvents = queuedEvents; + } + + public CheatType getDetectedHack() { + return detectedHack; + } + + public void setDetectedHack(CheatType detectedHack) { + if (this.detectedHack != null && detectedHack.getName().equalsIgnoreCase(this.detectedHack.getName())) return; + this.detectedHack = detectedHack; + addCount(detectedHack); + } + + public void resetDetection() { + this.detectedHack = null; + } + + public String getDetectedHackAttribute() { + return detectedHackAttribute; + } + + public void setDetectedHackAttribute(String detectedHackAttribute) { + this.detectedHackAttribute = detectedHackAttribute; + } + + public String getDetectedHackBanMessage() { + return detectedHackBanMessage; + } + + public void setDetectedHackBanMessage(String detectedHackBanMessage) { + this.detectedHackBanMessage = detectedHackBanMessage; + } + + public Severity getLastSeverity() { + return lastSeverity; + } + + public void setLastSeverity(Severity lastSeverity) { + this.lastSeverity = lastSeverity; + } + + public double getvL() { + return vL; + } + + public void setvL(double vL) { + this.vL = vL; + } + + public double getAutoBanVL() { + return autoBanVL; + } + + public void setAutoBanVL(double autoBanVL) { + this.autoBanVL = autoBanVL; + } + + public MovementTrigger[] getRecording() { + return recording; + } + + public void setRecording(MovementTrigger[] recording) { + this.recording = recording; + } + + public int getCPS() { + return CPS; + } + + public void setCPS(int cPS) { + CPS = cPS; + } + + public int getHits() { + return Hits; + } + + public void setHits(int hits) { + Hits = hits; + } + + public int getMisses() { + return Misses; + } + + public void setMisses(int misses) { + Misses = misses; + } + + public double getLastReachDistance() { + return lastReachDistance; + } + + public void setLastReachDistance(double lastReachDistance) { + this.lastReachDistance = lastReachDistance; + } + + public void setLastTarget(ClientData target) { + this.lastTarget = target; + } + + public double getLastSwingTime() { + return lastSwingTime; + } + + public void setLastSwingTime(double lastSwingTime) { + this.lastSwingTime = lastSwingTime; + } + + public double getLastEnderpearlTime() { + return lastEnderpearlTime; + } + + public void setLastEnderpearlTime(double lastEnderpearlTime) { + this.lastEnderpearlTime = lastEnderpearlTime; + } + + public ClientData getLastTarget() { + return lastTarget; + } + + public double getAutoBanTime() { + return autoBanTime; + } + + public void setAutoBanTime(double autoBanTime) { + this.autoBanTime = autoBanTime; + } + + public boolean isAutoBanning() { + return autoBanning; + } + + public void setAutoBanning(boolean autoBanning) { + this.autoBanning = autoBanning; + } + + public double getTimeSinceLastTeleport() { + return timeSinceLastTeleport; + } + + public void setTimeSinceLastTeleport(double timeSinceLastTeleport) { + this.timeSinceLastTeleport = timeSinceLastTeleport; + } + + private void addCount(CheatType key) { + countEvent.putIfAbsent(key.getType(), 0); + countEvent.put(key.getType(), countEvent.get(key.getType()) + 1); + } + + public int getCount(CheatType key) { + return countEvent.getOrDefault(key.getType(), 1); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/data/ClientHandler.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/data/ClientHandler.java new file mode 100644 index 0000000..08f8fd3 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/data/ClientHandler.java @@ -0,0 +1,91 @@ +package net.grandtheftmc.core.anticheat.data; + +import java.util.HashMap; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import com.google.common.collect.Maps; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.anticheat.Anticheat; +import net.grandtheftmc.core.anticheat.check.CheatType; +import net.grandtheftmc.core.anticheat.report.ReportManager; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserManager; +import net.grandtheftmc.core.util.ServerUtil; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.TextComponent; + +public class ClientHandler { + + private final HashMap players = Maps.newHashMap(); + + public HashMap getPlayers() { + return this.players; + } + private final Anticheat anticheat; + private final ReportManager reportManager; + + public ClientHandler(Anticheat anticheat, ReportManager reportManager) { + this.anticheat = anticheat; + this.reportManager = reportManager; + } + + public ClientData addClientData(Player player) { + players.putIfAbsent(player.getUniqueId(), new ClientData(player, this.anticheat)); + return players.get(player.getUniqueId()); + } + + public ClientData getClientData(Player player) { + return players.getOrDefault(player.getUniqueId(), null); + } + + public void removeClientData(UUID uuid) { + this.players.remove(uuid); + } + + /** + * Notify staff when a client is hacking. + * + * @param client + */ + public void notifyCheck(ClientData client) { + CheatType cheatType = client.getDetectedHack(); + int count = client.getCount(cheatType); + double cps = client.getCPS(); + int hits = client.getHits(); + int misses = client.getMisses(); + double lrd = client.getLastReachDistance(); + int lag = client.getPing(); + int reports = this.reportManager.getReports(client.getPlayer()); + Player player = client.getPlayer(); + +// DecimalFormat f = new DecimalFormat("##.00"); +// lrd = Double.parseDouble(f.format(lrd)); + + BaseComponent[] components = TextComponent.fromLegacyText(Lang.ANTICHEAT.s() + Utils.f("&c" + player.getName() + "&7 has triggered &c" + cheatType.getName().toUpperCase() + "&7 event! &fx&l" + count + "&7")); + for (BaseComponent c : components) { + c.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText(Utils.f("&7Reports&f: &c&l" + reports + "\n&7Ping&f: &a&l" + lag + "\n\n" + "&7&oClick to inspect")))); + c.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/inspect " + player.getName())); + } + + ServerUtil.runTask(() -> { + if(count % 10 == 0) { + for (User user : UserManager.getInstance().getUsers()) { + if (!user.isStaff()){ + continue; + } + + Bukkit.getPlayer(user.getUUID()).spigot().sendMessage(components); + } + } + + client.resetDetection(); + }); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/event/CombatCheatEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/event/CombatCheatEvent.java new file mode 100644 index 0000000..6b2ae71 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/event/CombatCheatEvent.java @@ -0,0 +1,4 @@ +package net.grandtheftmc.core.anticheat.event; + +public class CombatCheatEvent { +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/event/MovementCheatEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/event/MovementCheatEvent.java new file mode 100644 index 0000000..6c0622f --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/event/MovementCheatEvent.java @@ -0,0 +1,53 @@ +package net.grandtheftmc.core.anticheat.event; + +import net.grandtheftmc.core.anticheat.check.CheatType; +import net.grandtheftmc.core.anticheat.data.ClientData; +import net.grandtheftmc.core.events.CoreEvent; +import org.bukkit.event.Cancellable; + +public final class MovementCheatEvent extends CoreEvent implements Cancellable { + + private final ClientData playerData; + private final CheatType cheatType; + private T obj; + private boolean cancelled; + + /** + * Construct a new Event + */ + public MovementCheatEvent(ClientData playerData, CheatType cheatType) { + super(true); + this.playerData = playerData; + this.cheatType = cheatType; + } + + /** + * Construct a new Event + */ + public MovementCheatEvent(ClientData playerData, CheatType cheatType, T obj) { + this(playerData, cheatType); + this.obj = obj; + } + + public ClientData getPlayerData() { + return this.playerData; + } + + public CheatType getCheatType() { + return this.cheatType; + } + + public T getObj() { + return this.obj; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + @Override + public void setCancelled(boolean b) { + this.cancelled = b; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/inspect/InspectCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/inspect/InspectCommand.java new file mode 100644 index 0000000..8a648a0 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/inspect/InspectCommand.java @@ -0,0 +1,34 @@ +package net.grandtheftmc.core.anticheat.inspect; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.commands.CoreCommand; +import net.grandtheftmc.core.users.User; +import org.bukkit.entity.Player; + +public class InspectCommand extends CoreCommand { + + /** + * Construct a new command. + */ + public InspectCommand() { + super("inspect", "Inspect a hacker."); + } + + /** + * This method is fired when the command is executed. + * + * @param sender sender type of the command + * @param args command arguments + */ + @Override + public void execute(Player sender, String[] args) { + User user = Core.getUserManager().getLoadedUser(sender.getUniqueId()); + if(!user.isStaff()) { + sender.sendMessage(Lang.NOPERM.s()); + return; + } + sender.performCommand("gm3staff true"); + sender.performCommand("tp " + args[0]); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/report/ReportCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/report/ReportCommand.java new file mode 100644 index 0000000..f6b2e2c --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/report/ReportCommand.java @@ -0,0 +1,62 @@ +package net.grandtheftmc.core.anticheat.report; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.commands.CoreCommand; +import net.grandtheftmc.core.users.User; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +public class ReportCommand extends CoreCommand { + + private final ReportManager reportManager; + + /** + * Construct a new command. + */ + public ReportCommand(ReportManager reportManager) { + super("report", "Report a player if you think they're hacking."); + this.reportManager = reportManager; + } + + /** + * This method is fired when the command is executed. + * + * @param sender sender type of the command + * @param args command arguments + */ + @Override + public void execute(Player sender, String[] args) { + if(sender == null) return; + + if(args.length < 2) { + sender.sendMessage(Lang.ANTICHEAT.f("&cIncorrect arguments!")); + sender.sendMessage(Lang.ANTICHEAT.f("&7Usage: /report <&fplayer&7> <&freason&7>")); + return; + } + + Player victim = Bukkit.getPlayer(args[0]); + if (victim == null) { + sender.sendMessage(Lang.ANTICHEAT.f("&cPlayer cannot be found.")); + return; + } + + User user = Core.getUserManager().getLoadedUser(victim.getUniqueId()); + if(user == null) { + sender.sendMessage(Lang.ANTICHEAT.f("&cPlayer cannot be found.")); + return; + } + + if(user.isStaff()) { + sender.sendMessage(Lang.ANTICHEAT.f("&cYou cannot report staff members.")); + return; + } + + StringBuilder reason = new StringBuilder(""); + for(int i = 1; i < args.length; i++) + reason.append(args[i]).append(" "); + reason.setLength(reason.length() - 1); + + reportManager.report(sender, victim, reason.toString()); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/report/ReportDAO.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/report/ReportDAO.java new file mode 100644 index 0000000..f022e3c --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/report/ReportDAO.java @@ -0,0 +1,112 @@ +package net.grandtheftmc.core.anticheat.report; + +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.servers.ServerType; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.Optional; +import java.util.UUID; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ReportDAO { + + /** + * A {@link Pattern} used to identify and/or split full UUIDs + */ + public static final Pattern PATTERN_UUID = Pattern.compile("^[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}$", Pattern.CASE_INSENSITIVE); + /** + * A {@link Pattern} used to identify and/or split trimmed UUIDs + */ + public static final Pattern PATTERN_TRIMMED_UUID = Pattern.compile("^([a-z0-9]{8})([a-z0-9]{4})([a-z0-9]{4})([a-z0-9]{4})([a-z0-9]{12})$", Pattern.CASE_INSENSITIVE); + + + public static void createLogTable() { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("CREATE TABLE IF NOT EXIST `report_logs`(" + + "`reporter` BINARY(16) NOT NULL," + + "`reporterName` BINARY(16) NOT NULL," + + "`timeReported` BIGINT NOT NULL," + + "`reason` VARCHAR(32) NOT NULL," + + "`victim` BINARY(16) NOT NULL," + + "`victimName` BINARY(16) NOT NULL," + + "`serverType` VARCHAR(10) NOT NULL," + + "`serverId` INT NOT NULL," + + "INDEX(`reporterName`,`victim`,`victimName`,`serverType`,`serverId`)" + + ");")) { + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + } + } + + public static void insertReport(UUID reporterUniqueId, UUID victimUniqueId, String reporterName, String victimName, String reason, long timeReported, ServerType serverType, int serverId) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO `report_logs`(" + + "`reporter`,`reporterName`,`timeReported`,`reason`,`victim`,`victimName`,`serverType`,`serverId`) VALUES(?,?,?,?,?,?,?,?);")) { + statement.setString(1, reporterUniqueId.toString().replaceAll("-", "")); + statement.setString(2, reporterName); + statement.setLong(3, timeReported); + statement.setString(4, reason); + statement.setString(5, victimUniqueId.toString().replaceAll("-", "")); + statement.setString(6, victimName); + statement.setString(6, serverType.name()); + statement.setInt(6, serverId); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + } + } + + /** + * Create a UUID safely from a {@link String}. + * + * @param string The {@link String} to deserialize into an {@link UUID} object. + * @return {@link Optional#empty()} if the provided {@link String} is illegal, otherwise an {@link Optional} + * containing the deserialized {@link UUID} object. + */ + private Optional createUUID(String string) { + if (string == null) { + return Optional.empty(); + } + + UUID result = null; + + try { + // Is it a valid UUID? + if (!PATTERN_UUID.matcher(string).matches()) { + // Un-trim UUID if it is trimmed + Matcher matcher = PATTERN_TRIMMED_UUID.matcher(string); + if (matcher.matches()) { + StringBuilder sb = new StringBuilder(); + + for (int i = 1; i <= matcher.groupCount(); i++) { + if (i != 1) { + sb.append("-"); + } + + sb.append(matcher.group(i)); + } + + string = sb.toString(); + } else { + // Invalid UUID + string = null; + } + } + + if (string != null) { + result = UUID.fromString(string); + } + } catch (IllegalArgumentException ignored) { + // Useless data passed + } + + return Optional.ofNullable(result); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/report/ReportManager.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/report/ReportManager.java new file mode 100644 index 0000000..353eee4 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/report/ReportManager.java @@ -0,0 +1,141 @@ +package net.grandtheftmc.core.anticheat.report; + +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerQuitEvent; + +import com.google.common.base.Preconditions; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.anticheat.Anticheat; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserManager; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.Component; + +public class ReportManager implements Component { + +// public final HashMap cache = Maps.newHashMap(); +// +// public PlayerReportData getPlayerReportData(UUID uniqueId) { +// if(!cache.containsKey(uniqueId)) { +// PlayerReportData playerReportData = new PlayerReportData(uniqueId); +// cache.put(uniqueId, playerReportData); +// } +// return null; +// } + + private static final long counter; + private static final long reportCooldown, watchTime; + private static final ConcurrentHashMap storedData; + + static { + counter = 20*60; + reportCooldown = 1000 * 60 * 5; + watchTime = 1000 * 60 * 5; + storedData = new ConcurrentHashMap<>(); + } + + private Anticheat anticheat; + + public ReportManager(Core core, Anticheat anticheat) { + this.anticheat = anticheat; + Bukkit.getPluginManager().registerEvents(this, core); + new ReportCommand(this); + + Bukkit.getScheduler().runTaskTimerAsynchronously(Core.getInstance(), () -> { + for(UUID uuid : storedData.keySet()) { + Data data = storedData.get(uuid); + if(data.timeReported != -1 && System.currentTimeMillis() - data.timeReported >= watchTime) { + data.timeReported = -1; + anticheat.getClientHandler().removeClientData(uuid); + System.out.println("Removed " + uuid.toString()); + } + } + }, counter, counter); + } + + public int getReports(Player player) { + Preconditions.checkNotNull(player); + if(!storedData.containsKey(player.getUniqueId())) return 0; + return storedData.get(player.getUniqueId()).reports; + } + + public void report(Player player, Player target, String reason) { + Preconditions.checkNotNull(player); + Preconditions.checkNotNull(target); + + storedData.computeIfAbsent(player.getUniqueId(), k -> new Data()); + storedData.computeIfAbsent(target.getUniqueId(), k -> new Data()); + + Data pd = storedData.getOrDefault(player.getUniqueId(), null); + Preconditions.checkNotNull(pd); + if (pd.lastReport > -1 && System.currentTimeMillis() - pd.lastReport < reportCooldown) { + long difference = 300 - ((System.currentTimeMillis() - pd.lastReport) / 1000); + player.sendMessage(Lang.ANTICHEAT.f("&cPlease wait " + Utils.timeInSecondsToText(difference, C.DARK_RED, C.RED, C.WHITE) + " &cto report again.")); + return; + } + pd.lastReport = System.currentTimeMillis(); + player.sendMessage(Lang.ANTICHEAT.f("Reported " + target.getName() + " for '" + reason + "'")); + player.sendMessage(Lang.ANTICHEAT.f("Note that false reporting is punishable.")); + + Data td = storedData.getOrDefault(target.getUniqueId(), null); + Preconditions.checkNotNull(td); + td.timeReported = System.currentTimeMillis(); + td.reports += 1; + + anticheat.getClientHandler().addClientData(target); + + for (User user : UserManager.getInstance().getUsers()) { + if (!user.isStaff()){ + continue; + } + Bukkit.getPlayer(user.getUUID()).sendMessage(Lang.ANTICHEAT.f("&c" + target.getName() + "&7 has been reported by &c" + player.getName() + "&7 for '&f" + reason + "&7'")); + } + } + + public class Data { + private long lastReport = -1, timeReported = -1; + private int reports = 0; + + public long getLastReport() { + return lastReport; + } + + public long getTimeReported() { + return timeReported; + } + + public int getReports() { + return reports; + } + + public void setLastReport(long lastReport) { + this.lastReport = lastReport; + } + + public void setTimeReported(long timeReported) { + this.timeReported = timeReported; + } + + public void addReports(int value) { + this.reports += value; + } + + @Override + public String toString() { + return "ReportManager.Data [ {lastReport:" + lastReport + "}, {timeReported:" + timeReported + "}, {reports:" + reports + "} ];"; + } + } + + @EventHandler + protected final void onPlayerQuit(PlayerQuitEvent event) { + storedData.remove(event.getPlayer().getUniqueId()); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/report/data/PlayerReportData.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/report/data/PlayerReportData.java new file mode 100644 index 0000000..19edd73 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/report/data/PlayerReportData.java @@ -0,0 +1,40 @@ +package net.grandtheftmc.core.anticheat.report.data; + +import com.google.common.collect.Lists; + +import java.util.List; +import java.util.UUID; + +public final class PlayerReportData { + + private final List reports; + + private UUID uniqueId; + private long lastReport = -1; + + public PlayerReportData(UUID uniqueId) { + this.uniqueId = uniqueId; + this.reports = Lists.newArrayList(); + } + + public List getReports() { + return reports; + } + + public void addReport(ReportData reportData) { + reports.add(reportData); + lastReport = System.currentTimeMillis(); + } + + public boolean canReport() { + return (System.currentTimeMillis() - lastReport) > (1000 * 60 * 5); + } + + public long getIssuedReports() { + return reports.stream().filter(r -> !r.isPersonal(uniqueId)).count(); + } + + public long getPersonalReports() { + return reports.stream().filter(r -> r.isPersonal(uniqueId)).count(); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/report/data/ReportData.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/report/data/ReportData.java new file mode 100644 index 0000000..7e2b2fc --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/report/data/ReportData.java @@ -0,0 +1,61 @@ +package net.grandtheftmc.core.anticheat.report.data; + +import net.grandtheftmc.core.servers.ServerType; + +import java.util.UUID; + +public final class ReportData { + + private final UUID reporterUniqueId, victimUniqueId; + private final String reporterName, victimName, reason; + private final long timeReported; + private final ServerType serverType; + private final int serverId; + + public ReportData(UUID reporterUniqueId, UUID victimUniqueId, String reporterName, String victimName, String reason, long timeReported, ServerType serverType, int serverId) { + this.reporterUniqueId = reporterUniqueId; + this.victimUniqueId = victimUniqueId; + this.reporterName = reporterName; + this.victimName = victimName; + this.reason = reason; + this.timeReported = timeReported; + this.serverType = serverType; + this.serverId = serverId; + } + + public boolean isPersonal(UUID uuid) { + return this.victimUniqueId.equals(uuid); + } + + public UUID getReporterUniqueId() { + return reporterUniqueId; + } + + public UUID getVictimUniqueId() { + return victimUniqueId; + } + + public String getReporterName() { + return reporterName; + } + + public String getVictimName() { + return victimName; + } + + public String getReason() { + return reason; + } + + public long getTimeReported() { + return timeReported; + } + + public ServerType getServerType() { + return serverType; + } + + public int getServerId() { + return serverId; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/trigger/MovementTrigger.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/trigger/MovementTrigger.java new file mode 100644 index 0000000..437ac26 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/trigger/MovementTrigger.java @@ -0,0 +1,93 @@ +package net.grandtheftmc.core.anticheat.trigger; + +import net.grandtheftmc.core.anticheat.data.ClientData; +import org.bukkit.Location; + +public class MovementTrigger extends Trigger { + + private boolean flying; + private Location from, to; + + /** Distance */ + private double xD, yD, zD; + + /** Velocity */ + private double xV, yV, zV; + + private boolean sprinting, sneaking, onground; + + /** + * Construct new Trigger. + */ + public MovementTrigger(ClientData data, Location from, Location to, boolean flying) { + super(data, System.currentTimeMillis()); + + this.flying = flying; + if (!flying) { + this.from = from; + this.to = to; + + this.xD = to.getX() - from.getX(); + this.yD = to.getY() - from.getY(); + this.zD = to.getZ() - from.getZ(); + + data.xSpeed = xD; + data.zSpeed = zD; + + data.lastX = to.getX(); + data.lastY = to.getY(); + data.lastZ = to.getZ(); + data.lastWorld = to.getWorld(); + data.lastYaw = to.getYaw(); + data.lastPitch = to.getPitch(); + + this.xV = data.getPlayer().getVelocity().getX(); + this.yV = data.getPlayer().getVelocity().getY(); + this.zV = data.getPlayer().getVelocity().getZ(); + + this.sprinting = data.getPlayer().isSprinting(); + this.sneaking = data.getPlayer().isSneaking(); + this.onground = data.getPlayer().isOnGround(); + } + } + + public boolean isSneaking() { + return sneaking; + } + + public boolean isFlying() { + return flying; + } + + public boolean isOnground() { + return onground; + } + + public Location getTo() { + return to; + } + + public double getxD() { + return xD; + } + + public double getyD() { + return yD; + } + + public double getzD() { + return zD; + } + + public double getxV() { + return xV; + } + + public double getyV() { + return yV; + } + + public double getzV() { + return zV; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/trigger/Trigger.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/trigger/Trigger.java new file mode 100644 index 0000000..fa02f69 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/trigger/Trigger.java @@ -0,0 +1,25 @@ +package net.grandtheftmc.core.anticheat.trigger; + +import net.grandtheftmc.core.anticheat.data.ClientData; + +public class Trigger { + + private ClientData data; + private double timeCreated; + + /** + * Construct new Trigger. + */ + public Trigger(ClientData data, double timeCreated) { + this.data = data; + this.timeCreated = timeCreated; + } + + public double getTimeCreated() { + return timeCreated; + } + + public ClientData getData() { + return data; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/util/DummyIdentity.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/util/DummyIdentity.java new file mode 100644 index 0000000..adfd19d --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/util/DummyIdentity.java @@ -0,0 +1,87 @@ +package net.grandtheftmc.core.anticheat.util; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; + +public class DummyIdentity { + + public UUID uuid; + public String name; + public EntityType type = EntityType.PLAYER; + + public boolean isAlreadyOnline; + public boolean visible; + + public static class Generator { + private static Random rnd = ThreadLocalRandom.current(); + + private static char[] chars = new char[]{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', + 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; + + public static String generateName() { + int length = 9 + rnd.nextInt(5); + return "§c" + getRandomString(length - 2); + } + + private static String getRandomString(int length) { + StringBuilder sb = new StringBuilder(length); + for (int i = 0; i < length; i += 1) { + sb.append(chars[rnd.nextInt(chars.length)]); + } + return sb.toString(); + } + + public static DummyIdentity generateRandomIdentity() { + DummyIdentity id = new DummyIdentity(); + + id.name = generateName(); + id.uuid = UUID.randomUUID(); + id.isAlreadyOnline = false; + id.type = EntityType.PLAYER; + + return id; + } + + public static DummyIdentity generateIdentityForPlayer(Player p) { + DummyIdentity id = new DummyIdentity(); + + if (Bukkit.getOnlinePlayers().size() == 1) + id = generateRandomIdentity(); + else { + List onlinePlayers = new ArrayList<>(Bukkit.getOnlinePlayers()); + onlinePlayers.remove(p); + + Player idPlayer = onlinePlayers.get(rnd.nextInt(onlinePlayers.size())); + + id.name = idPlayer.getName(); + id.uuid = idPlayer.getUniqueId(); + id.isAlreadyOnline = true; + } + + id.visible = true; + + return id; + } + + public static DummyIdentity generateIdentityForPlayer(Player p, Entity attacked) { + DummyIdentity id = generateRandomIdentity(); + if (attacked.getType() == EntityType.PLAYER) + id = generateIdentityForPlayer(p); + else { + id.type = attacked.getType(); + } + + return id; + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/util/DummyPacketGen.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/util/DummyPacketGen.java new file mode 100644 index 0000000..aeec46e --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/util/DummyPacketGen.java @@ -0,0 +1,119 @@ +package net.grandtheftmc.core.anticheat.util; + +import com.comphenix.protocol.wrappers.*; +import net.grandtheftmc.core.wrapper.packet.out.*; +import org.bukkit.Location; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +public class DummyPacketGen { + + public static WrapperPlayServerNamedEntitySpawn getIdentityPlayerSpawnPacket(DummyIdentity id, int entityId, Location loc) { + WrapperPlayServerNamedEntitySpawn spawnPacket = new WrapperPlayServerNamedEntitySpawn(); + + spawnPacket.setEntityID(entityId); + spawnPacket.setPlayerUUID(id.uuid); + + spawnPacket.setPosition(new Vector(loc.getX(), loc.getY(), loc.getZ())); + spawnPacket.setYaw(loc.getYaw()); + spawnPacket.setPitch(loc.getPitch()); + + WrappedDataWatcher meta = new WrappedDataWatcher(); + spawnPacket.setMetadata(meta); + + return spawnPacket; + } + + public static WrapperPlayServerSpawnEntityLiving getIdentityNotPlayerSpawnPacket(DummyIdentity id, int entityId, Location loc) { + WrapperPlayServerSpawnEntityLiving spawnPacket = new WrapperPlayServerSpawnEntityLiving(); + + spawnPacket.setEntityID(entityId); + spawnPacket.setUniqueId(id.uuid); + spawnPacket.setType(id.type); + + spawnPacket.setX(loc.getX()); + spawnPacket.setY(loc.getY()); + spawnPacket.setZ(loc.getZ()); + spawnPacket.setYaw(loc.getYaw()); + spawnPacket.setPitch(loc.getPitch()); + spawnPacket.setHeadPitch(loc.getPitch()); + + WrappedDataWatcher meta = new WrappedDataWatcher(); + //if(!id.visible) + // meta.setObject(0, (byte) 0x20); + spawnPacket.setMetadata(meta); + + return spawnPacket; + } + + public static void sendSpawnPacket(Player p, DummyIdentity id, int entityId, Location loc) { + if (id.type == EntityType.PLAYER) { + getIdentityPlayerSpawnPacket(id, entityId, loc).sendPacket(p); + } else { + getIdentityNotPlayerSpawnPacket(id, entityId, loc).sendPacket(p); + } + } + + public static WrapperPlayServerEntityTeleport getTeleportPacket(int entityId, Location loc) { + WrapperPlayServerEntityTeleport packet = new WrapperPlayServerEntityTeleport(); + packet.setEntityID(entityId); + packet.setX(loc.getX()); + packet.setY(loc.getY()); + packet.setZ(loc.getZ()); + packet.setPitch(loc.getPitch()); + packet.setYaw(loc.getYaw()); + + return packet; + } + + public static WrapperPlayServerRelEntityMoveLook getRelativeMovementPacket(int entityId, Vector movement) { + WrapperPlayServerRelEntityMoveLook packet = new WrapperPlayServerRelEntityMoveLook(); + packet.setEntityID(entityId); + packet.setDx(movement.getX()); + packet.setDy(movement.getY()); + packet.setDz(movement.getZ() * 32); + packet.setOnGround(true); + packet.setYaw(0); + packet.setPitch(0); + return packet; + } + + public static WrapperPlayServerPlayerInfo getInfoAddPacket(UUID playerUUID, String playerName) { + WrapperPlayServerPlayerInfo infoPacket = new WrapperPlayServerPlayerInfo(); + infoPacket.setAction(EnumWrappers.PlayerInfoAction.ADD_PLAYER); + + WrappedGameProfile profile = new WrappedGameProfile(playerUUID, playerName); + PlayerInfoData data = new PlayerInfoData(profile, 23, EnumWrappers.NativeGameMode.SURVIVAL, WrappedChatComponent.fromText(playerName)); + List dataList = new ArrayList<>(); + dataList.add(data); + + infoPacket.setData(dataList); + return infoPacket; + } + + public static WrapperPlayServerPlayerInfo getInfoRemovePacket(UUID playerUUID, String playerName) { + WrapperPlayServerPlayerInfo infoPacket = new WrapperPlayServerPlayerInfo(); + infoPacket.setAction(EnumWrappers.PlayerInfoAction.REMOVE_PLAYER); + + WrappedGameProfile profile = new WrappedGameProfile(playerUUID, playerName); + PlayerInfoData data = new PlayerInfoData(profile, 23, EnumWrappers.NativeGameMode.SURVIVAL, WrappedChatComponent.fromText(playerName)); + List dataList = new ArrayList<>(); + dataList.add(data); + + infoPacket.setData(dataList); + return infoPacket; + } + + public static WrapperPlayServerEntityDestroy getDestroyPacket(int entityId) { + WrapperPlayServerEntityDestroy destroyPacket = new WrapperPlayServerEntityDestroy(); + + destroyPacket.setEntityIds(new int[]{entityId}); + + return destroyPacket; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/util/DummyPlayer.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/util/DummyPlayer.java new file mode 100644 index 0000000..57a40af --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/anticheat/util/DummyPlayer.java @@ -0,0 +1,86 @@ +package net.grandtheftmc.core.anticheat.util; + +import com.google.common.collect.Maps; +import org.bukkit.Location; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; + +import java.util.Map; +import java.util.UUID; + +public class DummyPlayer { + + private int entityID; + private Map prevPlayerBotLocations; + + public DummyPlayer(int entityID) { + this.entityID = entityID; + prevPlayerBotLocations = Maps.newHashMap(); + } + + public void setEntityID(int entityID) { + this.entityID = entityID; + } + + public int getEntityID() { + return entityID; + } + + + public void spawnForPlayerWithIdentity(final Player p, final Location location, final DummyIdentity identity) { + if (!identity.isAlreadyOnline && identity.type == EntityType.PLAYER) + sendBotInfo(p, identity); + //DummyPacketGen.getIdentityPlayerSpawnPacket(identity, entityID, location).sendPacket(p); + DummyPacketGen.sendSpawnPacket(p, identity, entityID, location); + } + + public void sendBotInfo(Player p, DummyIdentity id) { + DummyPacketGen.getInfoAddPacket(id.uuid, id.name).sendPacket(p); + } + + public void destroyForPlayer(Player p) { + DummyPacketGen.getDestroyPacket(entityID).sendPacket(p); + } + + public void despawnTablistForPlayer(Player p, DummyIdentity identity) { + if (identity.type == EntityType.PLAYER) + DummyPacketGen.getInfoRemovePacket(identity.uuid, identity.name).sendPacket(p); + } + + public void moveTo(Player p, Location loc) { + UUID pUUID = p.getUniqueId(); + if (prevPlayerBotLocations.containsKey(pUUID)) { + Location prevLoc = prevPlayerBotLocations.get(pUUID); + + double deltaX = loc.getX() - prevLoc.getX(); + double deltaY = loc.getY() - prevLoc.getY(); + double deltaZ = loc.getZ() - prevLoc.getZ(); + double dist = deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ; + + if (dist > 4) + DummyPacketGen.getTeleportPacket(entityID, loc).sendPacket(p); + else + DummyPacketGen.getTeleportPacket(entityID, loc).sendPacket(p); + } else + DummyPacketGen.getTeleportPacket(entityID, loc).sendPacket(p); + + prevPlayerBotLocations.put(p.getUniqueId(), loc); + + } + + public void moveAround(Player p, double angle, double distance) { + moveTo(p, getAroundPos(p, angle, distance)); + } + + public static Location getAroundPos(Player p, double angle, double distance) { + Location loc = p.getLocation().clone(); + double realAngle = angle + 90; + + float deltaX = (float) (distance * Math.cos(Math.toRadians(loc.getYaw() + realAngle))); + float deltaZ = (float) (distance * Math.sin(Math.toRadians(loc.getYaw() + realAngle))); + + loc.add(deltaX, -0.1, deltaZ); + + return loc; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/boards/Board.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/boards/Board.java new file mode 100644 index 0000000..9fa678c --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/boards/Board.java @@ -0,0 +1,208 @@ +package net.grandtheftmc.core.boards; + +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import org.bukkit.entity.Player; +import org.bukkit.scoreboard.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class Board { + + private String name; + + private String header; + + private BoardType type; + + private List boardValues = new ArrayList<>(); + + private List list = new ArrayList<>(); + + private List scores = new ArrayList<>(); + + public Board(String name, String header, List values) { + this.name = name; + this.header = header; + this.boardValues = values; + this.type = BoardType.KEY_VALUE; + } + + public Board(String name, String header, String[] lines) { + this.name = name; + this.header = header; + this.list = Arrays.asList(lines); + this.type = BoardType.LIST; + } + + public Board(String name, List scores, String header) { + this.name = name; + this.header = header; + this.scores = scores; + this.type = BoardType.SCORES; + } + + public Board(String name, String header, BoardType type) { + this.name = name; + this.header = header; + this.type = type; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getHeader() { + return this.header; + } + + public void setHeader(String header) { + this.header = header; + } + + public BoardType getType() { + return this.type; + } + + public void setType(BoardType type) { + this.type = type; + } + + public List getBoardValues() { + return this.boardValues; + } + + public void setBoardValues(List boardValues) { + this.boardValues = boardValues; + } + + public List getList() { + return this.list; + } + + public void setList(List list) { + this.list = list; + } + + public List getScores() { + return this.scores; + } + + public void setScores(List scores) { + this.scores = scores; + } + + public Board addValue(String color, String name, String value) { + this.boardValues.add(new BoardValue(color, name, value)); + return this; + } + + public Board addScore(String name, int score) { + this.scores.add(new BoardScore(name, score)); + return this; + } + + public Board addLine(String line) { + this.list.add(line); + return this; + } + + public void updateFor(Player player, User user) { + List scores = new ArrayList<>(); + switch (this.type) { + case KEY_VALUE: { + int currentLine = 15; + int n = 5; + for (BoardValue value : this.boardValues) { + scores.add(new BoardScore("&" + n--, currentLine--)); + scores.add(new BoardScore('&' + value.getColor() + "&l" + value.getName(), currentLine--)); + scores.add(new BoardScore(' ' + value.getValue(), currentLine--)); + } + } + break; + case LIST: + int currentLine = 15; + for (String line : this.list) { + scores.add(new BoardScore(line, currentLine)); + currentLine--; + } + break; + case SCORES: + scores = this.scores; + break; + } + this.updateFor(player, user, scores); + } + + private void updateFor(Player player, User user, List scores) { + Scoreboard scoreboard = user.getScoreboard(); + Objective obj = scoreboard.getObjective(player.getName()); + if (obj == null) + obj = scoreboard.registerNewObjective(player.getName(), "dummy"); + for (String s : scoreboard.getEntries()) + if (obj.getScore(s).isScoreSet()) + scoreboard.resetScores(s); + obj.setDisplaySlot(DisplaySlot.SIDEBAR); + obj.setDisplayName(Utils.f(this.header)); + List playerNames = new ArrayList<>(); + for (BoardScore boardScore : scores) { + int lineNumber = boardScore.getScore(); + + String originalLine = boardScore.getName(); + String originalTeamPrefix = ""; + String originalPlayerName; + + if (originalLine.length() > 32) { + originalTeamPrefix = originalLine.substring(0, 16); + originalPlayerName = originalLine.substring(16, 32); + } else if (originalLine.length() > 16) { + originalTeamPrefix = originalLine.substring(0, originalLine.length() - 16); + originalPlayerName = originalLine.substring(originalLine.length() - 16, originalLine.length()); + } else { + originalPlayerName = originalLine; + } + String line; + String teamPrefix = originalTeamPrefix; + String playerName = originalPlayerName; + int t = 0; + while (playerNames.contains(playerName)) { + line = originalTeamPrefix + originalPlayerName; + if (line.length() > 30) + line = line.substring(0, 30); + line = line + '&' + t; + t++; + if (line.length() > 32) { + teamPrefix = line.substring(0, 16); + playerName = line.substring(16, 32); + } else if (line.length() > 16) { + teamPrefix = line.substring(0, line.length() - 16); + playerName = line.substring(line.length() - 16, line.length()); + } else { + playerName = line; + } + } + + playerNames.add(playerName); + Score score = obj.getScore(Utils.f(playerName)); + if (!teamPrefix.isEmpty()) { + Team team = scoreboard.getTeam(playerName); + if (team == null) + team = scoreboard.registerNewTeam(playerName); + team.setPrefix(Utils.f(teamPrefix)); + team.setSuffix(""); + team.addEntry(Utils.f(playerName)); +// team.setNameTagVisibility(NameTagVisibility.NEVER); + } + score.setScore(lineNumber); + } + + player.setScoreboard(scoreboard); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/boards/BoardScore.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/boards/BoardScore.java new file mode 100644 index 0000000..e477141 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/boards/BoardScore.java @@ -0,0 +1,29 @@ +package net.grandtheftmc.core.boards; + +public class BoardScore { + + private String name; + private int score; + + public BoardScore(String name, int currentLine) { + this.name = name; + this.score = currentLine; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public int getScore() { + return this.score; + } + + public void setScore(int i) { + this.score = i; + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/boards/BoardType.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/boards/BoardType.java new file mode 100644 index 0000000..4d76f26 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/boards/BoardType.java @@ -0,0 +1,7 @@ +package net.grandtheftmc.core.boards; + +public enum BoardType { + KEY_VALUE, + LIST, + SCORES +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/boards/BoardValue.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/boards/BoardValue.java new file mode 100644 index 0000000..556f470 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/boards/BoardValue.java @@ -0,0 +1,35 @@ +package net.grandtheftmc.core.boards; + +public class BoardValue { + + private String color; + private String name; + private String value; + + public BoardValue(String color, String name, String value) { + this.color = color; + this.name = name; + this.value = value; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + public String getValue() { + return this.value; + } + public void setValue(String value) { + this.value = value; + } + public String getColor() { + return this.color; + } + public void setColor(String color) { + this.color = color; + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/Casino.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/Casino.java new file mode 100644 index 0000000..752b7d5 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/Casino.java @@ -0,0 +1,44 @@ +package net.grandtheftmc.core.casino; + +import net.grandtheftmc.core.casino.game.CasinoGame; +import net.grandtheftmc.core.util.NMSVersion; +import net.grandtheftmc.core.util.title.NMSTitle; + +import java.util.List; + +public interface Casino { + + /** + * Get the currently available Casino Games. + * + * @return + */ + List getGames(); + + /** + * Remove casino game from the list of valid games. + * + * @param game - Casino Game + */ + void removeGame(CasinoGame game); + + /** + * Remove all current casino games. + */ + void removeAllGames(); + + /** + * Add a casino game to the list of valid games. + * + * @param game - Casino Game + */ + void addGame(CasinoGame game); + + NMSTitle getTitle(); + + void refreshAll(); + + NMSVersion getVersion(); + + void enabledAllGames(); +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/CoreCasino.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/CoreCasino.java new file mode 100644 index 0000000..d94f91b --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/CoreCasino.java @@ -0,0 +1,144 @@ +package net.grandtheftmc.core.casino; + +import com.google.common.collect.Lists; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.casino.coins.CoinManager; +import net.grandtheftmc.core.casino.game.CasinoGame; +import net.grandtheftmc.core.casino.game.component.CasinoGameComponent; +import net.grandtheftmc.core.util.Component; +import net.grandtheftmc.core.util.NMSVersion; +import net.grandtheftmc.core.util.title.NMSTitle; +import org.bukkit.Bukkit; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; +import org.bukkit.event.HandlerList; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.List; + +public class CoreCasino implements Casino { + + private final List games; + private final NMSTitle title; + private final NMSVersion nmsVersion; + private final CoinManager coinManager; + + public CoreCasino(T plugin, NMSTitle title, NMSVersion version) { + this.games = Lists.newArrayList(); + this.coinManager = new CoinManager(); + this.nmsVersion = version; + Bukkit.getPluginManager().registerEvents(new CasinoGameComponent(this), plugin); + this.title = title; + + new BukkitRunnable() { + @Override public void run() { + refreshIndex(); + } + }.runTaskTimer(plugin, 20*10, 20*10); + } + + public CoinManager getCoinManager() { + return this.coinManager; + } + + /** + * Add a casino game to the list of valid games. + * + * @param game - Casino Game + */ + @Override + public void addGame(CasinoGame game) { + if (game instanceof Component) + Bukkit.getPluginManager().registerEvents((Component) game, Core.getInstance()); + + this.games.add(game); + } + + + + @Override + public NMSTitle getTitle() { + return this.title; + } + + @Override + public void refreshAll() { + this.games.forEach(game -> { + if(!game.isInProgress()) { + game.disable(); + game.enable(); + } + }); + } + + private void refreshIndex() { + for(CasinoGame game : this.games) { + if(!game.getOriginLocation().getChunk().isLoaded()) game.getOriginLocation().getChunk().load(); + for (Entity entity : game.getOriginLocation().getWorld().getEntities()) { + if(game.isClicked(entity)) continue; + if (entity instanceof ArmorStand && entity.getLocation().distance(game.getOriginLocation()) < 0.7) { + entity.remove(); + } + } + } + } + + @Override + public NMSVersion getVersion() { + return this.nmsVersion; + } + + @Override + public void enabledAllGames() { + for(CasinoGame game : this.games) { + if(!game.getOriginLocation().getChunk().isLoaded()) game.getOriginLocation().getChunk().load(); + for (Entity entity : game.getOriginLocation().getWorld().getEntities()) { + if (entity instanceof ArmorStand && entity.getLocation().distance(game.getOriginLocation()) < 20) { + entity.remove(); + } + } + } + + this.games.forEach(CasinoGame::enable); + } + + /** + * Remove casino game from the list of valid games. + * + * @param game - Casino Game + */ + @Override + public void removeGame(CasinoGame game) { + if (game instanceof Component) + HandlerList.unregisterAll((Component) game); + + this.games.remove(game); + game.disable(); + } + + /** + * Remove all current casino games. + */ + @Override + public void removeAllGames() { + this.games.forEach(game -> { + if (game instanceof Component) HandlerList.unregisterAll((Component) game); + game.disable(); + }); + + this.getGames().clear(); + } + + + + /** + * Get the currently available Casino Games. + * + * @return + */ + @Override + public List getGames() { + return this.games; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/coins/ChipAmount.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/coins/ChipAmount.java new file mode 100644 index 0000000..ec33a43 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/coins/ChipAmount.java @@ -0,0 +1,57 @@ +package net.grandtheftmc.core.casino.coins; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.Optional; +import java.util.stream.Stream; + +/** + * Created by Timothy Lampen on 2017-11-12. + */ +public enum ChipAmount { + EIGHT_HUNDRED(ChatColor.LIGHT_PURPLE + "800", 800), + THREE_HUNDRED(ChatColor.BLUE + "300", 300), + HUNDRED(ChatColor.GREEN + "100", 100), + FIFTY(ChatColor.YELLOW + "50", 50), + TEN(ChatColor.GOLD + "10", 10), + ONE(ChatColor.RED + "1", 1); + + + private int amount; + private String prefix; + ChipAmount(String prefix, int amount){ + this.amount = amount; + this.prefix = prefix; + } + + public int getAmount() { + return amount; + } + + public String getPrefix() { + return this.prefix; + } + + public static Optional getChipAmount(String name) { + if(name==null) + return Optional.empty(); + return Stream.of(ChipAmount.values()).filter(c -> name.contains(c.prefix)).findFirst(); + } + + public ItemStack getItemStack(){ + ItemStack is = new ItemStack(Material.DIAMOND_SWORD); + ItemMeta im = is.getItemMeta(); + String disp = this.prefix; + is.setDurability((short)1002); + disp += ChatColor.GRAY + " Casino Coins"; + im.setUnbreakable(true); + im.addItemFlags(ItemFlag.HIDE_UNBREAKABLE); + im.setDisplayName(disp); + is.setItemMeta(im); + return is; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/coins/CoinManager.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/coins/CoinManager.java new file mode 100644 index 0000000..072b390 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/coins/CoinManager.java @@ -0,0 +1,155 @@ +package net.grandtheftmc.core.casino.coins; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.util.Component; +import net.grandtheftmc.core.util.ServerUtil; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +/** + * Created by Timothy Lampen on 2017-11-12. + */ +public class CoinManager implements Component{ + + private long lastResetTime = System.currentTimeMillis(); + private double currentMultiplier = 1.0; + private static final int baseCoinSellPrice = 150, baseCoinBuyPrice = 200; + private int soldCoins = 0; + + @Override + public CoinManager onEnable(Core plugin){ + new BukkitRunnable() { + @Override + public void run() { + Utils.insertLog(null, "Casino", "resetMultipler", "CHIPS", currentMultiplier + " cMulti", currentMultiplier, 0); + setCurrentMultiplier(1); + resetSoldCoins(); + Bukkit.broadcastMessage(Lang.CASINO.f("&aThe casino chip prices have been reset!")); + } + }.runTaskTimer(Core.getInstance(), 20*60*60, 20*60*60); + return this; + } + + public int getBaseCoinBuyPrice() { + return baseCoinBuyPrice; + } + + public int getBaseCoinSellPrice() { + return baseCoinSellPrice; + } + + public void addSoldCoins(int coins){ + soldCoins += coins; + if(soldCoins>=1000) { + setCurrentMultiplier(currentMultiplier + .1); + soldCoins = 0; + } + } + + private synchronized void resetSoldCoins(){ + this.soldCoins = 0; + } + + public synchronized double getCurrentMultiplier(){ + return currentMultiplier; + } + + private synchronized void setCurrentMultiplier(double d){ + currentMultiplier = d; + } + + public void giveCasinoChips(Player player, final int amount){ + ServerUtil.runTaskAsync(new BukkitRunnable() { + @Override + public void run() { + int dynamicAmount = amount; + dynamicAmount += getTotalCasinoChips(player); + for(ItemStack is : player.getInventory().getContents()) { + if(is==null) + continue; + if(isCasinoChip(is)) + player.getInventory().removeItem(is); + } + HashMap items = new HashMap<>(); + for(ChipAmount chip : ChipAmount.values()) { + while (dynamicAmount >= chip.getAmount()) { + ItemStack coin = chip.getItemStack(); + if (items.containsKey(coin)) + items.put(coin, items.get(coin) + 1); + else + items.put(coin, 1); + dynamicAmount -= chip.getAmount(); + } + } + List convertedItems = new ArrayList(); + items.entrySet().forEach(entry -> { + ItemStack key = entry.getKey(); + key.setAmount(entry.getValue()); + convertedItems.add(key); + }); + ServerUtil.runTask(new BukkitRunnable() { + @Override + public void run() { + for(ItemStack is : convertedItems) + Utils.giveItems(player, is); + } + }); + } + }); + + } + + public int getTotalCasinoChips(Player player) { + int amt = 0; + for(ItemStack is : player.getInventory().getContents()) { + if(is==null) + continue; + if(isCasinoChip(is)) { + ChipAmount chip = ChipAmount.getChipAmount(is.getItemMeta().getDisplayName()).get(); + amt += chip.getAmount()*is.getAmount(); + } + } + return amt; + } + + public boolean isCasinoChip(ItemStack is){ + if(is==null) + return false; + return is.getType()==Material.DIAMOND_SWORD && is.getDurability()==1002; + } + + public boolean removeCasinoChips(Player player, int amount) { + if(!hasCasinoChips(player, amount)) + return false; + int newTotal = getTotalCasinoChips(player)-amount; + for(ItemStack is : player.getInventory().getContents()) { + if(!isCasinoChip(is)) + continue; + player.getInventory().removeItem(is); + } + giveCasinoChips(player, newTotal); + return true; + } + + public boolean hasCasinoChips(Player player, int amount){ + int invAmount = 0; + for(ItemStack is : player.getInventory().getContents()) { + if(!isCasinoChip(is)) + continue; + ChipAmount chip = ChipAmount.getChipAmount(is.getItemMeta().getDisplayName()).get(); + invAmount += chip.getAmount()*is.getAmount(); + } + return invAmount>=amount; + } + + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/coins/VendorMenu.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/coins/VendorMenu.java new file mode 100644 index 0000000..30722ce --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/coins/VendorMenu.java @@ -0,0 +1,102 @@ +package net.grandtheftmc.core.casino.coins; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.inventory.CoreMenu; +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import net.grandtheftmc.core.inventory.button.ClickableItem; +import net.grandtheftmc.core.inventory.button.MenuItem; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.factory.ItemFactory; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.text.DecimalFormat; +import java.util.Arrays; + +/** + * Created by Timothy Lampen on 2017-11-12. + */ +public class VendorMenu extends CoreMenu{ + + public VendorMenu() { + super(1, ChatColor.GRAY + "Buy or Sell Casino Chips", CoreMenuFlag.CLOSE_ON_NULL_CLICK); + + ItemStack[] stacks = new ItemStack[]{ + new ItemFactory(Material.CHEST).setName(ChatColor.GREEN + "Buy Casino Chips").build(), + new ItemFactory(Material.CHEST).setName(ChatColor.RED + "Sell Casino Chips").build() + }; + + addItem(new ClickableItem(3, stacks[0], (player, clickType) -> { + new BuyChipMenu().openInventory(player); + })); + + addItem(new ClickableItem(5, stacks[1], (player, clickType) -> { + new SellChipMenu().openInventory(player); + })); + } + + private class SellChipMenu extends CoreMenu{ + + private SellChipMenu() { + super(1, ChatColor.RED + "Sell Casino Chips"); + int currentSlot = 2; + ChipAmount[] values = ChipAmount.values(); + for(int i = values.length -1; i>= 0; i--){ + ChipAmount chip = values[i]; + ItemStack is = chip.getItemStack(); + ItemMeta im = is.getItemMeta(); + im.setLore(Arrays.asList(ChatColor.GRAY + "Sell Price: $" + ChatColor.GREEN + Utils.formatMoney(chip.getAmount()*Core.getCoinManager().getBaseCoinSellPrice()))); + is.setItemMeta(im); + addItem(new ClickableItem(currentSlot, is, (player, clickType) -> { + if(Core.getCoinManager().hasCasinoChips(player, chip.getAmount())){ + Core.getCoinManager().removeCasinoChips(player, chip.getAmount()); + Core.getUserManager().getLoadedUser(player.getUniqueId()).addMoney(Core.getCoinManager().getBaseCoinSellPrice()*chip.getAmount()); + } + else + player.sendMessage(Lang.CASINO.f("&cYou do not have enough chips to sell!")); + })); + currentSlot++; + } + } + } + + private class BuyChipMenu extends CoreMenu { + private BuyChipMenu() { + super(1, ChatColor.GREEN + "Buy Casino Chips"); + int currentSlot = 1; + ChipAmount[] values = ChipAmount.values(); + for (int i = values.length - 1; i >= 0; i--) { + if (currentSlot == 4) { + currentSlot++; + } + ChipAmount chip = values[i]; + ItemStack is = chip.getItemStack(); + ItemMeta im = is.getItemMeta(); + im.setLore(Arrays.asList(ChatColor.GRAY + "Cost: $" + ChatColor.GREEN + Utils.formatMoney(Math.round(chip.getAmount() * Core.getCoinManager().getBaseCoinBuyPrice() * Core.getCoinManager().getCurrentMultiplier())))); + is.setItemMeta(im); + addItem(new ClickableItem(currentSlot, is, (player, clickType) -> { + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (user.hasMoney((int) Math.round(chip.getAmount() * Core.getCoinManager().getBaseCoinBuyPrice() * Core.getCoinManager().getCurrentMultiplier()))) { + Core.getCoinManager().giveCasinoChips(player, chip.getAmount()); + Core.getCoinManager().addSoldCoins(chip.getAmount()); + user.takeMoney(chip.getAmount() * Core.getCoinManager().getBaseCoinBuyPrice() * Core.getCoinManager().getCurrentMultiplier()); + } else + player.sendMessage(Lang.CASINO.f("&7You need $&b" + chip.getAmount() * Core.getCoinManager().getBaseCoinBuyPrice() * Core.getCoinManager().getCurrentMultiplier()) + " &7to buy these chips!"); + player.closeInventory(); + new BuyChipMenu().openInventory(player); + })); + currentSlot++; + } + ItemStack is = new ItemStack(Material.REDSTONE); + ItemMeta im = is.getItemMeta(); + DecimalFormat df = new DecimalFormat("#.#"); + im.setDisplayName(ChatColor.GRAY + "Current Cost Multiplier: " + ChatColor.GOLD + df.format(Core.getCoinManager().getCurrentMultiplier()) + ChatColor.GRAY + "x"); + is.setItemMeta(im); + addItem(new MenuItem(4, is, false)); + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/CasinoGame.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/CasinoGame.java new file mode 100644 index 0000000..e6765e4 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/CasinoGame.java @@ -0,0 +1,75 @@ +package net.grandtheftmc.core.casino.game; + +import net.grandtheftmc.core.casino.Casino; +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +public interface CasinoGame { + + /** + * Identifier of the casino game. + * @return + */ + int getIdentifier(); + + /** + * Name of the casino game. + * @return + */ + String getName(); + + /** + * Version of the casino game. + * @return + */ + String getVersion(); + + /** + * Get the current state of the casino game. + * @return + */ + CasinoGameState getState(); + + /** + * Set the current state of the casino game. + * @param state + */ + void setState(CasinoGameState state); + + /** + * This method will run when the Game is added
+ * To the list of valid games in Casino. + */ + void enable(); + + /** + * This method will run when the Game is removed
+ * From the list of valid games in Casino. + */ + void disable(); + + /** + * This is used so the Handler knows, + * which slot machine was interacted with. + * + * @param entity + * @return + */ + boolean isClicked(Entity entity); + + /** + * This will be used when a casino game is won. + * + * @param type + */ + void announce(Player player, int type, int reward); + + boolean isInProgress(); + + Casino getCasino(); + + boolean registered(); + + Location getOriginLocation(); +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/CasinoGameAttribute.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/CasinoGameAttribute.java new file mode 100644 index 0000000..7520434 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/CasinoGameAttribute.java @@ -0,0 +1,26 @@ +package net.grandtheftmc.core.casino.game; + +import java.lang.annotation.*; + +@Documented +@Target({ ElementType.TYPE }) +@Retention(RetentionPolicy.RUNTIME) +public @interface CasinoGameAttribute { + /** + * Identifier of the casino game. + * @return + */ + int id(); + + /** + * Name of the casino game. + * @return + */ + String name(); + + /** + * Version of the casino game. + * @return + */ + String version(); +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/CasinoGameState.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/CasinoGameState.java new file mode 100644 index 0000000..de82fc8 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/CasinoGameState.java @@ -0,0 +1,6 @@ +package net.grandtheftmc.core.casino.game; + +public enum CasinoGameState { + IDLE, BUSY, + ; +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/CasinoRunnable.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/CasinoRunnable.java new file mode 100644 index 0000000..ff09479 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/CasinoRunnable.java @@ -0,0 +1,8 @@ +package net.grandtheftmc.core.casino.game; + +import org.bukkit.entity.Player; + +public interface CasinoRunnable { + + void start(Player player); +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/CoreCasinoGame.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/CoreCasinoGame.java new file mode 100644 index 0000000..6ac283c --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/CoreCasinoGame.java @@ -0,0 +1,53 @@ +package net.grandtheftmc.core.casino.game; + +import net.grandtheftmc.core.casino.Casino; +import net.grandtheftmc.core.casino.game.event.CasinoGameStateChangeEvent; +import org.bukkit.Bukkit; + +@CasinoGameAttribute(id = 0, name = "Casino Game", version = "1.0") +public abstract class CoreCasinoGame implements CasinoGame { + + protected final Casino casino; + private CasinoGameState gameState; + + /** + * Construct a new Casino Game + */ + public CoreCasinoGame(Casino casino) { + this.casino = casino; + this.gameState = CasinoGameState.IDLE; + } + + @Override + public int getIdentifier() { + return this.getClass().getAnnotation(CasinoGameAttribute.class).id(); + } + + @Override + public String getName() { + return this.getClass().getAnnotation(CasinoGameAttribute.class).name(); + } + + @Override + public String getVersion() { + return this.getClass().getAnnotation(CasinoGameAttribute.class).version(); + } + + @Override + public CasinoGameState getState() { + return this.gameState; + } + + @Override + public void setState(CasinoGameState state) { + CasinoGameStateChangeEvent event = new CasinoGameStateChangeEvent(this, this.gameState, state); + Bukkit.getPluginManager().callEvent(event); + + this.gameState = state; + } + + @Override + public Casino getCasino() { + return this.casino; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/bet/CasinoBet.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/bet/CasinoBet.java new file mode 100644 index 0000000..ba98046 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/bet/CasinoBet.java @@ -0,0 +1,12 @@ +package net.grandtheftmc.core.casino.game.bet; + +import org.bukkit.entity.Player; + +public interface CasinoBet { + + CasinoBetType getBetType(); + + void start(Player player, SlotMachineBet bet); + + void openMenu(Player player); +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/bet/CasinoBetType.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/bet/CasinoBetType.java new file mode 100644 index 0000000..a1d29d0 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/bet/CasinoBetType.java @@ -0,0 +1,7 @@ +package net.grandtheftmc.core.casino.game.bet; + +public enum CasinoBetType { + TOKENS, + MONEY, + ; +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/bet/SlotMachineBet.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/bet/SlotMachineBet.java new file mode 100644 index 0000000..313b68e --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/bet/SlotMachineBet.java @@ -0,0 +1,28 @@ +package net.grandtheftmc.core.casino.game.bet; + +import net.grandtheftmc.core.casino.coins.ChipAmount; + +public enum SlotMachineBet { + TINY("Tiny Roller", ChipAmount.TEN), + SMALL("Small Roller",ChipAmount.FIFTY), + HIGH("High Roller",ChipAmount.HUNDRED), + INSANE("Insane Roller",ChipAmount.THREE_HUNDRED), + ALL_IN("All In!",ChipAmount.EIGHT_HUNDRED), + ; + + private final String name; + private final ChipAmount cost; + + SlotMachineBet(String name, ChipAmount cost) { + this.name = name; + this.cost = cost; + } + + public String getName() { + return name; + } + + public ChipAmount getCost() { + return this.cost; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/component/CasinoGameComponent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/component/CasinoGameComponent.java new file mode 100644 index 0000000..bc09602 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/component/CasinoGameComponent.java @@ -0,0 +1,102 @@ +package net.grandtheftmc.core.casino.game.component; + +import com.google.common.collect.Maps; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.casino.Casino; +import net.grandtheftmc.core.casino.game.CasinoGame; +import net.grandtheftmc.core.casino.game.CasinoRunnable; +import net.grandtheftmc.core.casino.game.bet.CasinoBet; +import net.grandtheftmc.core.casino.game.event.CasinoGameEndEvent; +import net.grandtheftmc.core.casino.game.event.CasinoGameStartEvent; +import net.grandtheftmc.core.util.Component; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.player.PlayerArmorStandManipulateEvent; +import org.bukkit.event.player.PlayerInteractAtEntityEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.plugin.java.JavaPlugin; + +import java.util.HashMap; +import java.util.Optional; +import java.util.UUID; + +public class CasinoGameComponent implements Component { + + private final HashMap game_users; + private final Casino casino; + + public CasinoGameComponent(Casino casino) { + this.casino = casino; + this.game_users = Maps.newHashMap(); + } + + @Override + public CasinoGameComponent onEnable(T plugin) { + return this; + } + + @Override + public CasinoGameComponent onDisable(T plugin) { + return this; + } + + @EventHandler + protected final void onArmorStandClick(PlayerArmorStandManipulateEvent event) { + if(event.getPlayer() == null || event.getRightClicked() == null) return; + if(!event.getRightClicked().getWorld().getName().equals("spawn")) return; + + Optional optional = casino.getGames().stream().filter(game -> game.isClicked(event.getRightClicked())).findFirst(); + if(!optional.isPresent()) return; + + event.setCancelled(true); + } + + @EventHandler + protected final void onMachineInteract(PlayerInteractAtEntityEvent event) { + if(event.getPlayer() == null || event.getRightClicked() == null) return; + Optional optional = casino.getGames().stream().filter(game -> game.isClicked(event.getRightClicked())).findFirst(); + if(!optional.isPresent()) return; + + if(this.game_users.containsKey(event.getPlayer().getUniqueId())) { + this.casino.getTitle().sendTitle(event.getPlayer(), Utils.f("&9&lCASINO"), Utils.f("&cYou cannot use multiple Casino games at once!"), 1*20, 2*20, 1*20); + return; + } + + if(optional.get() instanceof CasinoBet) { + ((CasinoBet) optional.get()).openMenu(event.getPlayer()); + return; + } + + if(optional.get() instanceof CasinoRunnable) { + ((CasinoRunnable) optional.get()).start(event.getPlayer()); + } + } + + @EventHandler + protected final void onPlayerQuit(PlayerQuitEvent event) { + game_users.remove(event.getPlayer().getUniqueId()); + } + + @EventHandler + protected final void onCasinoGameEnd(CasinoGameEndEvent event) { + game_users.remove(event.getPlayer().getUniqueId()); + } + + @EventHandler + protected final void onCasinoGameStart(CasinoGameStartEvent event) { + game_users.putIfAbsent(event.getPlayer().getUniqueId(), event.getGame()); + } + +// @EventHandler +// protected final void onEntityDeath(EntityDamageEvent event) { +// if(event.getEntity() == null) return; +// +// Optional optional = casino.getGames().stream().filter(game -> game.isClicked(event.getEntity())).findFirst(); +// if(!optional.isPresent()) return; +// +// if(optional.get().registered()) +// event.setCancelled(true); +// } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/event/CasinoGameEndEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/event/CasinoGameEndEvent.java new file mode 100644 index 0000000..bc68db4 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/event/CasinoGameEndEvent.java @@ -0,0 +1,28 @@ +package net.grandtheftmc.core.casino.game.event; + +import net.grandtheftmc.core.casino.game.CasinoGame; +import net.grandtheftmc.core.events.CoreEvent; +import org.bukkit.entity.Player; + +public class CasinoGameEndEvent extends CoreEvent { + + private final CasinoGame game; + private final Player player; + + /** + * Construct a new Event + */ + public CasinoGameEndEvent(CasinoGame game, Player player) { + super(false); + this.game = game; + this.player = player; + } + + public CasinoGame getGame() { + return game; + } + + public Player getPlayer() { + return player; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/event/CasinoGameStartEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/event/CasinoGameStartEvent.java new file mode 100644 index 0000000..ad5b3db --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/event/CasinoGameStartEvent.java @@ -0,0 +1,28 @@ +package net.grandtheftmc.core.casino.game.event; + +import net.grandtheftmc.core.casino.game.CasinoGame; +import net.grandtheftmc.core.events.CoreEvent; +import org.bukkit.entity.Player; + +public class CasinoGameStartEvent extends CoreEvent { + + private final CasinoGame game; + private final Player player; + + /** + * Construct a new Event + */ + public CasinoGameStartEvent(CasinoGame game, Player player) { + super(false); + this.game = game; + this.player = player; + } + + public CasinoGame getGame() { + return game; + } + + public Player getPlayer() { + return player; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/event/CasinoGameStateChangeEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/event/CasinoGameStateChangeEvent.java new file mode 100644 index 0000000..837b291 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/game/event/CasinoGameStateChangeEvent.java @@ -0,0 +1,45 @@ +package net.grandtheftmc.core.casino.game.event; + +import net.grandtheftmc.core.casino.game.CasinoGame; +import net.grandtheftmc.core.casino.game.CasinoGameState; +import net.grandtheftmc.core.events.CoreEvent; + +public class CasinoGameStateChangeEvent extends CoreEvent { + + private final CasinoGame casinoGame; + private final CasinoGameState from, to; + + /** + * Construct a new Event + */ + public CasinoGameStateChangeEvent(CasinoGame casinoGame, CasinoGameState from, CasinoGameState to) { + super(false); + this.casinoGame = casinoGame; + this.from = from; + this.to = to; + } + + /** + * Get the casino game. + * @return + */ + public CasinoGame getCasinoGame() { + return casinoGame; + } + + /** + * Get the previous casino game state. + * @return + */ + public CasinoGameState getFrom() { + return from; + } + + /** + * Get the new casino game state. + * @return + */ + public CasinoGameState getTo() { + return to; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/slot/CasinoSpinData.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/slot/CasinoSpinData.java new file mode 100644 index 0000000..3f6f2e6 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/slot/CasinoSpinData.java @@ -0,0 +1,120 @@ +package net.grandtheftmc.core.casino.slot; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.casino.game.CasinoGameAttribute; +import net.grandtheftmc.core.util.AngleUtil; +import org.bukkit.Location; +import org.bukkit.Sound; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.EntityType; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +public class CasinoSpinData { + + private final ArmorStand armorStand; + private final int id; + private final SlotWheelType wheelType; + private long ticks = 0, maxTicks = 100; + private double speed = 100; + private SpinState spinState = SpinState.SPINNING; + private float pitch = 0.25f; + + public CasinoSpinData(SlotMachine machine, Location location, int id, SlotWheelType wheelType, double defaultAngle) { + this.armorStand = (ArmorStand) location.getWorld().spawnEntity(location.clone(), EntityType.ARMOR_STAND); + this.armorStand.setCustomName(machine.getClass().getAnnotation(CasinoGameAttribute.class).id() + ";" + id); + this.armorStand.setCustomNameVisible(false); + if(id == 2) { + this.armorStand.setArms(true); + this.armorStand.getEquipment().setItemInOffHand(machine.getMachine(true)); + this.armorStand.setLeftArmPose(new EulerAngle(0, 0, 0)); + } + + this.armorStand.setCanPickupItems(false); + this.armorStand.setGravity(false); + this.armorStand.setBasePlate(false); + this.armorStand.setVisible(false); + this.armorStand.setInvulnerable(true); + this.armorStand.setRemoveWhenFarAway(false); + this.armorStand.setMarker(false); + this.armorStand.setMetadata("SLOT_MACHINE", new FixedMetadataValue(Core.getInstance(), machine)); + + this.wheelType = wheelType; + this.armorStand.setHelmet(wheelType.getModel()); + this.armorStand.getLocation().setPitch(90); + this.id = id; + + this.armorStand.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(defaultAngle), 0, 0)); + } + + public ArmorStand getArmorStand() { + return this.armorStand; + } + + public int getId() { + return this.id; + } + + public SlotWheelType getWheelType() { + return this.wheelType; + } + + public double getSpeed() { + return this.speed; + } + + public void setSpeed(double speed) { + this.speed = speed; + } + + public long getTicks() { + return this.ticks; + } + + public void setTicks(long tick) { + this.ticks = tick; + } + + public SpinState getSpinState() { + return this.spinState; + } + + public void setSpinState(SpinState spinState) { + this.spinState = spinState; + } + + public long getMaxTicks() { + return this.maxTicks; + } + + public void spin(boolean forward) { + if(this.armorStand == null) return; + EulerAngle c = this.armorStand.getHeadPose(); + this.armorStand.setHeadPose(new EulerAngle(Math.toRadians(Math.toDegrees(c.getX()) + (forward ? speed : -speed)), 0, 0)); + } + + public void playNote() { + Location l = this.armorStand.getEyeLocation(); + if(this.wheelType == SlotWheelType.THREE && this.speed <= 40) { + if(this.pitch >= 1.0) + this.pitch += 0.1f; + else + this.pitch += 0.25f; + l.getWorld().playSound(l, Sound.BLOCK_NOTE_PLING, 0.8f, this.pitch); + return; + } + + if(this.pitch >= 1.0) + this.pitch = 0.25f; + this.pitch += 0.25f; + l.getWorld().playSound(l, Sound.BLOCK_NOTE_PLING, 0.8f, this.pitch); + } + + protected void reset() { + this.ticks = 0; + this.maxTicks = 100; + this.speed = 100; + this.pitch = 0.1f; + this.spinState = SpinState.SPINNING; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/slot/SlotItem.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/slot/SlotItem.java new file mode 100644 index 0000000..316638c --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/slot/SlotItem.java @@ -0,0 +1,25 @@ +package net.grandtheftmc.core.casino.slot; + +public enum SlotItem { + DILDO("Dildo", new int[]{0, 2, 20}), + MDMA("MDMA", new int[]{0, 2, 5}), + LSD("LSD", new int[]{0, 2, 10}), + SEVEN("7", new int[]{0, 2, 500}), + CHERRY("Cherry", new int[]{1, 4, 35}); + + private String name; + private int[] reward; + + SlotItem(String name, int[] reward) { + this.name = name; + this.reward = reward; + } + + public String getName() { + return name; + } + + public int[] getReward() { + return reward; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/slot/SlotMachine.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/slot/SlotMachine.java new file mode 100644 index 0000000..58b6b7e --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/slot/SlotMachine.java @@ -0,0 +1,550 @@ +package net.grandtheftmc.core.casino.slot; + +import com.gmail.filoghost.holographicdisplays.api.Hologram; +import com.gmail.filoghost.holographicdisplays.api.HologramsAPI; +import com.google.common.collect.Lists; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.casino.Casino; +import net.grandtheftmc.core.casino.game.CasinoGameAttribute; +import net.grandtheftmc.core.casino.game.CasinoRunnable; +import net.grandtheftmc.core.casino.game.CoreCasinoGame; +import net.grandtheftmc.core.casino.game.bet.CasinoBet; +import net.grandtheftmc.core.casino.game.bet.CasinoBetType; +import net.grandtheftmc.core.casino.game.bet.SlotMachineBet; +import net.grandtheftmc.core.casino.game.event.CasinoGameEndEvent; +import net.grandtheftmc.core.casino.game.event.CasinoGameStartEvent; +import net.grandtheftmc.core.casino.slot.menu.SlotMachineBetMenu; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.util.factory.FireworkFactory; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.core.util.title.NMSTitle; +import net.grandtheftmc.core.wrapper.packet.out.WrapperPlayServerEntityDestroy; +import org.bukkit.*; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Item; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; + +import java.util.List; +import java.util.Random; + +@CasinoGameAttribute(id = 1, name = "Slot Machine", version = "1.0.0-BETA") +public class SlotMachine extends CoreCasinoGame implements CasinoRunnable, CasinoBet { + + private static final BlockFace[] AXIS = { BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST }; + private final Random random; + + private Hologram hologram; + private final Location originLocation; + private CasinoSpinData[] spinData; + private SlotReward[] rewards; + private boolean running; + private BukkitTask task; + private boolean registered = true; + + public SlotMachine(Casino casino, Location location) { + super(casino); + + this.task = null; + this.random = new Random(); + this.rewards = new SlotReward[3]; + this.running = false; + this.originLocation = location; + } + + public Hologram getHologram() { + return this.hologram; + } + + public boolean isRunning() { + return this.running; + } + + /** + * This method will run when the Game is added
+ * To the list of valid games in Casino. + */ + @Override + public void enable() { + if(!originLocation.getChunk().isLoaded()) + originLocation.getChunk().load(); + + this.spinData = new CasinoSpinData[] { + new CasinoSpinData(this, this.getNextOffset(this.originLocation.clone(), 0.475, true), 1, SlotWheelType.ONE, getRandomNumber()), + new CasinoSpinData(this, this.originLocation.clone(), 2, SlotWheelType.TWO, getRandomNumber()), + new CasinoSpinData(this, this.getNextOffset(this.originLocation.clone(), -0.475, true), 3, SlotWheelType.THREE, getRandomNumber()) + }; + + this.hologram = HologramsAPI.createHologram(Core.getInstance(), this.originLocation.clone().add(0, 3.5, 0)); + this.hologram.appendTextLine(Utils.f("&e&lClick to play!")); + this.hologram.getVisibilityManager().setVisibleByDefault(true); + this.hologram.getVisibilityManager().resetVisibilityAll(); + } + + /** + * This method will run when the Game is removed
+ * From the list of valid games in Casino. + */ + @Override + public void disable() { + this.registered = false; + if(this.hologram != null) this.hologram.delete(); + if(this.spinData != null) { + for (CasinoSpinData aSpinData : this.spinData) + aSpinData.getArmorStand().remove(); + } + + resetStands(true); + } + + /** + * This is used so the Handler knows, + * which slot machine was interacted with. + * + * @param entity + * @return + */ + @Override + public boolean isClicked(Entity entity) { + if(this.spinData != null) { + for (CasinoSpinData aSpinData : this.spinData) { + if (aSpinData == null || aSpinData.getArmorStand() == null) continue; + if (entity.getUniqueId().equals(aSpinData.getArmorStand().getUniqueId())) + return true; + } + } + + return false; + } + + @Override + public boolean isInProgress() { + return this.running; + } + + @Override + public boolean registered() { + return this.registered; + } + + @Override + public Location getOriginLocation() { + return this.originLocation.clone(); + } + + @Override + public void start(Player player) { + this.start(player, SlotMachineBet.TINY); + } + + public void resetStands(boolean shutdown) { + if (shutdown) { + this.hologram.delete(); + for (CasinoSpinData data : spinData) { + data.getArmorStand().remove(); + } + } + else { + this.hologram.getVisibilityManager().setVisibleByDefault(true); + this.hologram.getVisibilityManager().resetVisibilityAll(); + } + } + + @Override + public CasinoBetType getBetType() { + return CasinoBetType.TOKENS; + } + + public void pre(Player player) { + if (this.running) return; + + this.running = true; + CasinoGameStartEvent startEvent = new CasinoGameStartEvent(this, player); + Bukkit.getPluginManager().callEvent(startEvent); + this.originLocation.getWorld().spawnParticle(Particle.VILLAGER_HAPPY, this.originLocation, 100, 1.2, 1, 1.2); + this.hologram.clearLines(); + + CasinoSpinData[] old = this.spinData.clone(); + + this.spinData = new CasinoSpinData[] { + new CasinoSpinData(this, this.getNextOffset(this.originLocation.clone(), 0.475, true), 1, SlotWheelType.ONE, getRandomNumber()), + new CasinoSpinData(this, this.originLocation.clone(), 2, SlotWheelType.TWO, getRandomNumber()), + new CasinoSpinData(this, this.getNextOffset(this.originLocation.clone(), -0.475, true), 3, SlotWheelType.THREE, getRandomNumber()) + }; + + if(old != null) { + for(CasinoSpinData data : old) { + WrapperPlayServerEntityDestroy wrappedPacket = new WrapperPlayServerEntityDestroy(); + wrappedPacket.setEntityIds(new int[] {data.getArmorStand().getEntityId()}); + wrappedPacket.sendPacket(player); + data.getArmorStand().remove(); + } + old[0] = null; + old[1] = null; + old[2] = null; + old = null; + } + + this.spinData[1].getArmorStand().getEquipment().setItemInOffHand(this.getMachine(false)); + } + + @Override + public void start(Player player, SlotMachineBet bet) { + if (this.task != null) return; + + this.pre(player); + boolean[] b = {false, false, false}; + + task = new BukkitRunnable() { + @Override public void run() { + + for(int i = 0; i < spinData.length; i++) { + CasinoSpinData data = spinData[i]; + + if(data.getSpinState() == SpinState.END) { + if (data.getId() == 3) { + + SlotReward rewardOne = rewards[0]; + SlotReward rewardTwo = rewards[1]; + SlotReward rewardThree = rewards[2]; + + if(rewardOne == null || rewardTwo == null || rewardThree == null) + continue; + + int wonAmount = getReward(player, bet, rewardOne, rewardTwo, rewardThree); + if(wonAmount > 0) { + ServerUtil.runTask(() -> { + if (player != null && player.isOnline()) { + Core.getCoinManager().giveCasinoChips(player, wonAmount); + } + + hologram.clearLines(); + hologram.appendTextLine(C.GREEN + C.BOLD + "$" + wonAmount); + + ServerUtil.runTaskAsync(() -> { + if (player == null || !player.isOnline()) return; + Utils.insertLog(player.getUniqueId(), "casino_slot", "CHIPS", bet.getCost().getAmount() + " Chips","" + wonAmount, 0, bet.getCost().getAmount()); + }); + }); + } + + new BukkitRunnable() { + @Override public void run() { + resetStands(false); + + if (SlotMachine.this.task != null) + task.cancel(); + + task = null; + rewards = new SlotReward[3]; + spinData[1].getArmorStand().getEquipment().setItemInOffHand(getMachine(true)); + + if (player != null && player.isOnline()) { + NMSTitle.sendTitle(player, " ", " ", 20, 20, 20); + CasinoGameEndEvent endEvent = new CasinoGameEndEvent(SlotMachine.this, player); + Bukkit.getPluginManager().callEvent(endEvent); + } + + hologram.clearLines(); + hologram.appendTextLine(Utils.f("&e&lClick to play!")); + + for (CasinoSpinData aSpinData : spinData) + aSpinData.reset(); + + running = false; + } + }.runTaskLater(Core.getInstance(), 20*5); + this.cancel(); + break; + } + continue; + } + + data.setTicks(data.getTicks() + 1); + + if((i == 0 && !b[i]) || (i == 1 && (b[i-1] && !b[i])) || (i == 2 && (b[i-1] && !b[i]))) { + if ((data.getTicks() % 5 == 0)) { + if (data.getSpeed() - 4.5 > 0) data.setSpeed(data.getSpeed() - 4.5); + else b[i] = true; + + if(player != null && player.isOnline()) { + originLocation.getWorld().playSound(originLocation, Sound.BLOCK_WOOD_BUTTON_CLICK_ON, 0.3f, 1f); + data.playNote(); + } + } + } + + if(data.getSpinState() == SpinState.SPINNING) { + if(b[i] && (Math.abs(AngleUtil.getDegreesFromRadians(data.getArmorStand().getHeadPose().getX()) % 30) <= 10)) { + data.setSpinState(SpinState.STOPPING); + } + data.spin(true); + continue; + } + + if(data.getSpinState() == SpinState.STOPPING) { + SlotReward reward = data.getWheelType().getRewardByAngle(AngleUtil.getDegreesFromRadians(data.getArmorStand().getHeadPose().getX())); + if (reward != null) { + rewards[i] = reward; + int finalI = i; + ServerUtil.runTask(() -> { + hologram.appendTextLine(Utils.f("&f&l" + (finalI +1) + ". &7" + reward.getRewardItem().getName())); + originLocation.getWorld().playSound(originLocation, Sound.BLOCK_NOTE_BASS, 0.75f, 1f); + }); + } + + data.setSpinState(SpinState.END); + } + } + } + }.runTaskTimerAsynchronously(Core.getInstance(), 10, 1); + } + + @Override + public void openMenu(Player player) { + new SlotMachineBetMenu(this).openInventory(player); + } + + private Location getNextOffset(Location current, double offset, boolean b) { + double yaw = Math.toRadians(current.getYaw()) + (Math.PI / 2); + double x = current.getX() + offset * (b ? Math.sin(yaw) : Math.cos(yaw)); + double z = current.getZ() + offset * (b ? Math.cos(yaw) : Math.sin(yaw)); + return new Location(current.getWorld(), x, current.getY(), z, current.getYaw(), current.getPitch()); + } + + protected ItemStack getMachine(boolean idle) { + ItemStack machineItem = new ItemFactory(Material.DIAMOND_SWORD).setDurability(idle ? (short)820 : (short)821).build(); + Utils.applyItemFlags(machineItem, ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE); + return machineItem; + } + + private int getRandomNumber() { + int x = this.random.nextInt(73); + return x*5; + } + + private int getReward(Player player, SlotMachineBet bet, SlotReward one, SlotReward two, SlotReward three) { + //announce(player, jackpotType, winAmount); + int combinedAmount = 0; + SlotItem I = one.getRewardItem(), II = two.getRewardItem(), III = three.getRewardItem(); + if(I == II && II == III) { + if(I == SlotItem.SEVEN) {//JACKPOT + combinedAmount += I.getReward()[2] * bet.getCost().getAmount(); + this.announce(player, 1, combinedAmount); + } + else if(I == SlotItem.CHERRY) {//DEMI JACKPOT + combinedAmount += I.getReward()[2] * bet.getCost().getAmount(); + this.announce(player, 2, combinedAmount); + } + else {//3 IN A ROW + combinedAmount += I.getReward()[2] * bet.getCost().getAmount(); + this.announce(player, 3, combinedAmount); + } + return combinedAmount; + } + + if(I == II) { + combinedAmount += I.getReward()[1] * bet.getCost().getAmount(); + if(III == SlotItem.CHERRY) + combinedAmount += III.getReward()[0] * bet.getCost().getAmount(); + this.announce(player, 4, combinedAmount); + return combinedAmount; + } + + if(I == III) { + combinedAmount += I.getReward()[1] * bet.getCost().getAmount(); + if(II == SlotItem.CHERRY) + combinedAmount += II.getReward()[0] * bet.getCost().getAmount(); + this.announce(player, 4, combinedAmount); + return combinedAmount; + } + + if(II == III) { + combinedAmount += I.getReward()[1] * bet.getCost().getAmount(); + if(I == SlotItem.CHERRY) + combinedAmount += I.getReward()[0] * bet.getCost().getAmount(); + this.announce(player, 4, combinedAmount); + return combinedAmount; + } + + boolean cherry = false; + if(I == SlotItem.CHERRY) { + combinedAmount += I.getReward()[0] * bet.getCost().getAmount(); + cherry = true; + } + if(II == SlotItem.CHERRY) { + combinedAmount += II.getReward()[0] * bet.getCost().getAmount(); + cherry = true; + } + if(III == SlotItem.CHERRY) { + combinedAmount += III.getReward()[0] * bet.getCost().getAmount(); + cherry = true; + } + + if(cherry) { + this.announce(player, 5, combinedAmount); + return combinedAmount; + } + + this.announce(player, 0, combinedAmount); + return combinedAmount; + } + + /** + * This will be used when a casino game is won. + * + * @param type + */ + @Override + public void announce(Player player, int type, int reward) { + ServerUtil.runTask(() -> { + Location l = this.originLocation.clone(); + String r = reward + " Chips"; + switch (type) { + case 0: + if (reward > 0) { + NMSTitle.sendTitle(player, Utils.f("&9&lCASINO"), Utils.f("&fYou have won &a" + r + "&f!"), 3 * 20, 3 * 20, 1 * 20); + this.originLocation.getWorld().spawnParticle(Particle.VILLAGER_HAPPY, l.getX(), l.getY() + 1, l.getZ(), 100, 1.2, 1, 1.2); + this.originLocation.getWorld().playSound(l, Sound.ENTITY_PLAYER_LEVELUP, 0.5f, 1f); + } else { + this.originLocation.getWorld().spawnParticle(Particle.VILLAGER_ANGRY, l.getX(), l.getY() + 1, l.getZ(), 100, 1.2, 1, 1.2); + NMSTitle.sendTitle(player, Utils.f("&9&lCASINO"), Utils.f("&fUnlucky, You haven't won anything this time!"), 3 * 20, 3 * 20, 1 * 20); + this.originLocation.getWorld().playSound(l, Sound.ENTITY_PIG_DEATH, 0.5f, 1f); + } + break; + + case 1://JACKPOT + this.originLocation.getWorld().spawnParticle(Particle.VILLAGER_HAPPY, l.getX(), l.getY() + 1, l.getZ(), 200, 1.2, 1, 1.2); + this.originLocation.getWorld().playSound(l, Sound.ITEM_TOTEM_USE, 0.5f, 1f); + NMSTitle.sendTitle(player, Utils.f("&c&lJACKPOT"), Utils.f("&fYou have won &a" + r + "&f!"), 3 * 20, 3 * 20, 1 * 20); + Bukkit.broadcastMessage(Lang.CASINO.f(player.getName() + " has won the Slot Machine Jackpot of &a" + r + "&7!")); + new FireworkFactory(this.originLocation.clone().add(0, 1, 0)).setPower(0).setColor(Color.RED).setFadeColor(Color.WHITE).setFlicker(true).setTrail(true).setType(FireworkEffect.Type.BALL_LARGE).build(); + new FireworkFactory(this.originLocation.clone().add(0, 2, 0)).setPower(0).setColor(Color.RED).setFadeColor(Color.WHITE).setFlicker(true).setTrail(true).setType(FireworkEffect.Type.BALL).build(); + + new BukkitRunnable() { + private List items = Lists.newArrayList(); + private int ticks = 0; + + @Override + public void run() { + if (ticks >= 20) { + this.cancel(); + this.items.forEach(Entity::remove); + this.items.clear(); + return; + } + + if (player != null && player.isOnline()) { + Item item = getMoneyItem(); + item.getLocation().getWorld().playSound(item.getLocation(), Sound.ENTITY_ITEM_PICKUP, 0.5f, 1.5f); +// item.setVelocity(new Vector()); +// double xMod = random.nextBoolean() ? -(1 + random.nextDouble()) : (1 + random.nextDouble()), zMod = random.nextBoolean() ? -(1 + random.nextDouble()) : (1 + random.nextDouble()); +// item.setVelocity(new Vector(item.getLocation().getX() + xMod, item.)); + item.setVelocity(item.getLocation().toVector().subtract(player.getLocation().toVector()).normalize().multiply(1.4)); + this.items.add(item); + } + + ticks += 1; + } + }.runTaskTimer(Core.getInstance(), 0, 2); + + break; + + case 2://DEMI JACKPOT + this.originLocation.getWorld().spawnParticle(Particle.VILLAGER_HAPPY, l.getX(), l.getY() + 1, l.getZ(), 200, 1.2, 1, 1.2); + this.originLocation.getWorld().playSound(l, Sound.ITEM_TOTEM_USE, 0.5f, 1f); + NMSTitle.sendTitle(player, Utils.f("&9&lCASINO"), Utils.f("&fYou have won &a" + r + "&f!"), 3 * 20, 3 * 20, 1 * 20); + new FireworkFactory(this.originLocation.clone().add(0, 1, 0)).setPower(0).setColor(Color.RED).setFadeColor(Color.WHITE).setFlicker(true).setTrail(true).setType(FireworkEffect.Type.BALL).build(); + + new BukkitRunnable() { + private List items = Lists.newArrayList(); + private int ticks = 0; + + @Override + public void run() { + if (ticks >= 30) { + this.cancel(); + this.items.forEach(Entity::remove); + this.items.clear(); + return; + } + + if (player != null && player.isOnline()) { + Item item = getMoneyItem(); + item.getLocation().getWorld().playSound(item.getLocation(), Sound.ENTITY_ITEM_PICKUP, 0.5f, 1.5f); + item.setVelocity(item.getLocation().toVector().subtract(player.getLocation().toVector()).normalize().multiply(1.4)); + this.items.add(item); + } + + ticks += 1; + } + }.runTaskTimer(Core.getInstance(), 0, 2); + + break; + + case 3://3 IN A ROW + this.originLocation.getWorld().spawnParticle(Particle.VILLAGER_HAPPY, l.getX(), l.getY() + 1, l.getZ(), 200, 1.2, 1, 1.2); + this.originLocation.getWorld().playSound(l, Sound.ITEM_TOTEM_USE, 0.5f, 1f); + NMSTitle.sendTitle(player, Utils.f("&9&lCASINO"), Utils.f("&fYou have won &a" + r + "&f!"), 3 * 20, 3 * 20, 1 * 20); + new FireworkFactory(this.originLocation.clone().add(0, 1, 0)).setPower(0).setColor(Color.GREEN).setFadeColor(Color.WHITE).setFlicker(true).setTrail(true).setType(FireworkEffect.Type.BALL).build(); + + new BukkitRunnable() { + private List items = Lists.newArrayList(); + private int ticks = 0; + + @Override + public void run() { + if (ticks >= 15) { + this.cancel(); + this.items.forEach(Entity::remove); + this.items.clear(); + return; + } + + if (player != null && player.isOnline()) { + Item item = getMoneyItem(); + item.getLocation().getWorld().playSound(item.getLocation(), Sound.ENTITY_ITEM_PICKUP, 0.5f, 1.5f); + item.setVelocity(item.getLocation().toVector().subtract(player.getLocation().toVector()).normalize().multiply(1.4)); + this.items.add(item); + } + + ticks += 1; + } + }.runTaskTimer(Core.getInstance(), 0, 2); + break; + + case 4://WIN, 2 IN A ROW + this.originLocation.getWorld().spawnParticle(Particle.VILLAGER_HAPPY, l.getX(), l.getY() + 1, l.getZ(), 200, 1.2, 1, 1.2); + this.originLocation.getWorld().playSound(l, Sound.ITEM_TOTEM_USE, 0.5f, 1f); + NMSTitle.sendTitle(player, Utils.f("&9&lCASINO"), Utils.f("&fYou have won &a" + r + "&f!"), 3 * 20, 3 * 20, 1 * 20); + break; + + case 5://CHERRY + this.originLocation.getWorld().spawnParticle(Particle.VILLAGER_HAPPY, l.getX(), l.getY() + 1, l.getZ(), 200, 1.2, 1, 1.2); + this.originLocation.getWorld().playSound(l, Sound.ITEM_TOTEM_USE, 0.5f, 1f); + NMSTitle.sendTitle(player, Utils.f("&9&lCASINO"), Utils.f("&fYou have won &a" + r + "&f!"), 3 * 20, 3 * 20, 1 * 20); + break; + } + }); + } + + private BlockFace yawToDirection() { + return AXIS[Math.round(this.originLocation.getYaw() / 90f) & 0x3]; + } + + private Item getMoneyItem() { + ItemStack stack = new ItemFactory(Material.PAPER).setName(random.nextInt(999999) + "").build(); + Item item = this.originLocation.getWorld().dropItem(this.getNextOffset(this.originLocation.clone().add(0, 1.4, 0), 0.4, false), stack); + item.setPickupDelay(Integer.MAX_VALUE); + return item; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/slot/SlotReward.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/slot/SlotReward.java new file mode 100644 index 0000000..6b6bc76 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/slot/SlotReward.java @@ -0,0 +1,25 @@ +package net.grandtheftmc.core.casino.slot; + +public class SlotReward { + private final SlotItem slotItem; + private final int id; + private final int[] angle; + + public SlotReward(SlotItem slotItem, int id, int... angle) { + this.slotItem = slotItem; + this.id = id; + this.angle = angle; + } + + public SlotItem getRewardItem() { + return slotItem; + } + + public int getId() { + return id; + } + + public int[] getAngle() { + return angle; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/slot/SlotWheelType.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/slot/SlotWheelType.java new file mode 100644 index 0000000..9dc0cea --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/slot/SlotWheelType.java @@ -0,0 +1,107 @@ +package net.grandtheftmc.core.casino.slot; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.servers.ServerType; +import net.grandtheftmc.core.util.Utils; +import org.bukkit.Material; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +public enum SlotWheelType { + + ONE(817, new SlotReward[] { + new SlotReward(SlotItem.SEVEN, 4, 345, 0, 15),//0 + new SlotReward(SlotItem.CHERRY, 5, 15, 30, 45),//30 + new SlotReward(SlotItem.LSD, 6, 45, 60, 75),//60 + new SlotReward(SlotItem.MDMA, 7, 75, 90, 105),//90 + new SlotReward(SlotItem.LSD, 8, 105, 120, 135),//120 + new SlotReward(SlotItem.CHERRY, 9, 135, 150, 165),//150 + new SlotReward(SlotItem.DILDO, 10, 165, 180, 195),//180 + new SlotReward(SlotItem.MDMA, 11, 195, 210, 225),//210 + new SlotReward(SlotItem.LSD, 12, 225, 240, 255),//240 + new SlotReward(SlotItem.DILDO, 1, 255, 270, 285),//270 + new SlotReward(SlotItem.MDMA, 2, 285, 300, 315),//300 + new SlotReward(SlotItem.LSD, 3, 315, 330, 345),//330 + }), + + TWO(818, new SlotReward[] { + new SlotReward(SlotItem.CHERRY, 4, 345, 0, 15),//0 + new SlotReward(SlotItem.SEVEN, 5, 15, 30, 45),//30 + new SlotReward(SlotItem.MDMA, 6, 45, 60, 75),//60 + new SlotReward(SlotItem.LSD, 7, 75, 90, 105),//90 + new SlotReward(SlotItem.DILDO, 8, 105, 120, 135),//120 + new SlotReward(SlotItem.MDMA, 9, 135, 150, 165),//150 + new SlotReward(SlotItem.LSD, 10, 165, 180, 195),//180 + new SlotReward(SlotItem.DILDO, 11, 195, 210, 225),//210 + new SlotReward(SlotItem.LSD, 12, 225, 240, 255),//240 + new SlotReward(SlotItem.CHERRY, 1, 255, 270, 285),//270 + new SlotReward(SlotItem.MDMA, 2, 285, 300, 315),//300 + new SlotReward(SlotItem.LSD, 3, 315, 330, 345),//330 + }), + + THREE(819, new SlotReward[] { + new SlotReward(SlotItem.CHERRY, 4, 345, 0, 15),//0 + new SlotReward(SlotItem.LSD, 5, 15, 30, 45),//30 + new SlotReward(SlotItem.MDMA, 6, 45, 60, 75),//60 + new SlotReward(SlotItem.DILDO, 7, 75, 90, 105),//90 + new SlotReward(SlotItem.CHERRY, 8, 105, 120, 135),//120 + new SlotReward(SlotItem.LSD, 9, 135, 150, 165),//150 + new SlotReward(SlotItem.MDMA, 10, 165, 180, 195),//180 + new SlotReward(SlotItem.DILDO, 11, 195, 210, 225),//210 + new SlotReward(SlotItem.LSD, 12, 225, 240, 255),//240 + new SlotReward(SlotItem.MDMA, 1, 255, 270, 285),//270 + new SlotReward(SlotItem.LSD, 2, 285, 300, 315),//300 + new SlotReward(SlotItem.SEVEN, 3, 315, 330, 345),//330 + }), + ; + + private int durability; + private SlotReward[] slotRewards; + + SlotWheelType(int durability, SlotReward[] slotRewards) { + this.durability = durability; + this.slotRewards = slotRewards; + } + + public int getDurability() { + return durability; + } + + public SlotReward[] getSlotRewards() { + return slotRewards; + } + + public SlotReward getRewardByAngle(double angle) { + + if (this.slotRewards.length < 1) { + return null; + } + + for(SlotReward reward : this.slotRewards) { + if ((angle >= 0 && angle < 15 ) || (angle >= 345 && angle < 360)) + return reward; + + if (angle >= reward.getAngle()[0] && angle < reward.getAngle()[2]) { + return reward; + } + } + + return null; + } + + public ItemStack getModel() { + ItemStack model = new ItemStack(Material.DIAMOND_SWORD); + ItemMeta modelMeta = model.getItemMeta(); + + model.setDurability((short) (durability)); + + if(Core.getSettings().getType() == ServerType.VICE) modelMeta.setUnbreakable(true); + else modelMeta.spigot().setUnbreakable(true); + modelMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE); + + model.setItemMeta(modelMeta); + + return model; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/slot/SpinState.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/slot/SpinState.java new file mode 100644 index 0000000..1deb5e4 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/slot/SpinState.java @@ -0,0 +1,5 @@ +package net.grandtheftmc.core.casino.slot; + +public enum SpinState { + SPINNING, STOPPING, END, ; +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/slot/menu/SlotMachineBetMenu.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/slot/menu/SlotMachineBetMenu.java new file mode 100644 index 0000000..46c07a6 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/slot/menu/SlotMachineBetMenu.java @@ -0,0 +1,62 @@ +package net.grandtheftmc.core.casino.slot.menu; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.casino.coins.ChipAmount; +import net.grandtheftmc.core.casino.game.CasinoGame; +import net.grandtheftmc.core.casino.game.bet.CasinoBet; +import net.grandtheftmc.core.casino.game.bet.SlotMachineBet; +import net.grandtheftmc.core.inventory.CoreMenu; +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import net.grandtheftmc.core.inventory.button.ClickableItem; +import net.grandtheftmc.core.inventory.button.IMenuClickAction; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.core.util.title.NMSTitle; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; + +public class SlotMachineBetMenu extends CoreMenu { + + private final CasinoGame game; + + public SlotMachineBetMenu(CasinoGame game) { + super(3, "Place your bet", CoreMenuFlag.CLOSE_ON_NULL_CLICK, CoreMenuFlag.RESET_CURSOR_ON_OPEN); + this.game = game; + + addItem(new ClickableItem(11, ChipAmount.TEN.getItemStack(), (player, clickType) -> this.proceed(player, SlotMachineBet.TINY))); + addItem(new ClickableItem(12, ChipAmount.FIFTY.getItemStack(), (player, clickType) -> this.proceed(player, SlotMachineBet.SMALL))); + addItem(new ClickableItem(13, ChipAmount.HUNDRED.getItemStack(), (player, clickType) -> this.proceed(player, SlotMachineBet.HIGH))); + addItem(new ClickableItem(14, ChipAmount.THREE_HUNDRED.getItemStack(), (player, clickType) -> this.proceed(player, SlotMachineBet.INSANE))); + addItem(new ClickableItem(15, ChipAmount.EIGHT_HUNDRED.getItemStack(), (player, clickType) -> this.proceed(player, SlotMachineBet.ALL_IN))); + + + addItem(new ClickableItem(26, new ItemFactory(Material.GOLD_INGOT).setName(C.YELLOW + C.BOLD + "Rewards").setLore("", C.GRAY + "Click to see the roll rewards!").build(), new IMenuClickAction(){ + + @Override + public void onClick(Player player, ClickType clickType) { + new SlotRewardMenu().openInventory(player); + } + })); + } + + private void proceed(Player player, SlotMachineBet bet) { + player.closeInventory(); + if(game.isInProgress()) { + NMSTitle.sendTitle(player, "", Utils.f("&cThis Casino Game is in progress"), 1*20, 2*20, 1*20); + player.sendMessage(Lang.CASINO.f("This Casino Game is in progress.")); + return; + } + + if(!Core.getCoinManager().hasCasinoChips(player, bet.getCost().getAmount())) { + NMSTitle.sendTitle(player, "", Utils.f("&cYou cannot afford this bet"), 1*20, 2*20, 1*20); + player.sendMessage(Lang.CASINO.f("You cannot afford that bet, You have " + Core.getCoinManager().getTotalCasinoChips(player) + " chips.")); + return; + } + + Core.getCoinManager().removeCasinoChips(player, bet.getCost().getAmount()); + ((CasinoBet) game).start(player, bet); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/slot/menu/SlotRewardMenu.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/slot/menu/SlotRewardMenu.java new file mode 100644 index 0000000..444d052 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/casino/slot/menu/SlotRewardMenu.java @@ -0,0 +1,27 @@ +package net.grandtheftmc.core.casino.slot.menu; + +import org.bukkit.Material; + +import net.grandtheftmc.core.inventory.CoreMenu; +import net.grandtheftmc.core.inventory.button.MenuItem; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.factory.ItemFactory; + +public class SlotRewardMenu extends CoreMenu { + + /** + * Create a new SlotRewardMenu that tells players the rewards for winning. + */ + public SlotRewardMenu() { + super(3, "Rewards"); + + addItem(new MenuItem(10, new ItemFactory(Material.GOLD_INGOT).setName(C.WHITE + C.BOLD + "Roll 3x " + C.GOLD + C.BOLD + "'7's").setLore("", C.WHITE + "Reward: " + C.YELLOW + "$75,000-$60,000,000").build(), false)); + addItem(new MenuItem(11, new ItemFactory(Material.GOLD_INGOT).setName(C.WHITE + C.BOLD + "Roll 3x " + C.GOLD + C.BOLD + "'Cherry's").setLore("", C.WHITE + "Reward: " + C.YELLOW + "$15,000-$12,000,000").build(), false)); + addItem(new MenuItem(12, new ItemFactory(Material.GOLD_INGOT).setName(C.WHITE + C.BOLD + "Roll 3x " + C.GOLD + C.BOLD + "'Dildos's").setLore("", C.WHITE + "Reward: " + C.YELLOW + "$7,500-$2,400,000").build(), false)); + addItem(new MenuItem(13, new ItemFactory(Material.GOLD_INGOT).setName(C.WHITE + C.BOLD + "Roll 3x " + C.GOLD + C.BOLD + "'LSD's").setLore("", C.WHITE + "Reward: " + C.YELLOW + "$1,500-$1,200,000").build(), false)); + addItem(new MenuItem(14, new ItemFactory(Material.GOLD_INGOT).setName(C.WHITE + C.BOLD + "Roll 3x " + C.GOLD + C.BOLD + "'MDMA's").setLore("", C.WHITE + "Reward: " + C.YELLOW + "$750-$600,000").build(), false)); + addItem(new MenuItem(15, new ItemFactory(Material.GOLD_INGOT).setName(C.WHITE + C.BOLD + "Roll 2 " + C.GOLD + C.BOLD + "'Identicals").setLore("", C.WHITE + "Reward: " + C.YELLOW + "$450-$360,000").build(), false)); + addItem(new MenuItem(16, new ItemFactory(Material.GOLD_INGOT).setName(C.WHITE + C.BOLD + "Per " + C.GOLD + C.BOLD + "Cherry").setLore("", C.WHITE + "Reward: " + C.YELLOW + "$300-$240,000").build(), false)); + } +} + diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/BucksCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/BucksCommand.java new file mode 100644 index 0000000..0786cef --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/BucksCommand.java @@ -0,0 +1,200 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.events.UpdateEvent; +import net.grandtheftmc.core.events.UpdateEvent.UpdateReason; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserDAO; +import net.grandtheftmc.core.users.UserManager; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.UUID; + +public class BucksCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command cmd, String lbl, String[] args) { + UserManager um = Core.getUserManager(); + if (args.length == 0) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + s.sendMessage( + Utils.f("&7You have &a" + um.getLoadedUser(((Player) s).getUniqueId()).getBucks() + " Bucks&7!")); + return true; + } + if (s instanceof Player) { + User u = um.getLoadedUser(((Player) s).getUniqueId()); + if (!u.isAdmin()) { + s.sendMessage(Utils.f("&cYou do not have permission to execute this command!")); + return true; + } + } + switch (args[0].toLowerCase()) { + case "give": { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/bucks give ")); + return true; + } + int amnt; + try { + amnt = Integer.parseInt(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f("&cThe amount must be a numerical value!")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player != null) { + User user = um.getLoadedUser(player.getUniqueId()); + user.addBucks(amnt); + s.sendMessage(Utils.f("&7You gave &a$" + amnt + "&7 to &a" + player.getName())); + Bukkit.getPluginManager().callEvent(new UpdateEvent(player, UpdateReason.BUCKS)); + return true; + } +// Core.getSQL().updateAsyncLater("update users set bucks=bucks+" + amnt + " where lastname='" + args[1] + "';"); + ServerUtil.runTaskAsync(() -> UserDAO.addUserBucksByName(args[1], amnt)); + s.sendMessage(Utils.f("&cThat player is not online, so the bucks have been forcibly updated in the database.")); + return true; + } + case "giveuuid": { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/bucks give ")); + return true; + } + int amnt; + try { + amnt = Integer.parseInt(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f("&cThe amount must be a numerical value!")); + return true; + } + UUID uuid = UUID.fromString(args[1]); + Player player = Bukkit.getPlayer(uuid); + if (player != null) { + User user = um.getLoadedUser(uuid); + user.addBucks(amnt); + s.sendMessage(Utils.f("&7You gave &a$" + amnt + "&7 to &a" + player.getName())); + Bukkit.getPluginManager().callEvent(new UpdateEvent(player, UpdateReason.BUCKS)); + return true; + } +// Core.getSQL().updateAsyncLater("update users set bucks=bucks+" + amnt + " where uuid='" + uuid + "';"); + ServerUtil.runTaskAsync(() -> UserDAO.addUserBucks(uuid, amnt)); + s.sendMessage(Utils.f("&7You gave &a$" + amnt + "&7 to &a" + uuid + "&7.")); + return true; + } + case "take": { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/bucks take ")); + return true; + } + int amnt; + try { + amnt = Integer.parseInt(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f("&cThe amount must be a numerical value!")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player != null) { + User user = um.getLoadedUser(player.getUniqueId()); + user.takeBucks(amnt); + s.sendMessage(Utils.f("&7You took &a$" + amnt + "&7 to &a" + player.getName())); + Bukkit.getPluginManager().callEvent(new UpdateEvent(player, UpdateReason.BUCKS)); + return true; + } +// Core.getSQL().updateAsyncLater("update users set bucks=bucks-" + amnt + " where lastname='" + args[1] + "';"); + ServerUtil.runTaskAsync(() -> UserDAO.subtractUserBucksByName(args[1], amnt)); + s.sendMessage(Utils.f("&cThat player is not online, so the bucks have been forcibly updated in the database.")); + return true; + } + case "set": { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/bucks set ")); + return true; + } + int amnt; + try { + amnt = Integer.parseInt(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f("&cThe amount must be a numerical value!")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player != null) { + User user = um.getLoadedUser(player.getUniqueId()); + user.setBucks(amnt); + s.sendMessage(Utils.f("&7You set &a" + player.getName() + "&7's Bucks to &a$" + amnt + "&7.")); + Bukkit.getPluginManager().callEvent(new UpdateEvent(player, UpdateReason.BUCKS)); + return true; + } +// Core.getSQL().updateAsyncLater("update users set bucks=" + amnt + " where lastname='" + args[1] + "';"); + ServerUtil.runTaskAsync(() -> UserDAO.updateUserBucksByName(args[1], amnt)); + s.sendMessage(Utils.f("&cThat player is not online, so the bucks have been forcibly updated in the database.")); + return true; + } + case "balance": + if (args.length != 2) { + s.sendMessage(Utils.f("/bucks balance ")); + return true; + } + UUID sender = ((Player) s).getUniqueId(); + String name = args[1]; + Player player = Bukkit.getPlayer(args[1]); + if (player != null) { + User user = um.getLoadedUser(player.getUniqueId()); + s.sendMessage(Utils.f("&7The player &a" + player.getName() + "&7 has &a$" + user.getBucks() + " Bucks&7.")); + return true; + } + s.sendMessage(Utils.f("&cThat player is not online, so hold on a second while we gather the information from the database.")); + + ServerUtil.runTaskAsync(() -> { + int value = UserDAO.fetchUserBucksByName(name); + + ServerUtil.runTask(() -> { + if(value == -1) Bukkit.getPlayer(sender).sendMessage(Utils.f("&cThat player does not exist in the database!")); + else Bukkit.getPlayer(sender).sendMessage(Utils.f("&7The player &a" + name + "&7 has &a$" + value + " Bucks&7.")); + }); + }); + +// new BukkitRunnable() { +// @Override +// public void run() { +//// ResultSet rs = Core.getSQL().query("select bucks from users where lastname='" + name + "';"); +// int i; +// try { +// i = rs.next() ? rs.getInt("bucks") : -1; +// rs.close(); +// } catch (SQLException e) { +// e.printStackTrace(); +// return; +// } +// new BukkitRunnable() { +// @Override +// public void run() { +// if (i == -1) +// Bukkit.getPlayer(sender) +// .sendMessage(Utils.f("&cThat player does not exist in the database!")); +// else +// Bukkit.getPlayer(sender).sendMessage( +// Utils.f("&7The player &a" + name + "&7 has &a$" + i + " Bucks&7.")); +// } +// }.runTask(Core.getInstance()); +// } +// }.runTaskAsynchronously(Core.getInstance()); + default: + s.sendMessage(Utils.f("&c/bucks balance ")); + s.sendMessage(Utils.f("&c/bucks set ")); + s.sendMessage(Utils.f("&c/bucks give ")); + s.sendMessage(Utils.f("&c/bucks take ")); + return true; + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/BungeeCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/BungeeCommand.java new file mode 100644 index 0000000..333a663 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/BungeeCommand.java @@ -0,0 +1,54 @@ +package net.grandtheftmc.core.commands; + +import com.google.common.collect.Iterables; +import com.google.common.io.ByteArrayDataOutput; +import com.google.common.io.ByteStreams; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +/** + * Created by Timothy Lampen on 2017-09-04. + */ +public class BungeeCommand extends CoreCommand { + public BungeeCommand() { + super("bungeecommand", "to do bungeecommands on a bukkit server"); + } + + @Override + public void execute(CommandSender sender, String[] args) { + if(!sender.isOp()) { + sender.sendMessage(Lang.NOPERM.f("")); + return; + } + if(args.length==0) { + sender.sendMessage(Utils.f("&7/bungeecommand &e- Executes the selected command on the bungee server.")); + return; + } + StringBuilder sb = new StringBuilder(); + for(int i = 0; i onlinePlayers = Bukkit.getOnlinePlayers(); + if (!(s instanceof Player)) { + for (int i = 0; i < 300; i++) + onlinePlayers + .stream() + .filter(target -> !target.hasPermission("clearchat.staff")) + .forEach(target -> target.sendMessage("")); + s.sendMessage(Lang.GTM.f("&7Chat Cleared!")); + return true; + } + Player player = (Player) s; + if (!player.hasPermission("clearchat.staff")) { + player.sendMessage(Lang.NOPERM.toString()); + return true; + } + for (int i = 0; i < 300; i++) + onlinePlayers + .stream() + .filter(target -> !target.hasPermission("clearchat.staff")) + .forEach(target -> target.sendMessage("")); + Bukkit.broadcastMessage(Utils.f(IconConverter.convertInput("&7Chat has been cleared, sorry for the inconvenience &r:pig:"))); + return true; + } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/ConfigCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/ConfigCommand.java new file mode 100644 index 0000000..a3229a2 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/ConfigCommand.java @@ -0,0 +1,40 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.Utils; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +public class ConfigCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (!s.isOp()) { + s.sendMessage(Utils.f("&cYou do not have permission to execute this command!")); + return true; + } + if (args.length == 0) { + s.sendMessage(Utils.f("/config reload - Reload the config. Beware: this will delete changes made since the last save/restart!")); + s.sendMessage(Utils.f("/config save - Save the config. Beware: this will delete changes made in the config since the last reload/restart")); + return true; + } + switch (args[0].toLowerCase()) { + case "reload": { + Core.getInstance().reload(); + s.sendMessage(Utils.f("Reloaded the config.")); + return true; + } + case "save": { + Core.getInstance().save(false); + s.sendMessage(Utils.f("Saved the config.")); + return true; + } + default: + s.sendMessage(Utils.f("/config reload - Reload the config. Beware: this will delete changes made since the last save/restart!")); + s.sendMessage(Utils.f("/config save - Save the config. Beware: this will delete changes made in the config since the last reload/restart")); + return true; + } + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/CooldownCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/CooldownCommand.java new file mode 100644 index 0000000..8d1f5e5 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/CooldownCommand.java @@ -0,0 +1,66 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.CooldownPayload; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.Utils; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +/** + * Created by Timothy Lampen on 2017-08-26. + */ +public class CooldownCommand extends CoreCommand { + + + public CooldownCommand() { + super("cooldown", "changes cooldowns for a player"); + } + + @Override + public void execute(CommandSender sender, String[] args) { + if(args.length==0) { + sender.sendMessage(Utils.f("&e/cooldown remove ")); + sender.sendMessage(Utils.f("&e/cooldown list ")); + return; + } + if(sender instanceof Player && !Core.getUserManager().getLoadedUser(((Player)sender).getUniqueId()).getUserRank().isHigherThan(UserRank.ADMIN)) { + sender.sendMessage(Lang.NOPERM.f("")); + return; + } + switch (args[0].toLowerCase()) { + case "list": { + Player target = Bukkit.getPlayer(args[1]); + if(target==null){ + sender.sendMessage(Lang.HEY.f("&7That player is currently not online!")); + return; + } + User user = Core.getUserManager().getLoadedUser(target.getUniqueId()); + for(CooldownPayload cd : user.getCooldowns()) { + sender.sendMessage(Utils.f("&a" + cd.getId() + " &cExpire: " + cd.getExpireTime())); + } + break; + } + case "remove" : { + Player target = Bukkit.getPlayer(args[2]); + if(target==null){ + sender.sendMessage(Lang.HEY.f("&7That player is currently not online!")); + return; + } + String id = args[1].toLowerCase(); + User user = Core.getUserManager().getLoadedUser(target.getUniqueId()); + if(!user.isOnCooldown(id)){ + sender.sendMessage(Lang.HEY.f("&7That player isn't on a cooldown for that ID")); + return; + } + user.removeCooldown(id); + sender.sendMessage(Lang.HEY.f("&7You have removed the cooldown for &b" + target.getName() + " &7with id &e" + id)); + target.sendMessage(Lang.HEY.f("&7The cooldown &e" + id + " &7has been removed from your player.")); + break; + } + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/CoreCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/CoreCommand.java new file mode 100644 index 0000000..ae2d7b9 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/CoreCommand.java @@ -0,0 +1,124 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.users.User; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandMap; +import org.bukkit.command.CommandSender; +import org.bukkit.command.defaults.BukkitCommand; +import org.bukkit.entity.Player; + +import java.lang.reflect.Field; +import java.util.Arrays; + +/** + * Created by Luke Bingham on 06/07/2017. + */ +public abstract class CoreCommand extends BukkitCommand { + + private static CommandMap commandMap = null; + + private String noPermission = ChatColor.RED + "You don't have permission to use this!"; + private final String description; + private String[] aliases; + + /** + * Construct a new command. + * + * @param command command label + * @param description command description + * @param aliases command aliases + */ + public CoreCommand(String command, String description, String... aliases) { + super(command); + this.description = description; + this.aliases = aliases; + + register(); + } + + /** + * Construct a new command. + * + * @param command command label + * @param description command description + */ + public CoreCommand(String command, String description) { + super(command); + this.description = description; + + register(); + } + + @Override + public boolean execute(CommandSender commandSender, String s, String[] strings) { + if(commandSender instanceof Player && this instanceof RankedCommand) { + User u = Core.getUserManager().getLoadedUser(((Player) commandSender).getUniqueId()); + if(u.getUserRank().hasRank(((RankedCommand) this).requiredRank())) + execute((Sender) commandSender, strings); + else + sendNoPermission((Sender) commandSender); + return true; + } + + execute((Sender) commandSender, strings); + return true; + } + + /** + * This method is fired when the command is executed. + * + * @param sender sender type of the command + * @param args command arguments + */ + public abstract void execute(Sender sender, String[] args); + + private void register() { + if (commandMap != null) { + if(this.aliases != null && this.aliases.length > 0) + setAliases(Arrays.asList(this.aliases)); + setDescription(this.description); + commandMap.register(super.getName(), this); + return; + } + + try { + Field field = Bukkit.getServer().getClass().getDeclaredField("commandMap"); + field.setAccessible(true); + commandMap = (CommandMap) field.get(Bukkit.getServer()); + + if(this.aliases != null && this.aliases.length > 0) + setAliases(Arrays.asList(this.aliases)); + setDescription(this.description); + + commandMap.register(super.getName(), this); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + public String getCommand() { + return super.getName(); + } + + @Override + public String getDescription() { + return description; + } + + /** + * This string is displayed the user
+ * when they don't have the required rank. + * + * @param input permission input + */ + public void setNoPermissionMessage(String input) { + this.noPermission = ChatColor.translateAlternateColorCodes('&', input); + } + + public void sendNoPermission(Sender sender) { + sender.sendMessage(this.noPermission); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/CouponCreditsCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/CouponCreditsCommand.java new file mode 100644 index 0000000..5cacf86 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/CouponCreditsCommand.java @@ -0,0 +1,56 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +/** + * Created by Timothy Lampen on 12/7/2017. + */ +public class CouponCreditsCommand extends CoreCommand implements RankedCommand { + public CouponCreditsCommand() { + super("couponcredits", "Commands dealing with coupon credits"); + } + + @Override + public void execute(CommandSender sender, String[] args) { + if(args.length<3) { + sender.sendMessage("&7-/couponcredits give "); + return; + } + Player target = Bukkit.getPlayer(args[1]); + if(target==null) { + sender.sendMessage(Lang.REWARDS.f("&7That player is not currently online!")); + return; + } + switch (args[0].toLowerCase()) {//in case we have to add more functionality + case "give": { + int amt = 0; + try { + amt = Integer.parseInt(args[2]); + }catch (NumberFormatException nfe) { + sender.sendMessage(Lang.REWARDS.f("&6" + args[2] + " &7is not a number.")); + return; + } + User user = Core.getUserManager().getLoadedUser(target.getUniqueId()); + user.setCouponCredits(user.getCouponCredits()+amt); + target.sendMessage(Lang.REWARDS.f("&7Thanks for watching the ad! Here are &a" + amt + " &7coupon credits!")); + return; + } + } + } + + /** + * Get the required rank to use said command. + * + * @return UserRank + */ + @Override + public UserRank requiredRank() { + return UserRank.DEV; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/CrateCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/CrateCommand.java new file mode 100644 index 0000000..d314144 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/CrateCommand.java @@ -0,0 +1,126 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.voting.crates.Crate; +import net.grandtheftmc.core.voting.crates.listeners.CrateOpenListener; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; + +import java.util.Optional; + +/** + * Created by Timothy Lampen on 2017-04-24. + */ +public class CrateCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String s, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage(Lang.CRATES.f("&7Error: You have to be a player to execute this command!")); + return false; + } + + Player player = (Player) sender; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if(!user.getUserRank().isHigherThan(UserRank.ADMIN)) { + player.sendMessage(Lang.VOTE.f("&cYou do not have access to this command.")); + } + if(args.length==0 || args[0].equalsIgnoreCase("help")) { + if(user.getUserRank().isHigherThan(UserRank.ADMIN)){ + sender.sendMessage(Utils.f("&7/crate add - Creates a crate at your feet location with the specified amount of stars.")); + sender.sendMessage(Utils.f("&7/crate remove - Removes the crate that you are currently looking towards. &4/&7Uses your location so be very close to the crate&4/")); + sender.sendMessage(Utils.f("&7/crate load - Loads the rewards and crates from the config file.")); + sender.sendMessage(Utils.f("&7/crate save - Saves the rewards and crates to the config file.")); + sender.sendMessage(Utils.f("&7/crate open - Opens a specific crate at spawn.")); + } + else { + sender.sendMessage(Utils.f("&7/crate open - Opens a specific crate at spawn.")); + } + return true; + + } + if (!user.getUserRank().isHigherThan(UserRank.ADMIN) && !args[0].equalsIgnoreCase("open")) { + sender.sendMessage(Lang.CRATES.f("&7You do not have permission to execute this command.")); + return false; + } + switch (args[0].toLowerCase()) { + case "add": { + if (args.length != 2) { + sender.sendMessage(Lang.CRATES.f("&7/crate add ")); + return false; + } + if (!Utils.isInteger(args[1])) { + sender.sendMessage(Lang.CRATES.f("&7Error: The argument is not an integer!")); + return false; + } + int stars = Integer.parseInt(args[1]); + player.sendMessage(Lang.CRATES.f("&7You have created a new vote crate with " + stars + " stars!")); + Core.getCrateManager().addCrate(new Crate(player.getLocation(), stars)); + return true; + } + case "load": + Core.getSettings().setCratesConfig(Utils.loadConfig("crates")); + Core.getSettings().setCrateRewardsConfig(Utils.loadConfig("craterewards")); + Core.getCrateManager().loadCrates(); + Core.getCrateManager().loadRewards(); + player.sendMessage(Lang.CRATES.f("&7You have loaded crates & crate rewards.")); + return true; + case "save": + Core.getCrateManager().save(false); + player.sendMessage(Lang.CRATES.f("&7You have saved crates.")); + return true; + case "remove": + int amountRemoved = 0; + Crate crate; + for (Entity e : player.getNearbyEntities(1, 1, 1)) { + if (e.getType() == EntityType.ARMOR_STAND) { + if (Core.getCrateManager().getCrate((LivingEntity) e).isPresent()) { + crate = Core.getCrateManager().getCrate((LivingEntity) e).get(); + Core.getCrateManager().removeCrate(crate); + amountRemoved += 1; + } else { + ((LivingEntity) e).setHealth(0); + e.remove(); + } + } + } + player.sendMessage(Lang.CRATES.f("&7You have removed " + amountRemoved + " crates.")); + return true; + case "open": { + if(args.length != 2) { + sender.sendMessage(Lang.CRATES.f("&7/crate open ")); + return false; + } + if(!Utils.isInteger(args[1])) { + sender.sendMessage(Lang.CRATES.f("&7Error: The argument is not an integer!")); + return false; + } + int stars = Integer.parseInt(args[1]); + Optional optCrate = Core.getCrateManager().getCrates().stream().filter(c -> c.getCrateStars().getStars()==stars).findFirst(); + if(!optCrate.isPresent()) { + sender.sendMessage(Lang.CRATES.f("&7Unable to find crate with that amount of stars!")); + return false; + } + player.openInventory(CrateOpenListener.generateCratePreview(user, optCrate.get().getCrateStars()));//i know this is horrible but its only suppose to be temp. + user.setSelectedCrate(optCrate.get()); + return true; + } + default: + sender.sendMessage(Utils.f("&7/crate open - Creates a crate at your feet location with the specified amount of stars.")); + sender.sendMessage(Utils.f("&7/crate add - Creates a crate at your feet location with the specified amount of stars.")); + sender.sendMessage(Utils.f("&7/crate remove - Removes the crate that you are currently looking towards.")); + sender.sendMessage(Utils.f("&7/crate load - Loads the rewards and crates from the config file.")); + sender.sendMessage(Utils.f("&7/crate save - Saves the rewards and crates to the config file.")); + return false; + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/CrowbarCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/CrowbarCommand.java new file mode 100644 index 0000000..2e05952 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/CrowbarCommand.java @@ -0,0 +1,318 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.UserDAO; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.events.UpdateEvent; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserManager; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.UUID; + +/** + * Created by Timothy Lampen on 2017-04-24. + */ +public class CrowbarCommand implements CommandExecutor { + + @Override + @SuppressWarnings("deprecation") + public boolean onCommand(CommandSender s, Command cmd, String lbl, String[] args) { + UserManager um = Core.getUserManager(); + if (args.length == 0) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + s.sendMessage( + Utils.f("&7You have &e" + um.getLoadedUser(((Player) s).getUniqueId()).getCrowbars() + " &7Crowbars!")); + return true; + } + if (s instanceof Player) { + User u = um.getLoadedUser(((Player) s).getUniqueId()); + if (!u.isAdmin() && !args[0].equalsIgnoreCase("balance")) { + s.sendMessage(Utils.f("&cYou do not have permission to execute this command!")); + return true; + } + } + switch (args[0].toLowerCase()) { + case "give": { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/crowbar give ")); + return true; + } + int amnt; + try { + amnt = Integer.parseInt(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f("&cThe amount must be a numerical value!")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player != null) { + User user = um.getLoadedUser(player.getUniqueId()); + user.addCrowbars(amnt); + user.insertLog(player, "giveCrowbarsCommand", "CROWBARS", amnt + " Crowbars", amnt, 0); + Bukkit.getPluginManager().callEvent(new UpdateEvent(player, UpdateEvent.UpdateReason.CROWBARS)); + s.sendMessage(Utils.f("&7You gave &e" + amnt + " Crowbars&7 to &a" + player.getName())); + return true; + } +// Core.getSQL().updateAsyncLater("update users set crowbars=crowbars+" + amnt + " where lastname='" + args[1] + "';"); + + ServerUtil.runTaskAsync(() -> { + UUID uuid = UserDAO.getUuidByName(args[1]); + UserDAO.addUserCrowbars(uuid, amnt); +// UUID uuid = UserDAO.getUuidByName(args[1]); + + if(uuid == null) Core.log("Error while logging giveCrowbarsCommand for uuid " + uuid + ", name " + args[1] + ", amnt " + amnt); + else Utils.insertLog(uuid, args[1], "giveCrowbarsCommand", "CROWBARS", amnt + " Crowbars", amnt, 0); + }); + + s.sendMessage(Utils.f("&cThat player is not online, so the crowbars have been forcibly updated in the database.")); +// new BukkitRunnable() { +// @Override +// public void run() { +// ResultSet rs = Core.getSQL().query("select uuid,lastname from users where lastname='" + args[1] + "';"); +// UUID uuid = null; +// String name = args[1]; +// try { +// if (rs.next()) { +// uuid = UUID.fromString(rs.getString("uuid")); +// name = rs.getString("lastname"); +// } +// rs.close(); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// if (uuid == null) { +// Core.log("Error while logging giveCrowbarsCommand for uuid " + uuid + ", name " + name + ", amnt " + amnt); +// } else Utils.insertLog(uuid, name, "giveCrowbarsCommand", "CROWBARS", amnt + " Crowbars", amnt, 0); +// +// } +// }.runTaskAsynchronously(Core.getInstance()); + return true; + } + case "giveuuid": { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/crowbars give ")); + return true; + } + int amnt; + try { + amnt = Integer.parseInt(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f("&cThe amount must be a numerical value!")); + return true; + } + UUID uuid = UUID.fromString(args[1]); + Player player = Bukkit.getPlayer(uuid); + if (player != null) { + User user = um.getLoadedUser(uuid); + user.addCrowbars(amnt); + user.insertLog(player, "giveCrowbarsCommand", "CROWBARS", amnt + " Crowbars", amnt, 0); + Bukkit.getPluginManager().callEvent(new UpdateEvent(player, UpdateEvent.UpdateReason.CROWBARS)); + s.sendMessage(Utils.f("&7You gave &e" + amnt + " Crowbars&7 to &a" + player.getName())); + return true; + } +// Core.getSQL().updateAsyncLater("update users set crowbars=crowbars+" + amnt + " where uuid='" + uuid + "';"); + + ServerUtil.runTaskAsync(() -> { + UserDAO.addUserCrowbars(uuid, amnt); + String name = UserDAO.getNameByUuid(uuid); + + if(name == null) Core.log("Error while logging giveCrowbarsCommand for uuid " + uuid + ", name " + name + ", amnt " + amnt); + else Utils.insertLog(uuid, name, "giveCrowbarsCommand", "CROWBARS", amnt + " Crowbars", amnt, 0); + }); + + s.sendMessage(Utils.f("&cThat player is not online, so the crowbars have been forcibly updated in the database.")); +// new BukkitRunnable() { +// @Override +// public void run() { +// ResultSet rs = Core.getSQL().query("select lastname from users where uuid='" + args[1] + "';"); +// String name = null; +// try { +// if (rs.next()) { +// name = rs.getString("lastname"); +// } +// rs.close(); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// if (name == null) { +// Core.log("Error while logging giveCrowbarsCommand for uuid " + uuid + ", name " + name + ", amnt " + amnt); +// } else Utils.insertLog(uuid, name, "giveCrowbarsCommand", "CROWBARS", amnt + " Crowbars", amnt, 0); +// +// } +// }.runTaskAsynchronously(Core.getInstance()); + return true; + } + case "take": { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/crowbars take ")); + return true; + } + int amnt; + try { + amnt = Integer.parseInt(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f("&cThe amount must be a numerical value!")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player != null) { + User user = um.getLoadedUser(player.getUniqueId()); + user.takeCrowbars(amnt); + user.insertLog(player, "takeCrowbarsCommand", "CROWBARS", amnt + " Crowbars", -amnt, 0); + Bukkit.getPluginManager().callEvent(new UpdateEvent(player, UpdateEvent.UpdateReason.CROWBARS)); + s.sendMessage(Utils.f("&7You took &e" + amnt + " Crowbars&7 to &a" + player.getName())); + return true; + } +// Core.getSQL().updateAsyncLater("update users set crowbars=crowbars-" + amnt + " where lastname='" + args[1] + "';"); + + ServerUtil.runTaskAsync(() -> { + UUID uuid = UserDAO.getUuidByName(args[1]); + UserDAO.subtractUserCrowbars(uuid, amnt); + + if(uuid == null) Core.log("Error while logging takeCrowbarsCommand for uuid " + uuid + ", name " + args[1] + ", amnt " + -amnt); + else Utils.insertLog(uuid, args[1], "takeCrowbarsCommand", "CROWBARS", amnt + " Crowbars", -amnt, 0); + }); + + s.sendMessage(Utils.f("&cThat player is not online, so the crowbars have been forcibly updated in the database.")); +// new BukkitRunnable() { +// @Override +// public void run() { +// ResultSet rs = Core.getSQL().query("select uuid,lastname from users where lastname='" + args[1] + "';"); +// UUID uuid = null; +// String name = args[1]; +// try { +// if (rs.next()) { +// uuid = UUID.fromString(rs.getString("uuid")); +// name = rs.getString("lastname"); +// } +// rs.close(); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// if (uuid == null) { +// Core.log("Error while logging takeCrowbarsCommand for uuid " + uuid + ", name " + name + ", amnt " + -amnt); +// } else Utils.insertLog(uuid, name, "takeCrowbarsCommand", "CROWBARS", amnt + " Crowbars", -amnt, 0); +// +// } +// }.runTaskAsynchronously(Core.getInstance()); + return true; + } + case "set": { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/crowbars set ")); + return true; + } + int amnt; + try { + amnt = Integer.parseInt(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f("&cThe amount must be a numerical value!")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player != null) { + User user = um.getLoadedUser(player.getUniqueId()); + user.setCrowbars(amnt); + user.insertLog(player, "setCrowbarsCommand", "CROWBARS", amnt + " Crowbars", amnt, 0); + Bukkit.getPluginManager().callEvent(new UpdateEvent(player, UpdateEvent.UpdateReason.CROWBARS)); + s.sendMessage(Utils.f("&7You set &a" + player.getName() + "&7's Crowbars to &e" + amnt + "&7.")); + return true; + } +// Core.getSQL().updateAsyncLater("update users set crowbars=" + amnt + " where lastname='" + args[1] + "';"); + + ServerUtil.runTaskAsync(() -> { + UUID uuid = UserDAO.getUuidByName(args[1]); + UserDAO.updateUserCrowbars(uuid, amnt); + + if(uuid == null) Core.log("Error while logging setCrowbarsCommand for uuid " + uuid + ", name " + args[1] + ", amnt " + amnt); + else Utils.insertLog(uuid, args[1], "setCrowbarsCommand", "CROWBARS", amnt + " Crowbars", amnt, 0); + }); + + s.sendMessage(Utils.f("&cThat player is not online, so the crowbars have been forcibly updated in the database.")); +// new BukkitRunnable() { +// @Override +// public void run() { +// ResultSet rs = Core.getSQL().query("select uuid,lastname from users where lastname='" + args[1] + "';"); +// UUID uuid = null; +// String name = args[1]; +// try { +// if (rs.next()) { +// uuid = UUID.fromString(rs.getString("uuid")); +// name = rs.getString("lastname"); +// } +// rs.close(); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// if (uuid == null) { +// Core.log("Error while logging setCrowbarsCommand for uuid " + uuid + ", name " + name + ", amnt " + amnt); +// } else Utils.insertLog(uuid, name, "setCrowbarsCommand", "CROWBARS", amnt + " Crowbars", amnt, 0); +// +// } +// }.runTaskAsynchronously(Core.getInstance()); + return true; + } + case "balance": + if (args.length != 2) { + s.sendMessage(Utils.f("/crowbars balance ")); + return true; + } + UUID sender = ((Player) s).getUniqueId(); + String name = args[1]; + Player player = Bukkit.getPlayer(args[1]); + if (player != null) { + User user = um.getLoadedUser(player.getUniqueId()); + s.sendMessage( + Utils.f("&7The player &a" + player.getName() + "&7 has &a" + user.getCrowbars() + " Crowbars&7.")); + return true; + } + s.sendMessage(Utils.f("&cThat player is not online, so hold on a second while we gather the information from the database.")); + + ServerUtil.runTaskAsync(() -> { + UUID uuid = UserDAO.getUuidByName(args[1]); + int value = UserDAO.getUserCrowbars(uuid); + ServerUtil.runTask(() -> { + if (value == -1) Bukkit.getPlayer(sender).sendMessage(Utils.f("&cThat player does not exist in the database!")); + else Bukkit.getPlayer(sender).sendMessage(Utils.f("&7The player &a" + name + "&7 has &e" + value + " Crowbars&7.")); + }); + }); + +// Bukkit.getScheduler().scheduleAsyncDelayedTask(Core.getInstance(), () -> { +// ResultSet rs = Core.getSQL().query("select crowbars from users where lastname='" + name + "';"); +// int i; +// try { +// i = rs.next() ? rs.getInt("bucks") : -1; +// rs.close(); +// } catch (SQLException e) { +// e.printStackTrace(); +// return; +// } +// Bukkit.getScheduler().scheduleSyncDelayedTask(Core.getInstance(), () -> { +// if (i == -1) +// Bukkit.getPlayer(sender).sendMessage(Utils.f("&cThat player does not exist in the database!")); +// else +// Bukkit.getPlayer(sender).sendMessage(Utils.f("&7The player &a" + name + "&7 has &e" + i + " Crowbars&7.")); +// }); +// }); + default: + s.sendMessage(Utils.f("&c/crowbars balance [player]")); + s.sendMessage(Utils.f("&c/crowbars set ")); + s.sendMessage(Utils.f("&c/crowbars give ")); + s.sendMessage(Utils.f("&c/crowbars take ")); + return true; + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/DiscordCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/DiscordCommand.java new file mode 100644 index 0000000..9a663b4 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/DiscordCommand.java @@ -0,0 +1,20 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class DiscordCommand extends CoreCommand { + + public DiscordCommand() { + super("discord", "Get the invite link to Discord."); + } + + @Override + public void execute(Player sender, String[] args) { + sender.sendMessage(Lang.DISCORD.f("&7Discord Invite link: &9" + (Core.getSettings().isSister() ? "https://discord.gg/ZtpMZ6g" : "https://discord.gg/4P6DVKZ"))); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/EditModeCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/EditModeCommand.java new file mode 100644 index 0000000..0da18d9 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/EditModeCommand.java @@ -0,0 +1,111 @@ +package net.grandtheftmc.core.commands; + +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.entity.Player; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.Utils; + +public class EditModeCommand extends CoreCommand implements RankedCommand { + + /** + * Construct a new command. + */ + public EditModeCommand() { + super("editmode", "A staff command for allowing map editing."); + super.setNoPermissionMessage(Utils.f("&cYou do not have permission to execute this command!")); + } + + /** + * This method is fired when the command is executed. + * + * @param sender sender type of the command + * @param args command arguments + */ + @Override + public void execute(Player sender, String[] args) { + if (args.length >= 1) { + if (Bukkit.getPlayer(args[0]) != null) { + Player target = Bukkit.getPlayer(args[0]); + User u = Core.getUserManager().getLoadedUser(target.getUniqueId()); + if (u.hasEditMode()) { + u.setEditMode(false); + target.setGameMode(Core.getSettings().getDefaultGameMode()); + } else { + u.setEditMode(true); + target.setGameMode(GameMode.CREATIVE); + } + + sender.sendMessage(Utils.f("You " + (u.hasEditMode() ? "enabled" : "disabled") + " editmode for " + u.getColoredName(target))); + return; + } + } + + UUID uuid = sender.getUniqueId(); + User u = Core.getUserManager().getLoadedUser(uuid); + + boolean mode = !u.hasEditMode(); + u.setEditMode(mode); + sender.setGameMode(mode ? GameMode.CREATIVE : Core.getSettings().getDefaultGameMode()); + + sender.sendMessage(Utils.f("&a&lEDITMODE&7&l> &fYou " + (mode ? "enabled" : "disabled") + " edit mode.")); + } + + /** + * Get the required rank to use said command. + * + * @return UserRank + */ + @Override + public UserRank requiredRank() { + //return UserRank.ADMIN; + return UserRank.BUILDER; + } + + // @Override +// public boolean onCommand(CommandSender s, Command cmd, String label, String[] args) { +// if (!(s instanceof Player)) { +// if (args.length == 1) { +// if (Bukkit.getPlayer(args[0]) != null) { +// Player target = Bukkit.getPlayer(args[0]); +// User u = Core.getUserManager().getLoadedUser(target.getUniqueId()); +// if (u.hasEditMode()) { +// u.setEditMode(false); +// target.setGameMode(Core.getSettings().getDefaultGameMode()); +// } else { +// u.setEditMode(true); +// target.setGameMode(GameMode.CREATIVE); +// } +// s.sendMessage(Utils.f("You " + (u.hasEditMode() ? "enabled" : "disabled") + +// " editmode for " + u.getColoredName(target))); +// return true; +// } +// } +// s.sendMessage(Utils.f("&cYou are not a player!")); +// return true; +// } +// Player player = (Player) s; +// UUID uuid = ((Player) s).getUniqueId(); +// User u = Core.getUserManager().getLoadedUser(uuid); +// if (!u.isAdmin() && !s.hasPermission("editmode")) { +// s.sendMessage(Utils.f("&cYou do not have permission to execute this command!")); +// u.setEditMode(false); +// return true; +// } +// boolean mode = !u.hasEditMode(); +// u.setEditMode(mode); +// if (mode) { +// player.setGameMode(GameMode.CREATIVE); +// } else { +// player.setGameMode(Core.getSettings().getDefaultGameMode()); +// } +// +// s.sendMessage(Utils.f("&a&lEDITMODE&7&l> &fYou " + (mode ? "enabled" : "disabled") + " edit mode.")); +// return true; +// } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/EventTagCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/EventTagCommand.java new file mode 100644 index 0000000..c91ea60 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/EventTagCommand.java @@ -0,0 +1,157 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.users.eventtag.EventTag; +import net.grandtheftmc.core.users.UserDAO; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.users.eventtag.EventTagDAO; +import net.grandtheftmc.core.users.eventtag.TagVisibility; +import net.grandtheftmc.core.util.ServerUtil; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.Set; +import java.util.UUID; + +/** + * Created by Timothy Lampen on 1/4/2018. + */ +public class EventTagCommand extends CoreCommand { + public EventTagCommand() { + super("eventtag", "Commands dealing with the cosmetic tag system.", "tag", "tags"); + } + + @Override + public void execute(CommandSender sender, String[] args) { + if(sender instanceof Player) { + Player player = (Player)sender; + if(!Core.getUserManager().getLoadedUser(player.getUniqueId()).getUserRank().isHigherThan(UserRank.ADMIN)) + return; + } + + if(args.length==0){ + sender.sendMessage(Utils.f("&c/eventtag setvis - &7Sets the visibility of the specified tag. 0 = everyone, 1 = people who have unlocked it, 2 = no one.")); + sender.sendMessage(Utils.f("&c/eventtag refresh - &7Refreshes the visibility cache.")); + sender.sendMessage(Utils.f("&c/eventtag give - &7Gives the specified player the specified tag.")); + sender.sendMessage(Utils.f("&c/eventtag remove - &7Removes specified tag from the player.")); + sender.sendMessage(Utils.f("&c/eventtag list - &7Lists all the eventtags that the specified player has")); + sender.sendMessage(Utils.f("&c/eventtag avaliable - &7Lists all avaliable event tags.")); + sender.sendMessage(Utils.f("&4&lNote that players may have to relog for the changes to take place.")); + return; + } + + if(args[0].equalsIgnoreCase("avaliable")) { + for(EventTag tag : EventTag.values()) { + sender.sendMessage(Utils.f("&6Name: &a" + tag.toString() + " &6Visibility: &a" + EventTagDAO.getTagVisibility(tag))); + } + return; + } + if(args[0].equalsIgnoreCase("refresh")) { + ServerUtil.runTaskAsync(EventTagDAO::refreshTagVisiblity); + sender.sendMessage(Lang.REWARDS.f("&aYou have refreshed the local tag visibility cache.")); + return; + } + if(args[0].equalsIgnoreCase("setvis")) { + if(args.length!=3) { + sender.sendMessage(Utils.f("&c/eventtag setvis - &7Sets the visibility of the specified tag. 0 = everyone, 1 = people who have unlocked it, 2 = no one.")); + return; + } + EventTag tag; + try { + tag = EventTag.valueOf(args[1].toUpperCase()); + }catch (IllegalArgumentException iae) { + sender.sendMessage(Lang.REWARDS.f("&cThat event tag does not exist. Do the command /eventtag avaliable to view all event tags.")); + return; + } + + TagVisibility vis; + try { + vis = TagVisibility.fromID(Integer.parseInt(args[2])); + }catch (NumberFormatException nfe) { + sender.sendMessage(Lang.REWARDS.f("&a" + args[2] + " &cis not a number!")); + return; + } + + if(vis==null) { + sender.sendMessage(Lang.REWARDS.f("&a" + args[2] + " &cis not an id for visibility!")); + return; + } + ServerUtil.runTaskAsync(() -> { + EventTagDAO.setVisibility(tag, vis); + EventTagDAO.refreshTagVisiblity(); + }); + sender.sendMessage(Lang.REWARDS.f("&aYou have set the visibility of &6" + tag + " &ato &6" + vis)); + return; + } + + UUID targetUUID; + if(Bukkit.getPlayer(args[1])!=null) + targetUUID = Bukkit.getPlayer(args[1]).getUniqueId(); + else + targetUUID = UserDAO.getUuidByName(args[1]); + if(targetUUID==null) { + sender.sendMessage(Lang.REWARDS.f("&cThe requested player cannot be found online or in the database. If trying to select player that is offline, the name is case-sensitive.")); + return; + } + + if(args[0].equalsIgnoreCase("list")) { + if(args.length!=2){ + sender.sendMessage(Utils.f("&c/eventtag remove - &7Removes specified tag from the player.")); + return; + } + sender.sendMessage(Lang.REWARDS.f("&7Compiling list...")); + ServerUtil.runTaskAsync(() -> { + sender.sendMessage(Lang.REWARDS.f("&7Event Tags For &a" + args[1])); + Set tags = UserDAO.fetchReadablePlayerTags(targetUUID); + for(String t: tags) { + sender.sendMessage(Utils.f(t)); + } + }); + return; + } + + + try { + EventTag.valueOf(args[2].toUpperCase()); + }catch (IllegalArgumentException iae) { + sender.sendMessage(Lang.REWARDS.f("&cThat event tag does not exist. Do the command /eventtag avaliable to view all event tags.")); + return; + } + EventTag tag = EventTag.valueOf(args[2].toUpperCase()); + + + + switch (args[0].toLowerCase()) { + case "give": + if(args.length!=3) { + sender.sendMessage(Utils.f("&c/eventtag give - &7Gives the specified player the specified tag.")); + return; + } + ServerUtil.runTaskAsync(() -> { + UserDAO.addPlayerTag(targetUUID, tag); + }); + sender.sendMessage(Lang.REWARDS.f("&aYou have given the player the specified tag. The player will have to relog for the changes to take effect.")); + break; + case "remove": + if(args.length!=3) { + sender.sendMessage(Utils.f("&c/eventtag remove - &7Removes specified tag from the player.")); + return; + } + ServerUtil.runTaskAsync(() -> { + UserDAO.removePlayerTag(targetUUID, tag); + }); + sender.sendMessage(Lang.REWARDS.f("&cYou have removed the player the specified tag. The player will have to relog for the changes to take effect.")); + break; + default: + sender.sendMessage(Utils.f("&c/eventtag give - &7Gives the specified player the specified tag.")); + sender.sendMessage(Utils.f("&c/eventtag remove - &7Removes specified tag from the player.")); + sender.sendMessage(Utils.f("&c/eventtag list - &7Lists all the eventtags that the specified player has")); + sender.sendMessage(Utils.f("&c/eventtag avaliable - &7Lists all avaliable event tags.")); + sender.sendMessage(Utils.f("&4&lNote that players may have to relog for the changes to take place.")); + break; + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/ExampleCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/ExampleCommand.java new file mode 100644 index 0000000..90ebe0d --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/ExampleCommand.java @@ -0,0 +1,50 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.users.UserRank; +import org.bukkit.entity.Player; + +/** + * Created by Luke Bingham on 06/07/2017. + */ +public class ExampleCommand extends CoreCommand implements RankedCommand { + + // (Q) How to register this command? + // (A) Simply call the constructor in onEnable + //new ExampleCommand(); + + /** + * Construct a new command. + */ + public ExampleCommand() { + super( + "example", //Command + "Description here", //Description + "ex1", "ex2" //Aliases + ); + + setNoPermissionMessage("&c&lError&f: &7You cannot use this command!"); + } + + /** + * This method is fired when the command is executed. + * + * @param sender sender type of the command + * @param args command arguments + */ + @Override + public void execute(Player sender, String[] args) { + if(args.length <= 0) { + sender.sendMessage("Hey, It works!"); + } + } + + /** + * Get the required rank to use said command. + * + * @return UserRank + */ + @Override + public UserRank requiredRank() { + return UserRank.DEV; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/FacebookCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/FacebookCommand.java new file mode 100644 index 0000000..08a1fdc --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/FacebookCommand.java @@ -0,0 +1,18 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import org.bukkit.entity.Player; + +public class FacebookCommand extends CoreCommand { + + public FacebookCommand() { + super("facebook", "Get the link to our official Facebook page."); + } + + @Override + public void execute(Player sender, String[] args) { + if (Core.getSettings().isSister()) return; + sender.sendMessage(Lang.FACEBOOK.f("&7Here is the link to our official Facebook page! &9https://www.facebook.com/Grandtheftminecart/")); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/ForumRankCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/ForumRankCommand.java new file mode 100644 index 0000000..4e4a9dc --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/ForumRankCommand.java @@ -0,0 +1,61 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.enjin.EnjinCache; +import net.grandtheftmc.core.enjin.EnjinCore; +import net.grandtheftmc.core.enjin.data.EnjinResponse; +import net.grandtheftmc.core.enjin.data.EnjinResult; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class ForumRankCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (s instanceof Player) { + User u = Core.getUserManager().getLoadedUser(((Player) s).getUniqueId()); + if (!u.isRank(UserRank.MANAGER)) { + s.sendMessage(Utils.f("&cYou do not have permission to execute this command!")); + return true; + } + } + + if (args.length == 2 && l.equalsIgnoreCase("forumrank")) { + String playername = args[0], targetRank = args[1]; + + //We can set his rank, add a forum update for Enjin. + EnjinCore.tagUser(playername, targetRank, new EnjinResponse() { + @Override + public void callback(EnjinResult response, String user, String tag) { + if (response.equals(EnjinResult.SUCCESS)) { + s.sendMessage(ChatColor.GREEN + "Enjin forum rank set successfully (" + user + " -> " + tag + ")"); + } else { + s.sendMessage(ChatColor.RED + "Failed to update Enjin form rank (" + user + " -> " + tag + "). Reason = " + response.toString() + "."); + + //try listing valid tags. + StringBuilder valTags = new StringBuilder(); + for (String r : EnjinCache.getTagNames()) { + valTags.append(r).append(", "); + } + + //Remove trailing ", " + valTags.setLength(valTags.length() - 2); + + s.sendMessage(Utils.f("&cValid Tags: " + valTags.toString())); + } + } + }); + + return true; + } else { + s.sendMessage(Utils.f("&c/forumrank ")); + return false; + } + } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/GlobalMuteCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/GlobalMuteCommand.java new file mode 100644 index 0000000..6d55cfe --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/GlobalMuteCommand.java @@ -0,0 +1,32 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class GlobalMuteCommand implements CommandExecutor { + public static boolean chatMuted; + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof Player)) { + chatMuted = !chatMuted; + s.sendMessage(Lang.GTM.f("&7Chat has been &a" + (chatMuted ? "muted&7!" : "unmuted&7!"))); + return true; + } + Player player = (Player) s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (!user.isRank(UserRank.SRMOD)) { + player.sendMessage(Lang.NOPERM.toString()); + return true; + } + chatMuted = !chatMuted; + player.sendMessage(Lang.GTM.f("&7Chat has been &a" + (chatMuted ? "muted&7!" : "unmuted&7!"))); + return true; + } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/IgnoreCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/IgnoreCommand.java new file mode 100644 index 0000000..08819b8 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/IgnoreCommand.java @@ -0,0 +1,66 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +/** + * Created by Liam on 2/10/2016. + */ +public class IgnoreCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command cmd, String lbl, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + Player player = (Player) s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (lbl.equalsIgnoreCase("ignored") || args.length == 0 || (args.length > 0 && args[0].equalsIgnoreCase("list"))) { + if (user.getIgnored().isEmpty()) { + s.sendMessage(Lang.GTM.f("&7You are not ignoring any players!")); + return true; + } + s.sendMessage(Lang.GTM.f("&7You are ignoring the following players:")); + String st = ""; + for (String name : user.getIgnored()) + st += "&a" + name + "&7, "; + if (st.endsWith("&7, ")) + st = st.substring(0, st.length() - 4); + s.sendMessage(Utils.f(st)); + return true; + } + if (args[0].equalsIgnoreCase("clear")) { + user.getIgnored().clear(); + user.updateIgnored(); + s.sendMessage(Lang.MSG.f("&7You are no longer ignoring anyone!")); + return true; + } + Player target = Bukkit.getPlayer(args[0]); + if (target == null) { + s.sendMessage(Utils.f(Lang.MSG + "&7That player is not online!")); + return true; + } + if (Core.getUserManager().getLoadedUser(target.getUniqueId()).isRank(UserRank.HELPOP)) { + player.sendMessage(Lang.GTM.f("&7You may not ignore staff!")); + return true; + } + if (user.isIgnored(target.getName())) { + user.removeIgnored(target.getName()); + player.sendMessage(Lang.GTM.f("&7You are no longer ignoring &a" + Core.getUserManager().getLoadedUser(target.getUniqueId()).getColoredName(target) + "&7!")); + return true; + } + user.addIgnored(target.getName()); + player.sendMessage(Lang.GTM.f("&7You ignored &a" + Core.getUserManager().getLoadedUser(target.getUniqueId()).getColoredName(target) + "&7!")); + return true; + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/InfoCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/InfoCommand.java new file mode 100644 index 0000000..3693331 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/InfoCommand.java @@ -0,0 +1,42 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.tutorials.Help; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class InfoCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + Player player = (Player) s; + if(args.length == 1) { + if (args[0].equalsIgnoreCase("list")) { + String topics = StringUtils.join(Help.getHelpData().keySet(), "&7, &c"); + player.sendMessage(Lang.GTM.f("&7Topics: &c" + topics)); + return true; + } + if(Help.getHelpMessage(args[0]).isPresent()) { + player.sendMessage(Core.getAnnouncer().getHeader()); + for(String msg : Help.getHelpMessage(args[0]).get()) { + player.sendMessage(Utils.f(msg)); + } + player.sendMessage(Core.getAnnouncer().getFooter()); + } else { + player.sendMessage(Lang.HEY.f("&7Sorry! We don't have any information on that subject. \n&7Ask a staff member directly with /help ")); + } + } else { + player.sendMessage(Lang.HEY.f("&7You must specify what you need help with! \n&7Example: &c/how permits")); + } + return true; + } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/ListCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/ListCommand.java new file mode 100644 index 0000000..3e0d5d3 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/ListCommand.java @@ -0,0 +1,44 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import org.apache.commons.lang.StringUtils; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +import java.util.ArrayList; +import java.util.Collection; + +public class ListCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + Collection defaultPlayers = new ArrayList<>(); + Collection donators = new ArrayList<>(); + Bukkit.getOnlinePlayers().forEach(online -> { + User targetUser = Core.getUserManager().getLoadedUser(online.getUniqueId()); + if (online.getGameMode() == GameMode.CREATIVE || online.getGameMode() == GameMode.SPECTATOR || online.isOp()) + return; + if (targetUser.isRank(UserRank.VIP)) { + donators.add(online.getDisplayName()); + } else { + defaultPlayers.add(online.getDisplayName()); + } + }); + String list = StringUtils.join(donators, "&7, ") + "&7," + StringUtils.join(defaultPlayers, "&7, "); + if (donators.isEmpty() && defaultPlayers.isEmpty()) { + s.sendMessage(Lang.GTM.f("&7There are no players online!")); + } else { + s.sendMessage(Lang.GTM.f("&7There are &a" + Bukkit.getOnlinePlayers().size() + " &7players online" + + " out of a maximum of &a" + Bukkit.getMaxPlayers() + "&7!")); + s.sendMessage(Utils.f("&7" + list)); + } + return true; + } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/MaxPlayersCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/MaxPlayersCommand.java new file mode 100644 index 0000000..dfb39c2 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/MaxPlayersCommand.java @@ -0,0 +1,40 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class MaxPlayersCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender commandSender, Command command, String s, String[] strings) { + if (commandSender instanceof Player) { + User u = Core.getUserManager().getLoadedUser(((Player) commandSender).getUniqueId()); + if (!u.getUserRank().isHigherThan(UserRank.ADMIN)) { + commandSender.sendMessage(Lang.NOPERM.s()); + return true; + } + } + if (strings.length != 1) { + commandSender.sendMessage(Lang.GTM.f("&7Usage: &a/maxplayers [number]")); + return true; + } + int players; + try { + players = Integer.parseInt(strings[0]); + } catch (NumberFormatException exception) { + commandSender.sendMessage(Lang.GTM.f("&cThat is not a valid number!")); + return true; + } + Utils.setMaxPlayers(players); + commandSender.sendMessage(Lang.GTM.f("&aYou successfully set the number of max players!")); + return true; + } + +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/MessageCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/MessageCommand.java new file mode 100644 index 0000000..d16ba62 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/MessageCommand.java @@ -0,0 +1,74 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.handlers.chat.ChatManager; +import net.grandtheftmc.core.users.Pref; +import net.grandtheftmc.core.users.User; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class MessageCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command cmd, String lbl, String[] args) { + if (args.length < 2) { + s.sendMessage(Utils.f("&c/" + lbl + " ")); + return true; + } + Player target = Bukkit.getPlayer(args[0]); + if (target == null) { + s.sendMessage(Utils.f(Lang.MSG + "&7That player is not online!")); + return true; + } + User targetUser = Core.getUserManager().getLoadedUser(target.getUniqueId()); + if ((targetUser.isIgnored(s.getName()) || !targetUser.getPref(Pref.MESSAGES)) && !s.hasPermission("core.bypassmessages")) { + s.sendMessage(Utils.f(Lang.MSG + "&7That player has disabled PM's!")); + return true; + } + String message = args[1]; + for (int i = 2; i < args.length; i++) { + message = message + ' ' + args[i]; + } + String senderName; + if (s instanceof Player) { + Player player = (Player) s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + senderName = user.getColoredName(player); + user.setLastMessage(target.getUniqueId()); + targetUser.setLastMessage(player.getUniqueId()); + } else { + senderName = "&6&l" + s.getName(); + targetUser.setLastMessage(null); + } + for (String text : message.split(" ")) { + if (ChatManager.getAdHandler().matchesAdvertisement(text)) { + s.sendMessage(Lang.GTM.f("&7URL prohibited. Please do not attempt to advertise.")); + return true; + } + } + if (targetUser.isVanished(target) && !s.hasPermission("core.bypassmessages")) { + s.sendMessage(Utils.f(Lang.MSG + "&7That player is not online!")); + target.sendMessage(Utils.f(Lang.MSG + "&7[" + senderName + "&7 -> me] &f") + message); + return true; + } + if (s instanceof Player) { + User senderUser = Core.getUserManager().getLoadedUser(((Player) s).getUniqueId()); + Integer cooldown = senderUser.isSpecial() ? 4 : 5; + if (ChatManager.getRepeatHandler().canChatAgain(senderUser.getUUID(), message)) { + ChatManager.getRepeatHandler().addRecentMessage(senderUser.getUUID(), message, cooldown); + } else { + s.sendMessage(Lang.GTM.f("&7Please wait a few seconds before repeating that message.")); + return true; + } + } + target.sendMessage(Utils.f(Lang.MSG + "&7[" + senderName + "&7 -> me] &f") + message); + s.sendMessage(Utils.f(Lang.MSG + "&7[me -> " + targetUser.getColoredName(target) + "&7] &f") + message); + return true; + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/OpenMenuCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/OpenMenuCommand.java new file mode 100644 index 0000000..1cb34a4 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/OpenMenuCommand.java @@ -0,0 +1,32 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.menus.Menu; +import net.grandtheftmc.core.menus.MenuManager; +import org.bukkit.entity.Player; + +/** + * Created by Timothy Lampen on 2017-12-25. + */ +public class OpenMenuCommand extends CoreCommand { + public OpenMenuCommand() { + super("openmenu", "to open known menu names"); + } + + @Override + public void execute(Player player, String[] args) { + if(!player.isOp()) + return; + if(args.length!=1){ + player.sendMessage(Lang.ALERTS.f("&c/openmenu ")); + return; + } + String name = args[0]; + Menu menu = MenuManager.getMenu(name); + if(menu==null) { + player.sendMessage(Lang.ALERTS.f("&cThat menu does not exist!")); + return; + } + menu.openFor(player); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/PlaytimeCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/PlaytimeCommand.java new file mode 100644 index 0000000..8c03fe3 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/PlaytimeCommand.java @@ -0,0 +1,140 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.Playtime; +import net.grandtheftmc.core.util.TimeFormatter; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.SkullMeta; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +public class PlaytimeCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if(Playtime.playtime.isEmpty()) { + s.sendMessage("No data!"); + return true; + } + if(!(s instanceof Player)) { + for (Map.Entry entrySet : Playtime.playtime.entrySet()) { + TimeFormatter tf = Utils.timeFormatter(TimeUnit.MILLISECONDS, entrySet.getValue()); + s.sendMessage(Utils.f("&a&lPlaytime of &c&l" + tf.getHours() + "h &a" + tf.getMinutes() + "m")); + } + s.sendMessage(Utils.f("&7&lAnyone not listed here has not been online since the last server reboot.")); + } else { + Player player = (Player) s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if(!player.hasPermission("gtmcore.playtime")) { + player.sendMessage(Lang.NOPERM.f("&7You do not have permission to use this command.")); + return true; + } + Inventory inv = Bukkit.createInventory(null, 54, Utils.f("&e&lRecent Playtime")); + + ItemStack grayGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a"); + ItemStack whiteGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 0, "&a"); + + int[] offlineSlots = {0, 9, 18, 27, 36, 45, 8, 17, 26, 35, 44, 53}; + int[] whiteSlots = {1, 10, 19, 28, 37, 46, 7, 16, 25, 34, 43, 52}; + int[] graySlots = {2, 3, 4, 5, 6, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, + 29, 30, 31, 32, 33, 38, 39, 40, 41, 42, 47, 48, 49, 50, 51}; + int[] skullSlots = {11, 12, 13, 14, 15, 20, 21, 22, 23, 24, + 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + + ArrayList skulls = new ArrayList<>(); + ArrayList offlineSkulls = new ArrayList<>(); + + for (Map.Entry entrySet : Playtime.playtime.entrySet()) { + String name = Bukkit.getPlayer(entrySet.getKey()) != null ? + "&a&l" + entrySet.getKey() : "&c&l" + entrySet.getKey(); + ItemStack skull = Utils.createItem(Material.SKULL_ITEM, 3, Utils.f(name)); + SkullMeta meta = (SkullMeta)skull.getItemMeta(); + + List lore = new ArrayList<>(); + TimeFormatter tf = Utils.timeFormatter(TimeUnit.MILLISECONDS, entrySet.getValue()); + lore.add(Utils.f("&7Playtime: &a" + tf.getHours() + "h " + tf.getMinutes() + "m")); + + meta.setOwner(entrySet.getKey()); + meta.setLore(lore); + + skull.setItemMeta(meta); + + skulls.add(skull); + } + + Collection offlineStaff = Utils.getOfflineStaff(); + offlineStaff.removeIf(offlinePlayer -> Playtime.playtime.containsKey(offlinePlayer)); + + for(String offline : offlineStaff) { + String name = "&8&l" + offline; + ItemStack skull = Utils.createItem(Material.SKULL_ITEM, 3, Utils.f(name)); + SkullMeta meta = (SkullMeta)skull.getItemMeta(); + + List lore = new ArrayList<>(); + if(Bukkit.getPlayer(offline) != null) { + meta.setDisplayName(Utils.f("&a&l" + offline)); + Player target = Bukkit.getPlayer(offline); + User coreUser = Core.getUserManager().getLoadedUser(target.getUniqueId()); + TimeFormatter tf = Utils.timeFormatter(TimeUnit.MILLISECONDS, System.currentTimeMillis() - coreUser.getJoinTime()); + lore.add(Utils.f("&7Playtime: &a" + tf.getHours() + "h " + tf.getMinutes() + "m")); + } else { + lore.add(Utils.f("&7Playtime: &4&lNONE - HAS NOT BEEN ONLINE")); + } + + meta.setOwner(offline); + meta.setLore(lore); + + skull.setItemMeta(meta); + + if(Bukkit.getPlayer(offline) == null) { + offlineSkulls.add(skull); + } else { + skulls.add(skull); + } + } + + for(int skullSlot : skullSlots) { + if(inv.firstEmpty() == -1) break; + if(skulls.isEmpty()) break; + if(inv.getItem(skullSlot) != null && inv.getItem(skullSlot).getType() == Material.SKULL) continue; + ItemStack skull = skulls.stream().findFirst().get(); + inv.setItem(skullSlot, skull); + skulls.remove(skulls.stream().findFirst().get()); + } + + for(int skullSlot : offlineSlots) { + if(inv.firstEmpty() == -1) break; + if(offlineSkulls.isEmpty()) break; + if(inv.getItem(skullSlot) != null && inv.getItem(skullSlot).getType() == Material.SKULL) continue; + ItemStack skull = offlineSkulls.stream().findFirst().get(); + inv.setItem(skullSlot, skull); + offlineSkulls.remove(offlineSkulls.stream().findFirst().get()); + } + + for(int whiteSlot : whiteSlots) + inv.setItem(whiteSlot, whiteGlass); + + for(int graySlot : graySlots) { + if(inv.getItem(graySlot) != null) continue; + inv.setItem(graySlot, grayGlass); + } + + player.openInventory(inv); + } + return true; + } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/PrefsCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/PrefsCommand.java new file mode 100644 index 0000000..9d13687 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/PrefsCommand.java @@ -0,0 +1,23 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.menus.MenuManager; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class PrefsCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + Player player = (Player) s; + MenuManager.openMenu(player, "prefs"); + return true; + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/RankCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/RankCommand.java new file mode 100644 index 0000000..698eb92 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/RankCommand.java @@ -0,0 +1,410 @@ +package net.grandtheftmc.core.commands; + +import java.sql.Connection; +import java.util.List; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.entity.Player; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.events.UpdateEvent; +import net.grandtheftmc.core.perms.PermsManager; +import net.grandtheftmc.core.perms.RankPerms; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserDAO; +import net.grandtheftmc.core.users.UserManager; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; + +public class RankCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (s instanceof Player) { + User u = Core.getUserManager().getLoadedUser(((Player) s).getUniqueId()); + if (!u.isRank(UserRank.ADMIN)) { + s.sendMessage(Utils.f("&cYou do not have permission to execute this command!")); + return true; + } + } + if (args.length == 0) { + s.sendMessage(Utils.f("&c/rank set [serverKey]")); + s.sendMessage(Utils.f("&c/rank remove [serverKey]")); + s.sendMessage(Utils.f("&c/rank upgrade ")); + s.sendMessage(Utils.f("&c/rank addperm ")); + s.sendMessage(Utils.f("&c/rank delperm ")); + s.sendMessage(Utils.f("&c/rank listperms ")); + s.sendMessage(Utils.f("&c/rank player addperm ")); + s.sendMessage(Utils.f("&c/rank player delperm ")); + s.sendMessage(Utils.f("&c/rank player listperms ")); + s.sendMessage(Utils.f("&c/rank reload")); + s.sendMessage(Utils.f("&c/rank save")); + return true; + } + + UserManager um = Core.getUserManager(); + PermsManager pm = Core.getPermsManager(); + switch (args[0].toLowerCase()) { + case "reload": + Core.getSettings().setPermsConfig(Utils.loadConfig("perms")); + Core.getPermsManager().loadPerms(); + s.sendMessage(Utils.f("&7The perms config was reloaded!")); + return true; + case "save": + Core.getPermsManager().savePerms(false); + s.sendMessage(Utils.f("&7The perms config was saved!")); + return true; + case "set": { + if (args.length < 3 || args.length > 4) { + s.sendMessage(Utils.f("&c/rank set [serverKey]")); + return true; + } + + UserRank rank = UserRank.getUserRankOrNull(args[2]); + if (rank == null) { + String msg = Lang.RANKS + "&7There is no rank with the name &a" + args[2] + "&7! Valid ranks: "; + for (UserRank r : UserRank.getUserRanks()) + msg = msg + "&a" + r.getColoredName() + "&7, "; + if (msg.endsWith("&7, ")) + msg = msg.substring(0, msg.length() - 4); + msg += "&7."; + s.sendMessage(Utils.f(msg)); + return true; + } + + if (s instanceof Player) { + User u = Core.getUserManager().getLoadedUser(((Player) s).getUniqueId()); + if (rank.isHigherThan(UserRank.HELPOP) && !u.isRank(UserRank.MANAGER)) { + s.sendMessage(Utils.f("&cYou do not have permission to set that userrank")); + return true; + } + } + +// EnjinCore.tagUser(args[1], rank.getName(), new EnjinResponse() { +// @Override +// public void callback(EnjinResult response, String user, String tag) { +// if (response.equals(EnjinResult.SUCCESS)) { +// s.sendMessage(ChatColor.GREEN + "Enjin forum rank set successfully (" + user + " -> " + tag + ")"); +// } else { +// s.sendMessage(ChatColor.RED + "Failed to update Enjin form rank (" + user + " -> " + tag + "). Reason = " + response.toString() + "."); +// } +// } +// }); + + // determine server we are setting + String server = rank.getServerKey(); + if (args.length == 4){ + server = args[3]; + } + final String serverKey = server; + + Player player = Bukkit.getPlayer(args[1]); + if (player == null) { +// Core.getSQL().updateAsyncLater("update users set userrank='" + rank.getName() + "' where lastname='" + args[1] + "';"); + ServerUtil.runTaskAsync(() -> { + UUID uuid = UserDAO.getUuidByName(args[1]); + if (uuid != null){ + try (Connection conn = BaseDatabase.getInstance().getConnection()){ + UserDAO.saveRank(conn, serverKey, uuid, rank); + } + catch(Exception e){ + e.printStackTrace(); + } + } + + }); + s.sendMessage(Utils.f(Lang.RANKS + "&7That player is not online, so his rank has been forcibly updated in the database.")); + return true; + } + + User u = um.getLoadedUser(player.getUniqueId()); + + // specifying server key + u.setUserRank(rank, serverKey); + s.sendMessage(Utils.f(Lang.RANKS + u.getColoredName(player) + " &7is now a &a" + u.getUserRank().getColoredNameBold() + "&7!")); + Bukkit.getPluginManager().callEvent(new UpdateEvent(player, UpdateEvent.UpdateReason.RANK)); + return true; + } + case "remove": { + if (args.length < 3 || args.length > 4) { + s.sendMessage(Utils.f("&c/rank remove [serverKey]")); + return true; + } + + UserRank rank = UserRank.getUserRankOrNull(args[2]); + if (rank == null) { + String msg = Lang.RANKS + "&7There is no rank with the name &a" + args[2] + "&7! Valid ranks: "; + for (UserRank r : UserRank.getUserRanks()) + msg = msg + "&a" + r.getColoredName() + "&7, "; + if (msg.endsWith("&7, ")) + msg = msg.substring(0, msg.length() - 4); + msg += "&7."; + s.sendMessage(Utils.f(msg)); + return true; + } + + if (s instanceof Player) { + User u = Core.getUserManager().getLoadedUser(((Player) s).getUniqueId()); + if (rank.isHigherThan(UserRank.HELPOP) && !u.isRank(UserRank.MANAGER)) { + s.sendMessage(Utils.f("&cYou do not have permission to set that userrank")); + return true; + } + } + + // determine server we are setting + String server = rank.getServerKey(); + if (args.length == 4){ + server = args[3]; + } + final String serverKey = server; + + Player player = Bukkit.getPlayer(args[1]); + if (player == null) { + ServerUtil.runTaskAsync(() -> { + UUID targetUUID = UserDAO.getUuidByName(args[1]); + if (targetUUID != null){ + try (Connection conn = BaseDatabase.getInstance().getConnection()){ + UserDAO.deleteRank(conn, serverKey, targetUUID, rank); + } + catch(Exception e){ + e.printStackTrace(); + } + } + }); + s.sendMessage(Utils.f(Lang.RANKS + "&7That player is not online, so his rank has been forcibly updated in the database.")); + return true; + } + + User u = um.getLoadedUser(player.getUniqueId()); + + // a removal causes them to set back to default + u.setUserRank(UserRank.DEFAULT, serverKey); + s.sendMessage(Utils.f(Lang.RANKS + u.getColoredName(player) + " &7is now a &a" + u.getUserRank().getColoredNameBold() + "&7!")); + Bukkit.getPluginManager().callEvent(new UpdateEvent(player, UpdateEvent.UpdateReason.RANK)); + return true; + } + case "upgrade": { + if (!(s instanceof ConsoleCommandSender)) { + s.sendMessage(Utils.f("&cThis command can only be executed from the console!")); + return true; + } + if (args.length != 4) { + s.sendMessage(Utils.f("&c/rank upgrade ")); + return true; + } + UserRank from = UserRank.getUserRankOrNull(args[2]); + UserRank to = UserRank.getUserRankOrNull(args[3]); + if (from == null || to == null) { + String msg = Lang.RANKS + "&7There is no rank with the name &a" + (from == null ? args[2] : args[3]) + "&7! Valid ranks: "; + for (UserRank r : UserRank.getUserRanks()) + msg = msg + "&a" + r.getColoredName() + "&7, "; + if (msg.endsWith("&7, ")) + msg = msg.substring(0, msg.length() - 4); + msg += "&7."; + s.sendMessage(Utils.f(msg)); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player == null) { +// Core.getSQL().updateAsyncLater("update users set userrank='" + to.getName() + "' where lastname='" + args[1] + "' and userrank='" + from.getName() + "';"); + ServerUtil.runTaskAsync(() -> UserDAO.updateRankByNameAndRank(args[1], from, to)); + s.sendMessage(Utils.f(Lang.RANKS + "&7That player is not online, so his rank has been forcibly updated in the database.")); + return true; + } + User u = um.getLoadedUser(player.getUniqueId()); + if (u.getUserRankNonTrial() != from) { + s.sendMessage(Lang.RANKS.f("&7That player does not have the rank " + from.getColoredNameBold() + "&7!")); + return true; + } + u.setUserRank(to); + Bukkit.getPluginManager().callEvent(new UpdateEvent(player, UpdateEvent.UpdateReason.RANK)); + s.sendMessage(Utils.f(Lang.RANKS + u.getColoredName(player) + " &7is now a &a" + u.getUserRank().getColoredNameBold() + "&7!")); + return true; + } + case "addperm": { + if (s instanceof Player) { + User u = Core.getUserManager().getLoadedUser(((Player) s).getUniqueId()); + if (!u.isRank(UserRank.MANAGER)) { + s.sendMessage(Utils.f("&cYou do not have permission to execute this command!")); + return true; + } + } + if (args.length != 3) { + s.sendMessage(Utils.f("&c/rank addperm ")); + return true; + } + UserRank rank = UserRank.getUserRankOrNull(args[1]); + if (rank == null) { + String msg = Lang.RANKS + "&7There is no rank with the name &a" + args[2] + "&7! Valid ranks: "; + for (UserRank r : UserRank.getUserRanks()) + msg = msg + "&a" + r.getColoredNameBold() + "&7, "; + if (msg.endsWith("&7, ")) + msg = msg.substring(0, msg.length() - 4); + msg += "&7."; + s.sendMessage(Utils.f(msg)); + return true; + } + pm.getRankPerms(rank).addPerm(args[2]); + s.sendMessage(Utils.f(Lang.RANKS + "&7The rank &a" + rank.getColoredNameBold() + "&7 now has the permission &a" + args[2] + "&7!")); + return true; + } + case "delperm": { + if (s instanceof Player) { + User u = Core.getUserManager().getLoadedUser(((Player) s).getUniqueId()); + if (!u.isRank(UserRank.MANAGER)) { + s.sendMessage(Utils.f("&cYou do not have permission to execute this command!")); + return true; + } + } + if (args.length != 3) { + s.sendMessage(Utils.f("&c/rank delperm ")); + return true; + } + UserRank rank = UserRank.getUserRankOrNull(args[1]); + if (rank == null) { + String msg = Lang.RANKS + "&7There is no rank with the name &a" + args[2] + "&7! Valid ranks: "; + for (UserRank r : UserRank.getUserRanks()) + msg = msg + "&a" + r.getColoredNameBold() + "&7, "; + if (msg.endsWith("&7, ")) + msg = msg.substring(0, msg.length() - 4); + msg += "&7."; + s.sendMessage(Utils.f(msg)); + return true; + } + pm.getRankPerms(rank).removePerm(args[2]); + s.sendMessage(Utils.f(Lang.RANKS + "&7You removed the permission &a" + args[2] + " &7from the rank " + rank.getColoredNameBold() + "&7!")); + return true; + } + case "listperms": { + if (args.length != 2) { + s.sendMessage(Utils.f("&c/rank listperms ")); + return true; + } + UserRank rank = UserRank.getUserRankOrNull(args[1]); + if (rank == null) { + String msg = Lang.RANKS + "&7There is no rank with the name &a" + args[2] + "&7! Valid ranks: "; + for (UserRank r : UserRank.getUserRanks()) + msg = msg + "&a" + r.getColoredNameBold() + "&7, "; + if (msg.endsWith("&7, ")) + msg = msg.substring(0, msg.length() - 4); + msg += "&7."; + s.sendMessage(Utils.f(msg)); + return true; + } + RankPerms rankPerms = pm.getRankPerms(rank); + if (rankPerms == null || rankPerms.getPerms().isEmpty()) { + s.sendMessage(Utils.f(Lang.RANKS + "&7The rank " + rank.getColoredNameBold() + "&7 has no permissions.")); + return true; + } + List perms = rankPerms.getPerms(); + String msg1 = "&7The rank " + rank.getColoredNameBold() + " &7has the following permissions: "; + String msg2 = ""; + for (String perm : perms) + msg2 = msg2 + "&a" + perm + "&7, "; + if (msg2.endsWith("&7, ")) + msg2 = msg2.substring(0, msg2.length() - 4); + msg2 += "&7."; + s.sendMessage(Utils.f(Lang.RANKS + msg1)); + s.sendMessage(Utils.f(msg2)); + return true; + } + case "player": + if (args.length == 1) { + s.sendMessage(Utils.f("&c/rank player addperm ")); + s.sendMessage(Utils.f("&c/rank player delperm ")); + s.sendMessage(Utils.f("&c/rank player listperms ")); + return true; + } + switch (args[1].toLowerCase()) { + case "addperm": { + if (s instanceof Player) { + User u = Core.getUserManager().getLoadedUser(((Player) s).getUniqueId()); + if (!u.isRank(UserRank.MANAGER)) { + s.sendMessage(Utils.f("&cYou do not have permission to execute this command!")); + return true; + } + } + if (args.length != 4) { + s.sendMessage(Utils.f("&c/rank player addperm ")); + return true; + } + Player player = Bukkit.getPlayer(args[2]); + if (player == null) { + s.sendMessage(Utils.f(Lang.RANKS + "&7That player is not online!")); + return true; + } + pm.addPerm(player.getUniqueId(), args[3]); + s.sendMessage(Utils.f(Lang.RANKS + "&7You added the perm &a" + args[3] + "&7 to the player &a" + player.getName() + '.')); + return true; + } + case "delperm": { + if (s instanceof Player) { + User u = Core.getUserManager().getLoadedUser(((Player) s).getUniqueId()); + if (!u.isRank(UserRank.MANAGER)) { + s.sendMessage(Utils.f("&cYou do not have permission to execute this command!")); + return true; + } + } + if (args.length != 4) { + s.sendMessage(Utils.f("&c/rank player delperm ")); + return true; + } + Player player = Bukkit.getPlayer(args[2]); + if (player == null) { + s.sendMessage(Utils.f(Lang.RANKS + "&7That player is not online!")); + return true; + } + pm.removePerm(player.getUniqueId(), args[3]); + s.sendMessage(Utils.f(Lang.RANKS + "&7You removed the perm &a" + args[3] + "&7 from the player &a" + player.getName() + '.')); + return true; + } + case "listperms": + if (args.length != 3) { + s.sendMessage(Utils.f("&c/rank player listperms ")); + return true; + } + Player player = Bukkit.getPlayer(args[2]); + if (player == null) { + s.sendMessage(Utils.f("&7That player is not online!")); + return true; + } + User u = um.getLoadedUser(player.getUniqueId()); + List perms = pm.getPerms(player.getUniqueId()); + if (perms == null || perms.isEmpty()) { + s.sendMessage(Utils.f(Lang.RANKS + "&7The player &a" + player.getName() + "&7 has no permissions.")); + return true; + } + s.sendMessage(Utils.f(Lang.RANKS + "&7The player &a" + u.getColoredName(player) + " &7has the following permissions: ")); + String msg2 = ""; + for (String perm : perms) + msg2 = msg2 + "&7" + perm + "&7, "; + if (msg2.endsWith("&7, ")) + msg2 = msg2.substring(0, msg2.length() - 4); + msg2 += "&7."; + s.sendMessage(Utils.f(msg2)); + s.sendMessage(Utils.f(Lang.RANKS + "&7The player also has all the perms from the rank &a" + u.getUserRank().getColoredNameBold() + "&7.")); + return true; + } + default: + s.sendMessage(Utils.f("&c/rank set ")); + s.sendMessage(Utils.f("&c/rank upgrade ")); + s.sendMessage(Utils.f("&c/rank addperm ")); + s.sendMessage(Utils.f("&c/rank delperm ")); + s.sendMessage(Utils.f("&c/rank listperms ")); + s.sendMessage(Utils.f("&c/rank player addperm ")); + s.sendMessage(Utils.f("&c/rank player delperm ")); + s.sendMessage(Utils.f("&c/rank player listperms ")); + s.sendMessage(Utils.f("&c/rank reload")); + s.sendMessage(Utils.f("&c/rank save")); + return true; + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/RankedCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/RankedCommand.java new file mode 100644 index 0000000..73b2455 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/RankedCommand.java @@ -0,0 +1,16 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.users.UserRank; + +/** + * Created by Luke Bingham on 06/07/2017. + */ +public interface RankedCommand { + + /** + * Get the required rank to use said command. + * + * @return UserRank + */ + UserRank requiredRank(); +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/ReplyCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/ReplyCommand.java new file mode 100644 index 0000000..3c1e1ee --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/ReplyCommand.java @@ -0,0 +1,49 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.Pref; +import net.grandtheftmc.core.users.User; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class ReplyCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command cmd, String lbl, String[] args) { + if (args.length == 0) { + s.sendMessage(Utils.f("&c/" + lbl + " ")); + return true; + } + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + Player player = (Player) s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + Player target = Bukkit.getPlayer(user.getLastMessage()); + User targetUser = target == null ? null : Core.getUserManager().getLoadedUser(target.getUniqueId()); + if (target == null || (targetUser.isVanished(target) && !s.hasPermission("core.bypassmessages"))) { + s.sendMessage(Lang.MSG.f("&7You have no one to reply to!")); + return true; + } + if ((targetUser.isIgnored(s.getName()) || !targetUser.getPref(Pref.MESSAGES)) && + !s.hasPermission("core.bypassmessages")) { + s.sendMessage(Utils.f(Lang.MSG + "&7That player has disabled PM's!")); + return true; + } + String message = args[0]; + for (int i = 1; i < args.length; i++) + message = message + ' ' + args[i]; + target.sendMessage(Utils.f(Lang.MSG + "&7[" + user.getColoredName(player) + "&7 -> me] &f") + message); + s.sendMessage(Utils.f(Lang.MSG + "&7[me -> " + targetUser.getColoredName(target) + "&7] &f" + message)); + user.setLastMessage(target.getUniqueId()); + targetUser.setLastMessage(player.getUniqueId()); + return true; + } + +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/RewardCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/RewardCommand.java new file mode 100644 index 0000000..c8b0678 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/RewardCommand.java @@ -0,0 +1,71 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.redis.RedisManager; +import net.grandtheftmc.core.redis.data.DataType; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public class RewardCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (s instanceof Player) { + User u = Core.getUserManager().getLoadedUser(((Player) s).getUniqueId()); + if (!u.isRank(UserRank.MANAGER)) { + s.sendMessage(Utils.f("&cYou do not have permission to execute this command!")); + return true; + } + } + + if (args.length != 2) { + s.sendMessage(Utils.f("&c/reward ")); + return true; + } + + //Continute to execute + String target = args[1]; + + UUID targetUUID = null; + + try { + //try parse from string + targetUUID = UUID.fromString(target); + } catch (Exception e){ + //do nothing, if UUID is null we send the string. + } + + if (targetUUID == null) { + //Try obtain uuid externally + OfflinePlayer op = Bukkit.getOfflinePlayer(target); + if (op != null) { + targetUUID = op.getUniqueId(); + } + } + + if (targetUUID == null) { + //Still failed to find a uuid, so stop + s.sendMessage(Utils.f("&cFailed to find a UUID for '" + target + "', rewards cannot be given.")); + return true; + } + + + //Publish reward notification on redis channel. + Map data = new HashMap(); + data.put("target", targetUUID.toString()); + RedisManager.publishMessage(DataType.REWARD_NOTIFY, data); + + return true; + } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/RewardsCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/RewardsCommand.java new file mode 100644 index 0000000..0f765ed --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/RewardsCommand.java @@ -0,0 +1,23 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.menus.MenuManager; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +/** + * Created by Liam on 21/09/2016. + */ +public class RewardsCommand implements CommandExecutor { + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + MenuManager.openMenu((Player) s, "rewards"); + return true; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/RulesCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/RulesCommand.java new file mode 100644 index 0000000..1666cd4 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/RulesCommand.java @@ -0,0 +1,28 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; + +public class RulesCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.toString()); + return true; + } + Player player = (Player) s; + List rules = new ArrayList<>(); + Core.getSettings().getRulesConfig().getStringList("rules").forEach(rule -> rules.add(ChatColor.translateAlternateColorCodes('&', rule))); + player.sendMessage(rules.toArray(new String[rules.size()])); + return true; + } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/SaveCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/SaveCommand.java new file mode 100644 index 0000000..d755a9f --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/SaveCommand.java @@ -0,0 +1,29 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.events.ServerSaveEvent; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class SaveCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (s instanceof Player) { + User user = Core.getUserManager().getLoadedUser(((Player) s).getUniqueId()); + if(!user.isRank(UserRank.ADMIN)) { + return true; + } + } + ServerSaveEvent saveEvent = new ServerSaveEvent(); + Bukkit.getPluginManager().callEvent(saveEvent); + s.sendMessage(Lang.SAVE.f("&fSave Event called.")); + return true; + } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/ServerCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/ServerCommand.java new file mode 100644 index 0000000..baa81d0 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/ServerCommand.java @@ -0,0 +1,31 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.servers.menu.GTMTranzitMenu; +import net.grandtheftmc.core.servers.menu.TranzitMenu; +import org.bukkit.entity.Player; + +/** + * Created by Luke Bingham on 20/08/2017. + */ +public class ServerCommand extends CoreCommand { + + /** + * Construct a new command. + */ + public ServerCommand() { + super("server", "Travel to different servers.", "serv"); + } + + /** + * This method is fired when the command is executed. + * + * @param sender sender type of the command + * @param args command arguments + */ + @Override + public void execute(Player sender, String[] args) { + MenuManager.openMenu(sender, "serverwarper"); +// new TranzitMenu(new GTMTranzitMenu()).openInventory(sender); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/SocialSpyCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/SocialSpyCommand.java new file mode 100644 index 0000000..a1c80bb --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/SocialSpyCommand.java @@ -0,0 +1,50 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.Pref; +import net.grandtheftmc.core.users.User; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.UUID; + +public class SocialSpyCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command cmd, String label, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Utils.f("&cYou are not a player!")); + return true; + } + Player player = (Player) s; + UUID uuid = player.getUniqueId(); + User u = Core.getUserManager().getLoadedUser(uuid); + if (!Pref.SOCIALSPY.isEnabled(player, u, Core.getSettings().getType())) { + s.sendMessage(Utils.f("&cYou do not have permission to execute this command!")); + if (u.getPref(Pref.SOCIALSPY)) + u.setPref(player, Pref.SOCIALSPY, false); + return true; + } + boolean mode; + if (args.length == 1) { + if(Bukkit.getPlayer(args[0]) != null) { + Player target = Bukkit.getPlayer(args[0]); + u = Core.getUserManager().getLoadedUser(target.getUniqueId()); + u.setPref(target, Pref.SOCIALSPY, false); + player.sendMessage(Lang.SOCIALSPY.f("&7You have disabled the socialspy of " + u.getColoredName(target))); + } else { + player.sendMessage(Lang.SOCIALSPY.f("&7Invalid arguments! Use /socialspy (to toggle it for yourself) or /socialspy ")); + } + } else { + mode = !u.getPref(Pref.SOCIALSPY); + u.setPref(player, Pref.SOCIALSPY, mode); + s.sendMessage(Lang.SOCIALSPY.f("&7You " + (mode ? "enabled" : "disabled") + " socialspy.")); + } + return true; + } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/SpankCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/SpankCommand.java new file mode 100644 index 0000000..c86e2a0 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/SpankCommand.java @@ -0,0 +1,76 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.Pref; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import java.util.concurrent.TimeUnit; + +/** + * Created by ThatAbstractWolf on 2017-08-04. + */ +public class SpankCommand extends CoreCommand { + + public SpankCommand() { + super("spank", "Spank them all!"); + } + + @Override + public void execute(Player player, String[] args) { + + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + + if (player.getUniqueId().toString().equals("293af3b1-1cc7-47cb-bf50-d5318ea35def")) { + player.sendMessage(Lang.SPANK.f("Hey there bb, no spanking for you! ;)")); + return; + } + + if (user.getLastSpanked() == 0L || System.currentTimeMillis() >= user.getLastSpanked()) { + + if (user.isRank(UserRank.SUPREME)) { + + if (args.length == 1) { + + Player spanking = Bukkit.getPlayer(args[0]); + + if (spanking == null) { + player.sendMessage(Lang.SPANK.f("You can't spank that player, they're not around this server :(")); + return; + } + + if (spanking == player) { + player.sendMessage(Lang.SPANK.f("Ohh you're dirty.. but not dirty enough to spank yourself. :(")); + return; + } + + for (Player all : Bukkit.getOnlinePlayers()) { + + User allUser = Core.getUserManager().getLoadedUser(all.getUniqueId()); + + if (!allUser.getPref(Pref.MESSAGES) && !all.equals(player)) { + continue; + } + + if (allUser.getIgnored().contains(player.getName())) { + continue; + } + + all.sendMessage(Lang.SPANK.f("Daddy &d&l" + player.getName() + " &7spanked &b&l" + spanking.getName() + " &7:o")); + } + + user.setLastSpanked(System.currentTimeMillis() + 60000L); + } else { + player.sendMessage(Lang.SPANK.f("/spank ")); + } + } else { + player.sendMessage(Lang.SPANK.f("&7You must be " + UserRank.SUPREME.getColoredNameBold() + " &7to spank! ;)")); + } + } else { + player.sendMessage(Lang.SPANK.f("You cannot use spank yet! Please wait &d" + TimeUnit.MILLISECONDS.toSeconds(user.getLastSpanked() - System.currentTimeMillis()) + " &7seconds.")); + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/StoreCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/StoreCommand.java new file mode 100644 index 0000000..c13d865 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/StoreCommand.java @@ -0,0 +1,16 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +public class StoreCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command cmd, String label, String[] args) { + s.sendMessage(Lang.GTM.f("&7You can find the donation store at &e" + Core.getSettings().getStoreLink())); + return true; + } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/TokensCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/TokensCommand.java new file mode 100644 index 0000000..c8086af --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/TokensCommand.java @@ -0,0 +1,314 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.UserDAO; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.events.UpdateEvent; +import net.grandtheftmc.core.events.UpdateEvent.UpdateReason; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserManager; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.UUID; + +public class TokensCommand implements CommandExecutor { + @Override + @SuppressWarnings("deprecation") + public boolean onCommand(CommandSender s, Command cmd, String lbl, String[] args) { + UserManager um = Core.getUserManager(); + if (args.length == 0) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + s.sendMessage(Utils.f("&7You have &e" + um.getLoadedUser(((Player) s).getUniqueId()).getTokens() + " Tokens&7!")); + return true; + } + if (s instanceof Player) { + if ("shop".equalsIgnoreCase(args[0])) { + MenuManager.openMenu((Player) s, "tokenshop"); + return true; + } + User u = um.getLoadedUser(((Player) s).getUniqueId()); + if (!u.isAdmin()) { + s.sendMessage(Utils.f("&cYou do not have permission to execute this command!")); + return true; + } + } + switch (args[0].toLowerCase()) { + case "give": { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/tokens give ")); + return true; + } + int amnt; + try { + amnt = Integer.parseInt(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f("&cThe amount must be a numerical value!")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player != null) { + User user = um.getLoadedUser(player.getUniqueId()); + user.addTokens(amnt); + user.insertLog(player, "giveTokensCommand", "TOKENS", amnt + " Tokens", amnt, 0); + Bukkit.getPluginManager().callEvent(new UpdateEvent(player, UpdateReason.TOKENS)); + s.sendMessage(Utils.f("&7You gave &e" + amnt + " Tokens&7 to &a" + player.getName())); + return true; + } +// Core.getSQL().updateAsyncLater("update users set tokens=tokens+" + amnt + " where lastname='" + args[1] + "';"); + s.sendMessage(Utils.f("&cThat player is not online, so the tokens have been forcibly updated in the database.")); + + ServerUtil.runTaskAsync(() -> { + UUID uuid = UserDAO.getUuidByName(args[1]); + UserDAO.addUserTokens(uuid, amnt); + + if(uuid == null) Core.log("Error while logging giveTokensCommand for uuid " + uuid + ", name " + args[1] + ", amnt " + amnt); + else Utils.insertLog(uuid, args[1], "giveTokensCommand", "TOKENS", amnt + " Tokens", amnt, 0); + }); + +// new BukkitRunnable() { +// @Override +// public void run() { +// UUID uuid = null; +// String name = args[1]; +// try (ResultSet rs = Core.getSQL().query("select uuid,lastname from users where lastname='" + args[1] + "';")) { +// if (rs.next()) { +// uuid = UUID.fromString(rs.getString("uuid")); +// name = rs.getString("lastname"); +// } +// rs.close(); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// if (uuid == null) { +// Core.log("Error while logging giveTokensCommand for uuid " + uuid + ", name " + name + ", amnt " + amnt); +// } else Utils.insertLog(uuid, name, "giveTokensCommand", "TOKENS", amnt + " Tokens", amnt, 0); +// +// } +// }.runTaskAsynchronously(Core.getInstance()); + return true; + } + case "giveuuid": { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/tokens give ")); + return true; + } + int amnt; + try { + amnt = Integer.parseInt(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f("&cThe amount must be a numerical value!")); + return true; + } + UUID uuid = UUID.fromString(args[1]); + Player player = Bukkit.getPlayer(uuid); + if (player != null) { + User user = um.getLoadedUser(uuid); + user.addTokens(amnt); + user.insertLog(player, "giveTokensCommand", "TOKENS", amnt + " Tokens", amnt, 0); + Bukkit.getPluginManager().callEvent(new UpdateEvent(player, UpdateReason.TOKENS)); + s.sendMessage(Utils.f("&7You gave &e" + amnt + " Tokens&7 to &a" + player.getName())); + return true; + } +// Core.getSQL().updateAsyncLater("update users set tokens=tokens+" + amnt + " where uuid='" + uuid + "';"); + ServerUtil.runTaskAsync(() -> { + UserDAO.addUserTokens(uuid, amnt); + String name = UserDAO.getNameByUuid(uuid); + + if(name == null) Core.log("Error while logging giveTokensCommand for uuid " + uuid + ", name " + name + ", amnt " + amnt); + else Utils.insertLog(uuid, name, "giveTokensCommand", "TOKENS", amnt + " Tokens", amnt, 0); + }); + + s.sendMessage(Utils.f("&cThat player is not online, so the tokens have been forcibly updated in the database.")); +// new BukkitRunnable() { +// @Override +// public void run() { +// String name = null; +// try (ResultSet rs = Core.getSQL().query("select lastname from users where uuid='" + args[1] + "';")) { +// if (rs.next()) { +// name = rs.getString("lastname"); +// } +// rs.close(); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// if (name == null) { +// Core.log("Error while logging giveTokensCommand for uuid " + uuid + ", name " + name + ", amnt " + amnt); +// } else Utils.insertLog(uuid, name, "giveTokensCommand", "TOKENS", amnt + " Tokens", amnt, 0); +// +// } +// }.runTaskAsynchronously(Core.getInstance()); + return true; + } + case "take": { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/tokens take ")); + return true; + } + int amnt; + try { + amnt = Integer.parseInt(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f("&cThe amount must be a numerical value!")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player != null) { + User user = um.getLoadedUser(player.getUniqueId()); + user.takeTokens(amnt); + user.insertLog(player, "takeTokensCommand", "TOKENS", amnt + " Tokens", -amnt, 0); + Bukkit.getPluginManager().callEvent(new UpdateEvent(player, UpdateReason.TOKENS)); + s.sendMessage(Utils.f("&7You took &e" + amnt + " Tokens&7 from &a" + player.getName())); + return true; + } +// Core.getSQL().updateAsyncLater("update users set tokens=tokens-" + amnt + " where lastname='" + args[1] + "';"); + ServerUtil.runTaskAsync(() -> { +// UserDAO.subtractUserBucksByName(args[1], amnt); + UUID uuid = UserDAO.getUuidByName(args[1]); + UserDAO.subtractUserTokens(uuid, amnt); + + if(uuid == null) Core.log("Error while logging takeTokensCommand for uuid " + uuid + ", name " + args[1] + ", amnt " + -amnt); + else Utils.insertLog(uuid, args[1], "takeTokensCommand", "TOKENS", amnt + " Tokens", -amnt, 0); + }); + + s.sendMessage(Utils.f("&cThat player is not online, so the tokens have been forcibly updated in the database.")); +// new BukkitRunnable() { +// @Override +// public void run() { +// UUID uuid = null; +// String name = args[1]; +// try (ResultSet rs = Core.getSQL().query("select uuid,lastname from users where lastname='" + args[1] + "';")) { +// if (rs.next()) { +// uuid = UUID.fromString(rs.getString("uuid")); +// name = rs.getString("lastname"); +// } +// rs.close(); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// if (uuid == null) { +// Core.log("Error while logging takeTokensCommand for uuid " + uuid + ", name " + name + ", amnt " + -amnt); +// } else Utils.insertLog(uuid, name, "takeTokensCommand", "TOKENS", amnt + " Tokens", -amnt, 0); +// +// } +// }.runTaskAsynchronously(Core.getInstance()); + return true; + } + case "set": { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/tokens set ")); + return true; + } + int amnt; + try { + amnt = Integer.parseInt(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f("&cThe amount must be a numerical value!")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player != null) { + User user = um.getLoadedUser(player.getUniqueId()); + user.setTokens(amnt); + user.insertLog(player, "setTokensCommand", "TOKENS", amnt + " Tokens", amnt, 0); + Bukkit.getPluginManager().callEvent(new UpdateEvent(player, UpdateReason.TOKENS)); + s.sendMessage(Utils.f("&7You set &a" + player.getName() + "&7's Tokens to &e" + amnt + "&7.")); + return true; + } +// Core.getSQL().updateAsyncLater("update users set tokens=" + amnt + " where lastname='" + args[1] + "';"); + ServerUtil.runTaskAsync(() -> { +// UserDAO.updateUserTokensByName(args[1], amnt); + UUID uuid = UserDAO.getUuidByName(args[1]); + UserDAO.updateUserTokens(uuid, amnt); + + if(uuid == null) Core.log("Error while logging setTokensCommand for uuid " + uuid + ", name " + args[1] + ", amnt " + -amnt); + else Utils.insertLog(uuid, args[1], "setTokensCommand", "TOKENS", amnt + " Tokens", amnt, 0); + }); + + s.sendMessage(Utils.f("&cThat player is not online, so the tokens have been forcibly updated in the database.")); +// new BukkitRunnable() { +// @Override +// public void run() { +// UUID uuid = null; +// String name = args[1]; +// try (ResultSet rs = Core.getSQL().query("select uuid,lastname from users where lastname='" + args[1] + "';")) { +// if (rs.next()) { +// uuid = UUID.fromString(rs.getString("uuid")); +// name = rs.getString("lastname"); +// } +// rs.close(); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// if (uuid == null) { +// Core.log("Error while logging setTokensCommand for uuid " + uuid + ", name " + name + ", amnt " + amnt); +// } else Utils.insertLog(uuid, name, "setTokensCommand", "TOKENS", amnt + " Tokens", amnt, 0); +// +// } +// }.runTaskAsynchronously(Core.getInstance()); + return true; + } + case "balance": + if (args.length != 2) { + s.sendMessage(Utils.f("/tokens balance ")); + return true; + } + UUID sender = ((Player) s).getUniqueId(); + String name = args[1]; + Player player = Bukkit.getPlayer(args[1]); + if (player != null) { + User user = um.getLoadedUser(player.getUniqueId()); + s.sendMessage( + Utils.f("&7The player &a" + player.getName() + "&7 has &a" + user.getTokens() + " Tokens&7.")); + return true; + } + s.sendMessage(Utils.f("&cThat player is not online, so hold on a second while we gather the information from the database.")); + + ServerUtil.runTaskAsync(() -> { + UUID uuid = UserDAO.getUuidByName(args[1]); + int value = UserDAO.getUserTokens(uuid); + ServerUtil.runTask(() -> { + if (value == -1) Bukkit.getPlayer(sender).sendMessage(Utils.f("&cThat player does not exist in the database!")); + else Bukkit.getPlayer(sender).sendMessage(Utils.f("&7The player &a" + name + "&7 has &e" + value + " Tokens&7.")); + }); + }); + +// Bukkit.getScheduler().scheduleAsyncDelayedTask(Core.getInstance(), () -> { +// int i; +// try (ResultSet rs = Core.getSQL().query("select tokens from users where lastname='" + name + "';")) { +// i = rs.next() ? rs.getInt("tokens") : -1; +// rs.close(); +// } catch (SQLException e) { +// e.printStackTrace(); +// return; +// } +// Bukkit.getScheduler().scheduleSyncDelayedTask(Core.getInstance(), () -> { +// if (i == -1) +// Bukkit.getPlayer(sender) +// .sendMessage(Utils.f("&cThat player does not exist in the database!")); +// else +// Bukkit.getPlayer(sender).sendMessage( +// Utils.f("&7The player &a" + name + "&7 has &e" + i + " Tokens&7.")); +// }); +// }); + default: + s.sendMessage(Utils.f("&c/tokens balance ")); + s.sendMessage(Utils.f("&c/tokens set ")); + s.sendMessage(Utils.f("&c/tokens give ")); + s.sendMessage(Utils.f("&c/tokens take ")); + return true; + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/TradeCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/TradeCommand.java new file mode 100644 index 0000000..e7ad2f3 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/TradeCommand.java @@ -0,0 +1,117 @@ +package net.grandtheftmc.core.commands; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.GameMode; +import org.bukkit.entity.Player; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.trading.TradeManager; + +/** + * Created by Timothy Lampen on 11/1/2017. + */ +public class TradeCommand extends CoreCommand { + public TradeCommand() { + super("trade", "trade with other players", "tradeplayer"); + } + + @Override + public void execute(Player player, String[] args) { + if(args.length==0){ + player.sendMessage(Lang.TRADE.f("&7/trade &6- sends a trade request to the target player")); + return; + } + TradeManager tm = Core.getInstance().getTradeManager(); + + if (!tm.isEnabled()){ + player.sendMessage(ChatColor.RED + "Trading is currently disabled!"); + return; + } + + switch (args[0].toLowerCase()) { + case "accept": { + if(!tm.getPendingTrade(player.getUniqueId()).isPresent()) { + player.sendMessage(Lang.TRADE.f("&7You do not have any pending trade requests.")); + return; + } + Player origin = Bukkit.getPlayer(tm.getPendingTrade(player.getUniqueId()).get().getValue()); + if(origin == null) { + player.sendMessage(Lang.TRADE.f("&7The player who sent you the request is no longer online.")); + tm.removePendingTrade(player.getUniqueId()); + return; + } + if(Core.getTradeManager().getTrade(player).isPresent() || Core.getTradeManager().getTrade(origin).isPresent()) { + player.sendMessage(Lang.TRADE.f("&7You cannot trade with this player since they are already in a trade!")); + tm.removePendingTrade(player.getUniqueId()); + return; + } + if(player.getGameMode() != GameMode.SURVIVAL && player.getGameMode() != GameMode.ADVENTURE) { + player.sendMessage(Lang.TRADE.f("&7You cannot accept trades while spectating.")); + return; + } + if(origin.getGameMode() != GameMode.SURVIVAL && origin.getGameMode() != GameMode.ADVENTURE) { + player.sendMessage(Lang.TRADE.f("&7This player cannot accept trades just yet.")); + return; + } + if(!player.getWorld().getName().equals(origin.getWorld().getName()) || player.getLocation().distance(origin.getLocation())>10) { + player.sendMessage(Lang.TRADE.f("&7You cannot trade with this player because they are too far away!")); + tm.removePendingTrade(player.getUniqueId()); + return; + } + tm.removePendingTrade(player.getUniqueId()); + Core.getTradeManager().startTrade(origin, player); + return; + } + case "deny": { + if(!tm.getPendingTrade(player.getUniqueId()).isPresent()) { + player.sendMessage(Lang.TRADE.f("&7You do not have any pending trade requests.")); + return; + } + Player origin = Bukkit.getPlayer(tm.getPendingTrade(player.getUniqueId()).get().getValue()); + if(origin == null) { + player.sendMessage(Lang.TRADE.f("&7The player who sent you the request is no longer online.")); + return; + } + tm.removePendingTrade(player.getUniqueId()); + origin.sendMessage(Lang.TRADE.f("&7The player whom you sent the request to has declined it.")); + player.sendMessage(Lang.TRADE.f("&7You have declined the trade request.")); + return; + } + } + Player target = Bukkit.getPlayer(args[0]); + if(target==null) { + player.sendMessage(Lang.TRADE.f("&7That player is currently not online.")); + return; + } + + if(player.getGameMode() != GameMode.SURVIVAL && player.getGameMode() != GameMode.ADVENTURE) { + player.sendMessage(Lang.TRADE.f("&7You cannot request to trade while spectating.")); + return; + } + + if(target.getGameMode() != GameMode.SURVIVAL && target.getGameMode() != GameMode.ADVENTURE) { + player.sendMessage(Lang.TRADE.f("&7This player cannot accept trades just yet.")); + return; + } + + if(!target.getWorld().getName().equals(player.getWorld().getName())) { + player.sendMessage(Lang.TRADE.f("&7This player out of range..")); + return; + } + + if(target.getLocation().distance(player.getLocation()) > 10) { + player.sendMessage(Lang.TRADE.f("&7This player out of range..")); + return; + } + + if(target.equals(player)) { + player.sendMessage(Lang.TRADE.f("&7You cannot trade yourself.")); + return; + } + tm.addPendingTrade(player.getUniqueId(), target.getUniqueId()); + player.sendMessage(Lang.TRADE.f("&7You have sent a trade request to &6" + target.getName() + "&7.")); + target.sendMessage(Lang.TRADE.f("&7You have recieved a trade request from &6" + player.getName() + "&7. Please use '&a/trade accept&7' or '&c/trade deny&7' to respond.")); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/TrialCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/TrialCommand.java new file mode 100644 index 0000000..7dcf72c --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/TrialCommand.java @@ -0,0 +1,34 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.C; +import org.bukkit.entity.Player; + +/** + * Created by Timothy Lampen on 2017-11-06. + */ +public class TrialCommand extends CoreCommand { + public TrialCommand() { + super("trial", "displays the amount of time left for your trial rank"); + } + + @Override + public void execute(Player player, String[] args) { + if(args.length==0 || !args[0].equalsIgnoreCase("time")) { + player.sendMessage(Lang.SHOP.f("&6/trial time &7- displays the amount of time remaining for your trial rank.")); + return; + } + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if(user.getTrialRankExpiry()==0) { + player.sendMessage(Lang.SHOP.f("&7You do not have a trial rank!")); + return; + } + + long timeLeft = user.getTrialRankExpiry()-System.currentTimeMillis(); + player.sendMessage(Lang.SHOP.f("&7You have &6" + Utils.timeInMillisToText(timeLeft, C.GOLD, C.GRAY, C.GRAY) + " &7until your trial rank expires.")); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/TwitterCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/TwitterCommand.java new file mode 100644 index 0000000..53d5baf --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/TwitterCommand.java @@ -0,0 +1,18 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import org.bukkit.entity.Player; + +public class TwitterCommand extends CoreCommand { + + public TwitterCommand() { + super("twitter", "Get the link to our official Twitter page."); + } + + @Override + public void execute(Player sender, String[] args) { + if (Core.getSettings().isSister()) return; + sender.sendMessage(Lang.TWITTER.f("&7Here is the link to our official Twitter page! &9https://twitter.com/grandtheft_mc/")); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/VotestreakCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/VotestreakCommand.java new file mode 100644 index 0000000..46627cd --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/VotestreakCommand.java @@ -0,0 +1,68 @@ +package net.grandtheftmc.core.commands; + +import java.sql.Connection; +import java.util.UUID; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.database.dao.VoteDAO; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserDAO; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.ServerUtil; + +public class VotestreakCommand implements CommandExecutor { + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + Player player = (Player) s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (!user.isRank(UserRank.ADMIN)) { + player.sendMessage(Lang.NOPERM.s()); + return true; + } + if (args.length != 3) { + player.sendMessage(Lang.VOTE.f("&7/votestreak set &a ")); + return true; + } + switch (args[0]) { + case "set": + String target = args[1]; + int streak = 0; + try { + streak = Integer.valueOf(args[2]); + } + catch (NumberFormatException exception) { + } + + int finalStreak = streak; + + player.sendMessage(Lang.VOTE.f("&cAttempt to update manually...")); + ServerUtil.runTaskAsync(() -> { + try (Connection conn = BaseDatabase.getInstance().getConnection()){ + + UUID uuid = UserDAO.getUUID(conn, target); + if (uuid != null){ + VoteDAO.setVoteStreak(conn, uuid, finalStreak); + } + } + catch(Exception e){ + e.printStackTrace(); + } + }); + + return true; + default: + return true; + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/WhitelistCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/WhitelistCommand.java new file mode 100644 index 0000000..89e74ab --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/commands/WhitelistCommand.java @@ -0,0 +1,127 @@ +package net.grandtheftmc.core.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.whitelist.WhitelistManager; +import net.grandtheftmc.core.whitelist.WhitelistedUser; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.List; +import java.util.stream.Collectors; + +public class WhitelistCommand implements CommandExecutor { + + void unsafeMethod() { + throw new UnsupportedOperationException("You shouldn't call this!"); + } + + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (s instanceof Player) { + User u = Core.getUserManager().getLoadedUser(((Player) s).getUniqueId()); + if (!u.isAdmin()) { + s.sendMessage(Utils.f("&cYou do not have permission to execute this command!")); + return true; + } + +// unsafeMethod(); + } + if (args.length == 0) { + s.sendMessage(Utils.f("&c/whitelist add/remove ")); + s.sendMessage(Utils.f("&c/whitelist on/off")); + s.sendMessage(Utils.f("&c/whitelist list")); + return true; + } + WhitelistManager wm = Core.getWhitelistManager(); + switch (args[0].toLowerCase()) { + case "add": + if (args.length != 2) { + s.sendMessage(Utils.f("&c/whitelist add ")); + return true; + } + wm.whitelist(args[1]); + s.sendMessage(Utils.f("The player &a" + args[1] + " &fwas added to the whitelist.")); + return true; + case "remove": + if (args.length != 2) { + s.sendMessage(Utils.f("&c/whitelist remove ")); + return true; + } + wm.unwhitelist(args[1]); + s.sendMessage(Utils.f("The player &a" + args[1] + " &fwas removed from the whitelist.")); + return true; + case "on": + if (args.length != 1) { + s.sendMessage(Utils.f("&c/whitelist on")); + return true; + } + wm.setEnabled(true); + s.sendMessage(Utils.f("The whitelist was enabled.")); + return true; + case "off": + if (args.length != 1) { + s.sendMessage(Utils.f("&c/whitelist off")); + return true; + } + wm.setEnabled(false); + s.sendMessage(Utils.f("The whitelist was disabled.")); + return true; + case "list": { + if (args.length != 1) { + s.sendMessage(Utils.f("&c/whitelist list")); + return true; + } + List whitelist = wm.getWhitelistedUsers().stream().map(WhitelistedUser::getName).collect(Collectors.toList()); + + if (whitelist.isEmpty()) { + s.sendMessage("There are no whitelisted players!"); + return true; + } + String msg = "Whitelisted players: "; + for (String string : whitelist) + msg = msg + string + ", "; + if (msg.endsWith(", ")) + msg = msg.substring(0, msg.length() - 2); + s.sendMessage(Utils.f(msg)); + return true; + } + case "bypassrank": + if (args.length != 2) { + s.sendMessage(Utils.f("&c/whitelist bypassRank ")); + return true; + } + if ("none".equalsIgnoreCase(args[1])) { + wm.setBypassRank(null); + s.sendMessage(Utils.f("The whitelist can no longer be bypassed with a UserRank.")); + return true; + } + UserRank rank = UserRank.getUserRankOrNull(args[1]); + if (rank == null) { + String msg = Lang.RANKS + "&7There is no rank with the name &a" + args[2] + "&7! Valid ranks: "; + for (UserRank r : UserRank.getUserRanks()) + msg = msg + "&a" + r.getColoredName() + "&7, "; + if (msg.endsWith("&7, ")) + msg = msg.substring(0, msg.length() - 4); + msg += "&7."; + s.sendMessage(Utils.f(msg)); + return true; + } + wm.setBypassRank(rank); + s.sendMessage(Utils.f("&7Players with UserRank " + rank.getColoredNameBold() + "&7 can now bypass the whitelist.")); + return true; + default: + s.sendMessage(Utils.f("&c/whitelist add/remove ")); + s.sendMessage(Utils.f("&c/whitelist on/off")); + s.sendMessage(Utils.f("&c/whitelist list")); + return true; + } + + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/currency/Currency.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/currency/Currency.java new file mode 100644 index 0000000..02fb64a --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/currency/Currency.java @@ -0,0 +1,120 @@ +package net.grandtheftmc.core.currency; + +import java.util.Optional; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.Identifiable; + +public enum Currency implements Identifiable { + + CROWBAR("CROWBAR", "crowbar", "crowbars"), + TOKEN("TOKEN", "token", "tokens"), + MONEY("MONEY", "money", "money"), + PERMIT("PERMIT", "permit", "permits"), + COUPON_CREDIT("COUPON_CREDIT", "coupon credit", "coupon credits"), + VOTE_TOKEN("VOTE_TOKEN", "vote token", "vote tokens"); + + /** The id of the currency */ + private final String id; + /** The singular form for the currency */ + private final String singular; + /** The plural form for the currency */ + private final String plural; + /** The server_key that this currency is for */ + private String serverKey; + + /** + * Construct a new currency enum constant. + * + * @param id - the id of the currency + * @param singular - the singular representation for this currency + * @param plural - the plurarl representation for this currency + */ + Currency(String id, String singular, String plural) { + this.id = id; + this.singular = singular; + this.plural = plural; + } + + /** + * {@inheritDoc} + */ + @Override + public String getId() { + return id; + } + + /** + * Get the currency id representation as a singular id. + *

+ * Note: "coin" is now "coin" + *

+ * + * @return The currency id representation as a singular id. + */ + public String asSingular() { + return singular; + } + + /** + * Get the currency id representation as a plural id. + *

+ * Note: "coin" is now "coins" + *

+ * + * @return The currency id representation as a plural id. + */ + public String asPlural() { + return plural; + } + + /** + * Get the server key that this currency is for. + *

+ * Note: This must be set by the plugin or project for each currency. + *

+ * + * @return If a currency is a global one, "GLOBAL" is returned, or if it's a + * per server currency, the server will be returned, i.e. "GTM1". + */ + public String getServerKey() { + + // if not set, assume per server + if (serverKey == null || serverKey.isEmpty()){ + return Core.name().toUpperCase(); + } + + return serverKey; + } + + /** + * Set the server key that this currency is for. + *

+ * Note: This must be set by the plugin or project for each currency. + *

+ * If a currency is a global currency, set this as "GLOBAL". If a currency is per server, set this as the name of the server, "GTM1". + * + * @param serverKey - the server key for this currency + */ + public void setServerKey(String serverKey) { + this.serverKey = serverKey; + } + + /** + * Get the specified currency based off the id. + * + * @param id - the id of the currency + * + * @return The specified currency based off the id, if one exists, otherwise + * empty. + */ + public static Optional fromID(String id) { + for (Currency c : values()) { + if (c.getId().equalsIgnoreCase(id)) { + return Optional.of(c); + } + } + + return Optional.empty(); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/currency/Purse.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/currency/Purse.java new file mode 100644 index 0000000..d3be804 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/currency/Purse.java @@ -0,0 +1,160 @@ +package net.grandtheftmc.core.currency; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import net.grandtheftmc.core.currency.component.CurrencySource; +import net.grandtheftmc.core.currency.trans.CurrencyTransaction; + +public class Purse { + + /** Maps currency to amount of that currency */ + private Map currencyToAmount; + /** List of currency transactions to log */ + private List trans; + + /** + * Construct a new Purse to hold currencies. + */ + public Purse() { + this.currencyToAmount = new HashMap<>(); + this.trans = new ArrayList<>(); + } + + /** + * Register this currency to the purse. + * + * @param currency - the currency to register + * @result {@code true} if the currency was registered, {@code false} if it + * already exists. + */ + public boolean registerCurrency(Currency currency) { + if (!currencyToAmount.containsKey(currency)) { + currencyToAmount.put(currency, 0); + return true; + } + + return false; + } + + /** + * Get the balance of the specified currency. + * + * @param currency - the currency to get the balance of + * + * @return The amount of the currency currently within this purse, if it + * exists, otherwise -1. + */ + public int getBalance(Currency currency) { + if (currencyToAmount.containsKey(currency)) { + return currencyToAmount.get(currency); + } + + return -1; + } + + /** + * Deposit the selected currency in the purse. + * + * @param source - the reason for the deposit + * @param currency - the currency to deposit + * @param amount - the amount to deposit + * + * @return The new balance for the currency, if it exists, otherwise -1. + */ + public int deposit(CurrencySource source, Currency currency, int amount) { + + if (currencyToAmount.containsKey(currency)) { + int initial = currencyToAmount.get(currency); + + if (initial + amount < Integer.MAX_VALUE) { + currencyToAmount.put(currency, initial + amount); + } + else { + currencyToAmount.put(currency, Integer.MAX_VALUE); + } + + int newBal = currencyToAmount.get(currency); + + // log transaction + trans.add(new CurrencyTransaction(currency, source, amount, true)); + + return newBal; + } + + return -1; + } + + /** + * Withdraw the selected currency from the purse. + * + * @param source - the reason for the withdraw + * @param currency - the currency to withdraw + * @param amount - the amount to withdraw + * + * @return The new balance for the currency, if it exists, otherwise -1. If + * we cannot withdraw that amount, we will set the balance to 0. + */ + public int withdraw(CurrencySource source, Currency currency, int amount) { + + if (currencyToAmount.containsKey(currency)) { + int initial = currencyToAmount.get(currency); + int newValue = initial - amount; + + if (newValue >= 0) { + currencyToAmount.put(currency, newValue); + } + else { + currencyToAmount.put(currency, 0); + } + + // log transaction + trans.add(new CurrencyTransaction(currency, source, -1 * amount, false)); + + return currencyToAmount.get(currency); + } + + return -1; + } + + /** + * Sets the selected currency to the specified amount. + * + * @param currency - the currency to set + * @param value - the value to set the currency at + * + * @return {@code true} if the currency was set to the specified amount, + * {@code} false otherwise. + */ + public boolean set(Currency currency, int value) { + + if (currencyToAmount.containsKey(currency)) { + currencyToAmount.put(currency, value); + return true; + } + + return false; + } + + /** + * Get all the currencies that this Purse knows about. + * + * @return An unmodifiable map of all the currencies this purse knows about. + */ + public Map getCurrencies() { + return Collections.unmodifiableMap(currencyToAmount); + } + + /** + * Get a list of currency transactions that this purse has kept track of. + * + * @return An unmodifiable list of currency transactions that this purse has + * kept track of. + */ + public List getTransactionLog() { + return Collections.unmodifiableList(trans); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/currency/component/CurrencySource.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/currency/component/CurrencySource.java new file mode 100644 index 0000000..d54a76d --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/currency/component/CurrencySource.java @@ -0,0 +1,68 @@ +package net.grandtheftmc.core.currency.component; + +import java.util.Optional; + +/** + * This class should be treated as a static enum constant, where you can define + * currency source here, or create new Objects later. + * + * When this class is used in transaction history, it will log the source + * (type), and the reason (if one exists). + */ +public class CurrencySource { + + public static final CurrencySource CUSTOM = new CurrencySource(new Source("CUSTOM")); + public static final CurrencySource VOTE = new CurrencySource(new Source("VOTE")); + public static final CurrencySource KILL_PLAYER = new CurrencySource(new Source("KILL_PLAYER")); + public static final CurrencySource KILL_ENTITY = new CurrencySource(new Source("KILL_ENTITY")); + + /** The source for the currency */ + private final Source source; + /** The reason for the currency transaction */ + private final String reason; + + /** + * Construct a new CurrencySource. + * + * @param source - the source for the currency + * @param reason - the reason for the transaction. + */ + public CurrencySource(Source source, String reason) { + this.source = source; + this.reason = reason; + } + + /** + * Construct a new CurrencySource. + *

+ * Wrapper around {@link #CurrencySource(Source, String)}. + *

+ * + * @param source - the source for the currency + */ + public CurrencySource(Source source) { + this(source, null); + } + + /** + * Get the source of the currency. + * + * @return The source of the currency. + */ + public Source getSource() { + return source; + } + + /** + * Get the reason for the transaction. + * + * @return The reason for this currency to be given, if one exists. + */ + public Optional getReason() { + if (reason == null || reason.isEmpty()) { + return Optional.empty(); + } + + return Optional.of(reason); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/currency/component/Source.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/currency/component/Source.java new file mode 100644 index 0000000..ce001d5 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/currency/component/Source.java @@ -0,0 +1,31 @@ +package net.grandtheftmc.core.currency.component; + +import net.grandtheftmc.core.util.Identifiable; + +public class Source implements Identifiable { + + /** The id of the source */ + private final String id; + + /** + * Construct a new Source object. + *

+ * This is useful in conjunction with CurrencySource to determine the reason + * for a currency transaction. + * + * @param id - the id of the source + */ + public Source(String id) { + this.id = id; + } + + /** + * Get the id of the source. + * + * @return The id of the source. + */ + @Override + public String getId() { + return id; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/currency/trans/CurrencyTransaction.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/currency/trans/CurrencyTransaction.java new file mode 100644 index 0000000..7c99a09 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/currency/trans/CurrencyTransaction.java @@ -0,0 +1,71 @@ +package net.grandtheftmc.core.currency.trans; + +import net.grandtheftmc.core.currency.Currency; +import net.grandtheftmc.core.currency.component.CurrencySource; + +public class CurrencyTransaction { + + /** The currency involved */ + private final Currency currency; + /** The source of the transaction */ + private final CurrencySource source; + /** The amount involved */ + private final int amount; + /** Whether it was a deposit */ + private final boolean deposit; + + /** + * Construct a new CurrencyTransaction. + *

+ * This is used to log currency transfers in a player's purse. + *

+ * + * @param currency - the currency involved in the transaction + * @param source - the source of the currency + * @param amount - the amount of the currency + * @param deposit - what type of transaction this was + */ + public CurrencyTransaction(Currency currency, CurrencySource source, int amount, boolean deposit) { + this.currency = currency; + this.source = source; + this.amount = amount; + this.deposit = deposit; + } + + /** + * Get the currency involved in the transaction. + * + * @return The currency involved in the transaction. + */ + public Currency getCurrency() { + return currency; + } + + /** + * Get the source of the currency. + * + * @return The source of the currency. + */ + public CurrencySource getSource() { + return source; + } + + /** + * Get the amount of the currency in the transaction. + * + * @return The amount of currency in the transaction. + */ + public int getAmount() { + return amount; + } + + /** + * Get whether or not this is a deposit. + * + * @return {@code true} if the transaction was a deposit, {@code false} if + * it was a withdraw. + */ + public boolean isDeposit() { + return deposit; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/data/CompactLoc.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/data/CompactLoc.java new file mode 100644 index 0000000..d36ada6 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/data/CompactLoc.java @@ -0,0 +1,46 @@ +package net.grandtheftmc.core.data; + +import org.bukkit.Location; + +/** + * Created by Adam on 13/06/2017. + */ +public class CompactLoc { + + /* + Use this class as a quick and lightweight way of comparing player locations. + */ + + private final int x, z; + //If player has moved at least 1 block we mark them as not being afk. + private final static int threshold = 1; + + public CompactLoc(int x, int z) { + this.x = x; + this.z = z; + } + + public CompactLoc(Location l) { + this.x = l.getBlockX(); + this.z = l.getBlockZ(); + } + + public int getX() { + return x; + } + + public int getZ() { + return z; + } + + /** + * Check whether a CompactLoc is different from another within a configured range. + * @param loc The location to compare with. + * @return True if the distance between locations > threshold. + */ + public boolean differs(CompactLoc loc) { + //Keep it quick and simple. + int diff = Math.abs(loc.getX() - x) + Math.abs(loc.getZ() - z); + return diff >= threshold; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/BaseDatabase.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/BaseDatabase.java new file mode 100644 index 0000000..cf3ca8e --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/BaseDatabase.java @@ -0,0 +1,53 @@ +package net.grandtheftmc.core.database; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +/** + * A generic database handler that acts as a singleton so we can reference it + * anywhere. + * + * @author sbahr + */ +public class BaseDatabase extends DatabaseHandler { + + /** Singleton instance for this class */ + private static BaseDatabase instance; + + /** + * Private constructor as singleton's cannot be instantiated. + */ + private BaseDatabase() { + // Note: DatabaseHandler doesn't have a constructor for a reason + } + + /** + * Get the singleton instance of this class. + *

+ * This allows you to call {@link #getConnection()}. + *

+ * + * @return The instance of this database. + */ + public static BaseDatabase getInstance() { + if (instance == null) { + instance = new BaseDatabase(); + } + + return instance; + } + + public static boolean runCustomQuery(String query) { + try (Connection connection = getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement(query)) { + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/DatabaseHandler.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/DatabaseHandler.java new file mode 100644 index 0000000..8ce4074 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/DatabaseHandler.java @@ -0,0 +1,241 @@ +package net.grandtheftmc.core.database; + +import java.io.PrintWriter; +import java.sql.Connection; +import java.sql.SQLException; + +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.Plugin; + +import com.zaxxer.hikari.HikariDataSource; + +import net.grandtheftmc.core.database.component.Database; +import net.grandtheftmc.core.database.component.DatabaseCredentials; + +/** + * A generic database handler that holds a HikariCP data source so we can have + * multiple database connection. + * + * Note: This should be init() with either the Plugin/Config path to load + * settings, or can be init() with just database credentials, which uses default + * HikariCP settings. + * + * @author sbahr + */ +public class DatabaseHandler implements Database { + + /** The default MySQL driver */ + private static final String DEFAULT_MYSQL_DRIVER = "com.mysql.jdbc.Driver"; + /** The database credentials */ + private DatabaseCredentials dbCreds; + /** Data source connection pool from HikariCP */ + private HikariDataSource hikariSource = new HikariDataSource(); + + // NOTE: HikariCP performs best at fixed pool size, minIdle=maxConns + // https://github.com/brettwooldridge/HikariCP + + /** How many minimum idle connections should we always have (2) */ + protected int minIdle = 2; + /** How many max connections should exist in pool (2) */ + protected int maxPoolSize = 2; + /** How long, in millis, we stop waiting for new connection (15 secs) */ + protected int connectionTimeoutMs = 15 * 1000; + /** How long, in millis, before connections timeout (45 secs) */ + protected int idleTimeoutMs = 45 * 1000; + /** How long, in millis, this connection can be alive for (30 mins) */ + protected int maxLifetimeMs = 30 * 60 * 1000; + /** How long, in millis, can a connection be gone from a pool (4 secs) */ + protected int leakDetectionThresholdMs = 4 * 1000; + /** The ping alive query */ + protected String connectionTestQuery = "SELECT 1"; + /** Should the connection cache prepared statements */ + protected boolean cachePreparedStatements = true; + /** Number of prepared statements to cache per connection */ + protected int preparedStatementCache = 250; + /** Max number of prepared statements to have */ + protected int maxPreparedStatementCache = 2048; + /** The log writer for Hikari */ + protected PrintWriter logWriter = new PrintWriter(System.out); + + /** + * Initialize the handler with the specified database credentials. + *

+ * Sets up the configuration for the connection pool and default settings. + *

+ * + * @param dbCreds - the credentials for the database + * @param driver - the driver class + */ + public void init(DatabaseCredentials dbCreds, String driver) { + this.dbCreds = dbCreds; + + // set the driver name for the connection driver + hikariSource.setDriverClassName(driver); + + // assume host/port combo together, or could just be without port + String connURL = dbCreds.getHost(); + + // if a port is defined + if (dbCreds.getPort() > 0) { + connURL = dbCreds.getHost() + ":" + dbCreds.getPort(); + } + + // set the jdbc url, note the character encoding + // https://stackoverflow.com/questions/3040597/jdbc-character-encoding + hikariSource.setJdbcUrl("jdbc:mysql://" + connURL + "/" + dbCreds.getName() + "?characterEncoding=UTF-8"); + + // set user/pass + hikariSource.setUsername(dbCreds.getUser()); + hikariSource.setPassword(dbCreds.getPass()); + + /** General conf settings for hikari */ + // works best when minIdle=maxPoolSize + hikariSource.setMinimumIdle(minIdle); + hikariSource.setMaximumPoolSize(maxPoolSize); + + // how long to wait, for a new connection + hikariSource.setConnectionTimeout(connectionTimeoutMs); + // how long before idle connection is destroyed + hikariSource.setIdleTimeout(idleTimeoutMs); + // how long can a connection exist + hikariSource.setMaxLifetime(maxLifetimeMs); + // how long connection is away from a pool before saying uh oh + hikariSource.setLeakDetectionThreshold(leakDetectionThresholdMs); + // test query to confirm alive + hikariSource.setConnectionTestQuery(connectionTestQuery); + // should we cache prepared statements + hikariSource.addDataSourceProperty("cachePrepStmts", "" + cachePreparedStatements); + // the size of the prepared statement cache + hikariSource.addDataSourceProperty("prepStmtCacheSize", "" + preparedStatementCache); + // the maximum cache limit + hikariSource.addDataSourceProperty("prepStmtCacheSqlLimit", "" + maxPreparedStatementCache); + + // MUST set log writer + try { + hikariSource.setLogWriter(new PrintWriter(System.out)); + } + catch (SQLException e) { + e.printStackTrace(); + } + } + + /** + * Initialize the database handler given the credentials. + * + * @param credentials - the login details to this database + */ + protected void init(DatabaseCredentials credentials) { + this.init(credentials, DEFAULT_MYSQL_DRIVER); + } + + /** + * Load the settings for HikariCP from the plugin config and stores them + * locally in the object, then initializes the database handler. + * + * @param plugin - the owning plugin + * @param path - the path to load settings from + */ + public void init(Plugin plugin, String path) { + + // grab plugin file configuration + FileConfiguration config = plugin.getConfig(); + + String host = config.getString(path + ".host", "localhost"); + int port = config.getInt(path + ".port", 3306); + String dbName = config.getString(path + ".database", "hyphenical"); + String username = config.getString(path + ".user", "user"); + String password = config.getString(path + ".password", "pass123"); + + // connection stats + int minIdle = config.getInt(path + ".min-idle", 2); + int maxConns = config.getInt(path + ".max-conn", 2); + + // save db credentials + config.set(path + ".host", host); + config.set(path + ".port", port); + config.set(path + ".database", dbName); + config.set(path + ".user", username); + config.set(path + ".password", password); + + // save the config + plugin.saveConfig(); + + // load local fields + this.minIdle = minIdle < 0 ? 1 : minIdle; + this.maxPoolSize = maxConns < 1 ? 1 : maxConns; + + // create database credentials + DatabaseCredentials creds = new DatabaseCredentials(host, port, dbName, username, password); + // initialize hikari cp + init(creds); + } + + /** + * Load the settings for HikariCP from the yaml config and stores them + * locally in the object, then initializes the database handler. + * + * @param config - the yaml configuration + * @param path - the path to load settings from + */ + public void init(YamlConfiguration config, String path) { + + String host = config.getString(path + ".host", "localhost"); + int port = config.getInt(path + ".port", 3306); + String dbName = config.getString(path + ".database", "hyphenical"); + String username = config.getString(path + ".user", "user"); + String password = config.getString(path + ".password", "pass123"); + + // connection stats + int minIdle = config.getInt(path + ".min-idle", 2); + int maxConns = config.getInt(path + ".max-conn", 2); + + // load local fields + this.minIdle = minIdle < 0 ? 1 : minIdle; + this.maxPoolSize = maxConns < 1 ? 1 : maxConns; + + // create database credentials + DatabaseCredentials creds = new DatabaseCredentials(host, port, dbName, username, password); + // initialize hikari cp + init(creds); + } + + /** + * Close HikariCP connection pool, and all the connections. + *

+ * Note: This should be called whenever the plugin turns off! + *

+ */ + public void close() { + if (hikariSource != null && !hikariSource.isClosed()) { + hikariSource.close(); + } + } + + /** + * {@inheritDoc} + */ + @Override + public DatabaseCredentials getCredentials() { + return dbCreds; + } + + /** + * {@inheritDoc} + */ + @Override + public Connection getConnection() { + if (hikariSource != null) { + try { + Connection conn = hikariSource.getConnection(); + return conn; + } + catch (Exception e) { + System.out.println("[DatabaseHandler] Unable to grab a connection from the connection pool!"); + e.printStackTrace(); + } + } + + return null; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/component/Database.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/component/Database.java new file mode 100644 index 0000000..0df910d --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/component/Database.java @@ -0,0 +1,26 @@ +package net.grandtheftmc.core.database.component; + +import java.sql.Connection; + +/** + * An interface that represents a database (and it's credentials). + * + * @author sbahr + */ +public interface Database { + + /** + * Get the credentials for the database. + * + * @return The credentials for the database. + */ + DatabaseCredentials getCredentials(); + + /** + * Get the connection for the database. + * + * @return The connection for the database. + */ + Connection getConnection(); + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/component/DatabaseCredentials.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/component/DatabaseCredentials.java new file mode 100644 index 0000000..6481439 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/component/DatabaseCredentials.java @@ -0,0 +1,112 @@ +package net.grandtheftmc.core.database.component; + +/** + * Represents an immutable data object containing information about a connection + * to the database. + * + * @author sbahr + */ +public class DatabaseCredentials { + + /** The host of the db, ex: example.com */ + private final String host; + /** The port associated, ex: 3306 */ + private final int port; + /** The name of the database to use, ex: test_db */ + private final String dbName; + /** The name of the user that has access to the db, ex: user123 */ + private final String dbUser; + /** The password for the user, ex: pass123 */ + private final String dbPass; + + /** + * Construct a new DatabaseCredentials object. + * + * @param host - the host of the db, ex: example.com + * @param port - the port for the db, ex: 3306 + * @param dbName - the name of the db to use, ex: test_db + * @param dbUser - the user of the db, ex: user123 + * @param dbPass - the pass for the user, ex: pass123 + */ + public DatabaseCredentials(String host, int port, String dbName, String dbUser, String dbPass) { + this.host = host; + this.port = port; + this.dbName = dbName; + this.dbUser = dbUser; + this.dbPass = dbPass; + } + + /** + * Construct a new DatabaseCredentials object. + *

+ * The port for the host is not defined as an argument and either should be + * supplied in the host argument or use a different constructor. If no port + * is defined, we'll use the default port. + *

+ * + * @param host - the host of the db, ex: example.com + * @param dbName - the name of the db to use, ex: test_db + * @param dbUser - the user of the db, ex: user123 + * @param dbPass - the pass for the user, ex: pass123 + */ + public DatabaseCredentials(String host, String dbName, String dbUser, String dbPass) { + this(host, -1, dbName, dbUser, dbPass); + } + + /** + * Get the host associated with this database credentials. + *

+ * The host URL, ex: www.example.com + *

+ * + * @return The host URL for the database. + */ + public final String getHost() { + return host; + } + + /** + * Get the port number for the database. + *

+ * The port number could be irrelevant if defined in {@link #getHost()}. If + * the port number is -1, use the default port. + *

+ * + * @return The port number for the database. + */ + public final int getPort() { + return port; + } + + /** + * Get the name of the database that we are using. + *

+ * This is the name of the database, as there can be multiple databases + * within one database. + *

+ * + * @return The name of the database we are using. + */ + public final String getName() { + return dbName; + } + + /** + * Get the username of the user that has access to the database. + * + * @return The name for the user that has access to this database. + */ + public final String getUser() { + return dbUser; + } + + /** + * Get the password of the user that has access to the database. + * + * @return The password, associated with the user, that has access to this + * database. + */ + public final String getPass() { + return dbPass; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/dao/AlertsDAO.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/dao/AlertsDAO.java new file mode 100644 index 0000000..93a4943 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/dao/AlertsDAO.java @@ -0,0 +1,221 @@ +package net.grandtheftmc.core.database.dao; + +import com.google.common.collect.Lists; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.alert.Alert; +import net.grandtheftmc.core.alert.AlertEntry; +import net.grandtheftmc.core.alert.AlertManager; +import net.grandtheftmc.core.alert.type.AlertShowType; +import net.grandtheftmc.core.alert.type.AlertType; +import net.grandtheftmc.core.database.BaseDatabase; +import org.bukkit.entity.Player; + +import java.sql.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +public class AlertsDAO { + + public static boolean createAlertsTable() { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("CREATE TABLE IF NOT EXISTS `alerts`(" + + "`id` int NOT NULL AUTO_INCREMENT," + + "`name` varchar(255) NOT NULL," + + "`description` varchar(255) DEFAULT 'none'," + + "`image` varchar(255)," + + "`link` varchar(255)," + + "`showType` varchar(32) NOT NULL," + + "`type` varchar(32) NOT NULL," + + "`disabled` varchar(6)," + + "`start` timestamp NOT NULL," + + "`end` timestamp NOT NULL," + + "`player` varchar(32) NOT NULL," + + "`addon` longtext," + + "PRIMARY KEY (`id`));")) { + statement.execute(); + } + } catch (SQLException e) { + Core.error("[AlertsDAO:createAlertsTable()] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean createAlertUserTable() { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("CREATE TABLE IF NOT EXISTS `alert_users`(" + + "`uuid` varchar(36) NOT NULL," + + "`id` int NOT NULL," + + "`complete` varchar(6) NOT NULL," + + "`input` longtext);")) { + statement.execute(); + } + } catch (SQLException e) { + Core.error("[AlertsDAO:createAlertUserTable()] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + public static Optional[]> fetchAllAlerts() { + List[] alertList = new ArrayList[2];//0=alerts, 1=polls + alertList[0] = Lists.newArrayList(); + alertList[1] = Lists.newArrayList(); + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM `alerts`;")) { + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + int id = result.getInt("id"); + String name = result.getString("name"); + String player = result.getString("player"); + AlertType type; + AlertShowType showType; + try { + type = AlertType.valueOf(result.getString("type")); + showType = AlertShowType.valueOf(result.getString("showType")); + } catch (Exception e) { + continue; + } + String link = result.getString("link"), desc = result.getString("description"); + Timestamp start = result.getTimestamp("start"), end = result.getTimestamp("end"); + boolean disabled = Boolean.parseBoolean(result.getString("disabled")); + + if (type == AlertType.POLL) { + AlertEntry entry = new AlertEntry(name, null, showType, type, link, start, end, disabled); + entry.setUniqueIdentifier(id); + entry.setDescription(desc); + entry.setPlayer(player); + alertList[1].add(entry); + continue; + } + + String image = result.getString("image"); + AlertEntry entry = new AlertEntry(name, image, showType, type, link, start, end, disabled); + entry.setUniqueIdentifier(id); + entry.setDescription(desc); + entry.setPlayer(player); + alertList[0].add(entry); + } + } + } + } catch (SQLException e) { + Core.error("[AlertsDAO:createAlertUserTable()] SQLException occurred"); + e.printStackTrace(); + return Optional.empty(); + } + + return Optional.of(alertList); + } + + public static boolean insertAlert(Alert alert) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO `alerts` (`name`,`description`,`image`,`link`,`showType`,`type`,`disabled`,`start`,`end`,`player`,`addon`) VALUES(?,?,?,?,?,?,?,?,?,?,?);")) { + statement.setString(1, alert.getName()); + statement.setString(2, alert.getDescription()); + statement.setString(3, alert.getImageUrl()); + statement.setString(4, alert.getLink()); + statement.setString(5, alert.getShowType().name()); + statement.setString(6, alert.getAlertType().name()); + statement.setString(7, String.valueOf(alert.isDisabled())); + statement.setTimestamp(8, alert.getStart()); + statement.setTimestamp(9, alert.getEnd()); + statement.setString(10, alert.getPlayer()); + statement.setString(11, "views:0"); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[AlertsDAO:insertAlert(alert)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean insertAlertUser(Player player, Alert alert) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO `alert_users` (`uuid`,`id`,`complete`,`input`) VALUES(?,?,?,?);")) { + statement.setString(1, player.getUniqueId().toString()); + statement.setInt(2, alert.getUniqueIdentifier()); + statement.setString(3, "true"); + statement.setString(4, "none"); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[AlertsDAO:insertAlertUser(player,alert)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean updateAlert(Alert alert) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `alerts` SET `name`=?,`description`=?,`image`=?,`link`=?,`showType`=?,`type`=?,`disabled`=?,`start`=?,`end`=?,`player`=?,`addon`=? WHERE `id`=?;")) { + statement.setString(1, alert.getName()); + statement.setString(2, alert.getDescription()); + statement.setString(3, alert.getImageUrl()); + statement.setString(4, alert.getLink()); + statement.setString(5, alert.getShowType().name()); + statement.setString(6, alert.getAlertType().name()); + statement.setString(7, String.valueOf(alert.isDisabled())); + statement.setTimestamp(8, alert.getStart()); + statement.setTimestamp(9, alert.getEnd()); + statement.setString(10, alert.getPlayer()); + statement.setString(11, "views:0"); + statement.setInt(12, alert.getUniqueIdentifier()); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[AlertsDAO:updateAlert(alert)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean deleteAlert(Alert alert) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("DELETE FROM `alerts` WHERE `id`=?;")) { + statement.setInt(1, alert.getUniqueIdentifier()); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[AlertsDAO:deleteAlert(alert)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + public static Optional> fetchAlertsForPlayer(AlertManager alertManager, UUID uuid) { + List list = alertManager.getAvailableAlerts(); + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT `id` FROM `alert_users` WHERE `uuid`=?;")) { + statement.setString(1, uuid.toString()); + try (ResultSet result = statement.executeQuery()) { + while(result.next()) { + int id = result.getInt("id"); + alertManager.getAvailableAlertById(id).ifPresent(list::remove); + } + } + } + } catch (SQLException e) { + Core.error("[AlertsDAO:fetchAlertsForPlayer(uuid)] SQLException occurred"); + e.printStackTrace(); + return Optional.empty(); + } + + return Optional.of(list); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/dao/CurrencyDAO.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/dao/CurrencyDAO.java new file mode 100644 index 0000000..a704ebf --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/dao/CurrencyDAO.java @@ -0,0 +1,282 @@ +package net.grandtheftmc.core.database.dao; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.currency.Currency; +import net.grandtheftmc.core.currency.trans.CurrencyTransaction; + +public class CurrencyDAO { + + /** + * Get the amount of the specified currency for the specified uuid on the + * given serverKey. + * + * @param conn - the database connection thread + * @param serverKey - the key of server to lookup the currency for + * @param uuid - the uuid of the of the user + * @param currency - the currency to retrieve + * + * @return The amount of the specified currency the user has, if found, + * otherwise 0. + */ + public static Integer getCurrency(Connection conn, String serverKey, UUID uuid, Currency currency) { + + String query = "SELECT amount FROM user_currency WHERE uuid=UNHEX(?) AND server_key=? AND currency=?;"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setString(1, uuid.toString().replaceAll("-", "")); + ps.setString(2, serverKey); + ps.setString(3, currency.getId()); + + try (ResultSet result = ps.executeQuery()) { + if (result.next()) { + return result.getInt("amount"); + } + } + } + catch (SQLException exc) { + Core.log("[CurrencyDAO] Error attempting to getCurrency() for serverKey=" + serverKey + ", uuid=" + uuid.toString() + ", currency=" + currency.getId()); + exc.printStackTrace(); + } + + return 0; + } + + /** + * Save the specified currency/amount for the specified user. + * + * @param conn - the database connection thread + * @param serverKey - the server key + * @param uuid - the uuid of the user + * @param currency - the currency to save + * @param balance - the balance of the currency + * + * @return {@code true} if the currency was saved, {@code false} otherwise. + */ + public static boolean saveCurrency(Connection conn, String serverKey, UUID uuid, Currency currency, int balance){ + + String query = "INSERT IGNORE INTO user_currency (uuid, server_key, currency, amount) VALUES (UNHEX(?), ?, ?, ?) ON DUPLICATE KEY UPDATE amount = VALUES(amount);"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setString(1, uuid.toString().replaceAll("-", "")); + ps.setString(2, serverKey); + ps.setString(3, currency.getId()); + ps.setInt(4, balance); + + ps.executeUpdate(); + return true; + } + catch (SQLException exc) { + Core.log("[CurrencyDAO] Error attempting to saveCurrency() for serverKey=" + serverKey + ", uuid=" + uuid.toString() + ", currency=" + currency.getId() + ", amount=" + balance); + exc.printStackTrace(); + return false; + } + } + + /** + * Increments the specified currency/amount for the specified user. + * + * @param conn - the database connection thread + * @param serverKey - the server key + * @param uuid - the uuid of the user + * @param currency - the currency to save + * @param numToAdd - the number to add + * + * @return {@code true} if the currency was incremented, {@code false} otherwise. + * + * @deprecated - This only exists for compatibility purposes, and is not safe without mutex contention. + */ + @Deprecated + public static boolean addCurrency(Connection conn, String serverKey, UUID uuid, Currency currency, int numToAdd){ + + String query = "UPDATE user_currency SET amount=amount + ? WHERE uuid=UNHEX(?) AND server_key=? AND currency=?;"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setInt(1, numToAdd); + ps.setString(2, uuid.toString().replaceAll("-", "")); + ps.setString(3, serverKey); + ps.setString(4, currency.getId()); + + ps.executeUpdate(); + return true; + } + catch (SQLException exc) { + Core.log("[CurrencyDAO] Error attempting to addCurrency() for serverKey=" + serverKey + ", uuid=" + uuid.toString() + ", currency=" + currency.getId() + ", numToAdd=" + numToAdd); + exc.printStackTrace(); + return false; + } + } + + /** + * Creates the specified currency entry for the specified user. + *

+ * This is so they have a value to save to, and should be checked when a user logs in. + *

+ * + * @param conn - the database connection thread + * @param serverKey - the server key + * @param uuid - the uuid of the user + * @param currency - the currency to save + * + * @return {@code true} if the currency was created, {@code false} otherwise. + */ + public static boolean createCurrency(Connection conn, String serverKey, UUID uuid, Currency currency){ + + String existQuery = "SELECT currency FROM user_currency WHERE uuid=UNHEX(?) AND server_key=? AND currency=?"; + + boolean exists = false; + try (PreparedStatement ps = conn.prepareStatement(existQuery)) { + ps.setString(1, uuid.toString().replaceAll("-", "")); + ps.setString(2, serverKey); + ps.setString(3, currency.getId()); + + try (ResultSet result = ps.executeQuery()){ + if (result.next()){ + String c = result.getString("currency"); + if (c != null){ + exists = true; + } + } + } + } + catch (SQLException exc) { + Core.log("[CurrencyDAO] Error attempting to createCurrency(EXIST) for serverKey=" + serverKey + ", uuid=" + uuid.toString() + ", currency=" + currency.getId()); + exc.printStackTrace(); + return false; + } + + if (!exists){ + String query = "INSERT IGNORE INTO user_currency (uuid, server_key, currency, amount) VALUES (UNHEX(?), ?, ?, ?);"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setString(1, uuid.toString().replaceAll("-", "")); + ps.setString(2, serverKey); + ps.setString(3, currency.getId()); + ps.setInt(4, 0); + + ps.executeUpdate(); + + // currency was created, so return true + return true; + } + catch (SQLException exc) { + Core.log("[CurrencyDAO] Error attempting to createCurrency(CREATE) for serverKey=" + serverKey + ", uuid=" + uuid.toString() + ", currency=" + currency.getId()); + exc.printStackTrace(); + return false; + } + } + + return false; + } + + /** + * Get all the currencies for the specified user on the specified serverKey. + * + * @param conn - the database connection thread + * @param serverKey - the key of the server to lookup + * @param uuid - the uuid of the user to lookup + * + * @return A mapping of Currency to Integer where the currency is the unique + * lookup and the Integer is how much of that currency the player + * has. + */ + public static Map getAllCurrencies(Connection conn, String serverKey, UUID uuid) { + + Map currencies = new HashMap<>(); + + String query = "SELECT currency, amount FROM user_currency WHERE uuid=UNHEX(?) AND server_key=?;"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setString(1, uuid.toString().replaceAll("-", "")); + ps.setString(2, serverKey); + + try (ResultSet result = ps.executeQuery()) { + while (result.next()) { + + Currency curr = Currency.fromID(result.getString("currency")).orElse(null); + if (curr != null) { + int amount = result.getInt("amount"); + + currencies.put(curr, amount); + } + } + } + } + catch (SQLException exc) { + Core.log("[CurrencyDAO] Error attempting to getAllCurrencies() for serverKey=" + serverKey + ", uuid=" + uuid.toString()); + exc.printStackTrace(); + } + + return currencies; + } + + /** + * Saves all the currencies specified to the database for the given user. + * + * @param conn - the database connection thread + * @param serverKey - the server key to save for + * @param uuid - the uuid of the user + * @param currencies - the currencies to save + */ + public static void saveCurrencies(Connection conn, String serverKey, UUID uuid, Map currencies) { + + for (Currency currency : currencies.keySet()){ + + int balance = currencies.get(currency); + + String query = "INSERT IGNORE INTO user_currency (uuid, server_key, currency, amount) VALUES (UNHEX(?), ?, ?, ?) ON DUPLICATE KEY UPDATE amount = VALUES(amount);"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setString(1, uuid.toString().replaceAll("-", "")); + ps.setString(2, serverKey); + ps.setString(3, currency.getId()); + ps.setInt(4, balance); + + ps.executeUpdate(); + } + catch (SQLException exc) { + Core.log("[CurrencyDAO] Error attempting to saveCurrencies() for serverKey=" + serverKey + ", uuid=" + uuid.toString() + ", currency=" + currency.getId() + ", amount=" + balance); + exc.printStackTrace(); + } + } + } + + /** + * Logs the specified currency transactions to the database. + * + * @param conn - the database connection thread + * @param serverKey - the server key + * @param uuid - the uuid of the player saving their transaction + * @param trans - the list of transactions to save + */ + public static void logCurrencyTransaction(Connection conn, String serverKey, UUID uuid, List trans){ + + for (CurrencyTransaction t : trans){ + String query = "INSERT INTO log_currency_transaction (uuid, server_key, currency, amount, source, reason) VALUES (UNHEX(?), ?, ?, ?, ?, ?);"; + + try (PreparedStatement ps = conn.prepareStatement(query)){ + ps.setString(1, uuid.toString().replaceAll("-", "")); + ps.setString(2, serverKey); + ps.setString(3, t.getCurrency().getId()); + ps.setInt(4, t.getAmount()); + ps.setString(5, t.getSource().getSource().getId()); + ps.setString(6, t.getSource().getReason().isPresent() ? t.getSource().getReason().get() : ""); + + ps.executeUpdate(); + } + catch(SQLException exc){ + Core.log("[CurrencyDAO] Error logging currency transaction for server_key=" + serverKey + ", uuid=" + uuid.toString() + ", transaction=" + t.toString()); + exc.printStackTrace(); + } + } + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/dao/ExampleDAO.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/dao/ExampleDAO.java new file mode 100644 index 0000000..7197d47 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/dao/ExampleDAO.java @@ -0,0 +1,205 @@ +package net.grandtheftmc.core.database.dao; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.servers.Server; +import net.grandtheftmc.core.servers.ServerType; +import net.grandtheftmc.core.users.UserRank; + +/** + * Serves as an example of how DAOs should work. + * + * @author sbahr + */ +public class ExampleDAO { + + /** + * Example usage when running on a sync thread. + */ + public static void exampleUsageInCodeSync() { + + try (Connection conn = BaseDatabase.getInstance().getConnection()) { + ExampleDAO.setName(conn, UUID.randomUUID(), "HeyThere"); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * Example usage when wanting to update something async, not needing result + * return. + * + * @param plugin - the plugin instance + */ + public static void exampleUsageInCodeAsyncUpdate(Plugin plugin) { + + // this will update the username off main thread + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { + + try (Connection conn = BaseDatabase.getInstance().getConnection()) { + ExampleDAO.setName(conn, UUID.randomUUID(), "HeyThere"); + } + catch (Exception e) { + e.printStackTrace(); + } + }); + } + + /** + * Example usage when wanting an async fetch of information. + * + * @param plugin - the plugin instance + */ + public static void exampleUsageInCodeAsyncFetch(Plugin plugin) { + + // this will update the username off main thread + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { + + // build result OUTSIDE of try/with resource so connection + // closes + List servers = new ArrayList<>(); + try (Connection conn = BaseDatabase.getInstance().getConnection()) { + servers.addAll(ExampleDAO.getServers(conn)); + } + catch (Exception e) { + e.printStackTrace(); + } + + // if we need to get back on sync + Bukkit.getScheduler().runTask(plugin, () -> { + + if (!servers.isEmpty()){ + servers.forEach(s -> { + Bukkit.broadcastMessage("Server name: " + s.getName()); + }); + } + }); + }); + } + + /** + * Sets the name of a specified uuid. + * + * @param conn - the database connection thread + * @param uuid - the uuid of the user to set the name for + * @param name - the new name to set + * + * @return {@code true} if the query successfully ran, {@code false} + * otherwise. + */ + public static boolean setName(Connection conn, UUID uuid, String name) { + + String query = "UPDATE user SET name=? WHERE uuid=UNHEX(?);"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setString(1, name); + ps.setString(2, uuid.toString().replaceAll("-", "")); + ps.executeUpdate(); + return true; + } + catch (SQLException exc) { + Core.log("[ExampleDAO] Unable to execute setName() for uuid=" + uuid.toString() + " and name=" + name); + exc.printStackTrace(); + } + + return false; + } + + /** + * Delete from the database the specified user. + * + * @param conn - the database connection thread + * @param uuid - the uuid of the user to delete + * + * @return {@code true} if the query ran, {@code false} otherwise. + */ + public static boolean deleteUser(Connection conn, UUID uuid) { + + String query = "DELETE FROM user WHERE uuid=UNHEX(?);"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setString(1, uuid.toString().replaceAll("-", "")); + ps.executeUpdate(); + + return true; + } + catch (SQLException exc) { + Core.log("[ExampleDAO] Unable to execute deleteUser() for uuid=" + uuid.toString()); + exc.printStackTrace(); + } + + return false; + } + + /** + * Get a list of servers that are active in the database. + * + * @param conn - the database connection thread + * + * @return A list of servers that were located in the database. + */ + public static List getServers(Connection conn) { + + List servers = new ArrayList<>(); + String query = "SELECT * FROM servers"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + + try (ResultSet result = ps.executeQuery()) { + while (result.next()) { + Server server = new Server(result.getString("name"), ServerType.getType(result.getString("type")), result.getInt("number"), result.getString("ip"), result.getInt("port"), UserRank.getUserRankOrNull(result.getString("rankToJoin"))); + servers.add(server); + } + } + } + catch (SQLException exc) { + Core.log("[ExampleDAO] Unable to execute getServers()"); + exc.printStackTrace(); + } + + return servers; + } + + /** + * Get the server object given the specified server id, or server number. + * + * @param conn - the database connection thread + * @param serverID - the id of the server to get + * + * @return The server, if one was found. + */ + public static Optional getServer(Connection conn, int serverID) { + + String query = "SELECT * FROM servers WHERE number=?;"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setInt(1, serverID); + + try (ResultSet result = ps.executeQuery()) { + if (result.next()) { + Server server = new Server(result.getString("name"), ServerType.getType(result.getString("type")), result.getInt("number"), result.getString("ip"), result.getInt("port"), UserRank.getUserRankOrNull(result.getString("rankToJoin"))); + return Optional.of(server); + } + } + } + catch (SQLException exc) { + Core.log("[ExampleDAO] Unable to execute getServers()"); + exc.printStackTrace(); + } + + return Optional.empty(); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/dao/LogDAO.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/dao/LogDAO.java new file mode 100644 index 0000000..263b424 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/dao/LogDAO.java @@ -0,0 +1,35 @@ +package net.grandtheftmc.core.database.dao; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.database.BaseDatabase; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.UUID; + +public class LogDAO { + + public static boolean insertLog(UUID uuid, String name, String action, String type, String reward, double amount, double price) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO `logs`(`uuid`,`name`,`action`,`type`,`reward`,`amount`,`price`,`server`) VALUES(?,?,?,?,?,?,?,?);")) { + statement.setString(1, uuid.toString()); + statement.setString(2, name); + statement.setString(3, action); + statement.setString(4, type); + statement.setString(5, reward); + statement.setDouble(6, amount); + statement.setDouble(7, price); + statement.setString(8, Core.name()); + + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:insertLog()] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/dao/MutexDAO.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/dao/MutexDAO.java new file mode 100644 index 0000000..bd80e0c --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/dao/MutexDAO.java @@ -0,0 +1,68 @@ +package net.grandtheftmc.core.database.dao; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.UUID; + +import net.grandtheftmc.core.util.debug.Log; + +public class MutexDAO { + + /** + * Get the user's mutex. + *

+ * If this returns true, then the user's mutex is already lent out to + * someone else. If this returns false, then the user's mutex is not yet + * occupied. + * + * @param conn - the database connection thread + * @param uuid - the uuid of the user + * + * @return {@code true} if the user's mutex is already taken, {@code false} + * if the user's mutex is empty. + */ + public static boolean getUserMutex(Connection conn, UUID uuid) { + + boolean mutex = false; + + String query = "SELECT mutex FROM user WHERE uuid=UNHEX('" + uuid.toString().replaceAll("-", "") + "')"; + + try (ResultSet result = conn.createStatement().executeQuery(query)) { + if (result.next()) { + mutex = result.getBoolean("mutex"); + } + } + catch (SQLException exc) { + Log.error("Core", "Error executing getUserMutex() for user identified by " + uuid.toString()); + exc.printStackTrace(); + } + + return mutex; + } + + /** + * Updates the user's mutex. + * + * @param conn - the database connection thread + * @param uuid - the uuid of the user + * @param mutex - {@code true} if we still want to occupy the mutex, + * {@code false} otherwise. + */ + public static void setUserMutex(Connection conn, UUID uuid, boolean mutex) { + + String query = "UPDATE user SET mutex=? WHERE uuid=UNHEX('" + uuid.toString().replaceAll("-", "") + "')"; + + try (PreparedStatement statement = conn.prepareStatement(query)) { + statement.setBoolean(1, mutex); + + statement.executeUpdate(); + } + catch (SQLException exc) { + Log.error("Core", "Error executing setUserMutex() for user identified by " + uuid.toString()); + exc.printStackTrace(); + } + } +} + diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/dao/OldVoteDAO.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/dao/OldVoteDAO.java new file mode 100644 index 0000000..80c9d1f --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/dao/OldVoteDAO.java @@ -0,0 +1,439 @@ +package net.grandtheftmc.core.database.dao; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +import com.google.common.collect.Lists; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.users.UserRank; + +public class OldVoteDAO { + + public static Optional> fetchRelevantVoters() { + List list = Lists.newArrayList(); + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT `uuid` FROM `votes` WHERE `monthlyVotes`>0 ORDER BY `monthlyVotes` DESC;")) { + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + list.add(result.getString("uuid")); + } + } + } + } catch (SQLException e) { + Core.error("[VoteDAO:getRelevantVoters()] SQLException occurred"); + e.printStackTrace(); + return Optional.empty(); + } + + return Optional.of(list); + } + + public static boolean updateMonthlyVotes(UUID uuid, int amount) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `votes` SET `monthlyVotes`=? WHERE `uuid`=?;")) { + statement.setInt(1, amount); + statement.setString(2, uuid.toString()); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:updateMonthlyVotes(uuid,amount)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean updateTotalVotes(UUID uuid, int amount) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `votes` SET `totalVotes`=? WHERE `uuid`=?;")) { + statement.setInt(1, amount); + statement.setString(2, uuid.toString()); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:updateTotalVotes(uuid,amount)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean updateLastVote(UUID uuid, String voteSite, long timestamp) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `votes` SET " + voteSite + "=? WHERE `uuid`=?;")) { + statement.setLong(1, timestamp); + statement.setString(2, uuid.toString()); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:updateLastVote(uuid,voteSite,timestamp)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean updateUserVotes(UUID uuid, int amount) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `users` SET `votes`=? WHERE `uuid`=?;")) { + statement.setInt(1, amount); + statement.setString(2, uuid.toString()); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:updateUserVotes(uuid,amount)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean updateUserVotesByName(String name, int amount) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `users` SET `votes`=? WHERE `lastname`=?;")) { + statement.setInt(1, amount); + statement.setString(2, name); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:updateUserVotes(uuid,amount)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean updateUserVoteStreak(UUID uuid, int voteStreak) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `users` SET `voteStreak`=? WHERE `uuid`=?;")) { + statement.setInt(1, voteStreak); + statement.setString(2, uuid.toString()); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:updateUserVoteStreak(uuid,voteStreak)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean updateUserLastVoteStreak(UUID uuid, long lastVoteStreak) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `users` SET `lastVoteStreak`=? WHERE `uuid`=?;")) { + statement.setLong(1, lastVoteStreak); + statement.setString(2, uuid.toString()); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:updateUserLastVoteStreak(uuid,lastVoteStreak)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean updateUserLastVoteStreakByName(String name, long lastVoteStreak) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `users` SET `lastVoteStreak`=? WHERE `lastname`=?;")) { + statement.setLong(1, lastVoteStreak); + statement.setString(2, name); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:updateUserLastVoteStreakByName(name,lastVoteStreak)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean updateUserDailyStreak(UUID uuid, int dailyStreak) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `users` SET `dailyStreak`=? WHERE `uuid`=?;")) { + statement.setInt(1, dailyStreak); + statement.setString(2, uuid.toString()); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:updateUserDailyStreak(uuid,dailyStreak)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean updateUserDailyStreakByName(String name, int dailyStreak) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `users` SET `dailyStreak`=? WHERE `lastname`=?;")) { + statement.setInt(1, dailyStreak); + statement.setString(2, name); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:updateUserDailyStreakByName(name,dailyStreak)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean updateUserDaily(UUID uuid, int dailyStreak, long lastDailyReward) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `users` SET `dailyStreak`=?, `lastDailyReward`=? WHERE `uuid`=?;")) { + statement.setInt(1, dailyStreak); + statement.setLong(2, lastDailyReward); + statement.setString(3, uuid.toString()); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:updateUserDaily(uuid,dailyStreak,lastDailyReward)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean updateUserLastDailyReward(UUID uuid, long lastDailyReward) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `users` SET `lastDailyReward`=? WHERE `uuid`=?;")) { + statement.setLong(1, lastDailyReward); + statement.setString(2, uuid.toString()); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:updateUserLastDailyReward(uuid,lastDailyReward)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean updateUserLastDailyRewardByName(String name, long lastDailyReward) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `users` SET `lastDailyReward`=? WHERE `lastname`=?;")) { + statement.setLong(1, lastDailyReward); + statement.setString(2, name); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:updateUserLastDailyRewardByName(name,lastDailyReward)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean deleteLastMonthsVoters() { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("TRUNCATE TABLE `last_months_voters`;")) { + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:deleteLastMonthsVoters()] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + public static Optional getTopTenVoters() { + VoteUser[] voteUsers = new VoteUser[10]; + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT U.name AS voter_name, HEX(LUV.uuid), COUNT(*) AS total_votes FROM log_user_vote LUV, user U WHERE U.uuid=LUV.uuid AND YEAR(LUV.creation) = YEAR(CURRENT_DATE()) AND MONTH(LUV.creation) = MONTH(CURRENT_DATE()) GROUP by LUV.uuid ORDER BY COUNT(*) DESC LIMIT 10;")) { + try (ResultSet result = statement.executeQuery()) { + int i = 0; + while(result.next()) { + voteUsers[i] = new VoteUser(i + 1, result.getInt("total_votes"), result.getString("voter_name")); + i += 1; + } + + return Optional.of(voteUsers); + } + } + } catch (SQLException e) { + Core.error("[UserDAO:getTopTenVoters()] SQLException occurred"); + e.printStackTrace(); + return Optional.empty(); + } + } + + public static Optional getLastMonthsVoters() { + VoteUser[] voteUsers = new VoteUser[10]; + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM `last_months_voters` ORDER BY `slot` DESC LIMIT 10;")) { + try (ResultSet result = statement.executeQuery()) { + while(result.next()) { + int slot = result.getInt("slot"); + voteUsers[slot - 1] = new VoteUser(slot, result.getString("name")); + } + + return Optional.of(voteUsers); + } + } + } catch (SQLException e) { + Core.error("[UserDAO:getLastMonthsVoters()] SQLException occurred"); + e.printStackTrace(); + return Optional.empty(); + } + } + + public static Optional getTopVoter() { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM `votes` ORDER BY `votes`.`monthlyVotes` DESC LIMIT 1;")) { + try (ResultSet result = statement.executeQuery()) { + if (result.next()) { + return Optional.of(new VoteUser(1, result.getInt("monthlyVotes"), result.getString("name"))); + } + } + } + } catch (SQLException e) { + Core.error("[UserDAO:getTopVoter()] SQLException occurred"); + e.printStackTrace(); + return Optional.empty(); + } + + return Optional.empty(); + } + + public static boolean updateVoteStreakByName(String name, int streak) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `users` SET `voteStreak`=? WHERE `lastname`=?;")) { + statement.setInt(1, streak); + statement.setString(2, name); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:updateVoteStreakByName(name,streak)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + public static Optional fetchRandomVoteStreaker(int minStreak) { + //"SELECT * FROM users WHERE voteStreak >20 ORDER BY RAND() LIMIT 1;" + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM `users` WHERE `voteStreak`>? ORDER BY RAND() LIMIT 1;")) { + statement.setInt(1, minStreak); + try (ResultSet result = statement.executeQuery()) { + if (result.next()) { + return Optional.of(new VoteUser(UUID.fromString(result.getString("uuid")), + result.getString("name"), + result.getInt("voteStreak"), + UserRank.getUserRank(result.getString("userrank")))); + } + } + } + } catch (SQLException e) { + Core.error("[UserDAO:fetchRandomVoteStreaker(minStreak)] SQLException occurred"); + e.printStackTrace(); + return Optional.empty(); + } + + return Optional.empty(); + } + + /** + * Logs a user vote into the database for storage purposes. + * + * @param conn - the database connection thread + * @param voter - the uuid of the voter + * @param amount - the amount their vote is worth, as some can have higher values + * @param serviceID - the id of the service that they voted on + * + * @return {@code true} if the user vote was logged, {@code false} otherwise. + */ + public static boolean logUserVote(Connection conn, UUID voter, int amount, int serviceID){ + + String query = "INSERT INTO log_user_vote (uuid, amount, service_id) VALUES (UNHEX(?), ?, ?);"; + + try (PreparedStatement ps = conn.prepareStatement(query)){ + ps.setString(1, voter.toString().replace("-", "")); + ps.setInt(2, amount); + ps.setInt(3, serviceID); + + ps.executeUpdate(); + } + catch(SQLException e){ + Core.log("[VoteDAO] Error logging vote for voter uuid=" + voter.toString() + ", amount=" + amount + ", serviceID=" + serviceID); + e.printStackTrace(); + return false; + } + + return true; + } + + public static class VoteUser { + private int possition, votes; + private String name; + + private UUID uuid; + private int streak; + private UserRank rank; + + public VoteUser(int possition, int votes, String name) { + this.possition = possition; + this.votes = votes; + this.name = name; + } + + public VoteUser(int possition, String name) { + this.possition = possition; + this.name = name; + } + + public VoteUser(UUID uuid, String name, int streak, UserRank rank) { + this.uuid = uuid; + this.name = name; + this.streak = streak; + this.rank = rank; + } + + public int getPossition() { + return possition; + } + + public int getVotes() { + return votes; + } + + public String getName() { + return name; + } + + public UUID getUuid() { + return uuid; + } + + public int getStreak() { + return streak; + } + + public UserRank getRank() { + return rank; + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/dao/ServerInfoDAO.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/dao/ServerInfoDAO.java new file mode 100644 index 0000000..a3cfafb --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/dao/ServerInfoDAO.java @@ -0,0 +1,85 @@ +package net.grandtheftmc.core.database.dao; + +import com.google.common.collect.Lists; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.servers.Server; +import net.grandtheftmc.core.servers.ServerType; +import net.grandtheftmc.core.users.UserRank; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +public class ServerInfoDAO { + + public static Optional> fetchAllServers() { + List servers = Lists.newArrayList(); + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM `servers`;")) { + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + servers.add(new Server(result.getString("name"), ServerType.getType(result.getString("type")), + result.getInt("number"), result.getString("ip"), result.getInt("port"), + UserRank.getUserRankOrNull(result.getString("rankToJoin")))); + } + } + } + } catch (SQLException e) { + Core.error("[ServerInfoDAO:fetchAllServers()] SQLException occurred"); + e.printStackTrace(); + return Optional.empty(); + } + + return Optional.of(servers); + } + + public static boolean updateServerInfo(String name, ServerType type, int number, int onlinePlayers, int maxPlayers, String map, String gameState, int round, UserRank rankToJoin) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `servers` SET " + + "`type`=?,`number`=?,`onlinePlayers`=?,`maxPlayers`=?,`map`=?,`gameState`=?,`round`=?,`rankToJoin`=?,`lastCheck`=? WHERE `name`=?;")) { + statement.setString(1, type.name()); + statement.setInt(2, number); + statement.setInt(3, onlinePlayers); + statement.setInt(4, maxPlayers); + statement.setString(5, map); + statement.setString(6, gameState); + statement.setInt(7, round); + statement.setString(8, rankToJoin == null ? "DEFAULT" : rankToJoin.name()); + statement.setLong(9, System.currentTimeMillis()); + statement.setString(10, name); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[ServerInfoDAO:updateServerInfo(...)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + public static Collection getOnlineStaff() { + Collection collection = Lists.newArrayList(); + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT `lastname` FROM `users` WHERE `userrank` IN ('HELPOP','MOD','ADMIN','DEV');")) { + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + collection.add(result.getString("lastname")); + } + } + } + } catch (SQLException e) { + Core.error("[ServerInfoDAO:getOnlineStaff()] SQLException occurred"); + e.printStackTrace(); + return Lists.newArrayList(); + } + + return collection; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/dao/ServerStatsDAO.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/dao/ServerStatsDAO.java new file mode 100644 index 0000000..c0e698c --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/dao/ServerStatsDAO.java @@ -0,0 +1,235 @@ +package net.grandtheftmc.core.database.dao; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserDAO; +import net.grandtheftmc.core.users.UserRank; +import org.bukkit.entity.Player; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Date; +import java.util.Optional; +import java.util.UUID; + +public class ServerStatsDAO { + + public static boolean reset(boolean daily) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement(!daily ? "UPDATE `server_stats` SET `playedServers`=NULL,`weeklyLoginTime`=?;" : "UPDATE `server_stats` SET `dailyPlayTime`=0,`dailyLoginTime`=?;")) { + statement.setLong(1, System.currentTimeMillis()); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[ServerStatsDAO:reset(daily)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + public static Optional fetchWeeklyStats() { + WeeklyStatsData data = new WeeklyStatsData(); + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM `server_stats`;")) { + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + data.totalLogins += 1; + long firstLogin = result.getLong("firstLogin"); + long weeklyLogin = result.getLong("weeklyLoginTime"); + if ((System.currentTimeMillis() - firstLogin) <= (1000 * 60 * 60 * 24 * 7)) { + data.totalNewPlayers += 1; + if (weeklyLogin != 0 && weeklyLogin != firstLogin) { + data.totalNewPlayersLoginAgain += 1; + } + } + + String playedServers = result.getString("playedServers") == null ? result.getString("playedServers") : ""; + if (playedServers.contains("vice") && playedServers.contains("gtm")) { + data.totalPlayersPlayedBoth += 1; + continue; + } + + if (playedServers.contains("vice")) + data.totalPlayersPlayedVice += 1; + + if (playedServers.contains("gtm")) + data.totalPlayersPlayedGTM += 1; + } + + data.setData(new Date().toGMTString() + "-" + data.totalNewPlayersLoginAgain + "-" + data.totalPlayersPlayedBoth + "-" + data.totalPlayersPlayedVice + "-" + data.totalPlayersPlayedGTM + "-" + data.totalNewPlayers + "-" + data.totalLogins); + } + } + } catch (SQLException e) { + Core.error("[ServerStatsDAO:fetchWeeklyStats] SQLException occurred"); + e.printStackTrace(); + return Optional.empty(); + } + + return Optional.of(data); + } + + public static Optional fetchDailyStats() { + DailyStatsData data = new DailyStatsData(); + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM `server_stats`;")) { + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + String uuid = result.getString("uuid"); + + if((System.currentTimeMillis() - result.getLong("firstLogin")) <= 1000 * 60 * 60 * 24) + data.dailyNewPlayers++; + + if((System.currentTimeMillis() - result.getLong("dailyLoginTime")) <= 1000 * 60 * 60 * 24) { + data.dailyTotalLogins++; + long playtime = result.getLong("dailyPlayTime"); + data.dailyPlaytime += playtime; + + UserRank rank = UserDAO.fetchUserRank(UUID.fromString(uuid)); + if(rank == UserRank.DEFAULT) { + data.dailyLoginsDefault++; + data.dailyPlaytimeDefault += playtime; + } + else { + data.dailyLoginsRanked++; + data.dailyPlaytimeRanked += playtime; + } + } + } + + + } + } + } catch (SQLException e) { + Core.error("[ServerStatsDAO:fetchDailyStats] SQLException occurred"); + e.printStackTrace(); + return Optional.empty(); + } + + return Optional.of(data); + } + + public static void updatePlaytimeAndFirstlogin(Connection connection, Player player, User user) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `server_stats` set `dailyPlayTime`=?,`firstLogin`=? WHERE `uuid`=?;")) { + statement.setLong(1, System.currentTimeMillis() - user.getLoginTime() + user.getDailyPlayTime()); + statement.setLong(2, player.getFirstPlayed()); + statement.setString(3, player.getUniqueId().toString()); + statement.execute(); + } catch (SQLException e) { + Core.error("[ServerStatsDAO:updatePlaytimeAndFirstlogin(player,user)] SQLException occurred"); + e.printStackTrace(); + } + } + + + + public static class WeeklyStatsData { + private String data; + private double totalLogins = 0, totalNewPlayers = 0, totalNewPlayersLoginAgain = 0, totalPlayersPlayedBoth = 0, totalPlayersPlayedVice = 0, totalPlayersPlayedGTM = 0; + + public String getData() { + return data; + } + + public void setData(String data) { + this.data = data; + } + + public double getTotalLogins() { + return totalLogins; + } + + public double getTotalNewPlayers() { + return totalNewPlayers; + } + + public double getTotalNewPlayersLoginAgain() { + return totalNewPlayersLoginAgain; + } + + public double getTotalPlayersPlayedBoth() { + return totalPlayersPlayedBoth; + } + + public double getTotalPlayersPlayedVice() { + return totalPlayersPlayedVice; + } + + public double getTotalPlayersPlayedGTM() { + return totalPlayersPlayedGTM; + } + } + + public static class DailyStatsData { + private String data; + private double dailyTotalLogins = 0, dailyPlaytime = 0, dailyNewPlayers = 0, dailyPlaytimeRanked = 0, dailyLoginsRanked = 0, dailyLoginsDefault = 0, dailyPlaytimeDefault = 0; + + public String getData() { + return data; + } + + public void setData(String data) { + this.data = data; + } + + public double getDailyTotalLogins() { + return dailyTotalLogins; + } + + public void setDailyTotalLogins(double dailyTotalLogins) { + this.dailyTotalLogins = dailyTotalLogins; + } + + public void setDailyPlaytime(double dailyPlaytime) { + this.dailyPlaytime = dailyPlaytime; + } + + public void setDailyNewPlayers(double dailyNewPlayers) { + this.dailyNewPlayers = dailyNewPlayers; + } + + public void setDailyPlaytimeRanked(double dailyPlaytimeRanked) { + this.dailyPlaytimeRanked = dailyPlaytimeRanked; + } + + public void setDailyLoginsRanked(double dailyLoginsRanked) { + this.dailyLoginsRanked = dailyLoginsRanked; + } + + public void setDailyLoginsDefault(double dailyLoginsDefault) { + this.dailyLoginsDefault = dailyLoginsDefault; + } + + public void setDailyPlaytimeDefault(double dailyPlaytimeDefault) { + this.dailyPlaytimeDefault = dailyPlaytimeDefault; + } + + public double getDailyPlaytime() { + return dailyPlaytime; + } + + public double getDailyNewPlayers() { + return dailyNewPlayers; + } + + public double getDailyPlaytimeRanked() { + return dailyPlaytimeRanked; + } + + public double getDailyLoginsRanked() { + return dailyLoginsRanked; + } + + public double getDailyLoginsDefault() { + return dailyLoginsDefault; + } + + public double getDailyPlaytimeDefault() { + return dailyPlaytimeDefault; + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/dao/VoteDAO.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/dao/VoteDAO.java new file mode 100644 index 0000000..4f4a4c9 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/dao/VoteDAO.java @@ -0,0 +1,445 @@ +package net.grandtheftmc.core.database.dao; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.util.Optional; +import java.util.UUID; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.debug.Log; +import net.grandtheftmc.core.voting.VoteRecord; +import net.grandtheftmc.core.voting.VoteSite; + +public class VoteDAO { + + /** + * Creates an empty user vote record in the database. + * + * @param conn - the database connection thread + * @param uuid - the uuid of the user to create the record for + * + * @return {@code true} if the record was created, {@code false} otherwise. + */ + public static boolean createUserVoteRecord(Connection conn, UUID uuid) { + + String query = "INSERT IGNORE INTO user_vote (uuid) VALUES (UNHEX(?));"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setString(1, uuid.toString().replaceAll("-", "")); + + ps.executeUpdate(); + } + catch (SQLException exc) { + exc.printStackTrace(); + return false; + } + + return true; + } + + /** + * Obtain a read only version of the user's vote record. + *

+ * Note: If the vote record does not exist, create a new empty one for them. + *

+ * + * @param conn - the database connection thread + * @param uuid - the uuid of the user to get their vote record + * + * @return The VoteRecord for the specified user. + */ + public static VoteRecord getUserVoteRecord(Connection conn, UUID uuid) { + + String query = "SELECT streak, total_votes, max_streak, last_vote, site_one, site_two, site_three, site_four, site_five FROM user_vote WHERE uuid=UNHEX(?);"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setString(1, uuid.toString().replaceAll("-", "")); + + try (ResultSet result = ps.executeQuery()) { + + // if vote record + if (result.next()) { + + int streak = result.getInt("streak"); + int totalVotes = result.getInt("total_votes"); + int maxStreak = result.getInt("max_streak"); + Timestamp lastVote = result.getTimestamp("last_vote"); + Timestamp siteOne = result.getTimestamp("site_one"); + Timestamp siteTwo = result.getTimestamp("site_two"); + Timestamp siteThree = result.getTimestamp("site_three"); + Timestamp siteFour = result.getTimestamp("site_four"); + Timestamp siteFive = result.getTimestamp("site_five"); + + VoteRecord vr = new VoteRecord(uuid, totalVotes, streak, maxStreak, lastVote); + vr.setVoteTimestamp(VoteSite.ONE, siteOne); + vr.setVoteTimestamp(VoteSite.TWO, siteTwo); + vr.setVoteTimestamp(VoteSite.THREE, siteThree); + vr.setVoteTimestamp(VoteSite.FOUR, siteFour); + vr.setVoteTimestamp(VoteSite.FIVE, siteFive); + + return vr; + } + else { + + // create an empty record for them + createUserVoteRecord(conn, uuid); + } + } + } + catch (SQLException exc) { + exc.printStackTrace(); + } + + return new VoteRecord(uuid); + } + + /** + * Updates the player's total votes, incrementing it by one. + * + * @param conn - the database connection thread + * @param uuid - the uuid of the user to increment their total votes + * + * @return {@code true} if their total votes was successfully updated, + * {@code false} otherwise. + */ + public static boolean incrementTotalVotes(Connection conn, UUID uuid) { + + String query = "UPDATE user_vote SET total_votes=total_votes+1 WHERE uuid=UNHEX(?);"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setString(1, uuid.toString().replaceAll("-", "")); + + ps.executeUpdate(); + return true; + } + catch (SQLException exc) { + exc.printStackTrace(); + } + + return false; + } + + /** + * Updates the player's vote streak, incrementing it by one. + *

+ * Note: This also updates their last vote timestamp. + *

+ * + * @param conn - the database connection thread + * @param uuid - the uuid of the user to increment their vote streak + * + * @return {@code true} if their vote streak was successfully updated, + * {@code false} otherwise. + */ + public static boolean incrementVoteStreak(Connection conn, UUID uuid) { + + String query = "UPDATE user_vote SET streak=streak+1, last_vote=CURRENT_TIMESTAMP WHERE uuid=UNHEX(?);"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setString(1, uuid.toString().replaceAll("-", "")); + + ps.executeUpdate(); + return true; + } + catch (SQLException exc) { + exc.printStackTrace(); + } + + return false; + } + + /** + * Updates the player's vote streak to the specified amount. + * + * @param conn - the database connection thread + * @param uuid - the uuid of the user to update + * @param voteStreak - the vote streak amount to set it to + * + * @return {@code true} if their vote streak was successfully updated, + * {@code false} otherwise. + */ + public static boolean setVoteStreak(Connection conn, UUID uuid, int voteStreak) { + + String query = "UPDATE user_vote SET streak=? WHERE uuid=UNHEX(?);"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setInt(1, voteStreak); + ps.setString(2, uuid.toString().replaceAll("-", "")); + + ps.executeUpdate(); + return true; + } + catch (SQLException exc) { + exc.printStackTrace(); + } + + return false; + } + + /** + * Resets the vote streak of the specified user. + * + * @param conn - the database connection thread + * @param uuid - the uuid of the user to reset their vote streak + * + * @return {@code true} if the vote streak was reset, {@code false} + * otherwise. + */ + public static boolean resetVoteStreak(Connection conn, UUID uuid) { + + String query = "UPDATE user_vote SET streak=0 WHERE uuid=UNHEX(?);"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setString(1, uuid.toString().replaceAll("-", "")); + + ps.executeUpdate(); + return true; + } + catch (SQLException exc) { + exc.printStackTrace(); + } + + return false; + } + + /** + * Updates the max streak that this user has. + * + * @param conn - the database connection + * @param uuid - the uuid of the user + * @param maxStreak - the max streak that this user has + * + * @return {@code true} if the query ran, {@code false} otherwise. + */ + public static boolean updateMaxStreak(Connection conn, UUID uuid, int maxStreak) { + + String query = "UPDATE user_vote SET max_streak=? WHERE uuid=UNHEX(?);"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setInt(1, maxStreak); + ps.setString(2, uuid.toString().replaceAll("-", "")); + + ps.executeUpdate(); + return true; + } + catch (SQLException exc) { + exc.printStackTrace(); + } + + return false; + + } + + /** + * Update the vote site timestamp for the specified uuid. + * + * @param conn - the database connection + * @param uuid - the uuid of the user + * @param voteSite - the vote site to update + * + * @return {@code true} if the query ran, {@code false} otherwise. + */ + public static boolean updateVoteSiteTimestamp(Connection conn, UUID uuid, VoteSite voteSite) { + + String query = null; + + switch (voteSite) { + case ONE: + query = "UPDATE user_vote SET site_one=CURRENT_TIMESTAMP WHERE uuid=UNHEX(?);"; + break; + case TWO: + query = "UPDATE user_vote SET site_two=CURRENT_TIMESTAMP WHERE uuid=UNHEX(?);"; + break; + case THREE: + query = "UPDATE user_vote SET site_three=CURRENT_TIMESTAMP WHERE uuid=UNHEX(?);"; + break; + case FOUR: + query = "UPDATE user_vote SET site_four=CURRENT_TIMESTAMP WHERE uuid=UNHEX(?);"; + break; + case FIVE: + query = "UPDATE user_vote SET site_five=CURRENT_TIMESTAMP WHERE uuid=UNHEX(?);"; + break; + default: + Log.error("VoteDAO", "Unhandled vote site when updated timestamp, this could duplicate votes! Fix immediately."); + return false; + } + + if (query != null){ + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setString(1, uuid.toString().replaceAll("-", "")); + + ps.executeUpdate(); + return true; + } + catch (SQLException exc) { + exc.printStackTrace(); + } + } + + return false; + + } + + /** + * Logs a user vote into the database for storage purposes. + * + * @param conn - the database connection thread + * @param voter - the uuid of the voter + * @param amount - the amount their vote is worth, as some can have higher + * values + * @param serviceID - the id of the service that they voted on + * + * @return {@code true} if the user vote was logged, {@code false} + * otherwise. + */ + public static boolean logUserVote(Connection conn, UUID voter, int amount, int serviceID) { + + String query = "INSERT INTO log_user_vote (uuid, amount, service_id) VALUES (UNHEX(?), ?, ?);"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setString(1, voter.toString().replace("-", "")); + ps.setInt(2, amount); + ps.setInt(3, serviceID); + + ps.executeUpdate(); + } + catch (SQLException e) { + Core.log("[VoteDAO] Error logging vote for voter uuid=" + voter.toString() + ", amount=" + amount + ", serviceID=" + serviceID); + e.printStackTrace(); + return false; + } + + return true; + } + + /** + * Get the top voters for this month. + *

+ * If the specified amount is 10, that is the top 10 voters. + * + * Note: This mines the log_user_vote table and the result should be cached as it's a complicated query. + *

+ * + * @param conn - the database connection thread + * @param amount - the number of top voters to get + * + * @return The vote records for the top amount voters. + */ + public static Optional getTopVoters(Connection conn, int amount) { + VoteUser[] voteUsers = new VoteUser[amount]; + + String query = "SELECT U.name AS voter_name, HEX(LUV.uuid), COUNT(*) AS total_votes FROM log_user_vote LUV, user U WHERE U.uuid=LUV.uuid AND YEAR(LUV.creation) = YEAR(CURRENT_DATE()) AND MONTH(LUV.creation) = MONTH(CURRENT_DATE()) GROUP by LUV.uuid ORDER BY COUNT(*) DESC LIMIT ?;"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setInt(1, amount); + + try (ResultSet result = ps.executeQuery()) { + int i = 0; + while(result.next()) { + voteUsers[i] = new VoteUser(i + 1, result.getInt("total_votes"), result.getString("voter_name")); + i += 1; + } + + return Optional.of(voteUsers); + } + } + catch (SQLException e) { + Core.error("[UserDAO:getTopVoters()] SQLException occurred"); + e.printStackTrace(); + return Optional.empty(); + } + } + + /** + * Get the top voters for LAST month. + *

+ * If the specified amount is 10, that is the top 10 voters. + * + * Note: This mines the log_user_vote table and the result should be cached as it's a complicated query. + *

+ * + * @param conn - the database connection thread + * @param amount - the number of top voters to get + * + * @return The vote records for the top amount voters for LAST month. + */ + public static Optional getLastTopVoters(Connection conn, int amount) { + VoteUser[] voteUsers = new VoteUser[amount]; + + String query = "SELECT U.name AS voter_name, HEX(LUV.uuid), COUNT(*) AS total_votes FROM log_user_vote LUV, user U WHERE U.uuid=LUV.uuid AND YEAR(LUV.creation) = YEAR(CURRENT_DATE() - INTERVAL 1 MONTH) AND MONTH(LUV.creation) = MONTH(CURRENT_DATE() - INTERVAL 1 MONTH) GROUP by LUV.uuid ORDER BY COUNT(*) DESC LIMIT ?;"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setInt(1, amount); + + try (ResultSet result = ps.executeQuery()) { + int i = 0; + while(result.next()) { + voteUsers[i] = new VoteUser(i + 1, result.getInt("total_votes"), result.getString("voter_name")); + i += 1; + } + + return Optional.of(voteUsers); + } + } + catch (SQLException e) { + Core.error("[UserDAO:getLastTopVoters()] SQLException occurred"); + e.printStackTrace(); + return Optional.empty(); + } + } + + public static class VoteUser { + private int possition, votes; + private String name; + + private UUID uuid; + private int streak; + private UserRank rank; + + public VoteUser(int possition, int votes, String name) { + this.possition = possition; + this.votes = votes; + this.name = name; + } + + public VoteUser(int possition, String name) { + this.possition = possition; + this.name = name; + } + + public VoteUser(UUID uuid, String name, int streak, UserRank rank) { + this.uuid = uuid; + this.name = name; + this.streak = streak; + this.rank = rank; + } + + public int getPossition() { + return possition; + } + + public int getVotes() { + return votes; + } + + public String getName() { + return name; + } + + public UUID getUuid() { + return uuid; + } + + public int getStreak() { + return streak; + } + + public UserRank getRank() { + return rank; + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/mutex/Lockable.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/mutex/Lockable.java new file mode 100644 index 0000000..50fce43 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/mutex/Lockable.java @@ -0,0 +1,36 @@ +package net.grandtheftmc.core.database.mutex; + +public interface Lockable { + + /** + * Get the lock state of this object. + * + * @return {@code true} if this object is locked, {@code false} otherwise. + */ + boolean isLocked(); + + /** + * Sets the lock state of this object. + * + * @param locked - {@code true} if the object is locked, {@code false} + * otherwise. + */ + void setLocked(boolean locked); + + /** + * Attempt to lock this object. + * + * @return {@code true} if the object was successfully locked. {@code false} + * if the object was already locked. + */ + boolean lock(); + + /** + * Attempt to unlock this object. + * + * @return {@code true} if the object was successfully unlocked. + * {@code false} if the object was already unlocked. + */ + boolean unlock(); + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/mutex/Mutexable.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/mutex/Mutexable.java new file mode 100644 index 0000000..849ee80 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/mutex/Mutexable.java @@ -0,0 +1,72 @@ +package net.grandtheftmc.core.database.mutex; + +public abstract class Mutexable implements Lockable { + + /** The lock of this Mutex */ + private boolean lock; + + /** + * Construct a new Mutexable which holds a lock. + */ + public Mutexable() { + this.lock = false; + } + + /** + * Get the lock state of this object. + * + * @return {@code true} if this object is locked, {@code false} otherwise. + */ + @Override + public synchronized boolean isLocked() { + return lock; + } + + /** + * Sets the lock state of this object. + * + * @param locked - {@code true} if the object is locked, {@code false} + * otherwise. + */ + @Override + public synchronized void setLocked(boolean locked) { + this.lock = locked; + } + + /** + * Attempt to lock this object. + * + * @return {@code true} if the object was successfully locked. {@code false} + * if the object was already locked. + */ + @Override + public synchronized boolean lock() { + + boolean result = false; + + if (!lock) { + lock = true; + result = true; + } + + return result; + } + + /** + * Attempt to unlock this object. + * + * @return {@code true} if the object was successfully unlocked. + * {@code false} if the object was already unlocked. + */ + @Override + public synchronized boolean unlock() { + boolean result = false; + + if (lock) { + lock = false; + result = true; + } + + return result; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/mutex/common/LoadUserTask.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/mutex/common/LoadUserTask.java new file mode 100644 index 0000000..d0f6324 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/mutex/common/LoadUserTask.java @@ -0,0 +1,63 @@ +package net.grandtheftmc.core.database.mutex.common; + +import java.sql.Connection; + +import org.bukkit.plugin.Plugin; + +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.database.dao.MutexDAO; +import net.grandtheftmc.core.database.mutex.task.LoadMutexTask; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.debug.Log; + +public abstract class LoadUserTask extends LoadMutexTask { + + /** The user reference */ + private User user; + + /** + * Constructs a new LoadUserTask, which attempts to load a user, + * asynchronously. + * + * @param plugin - the owning plugin + * @param user - the user being loaded + */ + public LoadUserTask(Plugin plugin, User user) { + super(plugin, user); + this.user = user; + + // run async + execute(true); + } + + /** + * {@inheritDoc} + */ + @Override + protected boolean fetchMutex() { + try (Connection conn = BaseDatabase.getInstance().getConnection()) { + return MutexDAO.getUserMutex(conn, user.getUUID()); + } + catch (Exception e) { + e.printStackTrace(); + } + + // else not free + return true; + } + + /** + * {@inheritDoc} + */ + @Override + public void syncMutex() { + // TODO remove + Log.info("TEST-LoadUserTask", "Setting " + user.getUUID() + "'s mutex to " + user.isLocked()); + try (Connection conn = BaseDatabase.getInstance().getConnection()) { + MutexDAO.setUserMutex(conn, user.getUUID(), user.isLocked()); + } + catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/mutex/common/SaveUserTask.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/mutex/common/SaveUserTask.java new file mode 100644 index 0000000..27ae417 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/mutex/common/SaveUserTask.java @@ -0,0 +1,47 @@ +package net.grandtheftmc.core.database.mutex.common; + +import java.sql.Connection; + +import org.bukkit.plugin.Plugin; + +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.database.dao.MutexDAO; +import net.grandtheftmc.core.database.mutex.task.SaveMutexTask; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.debug.Log; + +public abstract class SaveUserTask extends SaveMutexTask { + + /** The user reference */ + private User user; + + /** + * Constructs a new SaveUserTask, which attempts to save the user, + * asynchronously. + * + * @param plugin - the owning plugin + * @param user - the user being saved + */ + public SaveUserTask(Plugin plugin, User user) { + super(plugin, user); + this.user = user; + + // run async + execute(true); + } + + /** + * {@inheritDoc} + */ + @Override + public void syncMutex() { + // TODO remove + Log.info("TEST-SaveUserTask", "Setting " + user.getUUID() + "'s mutex to " + user.isLocked()); + try (Connection conn = BaseDatabase.getInstance().getConnection()) { + MutexDAO.setUserMutex(conn, user.getUUID(), user.isLocked()); + } + catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/mutex/event/AsyncMutexLoadEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/mutex/event/AsyncMutexLoadEvent.java new file mode 100644 index 0000000..9a4f5e7 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/mutex/event/AsyncMutexLoadEvent.java @@ -0,0 +1,55 @@ +package net.grandtheftmc.core.database.mutex.event; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import net.grandtheftmc.core.database.mutex.Mutexable; + +public class AsyncMutexLoadEvent extends Event { + + /** List of handlers for this event. */ + private static final HandlerList HANDLERS = new HandlerList(); + /** The mutexable object that was loaded */ + private final Mutexable mutexable; + + /** + * Construct a new AsyncMutexLoadEvent. + *

+ * This is used as a notification to the server that a mutexable was loaded. + *

+ * This event occurs before LoadMutexTask#onLoadComplete() is called. + * + * @param mutexable - the mutexable that was loaded + */ + public AsyncMutexLoadEvent(Mutexable mutexable) { + super(true); + this.mutexable = mutexable; + } + + /** + * Get the mutexable that was loaded in this event. + * + * @return The mutexable involved in the event. + */ + public Mutexable getMutexable() { + return mutexable; + } + + /** + * {@inheritDoc} + */ + @Override + public HandlerList getHandlers() { + return HANDLERS; + } + + /** + * Get the handlers involved in the event. + * + * @return The handlers for this event. + */ + public static HandlerList getHandlerList() { + return HANDLERS; + } +} + diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/mutex/event/AsyncMutexSaveEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/mutex/event/AsyncMutexSaveEvent.java new file mode 100644 index 0000000..1570260 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/mutex/event/AsyncMutexSaveEvent.java @@ -0,0 +1,54 @@ +package net.grandtheftmc.core.database.mutex.event; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import net.grandtheftmc.core.database.mutex.Mutexable; + +public class AsyncMutexSaveEvent extends Event { + + /** List of handlers for this event. */ + private static final HandlerList HANDLERS = new HandlerList(); + /** The mutexable object that was saved */ + private final Mutexable mutexable; + + /** + * Construct a new AsyncMutexSaveEvent. + *

+ * This is used as a notification to the server that a mutexable was saved. + *

+ * This event occurs before SaveMutexTask#onLoadComplete() is called. + * + * @param mutexable - the mutexable that was saved + */ + public AsyncMutexSaveEvent(Mutexable mutexable) { + super(true); + this.mutexable = mutexable; + } + + /** + * Get the mutexable that was saved in this event. + * + * @return The mutexable involved in the event. + */ + public Mutexable getMutexable() { + return mutexable; + } + + /** + * {@inheritDoc} + */ + @Override + public HandlerList getHandlers() { + return HANDLERS; + } + + /** + * Get the handlers involved in the event. + * + * @return The handlers for this event. + */ + public static HandlerList getHandlerList() { + return HANDLERS; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/mutex/event/MutexLoadCompleteEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/mutex/event/MutexLoadCompleteEvent.java new file mode 100644 index 0000000..53a4d3c --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/mutex/event/MutexLoadCompleteEvent.java @@ -0,0 +1,52 @@ +package net.grandtheftmc.core.database.mutex.event; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import net.grandtheftmc.core.database.mutex.Mutexable; + +public class MutexLoadCompleteEvent extends Event { + + /** List of handlers for this event. */ + private static final HandlerList HANDLERS = new HandlerList(); + /** The mutexable object that was completely loaded */ + private final Mutexable mutexable; + + /** + * Construct a new MutexLoadCompleteEvent. + *

+ * This is used as an optional event fire, AFTER + * LoadMutexTask#onLoadComplete() is called. + * + * @param mutexable - the mutexable that was completely loaded + */ + public MutexLoadCompleteEvent(Mutexable mutexable) { + this.mutexable = mutexable; + } + + /** + * Get the mutexable that was completely loaded in this event. + * + * @return The mutexable involved in the event. + */ + public Mutexable getMutexable() { + return mutexable; + } + + /** + * {@inheritDoc} + */ + @Override + public HandlerList getHandlers() { + return HANDLERS; + } + + /** + * Get the handlers involved in the event. + * + * @return The handlers for this event. + */ + public static HandlerList getHandlerList() { + return HANDLERS; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/mutex/event/MutexSaveCompleteEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/mutex/event/MutexSaveCompleteEvent.java new file mode 100644 index 0000000..b334027 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/mutex/event/MutexSaveCompleteEvent.java @@ -0,0 +1,52 @@ +package net.grandtheftmc.core.database.mutex.event; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import net.grandtheftmc.core.database.mutex.Mutexable; + +public class MutexSaveCompleteEvent extends Event { + + /** List of handlers for this event. */ + private static final HandlerList HANDLERS = new HandlerList(); + /** The mutexable object that was completely saved */ + private final Mutexable mutexable; + + /** + * Construct a new MutexSaveCompleteEvent. + *

+ * This is used as an optional event fire, AFTER + * SaveMutexTask#onSaveComplete() is called. + * + * @param mutexable - the mutexable that was completely saved + */ + public MutexSaveCompleteEvent(Mutexable mutexable) { + this.mutexable = mutexable; + } + + /** + * Get the mutexable that was completely saved in this event. + * + * @return The mutexable involved in the event. + */ + public Mutexable getMutexable() { + return mutexable; + } + + /** + * {@inheritDoc} + */ + @Override + public HandlerList getHandlers() { + return HANDLERS; + } + + /** + * Get the handlers involved in the event. + * + * @return The handlers for this event. + */ + public static HandlerList getHandlerList() { + return HANDLERS; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/mutex/task/LoadMutexTask.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/mutex/task/LoadMutexTask.java new file mode 100644 index 0000000..823539e --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/mutex/task/LoadMutexTask.java @@ -0,0 +1,170 @@ +package net.grandtheftmc.core.database.mutex.task; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; + +import net.grandtheftmc.core.database.mutex.Mutexable; +import net.grandtheftmc.core.database.mutex.event.AsyncMutexLoadEvent; +import net.grandtheftmc.core.database.mutex.event.MutexLoadCompleteEvent; +import net.grandtheftmc.core.task.ExpirableTask; +import net.grandtheftmc.core.util.debug.Log; + +public abstract class LoadMutexTask extends ExpirableTask { + + /** The Mutexable object being manipulated */ + private Mutexable mutexable; + /** Whether or not we've requested to load */ + private boolean request; + + /** + * Construct a new LoadMutexTask, which loads a mutexable after grabbing the + * lock. + *

+ * This is a wrapper around + * {@link #LoadPlayerTask(Plugin, Mutexable, double, double, double)}, with + * a delay of 0.2 secs, an interval of 0.25 secs, and a length of 1.5 secs. + *

+ * Because there is a delay, after the delay is over, the task will execute + * as a 'starter' onInterval. + * + * @param plugin - the owning plugin + * @param mutexable - the mutexable to load + */ + public LoadMutexTask(Plugin plugin, Mutexable mutexable) { + this(plugin, mutexable, 0.2, 0.25, 1.5); + } + + /** + * Construct a new LoadMutexTask, which loads a mutexable after grabbing the + * lock. + * + * @param plugin - the owning plugin + * @param mutexable - the mutexable to load + * @param delay - the delay, in seconds, before trying to execute the task + * @param interval - the interval, in seconds, of repeating tries + * @param length - the length, in seconds, of the task + */ + public LoadMutexTask(Plugin plugin, Mutexable mutexable, double delay, double interval, double length) { + super(plugin, delay, interval, length); + Validate.notNull(mutexable); + this.mutexable = mutexable; + } + + /** + * Call-back for when the mutex of this task is available. + *

+ * Note: If the loading was successful, this method will automatically + * update the mutex state in the database. + * + * @return {@code true} if the load was successful, {@code false} otherwise. + */ + protected abstract boolean onLoad(); + + /** + * Optional call-back for when loading is complete. + */ + protected void onLoadComplete() { + }; + + /** + * Call-back for when the loading fails. + */ + protected abstract void onLoadFailure(); + + /** + * Fetches the mutex from the database. + * + * @return {@code true} if this mutex is taken by something else, + * {@code false} if the mutex is free. + */ + protected abstract boolean fetchMutex(); + + /** + * Syncs the Mutex with the database. + */ + public abstract void syncMutex(); + + @Override + protected void onInterval(double timeLeft) { + + try { + handleMutex(); + } + catch (Exception e) { + Log.info("Core", "Exception in onInterval() of LoadMutexTask()."); + e.printStackTrace(); + } + } + + @Override + protected void onDelayComplete() { + + // when delay is over, handle mutex + onInterval(getTimeLeft()); + } + + /** + * Call to {@link #onLoadFailure()}. + */ + @Override + protected void onExpire() { + onLoadFailure(); + } + + /** + * Handles the mutex interaction. + */ + private void handleMutex() { + + // TODO remove + long start = System.currentTimeMillis(); + + // fetch mutex from database + boolean mutex = fetchMutex(); + + // if not locked + if (!mutex) { + + // if we haven't sent a load request + if (!request) { + request = true; + + // cancel this task + cancel(); + + // TODO remove + Log.info("TEST-LoadMutexTask", "Mutex is available (" + start + ") for " + mutexable.toString() + " (" + (System.currentTimeMillis() - start) + " msecs)"); + + boolean result = onLoad(); + // TODO remove + Log.info("TEST-LoadMutexTask", "Did onLoad complete for " + mutexable.toString() + "? " + result + " (" + (System.currentTimeMillis() - start) + " msecs)"); + if (result) { + + // lock and sync to db + mutexable.lock(); + syncMutex(); + + // call bukkit event to say it was loaded + Bukkit.getPluginManager().callEvent(new AsyncMutexLoadEvent(mutexable)); + + // optional call-back + onLoadComplete(); + + // schedule a sync load complete event + Bukkit.getScheduler().runTask(getPlugin(), () -> { + Bukkit.getPluginManager().callEvent(new MutexLoadCompleteEvent(mutexable)); + }); + } + else { + onLoadFailure(); + } + } + } + else { + // TODO remove + Log.info("TEST-LoadMutexTask", "Mutex is locked (" + start + "), will retry for " + mutexable.toString() + " (" + (System.currentTimeMillis() - start) + " msecs)"); + } + } +} + diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/mutex/task/SaveMutexTask.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/mutex/task/SaveMutexTask.java new file mode 100644 index 0000000..3d24b33 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/database/mutex/task/SaveMutexTask.java @@ -0,0 +1,155 @@ +package net.grandtheftmc.core.database.mutex.task; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; + +import net.grandtheftmc.core.database.mutex.Mutexable; +import net.grandtheftmc.core.database.mutex.event.AsyncMutexSaveEvent; +import net.grandtheftmc.core.database.mutex.event.MutexSaveCompleteEvent; +import net.grandtheftmc.core.task.ExpirableTask; +import net.grandtheftmc.core.util.debug.Log; + +public abstract class SaveMutexTask extends ExpirableTask { + + /** The Mutexable object being manipulated */ + private Mutexable mutexable; + /** Whether or not we've requested to save */ + private boolean request; + + /** + * Construct a new SaveMutexTask, which saves a mutexable. + *

+ * This is a wrapper around + * {@link #SavePlayerTask(Plugin, Mutexable, double, double, double)}, with + * a delay of 0.05 secs, an interval of 0.25 secs, and a length of 1 sec. + *

+ * Because there is a delay, after the delay is over, the task will execute + * as a 'starter' onInterval. + * + * + * @param plugin - the owning plugin + * @param mutexable - the mutexable to save + */ + public SaveMutexTask(Plugin plugin, Mutexable mutexable) { + this(plugin, mutexable, 0.05, 0.25, 1); + } + + /** + * Construct a new SaveMutexTask, which saves a mutexable. + * + * @param plugin - the owning plugin + * @param mutexable - the mutexable to load + * @param delay - the delay, in seconds, before trying to execute the task + * @param interval - the interval, in seconds, of repeating tries + * @param length - the length, in seconds, of the task + */ + public SaveMutexTask(Plugin plugin, Mutexable mutexable, double delay, double interval, double length) { + super(plugin, delay, interval, length); + Validate.notNull(mutexable); + this.mutexable = mutexable; + } + + /** + * Call-back for when the mutex of this task is available. + *

+ * Note: If the savings was successful, this method will automatically + * update the mutex state in the database. + * + * @return {@code true} if the save was successful, {@code false} otherwise. + */ + protected abstract boolean onSave(); + + /** + * Optional Call-back for when saving is complete. + */ + protected void onSaveComplete() { + }; + + /** + * Call-back for when the saving fails. + */ + protected abstract void onSaveFailure(); + + /** + * Syncs the Mutex with the database. + */ + public abstract void syncMutex(); + + @Override + protected void onInterval(double timeLeft) { + + try { + handleMutex(); + } + catch (Exception e) { + Log.info("Core", "Exception in onInterval() of SaveMutexTask()."); + e.printStackTrace(); + } + } + + @Override + protected void onDelayComplete() { + + // when delay is over, handle mutex + onInterval(getTimeLeft()); + } + + @Override + protected void onExpire() { + onSaveFailure(); + } + + /** + * Handles the mutex interaction. + */ + private void handleMutex() { + + // TODO remove + long start = System.currentTimeMillis(); + + // if mutex is locked + if (mutexable.isLocked()) { + + // if not sent a save request + if (!request) { + request = true; + + // cancel this task + cancel(); + + // TODO remove + Log.info("TEST-SaveMutexTask", "Mutex is unique(" + start + ") for " + mutexable.toString()); + + boolean result = onSave(); + // TODO remove + Log.info("TEST-SaveMutexTask", "Did onSave complete for " + mutexable.toString() + "? " + result + " (" + (System.currentTimeMillis() - start) + " msecs)"); + if (result) { + + // unlock the mutex and sync it to db + mutexable.unlock(); + syncMutex(); + + // call bukkit event to say it was saved + Bukkit.getPluginManager().callEvent(new AsyncMutexSaveEvent(mutexable)); + + // optional call-back + onSaveComplete(); + + // schedule a sync save complete event + Bukkit.getScheduler().runTask(getPlugin(), () -> { + Bukkit.getPluginManager().callEvent(new MutexSaveCompleteEvent(mutexable)); + }); + } + else { + onSaveFailure(); + } + } + } + else { + // TODO remove + Log.info("TEST-SaveMutexTask", "Mutex not locked(" + start + "), will retry for " + mutexable.toString() + " (" + (System.currentTimeMillis() - start) + " msecs)"); + } + } +} + diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/BlockChange.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/BlockChange.java new file mode 100644 index 0000000..d262733 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/BlockChange.java @@ -0,0 +1,91 @@ +package net.grandtheftmc.core.editmode; + +import org.bukkit.Material; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.BlockBurnEvent; +import org.bukkit.event.block.BlockFadeEvent; +import org.bukkit.event.block.BlockFormEvent; +import org.bukkit.event.block.BlockFromToEvent; +import org.bukkit.event.block.BlockIgniteEvent; +import org.bukkit.event.block.BlockIgniteEvent.IgniteCause; +import org.bukkit.event.block.BlockPhysicsEvent; +import org.bukkit.event.block.BlockSpreadEvent; +import org.bukkit.event.block.LeavesDecayEvent; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.player.PlayerInteractEvent; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.users.User; + +public class BlockChange implements Listener { + + @EventHandler + public void blockChange(BlockFromToEvent e) { + if (Core.getWorldManager().usesEditMode(e.getBlock().getWorld().getName())) + e.setCancelled(true); + } + + @EventHandler + public void onBurn(BlockBurnEvent e) { + if (Core.getWorldManager().usesEditMode(e.getBlock().getWorld().getName())) + e.setCancelled(true); + + } + + @EventHandler + public void onExplode(EntityExplodeEvent e) { + if (Core.getWorldManager().usesEditMode(e.getLocation().getWorld().getName())) { + e.blockList().clear(); + } + } + + @EventHandler + public void onIgnite(BlockIgniteEvent e) { + if (Core.getWorldManager().usesEditMode(e.getBlock().getWorld().getName())) { + if (e.getCause() == IgniteCause.FLINT_AND_STEEL) { + User u = Core.getUserManager().getLoadedUser(e.getPlayer().getUniqueId()); + if (!u.hasEditMode()) + e.setCancelled(true); + } else + e.setCancelled(true); + } + } + + // @EventHandler This event disables redstone and stuff + public void onBlockPhysics(BlockPhysicsEvent e) { + if (Core.getWorldManager().usesEditMode(e.getBlock().getWorld().getName())) + e.setCancelled(true); + } + + @EventHandler + public void onLeavesDecay(LeavesDecayEvent e) { + if (Core.getWorldManager().usesEditMode(e.getBlock().getWorld().getName())) + e.setCancelled(true); + } + + @EventHandler + public void noUproot(PlayerInteractEvent event) { + if (Core.getWorldManager().usesEditMode(event.getPlayer().getWorld().getName()) && event.getAction() == Action.PHYSICAL && event.getClickedBlock().getType() == Material.SOIL) + event.setCancelled(true); + } + + @EventHandler + public void onBlockForm(BlockFormEvent e) { + if (Core.getWorldManager().usesEditMode(e.getBlock().getWorld().getName())) + e.setCancelled(true); + } + + @EventHandler + public void onBlockSpread(BlockSpreadEvent e) { + if (Core.getWorldManager().usesEditMode(e.getBlock().getWorld().getName())) + e.setCancelled(true); + } + + @EventHandler + public void onBlockFade(BlockFadeEvent e) { + if (Core.getWorldManager().usesEditMode(e.getBlock().getWorld().getName())) e.setCancelled(true); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/BreakBlock.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/BreakBlock.java new file mode 100644 index 0000000..c7dc975 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/BreakBlock.java @@ -0,0 +1,18 @@ +package net.grandtheftmc.core.editmode; + +import net.grandtheftmc.core.Core; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; + +public class BreakBlock implements Listener { + + + @EventHandler(priority = EventPriority.HIGHEST) + public void onBreak(BlockBreakEvent e) { + if (Core.getWorldManager().usesEditMode(e.getBlock().getWorld().getName()) && !Core.getUserManager().getLoadedUser(e.getPlayer().getUniqueId()).hasEditMode()) { + e.setCancelled(true); + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/Craft.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/Craft.java new file mode 100644 index 0000000..9e59d16 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/Craft.java @@ -0,0 +1,17 @@ +package net.grandtheftmc.core.editmode; + +import net.grandtheftmc.core.Core; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.CraftItemEvent; + +public class Craft implements Listener { + + @EventHandler + public void onCraft(CraftItemEvent e) { + if (Core.getSettings().canCraft()) return; + e.setResult(null); + e.setCancelled(true); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/Damage.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/Damage.java new file mode 100644 index 0000000..37726c0 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/Damage.java @@ -0,0 +1,54 @@ +package net.grandtheftmc.core.editmode; + +import net.grandtheftmc.core.Core; +import org.bukkit.Material; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.inventory.ItemStack; + +public class Damage implements Listener { + + @EventHandler + public void onDamage(EntityDamageEvent e) { + //Faster to check a boolean first than comparing entities. + if (Core.getWorldManager().usesEditMode(e.getEntity().getWorld().getName()) + && e.getEntity().getType() == EntityType.ARMOR_STAND + && (e.getCause() == EntityDamageEvent.DamageCause.BLOCK_EXPLOSION + || e.getCause() == EntityDamageEvent.DamageCause.ENTITY_EXPLOSION)) + e.setCancelled(true); + } + + @EventHandler + public void onDamage(EntityDamageByEntityEvent e) { + if (!Core.getWorldManager().usesEditMode(e.getEntity().getWorld().getName())) + return; + + Entity entity = e.getEntity(); + switch (entity.getType()) { + case ITEM_FRAME: + if (e.getDamager() instanceof Player + && Core.getUserManager().getLoadedUser(e.getDamager().getUniqueId()).hasEditMode()) + break; + e.setCancelled(true); + return; + case ARMOR_STAND: + if (e.getDamager() instanceof Player + && Core.getUserManager().getLoadedUser(e.getDamager().getUniqueId()).hasEditMode()) { + ItemStack item = ((Player) e.getDamager()).getInventory().getItemInMainHand(); + if (item != null && item.getType() == Material.DIAMOND_SWORD && entity.isInvulnerable()) + entity.remove(); + break; + } + + e.setCancelled(true); + return; + default: + } + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/HangingBreak.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/HangingBreak.java new file mode 100644 index 0000000..eb461f1 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/HangingBreak.java @@ -0,0 +1,37 @@ +package net.grandtheftmc.core.editmode; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.hanging.HangingBreakByEntityEvent; +import org.bukkit.event.hanging.HangingBreakEvent; + +import net.grandtheftmc.core.Core; + +public class HangingBreak implements Listener { + + @EventHandler + public void onEntityDeath(HangingBreakEvent e) { + if (Core.getWorldManager().usesEditMode(e.getEntity().getWorld().getName()) && e.getCause() == HangingBreakEvent.RemoveCause.EXPLOSION) + e.setCancelled(true); + } + + @EventHandler + public void onHangingBreak(HangingBreakByEntityEvent e) { + if (!Core.getWorldManager().usesEditMode(e.getEntity().getWorld().getName())) + return; + Entity hanging = e.getEntity(); + switch (hanging.getType()) { + case ITEM_FRAME: + case PAINTING: + Entity remover = e.getRemover(); + if (remover instanceof Player + && Core.getUserManager().getLoadedUser(remover.getUniqueId()).hasEditMode()) + return; + e.setCancelled(true); + return; + default: + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/Interact.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/Interact.java new file mode 100644 index 0000000..ef5a83c --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/Interact.java @@ -0,0 +1,104 @@ +package net.grandtheftmc.core.editmode; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.users.User; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractAtEntityEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; + +import java.util.UUID; + +public class Interact implements Listener { + + @EventHandler + public void onInteractEntity(PlayerInteractEntityEvent e) { + Player player = e.getPlayer(); + Entity en = e.getRightClicked(); + if (Core.getWorldManager().usesEditMode(en.getWorld().getName())) + checkTypes(e, player.getUniqueId(), en.getType()); + } + + @EventHandler + public void onInteractAtEntity(PlayerInteractAtEntityEvent e) { + Player player = e.getPlayer(); + Entity en = e.getRightClicked(); + if (Core.getWorldManager().usesEditMode(en.getWorld().getName())) + checkTypes(e, player.getUniqueId(), en.getType()); + } + + private void checkTypes(Cancellable e, UUID u, EntityType et) { + switch (et) { + case PAINTING: + case ITEM_FRAME: + case ARMOR_STAND: + if (!Core.getUserManager().getLoadedUser(u).hasEditMode()) + e.setCancelled(true); + return; + } + } + + @EventHandler + public void onInteract(PlayerInteractEvent e) { + Player player = e.getPlayer(); + if (!Core.getWorldManager().usesEditMode(player.getWorld().getName()) || e.getAction() != Action.RIGHT_CLICK_BLOCK) + return; + User u = Core.getUserManager().getLoadedUser(player.getUniqueId()); + ItemStack item = player.getInventory().getItemInMainHand(); + if (item != null) { + switch (item.getType()) { + case ITEM_FRAME: + case WATER_BUCKET: + case LAVA_BUCKET: + + if (!u.hasEditMode()) + e.setCancelled(true); + break; + case BUCKET: + switch (e.getClickedBlock().getType()) { + case WATER: + case STATIONARY_WATER: + case LAVA: + case STATIONARY_LAVA: + if (!u.hasEditMode()) + e.setCancelled(true); + default: + break; + } + default: + break; + } + } + + switch (e.getClickedBlock().getType()) { + case CHEST: + case TRAPPED_CHEST: + case DROPPER: + case HOPPER: + case FURNACE: + case BURNING_FURNACE: + case BREWING_STAND: + if (!Core.getSettings().canOpenChests() && !u.hasEditMode()) + e.setCancelled(true); + break; + + case FLOWER_POT: + if (!u.hasEditMode()) { + e.setCancelled(true); + e.getClickedBlock().getState().update(); + } + break; + + default: + break; + } + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/InventoryClick.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/InventoryClick.java new file mode 100644 index 0000000..079f463 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/InventoryClick.java @@ -0,0 +1,23 @@ +package net.grandtheftmc.core.editmode; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.users.User; + +public class InventoryClick implements Listener { + + //@EventHandler idk why this is here ~ Tim. + public void onClick(InventoryClickEvent e) { + Player player = (Player) e.getWhoClicked(); + User u = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (Core.getWorldManager().usesEditMode(player.getWorld().getName()) && !u.hasEditMode()) { + e.setCancelled(false); + } + + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/Liquid.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/Liquid.java new file mode 100644 index 0000000..7515c3b --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/Liquid.java @@ -0,0 +1,24 @@ +package net.grandtheftmc.core.editmode; + +import net.grandtheftmc.core.Core; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerBucketEmptyEvent; +import org.bukkit.event.player.PlayerBucketFillEvent; + +public class Liquid implements Listener { + + @EventHandler + public void onFillBucket(PlayerBucketFillEvent e) { + if (Core.getWorldManager().usesEditMode(e.getBlockClicked().getWorld().getName()) && !Core.getUserManager().getLoadedUser(e.getPlayer().getUniqueId()).hasEditMode()) { + e.setCancelled(true); + } + } + + @EventHandler + public void onEmptyBucket(PlayerBucketEmptyEvent e) { + if (Core.getWorldManager().usesEditMode(e.getBlockClicked().getWorld().getName()) && !Core.getUserManager().getLoadedUser(e.getPlayer().getUniqueId()).hasEditMode()) { + e.setCancelled(true); + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/PlaceBlock.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/PlaceBlock.java new file mode 100644 index 0000000..cbecd79 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/PlaceBlock.java @@ -0,0 +1,19 @@ +package net.grandtheftmc.core.editmode; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.users.User; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockPlaceEvent; + +public class PlaceBlock implements Listener { + + @EventHandler + public void onPlace(BlockPlaceEvent e) { + Player player = e.getPlayer(); + if (Core.getWorldManager().usesEditMode(player.getWorld().getName()) && !Core.getUserManager().getLoadedUser(player.getUniqueId()).hasEditMode()) { + e.setCancelled(true); + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/WorldConfig.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/WorldConfig.java new file mode 100644 index 0000000..309e486 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/WorldConfig.java @@ -0,0 +1,66 @@ +package net.grandtheftmc.core.editmode; + +public class WorldConfig { + + + private String world; + private boolean editMode; + private RestrictedType type; + private String restricted; + + public WorldConfig(String world, boolean editMode) { + this.world = world; + this.editMode = editMode; + this.type = RestrictedType.NONE; + } + + public WorldConfig(String world, boolean editMode, RestrictedType type, String restricted) { + this.world = world; + this.editMode = editMode; + this.type = type; + this.restricted = restricted; + } + + public String getWorld() { + return this.world; + } + + public void setWorld(String world) { + this.world = world; + } + + public boolean isEditMode() { + return this.editMode; + } + + public void setEditMode(boolean editMode) { + this.editMode = editMode; + } + + public RestrictedType getType() { + return this.type; + } + + public void setType(RestrictedType type) { + this.type = type; + } + + public String getRestricted() { + return this.restricted; + } + + public void setRestricted(String restricted) { + this.restricted = restricted; + } + + public boolean isRestricted() { + return this.type != RestrictedType.NONE; + } + + public enum RestrictedType { + USERRANK, + RESTRICTED, + GAMERANK, + NONE; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/WorldManager.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/WorldManager.java new file mode 100644 index 0000000..cfe09f8 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/editmode/WorldManager.java @@ -0,0 +1,105 @@ +package net.grandtheftmc.core.editmode; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.Component; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.WorldCreator; +import org.bukkit.WorldType; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +/** + * Created by Liam on 26/07/2017. + */ +public class WorldManager implements Component { + + private final HashMap worldConfigs = new HashMap<>(); + + public WorldManager() { + this.loadWorlds(); + } + + @Override + public WorldManager onDisable(Core plugin) { + this.worldConfigs.clear(); + return this; + } + + private void loadWorlds() { + YamlConfiguration c = Core.getSettings().getWorldsConfig(); + this.worldConfigs.clear(); + if (c.getKeys(false).isEmpty()) + for (World world : Bukkit.getWorlds()) + this.worldConfigs.put(world.getName(), new WorldConfig(world.getName(), true)); + if (c.get("worlds") != null) { + for (World world : Bukkit.getWorlds()) + this.worldConfigs.put(world.getName(), new WorldConfig(world.getName(), true)); + for (String s : c.getStringList("worlds")) { + this.worldConfigs.put(s, new WorldConfig(s, true)); + if (Bukkit.getWorld(s) == null) + new WorldCreator(s).createWorld(); + } + c.getStringList("worlds").stream().filter(s -> Bukkit.getWorld(s) == null).forEach(s -> new WorldCreator(s).createWorld()); + return; + } + for (String s : c.getKeys(false)) { + boolean editMode = c.getBoolean(s + ".editMode", true); + if (Bukkit.getWorld(s) == null) { + WorldCreator wc = new WorldCreator(s); + if (c.get(s + ".worldType") != null) + wc.type(WorldType.valueOf(c.getString(s + ".worldType"))); + if (c.get(s + ".seed") != null) + wc.seed(c.getLong(s + ".seed")); + if (c.get(s + ".environment") != null) + wc.environment(World.Environment.valueOf(c.getString(s + ".environment"))); + if (c.get(s + ".generator") != null) + wc.generator(c.getString(s + ".generator")); + if (c.get(s + ".generatorSettings") != null) + wc.generatorSettings(c.getString(s + ".generatorSettings")); + if (c.get(s + ".generateStructures") != null) + wc.generateStructures(c.getBoolean(s + ".generateStructures")); + wc.createWorld(); + } + WorldConfig.RestrictedType type = c.get(s + ".restrictedType") == null ? WorldConfig.RestrictedType.NONE : WorldConfig.RestrictedType.valueOf(c.getString(s + ".restrictedType")); + String restricted = c.getString(s + ".restricted"); + this.worldConfigs.put(s, new WorldConfig(s, editMode, type, restricted)); + + + } + } + + public List getEditModeWorlds() { + List list = new ArrayList<>(); + this.worldConfigs.values().stream().filter(WorldConfig::isEditMode).forEach(w -> list.add(w.getWorld())); + return list; + + } + + public void addEditModeWorlds(String... worlds) { + for (String str : worlds) { + if (this.worldConfigs.containsKey(str)) this.worldConfigs.get(str).setEditMode(true); + this.worldConfigs.put(str, new WorldConfig(str, true)); + } + } + +// public void setEditModeWorlds(List editModeWorlds) { +// this.editModeWorlds = editModeWorlds; +// } + + public boolean usesEditMode(String world) { + return this.worldConfigs.get(world).isEditMode(); + } + + public HashMap getWorldConfigs() { + return this.worldConfigs; + } + + public WorldConfig getWorldConfig(String s) { + return this.worldConfigs.getOrDefault(s, new WorldConfig(s, true, WorldConfig.RestrictedType.RESTRICTED, null)); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/enjin/EnjinCache.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/enjin/EnjinCache.java new file mode 100644 index 0000000..78ed0c8 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/enjin/EnjinCache.java @@ -0,0 +1,96 @@ +package net.grandtheftmc.core.enjin; + +import net.grandtheftmc.core.Core; +import org.json.JSONObject; + +import java.util.*; + +/** + * Created by Adam on 10/06/2017. + */ +public class EnjinCache { + + /* + Want to avoid calling get-users and get-tags all the time so store a cache. + */ + + //Map a users name to their enjin ID + private static Map userIDs = new HashMap<>(); + + //Map a tag name to its id + private static Map tagIDs = new HashMap<>(); + + /** + * Cache the entire list of users. + */ + protected static void cacheAll() { + //CLear any existing + tagIDs.clear(); + userIDs.clear(); + + //Cache users + JSONObject json = HTTPInterface.post("http://www.grandtheftmc.net/api/get-users", ""); + if(json==null) { + Core.error("Couldn't cache enjin users as website didnt respond"); + return; + } + Iterator it = json.keys(); + while (it.hasNext()) { + int id = Integer.parseInt(it.next()); + String name = json.getJSONObject(Integer.toString(id)).getString("username"); + userIDs.put(name.toLowerCase(), id); + } + + //Cache tags + json = HTTPInterface.post("http://www.grandtheftmc.net/api/get-tags", ""); + + JSONObject tags = json.getJSONObject("tags"); + it = tags.keys(); + while (it.hasNext()) { + int tagID = Integer.parseInt(it.next()); + String tagName = tags.getJSONObject(Integer.toString(tagID)).getString("name"); + tagIDs.put(tagName.toLowerCase(), tagID); + } + } + + /** + * Attempt to get the user ID of a user. + * + * @param username The users username + * @return + */ + protected static Optional getUserID(String username) { + Optional ret = Optional.empty(); + + if (userIDs.containsKey(username.toLowerCase())) { + ret = Optional.of(userIDs.get(username.toLowerCase())); + } + + return ret; + } + + /** + * Attempt to get the tag ID associated with a tag. + * + * @param tag + * @return + */ + protected static Optional getTagID(String tag) { + Optional ret = Optional.empty(); + + if (tagIDs.containsKey(tag.toLowerCase())) { + ret = Optional.of(tagIDs.get(tag.toLowerCase())); + } + + return ret; + } + + /** + * Return a set of valid tags. + * + * @return + */ + public static Set getTagNames() { + return tagIDs.keySet(); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/enjin/EnjinCore.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/enjin/EnjinCore.java new file mode 100644 index 0000000..7fc93d2 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/enjin/EnjinCore.java @@ -0,0 +1,73 @@ +package net.grandtheftmc.core.enjin; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.enjin.data.EnjinResponse; +import net.grandtheftmc.core.enjin.data.EnjinResult; +import org.bukkit.Bukkit; +import org.json.JSONObject; + +import java.util.Optional; + +/** + * Created by Adam on 10/06/2017. + */ +public class EnjinCore { + + public static void init(){ + EnjinCache.cacheAll(); + } + + /** + * Attempt to a tag a user on Enjin, EnjinResponse class allows for a callback as this function is asynchronous. + * @param username The username of the user. + * @param tag The tag we wish to associate with them. + * @param resp The response callback function. + */ + public static void tagUser(String username, String tag, final EnjinResponse resp) { + Bukkit.getScheduler().runTaskAsynchronously(Core.getInstance(), () -> { + //Attempt to associate username with a userID + + Optional userID = EnjinCache.getUserID(username); + Optional tagID = EnjinCache.getTagID(tag); + + if (!userID.isPresent() || !tagID.isPresent()) { + //try to update the cache + EnjinCache.cacheAll(); + //Try to obtain the user ID and tagID again + userID = EnjinCache.getUserID(username); + tagID = EnjinCache.getTagID(username); + + if (!userID.isPresent()) { + Core.getInstance().getLogger().warning("Failed to set tag (" + tag + ") for user" + + " (" + username + ") as the USER ID could not be found in the Enjin database."); + resp.callback(EnjinResult.FAIL_USERID, username, tag); + return; + } + + if (!tagID.isPresent()) { + Core.getInstance().getLogger().warning("Failed to set tag (" + tag + ") for user" + + " (" + username + ") as the TAG ID could not be found in the Enjin database."); + resp.callback(EnjinResult.FAIL_TAGID, username, tag); + return; + } + } + + //Build our JSON object + JSONObject obj = new JSONObject(); + obj.put("jsonrpc", "2.0"); + obj.put("method", "Tags.tagUser"); + + JSONObject sub = new JSONObject(); + sub.put("api_key", "4e2846cb945359f54777f27348c2ea9720a78ece7e05e225"); + sub.put("user_id", userID.get()); + sub.put("tag_id", tagID.get()); + + obj.put("params", sub); + JSONObject jsonOut = HTTPInterface.post("http://www.grandtheftmc.net/api/v1/api.php", obj.toString()); + + //if the object is null we know something went wrong, otherwise it should be an empty JSON + resp.callback(jsonOut == null ? EnjinResult.FAIL_OTHER : EnjinResult.SUCCESS, username, tag); + + }); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/enjin/HTTPInterface.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/enjin/HTTPInterface.java new file mode 100644 index 0000000..011d16a --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/enjin/HTTPInterface.java @@ -0,0 +1,64 @@ +package net.grandtheftmc.core.enjin; + +import org.json.JSONObject; +import sun.net.www.http.HttpClient; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Iterator; + +/** + * Created by Adam on 10/06/2017. + */ +public class HTTPInterface { + + /** + * Send a HTTP POST request to the specified url, with the body content. + * + * @param u URL to POST to. + * @param body Body of the POST request. + */ + public static JSONObject post(String u, String body) { + try { + URL url = new URL(u); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + + conn.setDoOutput(true); + conn.setRequestMethod("POST"); + conn.addRequestProperty("Content-Type", "application/json"); + conn.setRequestProperty("Content-Length", Integer.toString(body.length())); + conn.getOutputStream().write(body.getBytes("UTF8")); + conn.getOutputStream().flush(); + conn.getOutputStream().close(); + + int responseCode = conn.getResponseCode(); + + BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); + String inputLine; + StringBuffer response = new StringBuffer(); + + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + in.close(); + + //System.out.println("Response code = " + responseCode); + //System.out.println("Response = " + response.toString()); + + if(response.toString().length() > 0) { + JSONObject json = new JSONObject(response.toString()); + return json; + } else { + return new JSONObject(); + } + + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/enjin/data/EnjinResponse.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/enjin/data/EnjinResponse.java new file mode 100644 index 0000000..f4c4f1e --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/enjin/data/EnjinResponse.java @@ -0,0 +1,10 @@ +package net.grandtheftmc.core.enjin.data; + +/** + * Created by Adam on 10/06/2017. + */ +public abstract class EnjinResponse { + + public abstract void callback(EnjinResult response, String user, String tag); + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/enjin/data/EnjinResult.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/enjin/data/EnjinResult.java new file mode 100644 index 0000000..10e0dca --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/enjin/data/EnjinResult.java @@ -0,0 +1,12 @@ +package net.grandtheftmc.core.enjin.data; + +/** + * Created by Adam on 10/06/2017. + */ +public enum EnjinResult { + + SUCCESS, + FAIL_USERID, + FAIL_TAGID, + FAIL_OTHER; +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/event/BaseEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/event/BaseEvent.java new file mode 100644 index 0000000..6412481 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/event/BaseEvent.java @@ -0,0 +1,136 @@ +package net.grandtheftmc.core.event; + +import java.util.logging.Level; + +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; + +/** + * Implementation of the interface Event, with basic handles for an event. + * + * @author sbahr + */ +public abstract class BaseEvent implements Event { + + /** The owning plugin */ + private final Plugin plugin; + /** The identification for this event */ + private final String id; + /** The state of this event */ + private EventState state; + /** The time the event started in millis */ + private long startTimeMillis; + /** The time the event is supposed to end, in millis */ + private long endTimeMillis; + + /** + * Construct a new BaseEvent. + *

+ * This is the implementation of a generic event. + * + * @param plugin - the owning plugin + * @param id - the id to call this event + * @param startTime - the time, in millis since epoch, that this event starts + * @param endTime - the time, in millis since epoch, that this event ends + */ + public BaseEvent(Plugin plugin, String id, long startTime, long endTime) { + this.plugin = plugin; + this.id = id; + this.startTimeMillis = startTime; + this.endTimeMillis = endTime; + + // initialize + init(); + } + + /** + * {@inheritDoc} + */ + @Override + public void init() { + Bukkit.getLogger().log(Level.INFO, "Initializing event=" + getId()); + + setState(EventState.CONSTRUCTED); + + // call on init for implementation + onInit(); + } + + /** + * {@inheritDoc} + */ + @Override + public void start() { + Bukkit.getLogger().log(Level.INFO, "Starting event=" + getId()); + + setState(EventState.ENABLED); + + // call on start for implementation + onStart(); + } + + /** + * {@inheritDoc} + */ + @Override + public void end() { + Bukkit.getLogger().log(Level.INFO, "Ending event=" + getId()); + + setState(EventState.DISABLED); + + // call on end for implementation + onEnd(); + } + + /** + * {@inheritDoc} + */ + @Override + public EventState getState() { + return state; + } + + /** + * {@inheritDoc} + */ + @Override + public void setState(EventState eventState) { + this.state = eventState; + } + + /** + * Get the start time of this event. + * + * @return The start time of this event. + */ + public long getStartTime() { + return startTimeMillis; + } + + /** + * Get the end time of this event. + * + * @return The end time of this event. + */ + public long getEndTime() { + return endTimeMillis; + } + + /** + * Get the owning plugin. + * + * @return The owning plugin for this event. + */ + @Override + public final Plugin getPlugin() { + return plugin; + } + + /** + * {@inheritDoc} + */ + @Override + public String getId() { + return id; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/event/Event.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/event/Event.java new file mode 100644 index 0000000..55b8935 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/event/Event.java @@ -0,0 +1,57 @@ +package net.grandtheftmc.core.event; + +import net.grandtheftmc.core.util.Identifiable; +import net.grandtheftmc.core.util.PluginAssociated; + +/** + * Interface representation of an event, something like Halloween, or Easter. + * + * @author sbahr + */ +public interface Event extends Identifiable, PluginAssociated { + + /** + * Initialize the event. + */ + void init(); + + /** + * Optional call-back for when the event is initialized. + */ + void onInit(); + + /** + * Start the event. + */ + void start(); + + /** + * Optional call-back for when the event starts. + */ + void onStart(); + + /** + * End the event. + */ + void end(); + + /** + * Optional call-back for when the event ends. + */ + void onEnd(); + + /** + * Get the state of this event. + * + * @return The state of this event. + */ + EventState getState(); + + /** + * Set the state of this event. + * + * @param eventState - the new state + */ + void setState(EventState eventState); + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/event/EventCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/event/EventCommand.java new file mode 100644 index 0000000..b0aebb6 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/event/EventCommand.java @@ -0,0 +1,245 @@ +package net.grandtheftmc.core.event; + +import java.sql.Connection; +import java.sql.Timestamp; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; +import org.json.simple.JSONObject; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; + +public class EventCommand implements CommandExecutor { + + /** The owning plugin */ + private Plugin plugin; + + /** + * Construct a new EventCommand. + *

+ * This command is used to schedule events in the future. + *

+ * + * @param plugin - the owning plugin + */ + public EventCommand(Plugin plugin) { + this.plugin = plugin; + } + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + + if (s instanceof Player) { + Player player = (Player) s; + + // get the user + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (!user.isRank(UserRank.ADMIN)) { + player.sendMessage(Lang.NOPERM.toString()); + return true; + } + + if (args.length > 0) { + + switch (args[0].toLowerCase()) { + case "schedule": + handleScheduleCommand(player, args); + return true; + case "clear": + handleClearCommand(player, args); + return true; + case "help": + handleHelpCommand(player); + return true; + } + } + + handleHelpCommand(player); + return true; + } + + return true; + } + + /** + * Handles the executing of the help subcommand. + * + * @param player - the player executing the command + */ + protected void handleHelpCommand(Player player) { + + // event schedule server_key halloween 10-29-17 + // event schedule server_key halloween 10-22-17 10-29-17 + // event clear all + // event clear server_key halloween + + player.sendMessage(ChatColor.GRAY + "--- " + ChatColor.GOLD + "Event Scheduling" + ChatColor.GRAY + " ---"); + player.sendMessage(ChatColor.WHITE + "/event schedule [serverKey] [eventType] [end_date]" + ChatColor.GRAY + " Schedules event for given server, starting now and ending on endDate."); + player.sendMessage(ChatColor.GRAY + "Example usage: " + ChatColor.WHITE + "/event schedule " + Core.getSettings().getServer_GTM_shortName() + "1 HALLOWEEN 2017-10-31.10:00:00"); + player.sendMessage(""); + + player.sendMessage(ChatColor.WHITE + "/event schedule [serverKey] [eventType] [endDate] [startDate]" + ChatColor.GRAY + " Schedules event for given server, with the startDate / endDate."); + player.sendMessage(""); + + player.sendMessage(ChatColor.WHITE + "/event clear all" + ChatColor.GRAY + " Clear all events across all servers."); + player.sendMessage(""); + + player.sendMessage(ChatColor.WHITE + "/event clears [serverKey]" + ChatColor.GRAY + " Clear the event for the given serverKey."); + player.sendMessage(""); + } + + /** + * Handles the executing of the schedule subcommand. + * + * @param player - the player executing the command + * @param args - the args + */ + protected void handleScheduleCommand(Player player, String[] args) { + + // event schedule [serverKey] [eventType] [end_date] + if (args.length == 4) { + String serverKey = args[1]; + EventType eventType = EventType.fromID(args[2]).orElse(null); + Timestamp endDate = getTimestamp(args[3]); + + if (eventType == null){ + player.sendMessage(ChatColor.RED + "Invalid event type. Please try one of the following: "); + for (EventType et : EventType.values()){ + player.sendMessage(ChatColor.RED + "- " + ChatColor.WHITE + et.getId()); + } + return; + } + + if (endDate == null){ + player.sendMessage(ChatColor.RED + "Invalid end date as it must be in the form of " + ChatColor.WHITE + "2017-10-31.10:00:00"); + return; + } + + player.sendMessage(ChatColor.YELLOW + "Attempting to register event " + ChatColor.WHITE + eventType.getId() + ChatColor.YELLOW + " for " + ChatColor.WHITE + serverKey + ChatColor.YELLOW + " ending on " + ChatColor.WHITE + endDate.toString()); + + // TODO add extra data support here + JSONObject data = new JSONObject(); + + // async update + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { + try (Connection conn = BaseDatabase.getInstance().getConnection()) { + EventDAO.scheduleEvent(conn, serverKey, eventType, data, endDate); + } + catch (Exception e) { + e.printStackTrace(); + } + }); + } + // event schedule [serverKey] [eventType] [endDate] [startDate] + else if (args.length == 5) { + String serverKey = args[1]; + EventType eventType = EventType.fromID(args[2]).orElse(null); + Timestamp endDate = getTimestamp(args[3]); + Timestamp startDate = getTimestamp(args[4]); + + if (eventType == null){ + player.sendMessage(ChatColor.RED + "Invalid event type. Please try one of the following: "); + for (EventType et : EventType.values()){ + player.sendMessage(ChatColor.RED + "- " + ChatColor.WHITE + et.getId()); + } + return; + } + + if (endDate == null){ + player.sendMessage(ChatColor.RED + "Invalid end date as it must be in the form of " + ChatColor.WHITE + "2017-10-31.10:00:00"); + return; + } + + if (startDate == null){ + player.sendMessage(ChatColor.RED + "Invalid start date as it must be in the form of " + ChatColor.WHITE + "2017-10-31.10:00:00"); + return; + } + + player.sendMessage(ChatColor.YELLOW + "Attempting to register event " + ChatColor.WHITE + eventType.getId() + ChatColor.YELLOW + " for " + ChatColor.WHITE + serverKey + ChatColor.YELLOW + " ending on " + ChatColor.WHITE + endDate.toString() + ChatColor.YELLOW + " and starting on " + ChatColor.WHITE + startDate.toString()); + + // TODO add extra data support here + JSONObject data = new JSONObject(); + + // async update + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { + try (Connection conn = BaseDatabase.getInstance().getConnection()) { + EventDAO.scheduleEvent(conn, serverKey, eventType, data, startDate, endDate); + } + catch (Exception e) { + e.printStackTrace(); + } + }); + } + } + + /** + * Handles the executing of the clear subcommand. + * + * @param player - the player executing the command + * @param args - the args + */ + protected void handleClearCommand(Player player, String[] args) { + + // /event clear [serverKey] + if (args.length == 2) { + + String serverKey = args[1]; + + if (serverKey.equalsIgnoreCase("all")) { + player.sendMessage(ChatColor.YELLOW + "Attempting to clear ALL events..."); + + // async update + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { + try (Connection conn = BaseDatabase.getInstance().getConnection()) { + EventDAO.clearAllActiveEvents(conn); + } + catch (Exception e) { + e.printStackTrace(); + } + }); + } + else { + + player.sendMessage(ChatColor.YELLOW + "Attempting to clear the event for server=" + ChatColor.WHITE + serverKey); + + // async update + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { + try (Connection conn = BaseDatabase.getInstance().getConnection()) { + EventDAO.clearActiveEvent(conn, serverKey); + } + catch (Exception e) { + e.printStackTrace(); + } + }); + } + } + } + + /** + * Get the timestamp from the given text. + * + * @param text - the input text + * @return The timestamp from the given text, if one exists + */ + protected Timestamp getTimestamp(String text){ + + // our input is 2017-10-31.10:00:00 + String[] parts = text.split("\\."); + + if (parts.length == 2){ + // replaces . with space + return Timestamp.valueOf(parts[0] + " " + parts[1]); + } + + return null; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/event/EventDAO.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/event/EventDAO.java new file mode 100644 index 0000000..304c6a2 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/event/EventDAO.java @@ -0,0 +1,183 @@ +package net.grandtheftmc.core.event; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.util.Optional; + +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; + +import net.grandtheftmc.core.Core; + +/** + * Data access object for event specific data. + * + * @author sbahr + */ +public class EventDAO { + + /** + * Get the active event that the specified key as. + *

+ * For example, a serverKey would be "gtm1", and if there is an active event + * for this server, it will return the event type that is active. + * + * @param conn - the database connection thread + * @param serverKey - the key of the server to lookup the event for + * + * @return The event data that is currently active for the specified event. + */ + public static Optional getActiveEvent(Connection conn, String serverKey) { + + String query = "SELECT * FROM event WHERE server_key=?;"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setString(1, serverKey); + + try (ResultSet result = ps.executeQuery()) { + + if (result.next()){ + EventType eventType = EventType.fromID(result.getString("event_type")).orElse(null); + + // convert string to json object + JSONParser parser = new JSONParser(); + JSONObject json = (JSONObject) parser.parse(result.getString("data")); + + Timestamp startTime = result.getTimestamp("start_time"); + Timestamp endTime = result.getTimestamp("end_time"); + + return Optional.of(new EventData(serverKey, eventType, json, startTime, endTime)); + + } + } + } + catch (Exception exc) { + Core.log("[EventDAO] Error executing getActiveEvent() for serverKey=" + serverKey); + exc.printStackTrace(); + } + + return Optional.empty(); + } + + /** + * Schedules an event at the specified start/end time for the given server. + * + * @param conn - the database connection thread + * @param serverKey - the server key for the server to schedule the event on + * @param eventType - the type of the event to run + * @param data - the data associated with the event + * @param startTime - the start time of the event + * @param endTime - the end time of the event + * + * @return {@code true} if the query ran, {@code false} otherwise. + */ + public static boolean scheduleEvent(Connection conn, String serverKey, EventType eventType, JSONObject data, Timestamp startTime, Timestamp endTime) { + + String query = "INSERT INTO event (server_key, event_type, data, start_time, end_time) VALUES (?, ?, ?, ?, ?);"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setString(1, serverKey); + ps.setString(2, eventType.getId()); + ps.setString(3, data.toJSONString()); + ps.setTimestamp(4, startTime); + ps.setTimestamp(5, endTime); + + ps.executeUpdate(); + return true; + } + catch (SQLException exc) { + Core.log("[EventDAO] Error executing scheduleEvent() for serverKey=" + serverKey + " and eventType=" + eventType); + exc.printStackTrace(); + + return false; + } + } + + /** + * Schedules an event at the specified start/end time for the given server. + *

+ * Note: This uses a default start time according to the current timestamp. + *

+ * + * @param conn - the database connection thread + * @param serverKey - the server key for the server to schedule the event on + * @param eventType - the type of the event to run + * @param data - the data associated with the event + * @param endTime - the end time of the event + * + * @return {@code true} if the query ran, {@code false} otherwise. + */ + public static boolean scheduleEvent(Connection conn, String serverKey, EventType eventType, JSONObject data, Timestamp endTime) { + + String query = "INSERT INTO event (server_key, event_type, data, start_time, end_time) VALUES (?, ?, ?, CURRENT_TIMESTAMP, ?);"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setString(1, serverKey); + ps.setString(2, eventType.getId()); + ps.setString(3, data.toJSONString()); + ps.setTimestamp(4, endTime); + + ps.executeUpdate(); + return true; + } + catch (SQLException exc) { + Core.log("[EventDAO] Error executing scheduleEvent() for serverKey=" + serverKey + " and eventType=" + eventType); + exc.printStackTrace(); + + return false; + } + } + + /** + * Clears the active event for the specified server key. + * + * @param conn - the database connection thread + * @param serverKey - the key of the serverup to clear the event for + * + * @return {@code true} if the query ran, {@code false} otherwise. + */ + public static boolean clearActiveEvent(Connection conn, String serverKey) { + + String query = "DELETE FROM event WHERE server_key=?;"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setString(1, serverKey); + + ps.executeUpdate(); + return true; + } + catch (SQLException exc) { + Core.log("[EventDAO] Error executing clearActiveEvent() for serverKey=" + serverKey); + exc.printStackTrace(); + + return false; + } + } + + /** + * Clear all the active events, regardless of server id. + * + * @param conn - the database connection thread + * + * @return {@code true} if the query ran, {@code false} otherwise. + */ + public static boolean clearAllActiveEvents(Connection conn) { + + String query = "DELETE FROM event;"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.executeUpdate(); + return true; + } + catch (SQLException exc) { + Core.log("[EventDAO] Error executing clearAllActiveEvents()"); + exc.printStackTrace(); + + return false; + } + } +} + diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/event/EventData.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/event/EventData.java new file mode 100644 index 0000000..cbb173e --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/event/EventData.java @@ -0,0 +1,96 @@ +package net.grandtheftmc.core.event; + +import java.sql.Timestamp; + +import org.json.simple.JSONObject; + +/** + * Data object for events, like halloween, easter, etc. Typically read from the + * database. + * + * @author sbahr + */ +public class EventData { + + /** The key of the server for this event */ + private final String serverKey; + /** The event type for this data */ + private final EventType eventType; + /** The JSON data for this event */ + private final JSONObject data; + /** The start time for this event */ + private final Timestamp startTime; + /** The end time for this event */ + private final Timestamp endTime; + + /** + * Create the event data for this event. + * + * @param serverKey - the server key for this event, typically something + * like "gtm1" + * @param eventType - the type of the event to do + * @param jsonData - the attached json data associated with this event + * @param startTime - the start time for this event + * @param endTime - the end time for this event + */ + public EventData(String serverKey, EventType eventType, JSONObject jsonData, Timestamp startTime, Timestamp endTime) { + this.serverKey = serverKey; + this.eventType = eventType; + this.data = jsonData; + this.startTime = startTime; + this.endTime = endTime; + } + + /** + * Get the server key for this event. + *

+ * This is typically something like "gtm1". + *

+ * + * @return The server key for this event. + */ + public String getServerKey() { + return serverKey; + } + + /** + * Get the type of the event. + * + * @return The type of the event for this event data. + */ + public EventType getEventType() { + return eventType; + } + + /** + * Get the associated data for this event. + *

+ * This can be attached attributes, or values to help make this event + * dynamic. + *

+ * + * @return The associated data for this event. + */ + public JSONObject getData() { + return data; + } + + /** + * Get the start time for this event. + * + * @return The start time for this event. + */ + public Timestamp getStartTime() { + return startTime; + } + + /** + * Get the end time for this event. + * + * @return The end time for this event. + */ + public Timestamp getEndTime() { + return endTime; + } +} + diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/event/EventManager.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/event/EventManager.java new file mode 100644 index 0000000..3b2ab4d --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/event/EventManager.java @@ -0,0 +1,275 @@ +package net.grandtheftmc.core.event; + +import java.sql.Connection; +import java.util.Optional; + +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitTask; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.database.BaseDatabase; + +/** + * An event manager, which should be subclassed and init() should be overloaded to create the new init class for this manager. + * + * @author sbahr + */ +public class EventManager { + + /** How often we tick with the sync task (20 ticks) */ + protected static long TICK_INTERVAL = 20; + + /** The instance of this class */ + protected static EventManager instance; + /** Whether or not this manager was initialized */ + protected static boolean initialized; + + /** The owning plugin */ + protected Plugin plugin; + /** The server key for this manager */ + protected String serverKey; + /** The active event */ + protected Event event; + // deprecated due to not needing multiple events + // /** Maps the event id to the event */ + //private Map idToEvent; + + /** + * Construct a new EventManager. + *

+ * This handles and stores all events. + * + * @param plugin - the owning plugin + * @param serverKey - the server key for this manager + */ + protected EventManager(Plugin plugin, String serverKey) { + this.plugin = plugin; + this.serverKey = serverKey; + //this.idToEvent = new HashMap<>(); + + Core.log("[EventManager] Constructed EventManager... Listening on serverKey=" + serverKey); + } + + /** + * Initialize the manager. + * + * @param plugin - the owning plugin + * @param serverKey - the key of this server instance + */ + public static void init(Plugin plugin, String serverKey) { + + // create singleton instance + instance = new EventManager(plugin, serverKey); + initialized = true; + + // start sync task + instance.getSyncTask(); + } + + /** + * Get the instance of this manager. + * + * @return The singleton instance for this manager. + * + * @throws IllegalStateException if the manager was never initialized with + * {@link #init(Plugin)}. + */ + public static EventManager getInstance() throws IllegalStateException { + if (instance == null) { + if (!initialized) { + throw new IllegalStateException("The EventManager was never initialized by the owning plugin! This is a severe error and should be fixed. Please call EventManager.init() first!"); + } + } + + return instance; + } + +// /** +// * Adds the specified event to the manager. +// * +// * @param event - the event to add +// * +// * @return {@code true} if the event was added, {@code false} otherwise. +// * @deprecated - this is for multiple event handling +// */ +// @Deprecated +// public boolean addEvent(Event event) { +// if (!idToEvent.containsKey(event.getId())) { +// idToEvent.put(event.getId(), event); +// return true; +// } +// +// return false; +// } + +// /** +// * Get the event from the manager with the specified id. +// * +// * @param id - the id of the event to get +// * +// * @return The event, with the given id, if one exists. +// * @deprecated - this is for multiple event handling +// */ +// @Deprecated +// public Optional getEvent(String id) { +// if (idToEvent.containsKey(id)) { +// return Optional.of(idToEvent.get(id)); +// } +// +// return Optional.empty(); +// } + +// /** +// * Remove the event from the manager with the specified id. +// * +// * @param id - the id of the event to remove +// * +// * @return The event, with the given id, if one exists, and was successfully +// * removed. +// * @deprecated - this is for multiple event handling +// */ +// @Deprecated +// public Optional removeEvent(String id) { +// if (idToEvent.containsKey(id)) { +// return Optional.of(idToEvent.remove(id)); +// } +// +// return Optional.empty(); +// } + + /** + * Get the active event from this manager, if one exists. + * + * @return The active event, if one exists. + */ + public Optional getEvent() { + return Optional.ofNullable(event); + } + + /** + * Get the sync task for this event manager. + *

+ * This fetches the database to learn about new events. + *

+ * + * @return The sync task for this event manager. + */ + public BukkitTask getSyncTask() { + return Bukkit.getScheduler().runTaskTimer(getPlugin(), () -> { + + // if we have an active event + if (getEvent().isPresent()){ + Event current = getEvent().get(); + if (current != null && current instanceof BaseEvent){ + BaseEvent baseEvent = (BaseEvent) current; + + // if the event is over + if (System.currentTimeMillis() > baseEvent.getEndTime()){ + + // end the event and nullify + baseEvent.end(); + this.event = null; + + // async clear active event + Bukkit.getScheduler().runTaskAsynchronously(getPlugin(), () -> { + try (Connection conn = BaseDatabase.getInstance().getConnection()){ + EventDAO.clearActiveEvent(conn, serverKey); + } + catch(Exception e){ + e.printStackTrace(); + } + }); + } + } + } + + // async fetch + Bukkit.getScheduler().runTaskAsynchronously(getPlugin(), () -> { + + EventData eventData = null; + try (Connection conn = BaseDatabase.getInstance().getConnection()){ + eventData = EventDAO.getActiveEvent(conn, serverKey).orElse(null); + } + catch(Exception e){ + e.printStackTrace(); + } + + final EventData event = eventData; + Bukkit.getScheduler().runTask(getPlugin(), () -> { + + // if we have an event in the database + if (event != null){ + + // do we have a current event + Event current = getEvent().orElse(null); + if (current == null){ + + // construct and start the event + BaseEvent baseEvent = constructEvent(getPlugin(), event).orElse(null); + + if(baseEvent == null) + return; + this.event = baseEvent; + this.event.start(); + } + } + else{ + + // do we have a current event + Event current = getEvent().orElse(null); + + if (current != null){ + current.end(); + + // null the event + this.event = null; + } + } + + }); + }); + + }, 0, TICK_INTERVAL); + } + + /** + * {@inheritDoc} + */ + public Plugin getPlugin() { + return plugin; + } + + /** + * Construct a BaseEvent object based off the event data. + * + * @param plugin - the owning plugin + * @param data - the data bound for the event + * + * @return The BaseEvent object that was constructed, if one exists. + */ + public Optional constructEvent(Plugin plugin, EventData data){ + + BaseEvent event = null; + switch(data.getEventType()){ + // TODO add more CORE events here + default: + break; + } + + return Optional.ofNullable(event); + } + +// /** +// * Get all the events this manager knows about. +// * +// * @return An unmodifiable collection of all the events the manager knows +// * about. +// * @deprecated - this is for multiple event handling +// */ +// @Deprecated +// public Collection getEvents() { +// return Collections.unmodifiableCollection(idToEvent.values()); +// } +} + diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/event/EventState.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/event/EventState.java new file mode 100644 index 0000000..9ae74d3 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/event/EventState.java @@ -0,0 +1,21 @@ +package net.grandtheftmc.core.event; + +public enum EventState { + + /** + * When the event is constructed, usually by a constructor. + */ + CONSTRUCTED, + + /** + * When the event is enabled. + */ + ENABLED, + + /** + * When the event is disabled. + */ + DISABLED; + +} + diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/event/EventType.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/event/EventType.java new file mode 100644 index 0000000..da0ba4a --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/event/EventType.java @@ -0,0 +1,50 @@ +package net.grandtheftmc.core.event; + +import java.util.Optional; + +public enum EventType { + + HALLOWEEN("HALLOWEEN"), + CHRISTMAS("CHRISTMAS"), + EASTER("EASTER"), + ; + + /** The ID of the event type */ + private final String id; + + /** + * Create a new event type constant. + * + * @param id - the id of the event + */ + EventType(String id) { + this.id = id; + } + + /** + * Get the ID of the event. + * + * @return The id of the event. + */ + public final String getId() { + return id; + } + + /** + * Get the event type from the specified id. + * + * @param id - the id of the event + * + * @return The event type with the specified id, if one exists. + */ + public static Optional fromID(String id) { + for (EventType et : values()) { + if (et.getId().equalsIgnoreCase(id)) { + return Optional.of(et); + } + } + + return Optional.empty(); + } +} + diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/ChatEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/ChatEvent.java new file mode 100644 index 0000000..fe6d398 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/ChatEvent.java @@ -0,0 +1,64 @@ +package net.grandtheftmc.core.events; + +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import java.util.Set; + +public class ChatEvent extends Event implements Cancellable { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final Player sender; + private TextComponent textComponent; + private Set recipients; + + private boolean cancelled; + + public ChatEvent(Player sender, TextComponent textComponent, Set recipients) { + this.sender = sender; + this.textComponent = textComponent; + this.recipients = recipients; + } + + public Player getSender() { + return this.sender; + } + + public TextComponent getTextComponent() { + return this.textComponent; + } + + public void setTextComponent(TextComponent textComponent) { + this.textComponent = textComponent; + } + + public Set getRecipients() { + return this.recipients; + } + + public void setRecipients(Set recipients) { + this.recipients = recipients; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + @Override + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/CoreEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/CoreEvent.java new file mode 100644 index 0000000..b1908f3 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/CoreEvent.java @@ -0,0 +1,27 @@ +package net.grandtheftmc.core.events; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * Created by Luke Bingham on 06/07/2017. + */ +public class CoreEvent extends Event { + private static final HandlerList handlers = new HandlerList(); + + /** + * Construct a new Event + */ + public CoreEvent(boolean async) { + super(async); + } + + @Override + public final HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/DisplayNameUpdateEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/DisplayNameUpdateEvent.java new file mode 100644 index 0000000..be7b4e8 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/DisplayNameUpdateEvent.java @@ -0,0 +1,59 @@ +package net.grandtheftmc.core.events; + +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; + +public class DisplayNameUpdateEvent extends PlayerEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private String rankPrefix; + private String prefix; + private String nameColor; + private String suffix; + + public DisplayNameUpdateEvent(Player player) { + super(player); + } + + public String getPrefix() { + return this.prefix; + } + + public void setPrefix(String prefix) { + this.prefix = prefix; + } + + public String getSuffix() { + return this.suffix; + } + + public void setSuffix(String suffix) { + this.suffix = suffix; + } + + public String getRankPrefix() { + return this.rankPrefix; + } + + public void setRankPrefix(String rankPrefix) { + this.rankPrefix = rankPrefix; + } + + public String getNameColor() { + return this.nameColor; + } + + public void setNameColor(String nameColor) { + this.nameColor = nameColor; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/GetPermsEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/GetPermsEvent.java new file mode 100644 index 0000000..b7800d5 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/GetPermsEvent.java @@ -0,0 +1,40 @@ +package net.grandtheftmc.core.events; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +public class GetPermsEvent extends Event { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final UUID uuid; + private final List perms = new ArrayList<>(); + + public GetPermsEvent(UUID uuid) { + this.uuid = uuid; + } + + public UUID getUUID() { + return this.uuid; + } + + public void addPerm(String perm) { + if(perm != null && !this.perms.contains(perm)) this.perms.add(perm); + } + + public List getPerms() { + return this.perms; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/ItemStackEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/ItemStackEvent.java new file mode 100644 index 0000000..922e2ec --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/ItemStackEvent.java @@ -0,0 +1,45 @@ +package net.grandtheftmc.core.events; + +import org.bukkit.event.Cancellable; +import org.bukkit.inventory.ItemStack; + +/** + * Created by Luke Bingham on 06/08/2017. + */ +public class ItemStackEvent extends CoreEvent implements Cancellable { + + private boolean b; + private ItemStack itemStack; + private boolean clickOnly; + + /** + * Construct a new Event + */ + public ItemStackEvent(ItemStack itemStack) { + super(false); + this.itemStack = itemStack; + this.clickOnly = false; + } + + public ItemStack getItemStack() { + return itemStack; + } + + public boolean isClickOnly() { + return clickOnly; + } + + public void setClickOnly(boolean clickOnly) { + this.clickOnly = clickOnly; + } + + @Override + public boolean isCancelled() { + return b; + } + + @Override + public void setCancelled(boolean b) { + this.b = b; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/MoneyEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/MoneyEvent.java new file mode 100644 index 0000000..a07fc97 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/MoneyEvent.java @@ -0,0 +1,94 @@ +package net.grandtheftmc.core.events; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import java.util.UUID; + +public class MoneyEvent extends Event { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private UUID uuid; + private MoneyEventType type; + private double amount; + private double balance; + private boolean successful; + + public MoneyEvent(UUID uuid) { + this.uuid = uuid; + this.type = MoneyEventType.BALANCE; + } + + public MoneyEvent(UUID uuid, double amount) { + this.uuid = uuid; + if (amount < 0) { + this.amount = -amount; + this.type = MoneyEventType.TAKE; + } else { + this.amount = amount; + this.type = MoneyEventType.ADD; + } + } + + public MoneyEvent(UUID uuid, MoneyEventType type, double amount) { + this.uuid = uuid; + this.type = type; + this.amount = amount; + } + + public UUID getUUID() { + return this.uuid; + } + + public void setUUID(UUID uuid) { + this.uuid = uuid; + } + + public MoneyEventType getType() { + return this.type; + } + + public void setType(MoneyEventType type) { + this.type = type; + } + + public double getAmount() { + return this.amount; + } + + public void setAmount(double amount) { + this.amount = amount; + } + + public double getBalance() { + return this.balance; + } + + public void setBalance(double d) { + this.balance = d; + } + + // TODO please fix spelling (http://www.dictionary.com/browse/successful) + public boolean isSuccessfull() { + return this.successful; + } + + public void setSuccessfull() { + this.successful = true; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } + + public enum MoneyEventType { + TAKE, + ADD, + BALANCE + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/NametagUpdateEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/NametagUpdateEvent.java new file mode 100644 index 0000000..af915c5 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/NametagUpdateEvent.java @@ -0,0 +1,65 @@ +package net.grandtheftmc.core.events; + +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; + +public class NametagUpdateEvent extends PlayerEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private String prefix; + private String nameColor; + private String suffix; + // private int value; + // private String belowName; + + public NametagUpdateEvent(Player player) { + super(player); + } + + public String getPrefix() { + return this.prefix; + } + + public void setPrefix(String prefix) { + this.prefix = prefix; + } + + public String getSuffix() { + return this.suffix; + } + + public void setSuffix(String suffix) { + this.suffix = suffix; + } + + /* + * + * public int getValue() { return value; } + * + * public void setValue(int value) { this.value = value; } + * + * public String getBelowName() { return belowName; } + * + * public void setBelowName(String belowName) { this.belowName = belowName; + * + * } + */ + + public String getNameColor() { + return this.nameColor; + } + + public void setNameColor(String nameColor) { + this.nameColor = nameColor; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/PlayerFActionEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/PlayerFActionEvent.java new file mode 100644 index 0000000..0bd2c0c --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/PlayerFActionEvent.java @@ -0,0 +1,40 @@ +package net.grandtheftmc.core.events; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class PlayerFActionEvent extends Event implements Cancellable { + private static final HandlerList HANDLERS = new HandlerList(); + + private final Player player; + private boolean cancelled; + + public PlayerFActionEvent(Player player) { + this.player = player; + } + + public Player getPlayer() { + return this.player; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + @Override + public HandlerList getHandlers() { + return HANDLERS; + } + + public static HandlerList getHandlerList() { + return HANDLERS; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/PlayerSwitchWorldEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/PlayerSwitchWorldEvent.java new file mode 100644 index 0000000..180f9cf --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/PlayerSwitchWorldEvent.java @@ -0,0 +1,61 @@ +package net.grandtheftmc.core.events; + +import net.grandtheftmc.core.editmode.WorldConfig; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class PlayerSwitchWorldEvent extends Event implements Cancellable { + private static final HandlerList HANDLERS = new HandlerList(); + + private final Player player; + + private final Location from; + private final Location to; + private final WorldConfig toWorldConfig; + private boolean cancelled; + + public PlayerSwitchWorldEvent(Player player, Location from, Location to, WorldConfig toWorldConfig) { + this.player = player; + this.from = from; + this.to = to; + this.toWorldConfig = toWorldConfig; + } + + public Player getPlayer() { + return this.player; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + public Location getFrom() { + return this.from; + } + + public Location getTo() { + return this.to; + } + + public WorldConfig getToWorldConfig() { + return this.toWorldConfig; + } + + @Override + public HandlerList getHandlers() { + return HANDLERS; + } + + public static HandlerList getHandlerList() { + return HANDLERS; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/RequestEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/RequestEvent.java new file mode 100644 index 0000000..0eab9d0 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/RequestEvent.java @@ -0,0 +1,54 @@ +package net.grandtheftmc.core.events; + +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import java.util.Collection; +import java.util.HashMap; + +public class RequestEvent extends Event { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private Collection players; + private String type; + private HashMap result; + + public RequestEvent(Collection players, String type) { + this.players = players; + this.type = type; + } + + public String getType() { + return this.type; + } + + public void setType(String type) { + this.type = type; + } + + public HashMap getResult() { + return this.result; + } + + public void setResult(HashMap result) { + this.result = result; + } + + public Collection getPlayers() { + return this.players; + } + + public void setPlayers(Collection players) { + this.players = players; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/RewardEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/RewardEvent.java new file mode 100644 index 0000000..d72316d --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/RewardEvent.java @@ -0,0 +1,46 @@ +package net.grandtheftmc.core.events; + +import net.grandtheftmc.core.voting.Reward; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; + +/** + * Created by Liam on 16/11/2016. + */ +public class RewardEvent extends PlayerEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private Reward reward; + private boolean successful; + + public RewardEvent(Player player, Reward reward) { + super(player); + this.reward = reward; + } + + public Reward getReward() { + return this.reward; + } + + public void setReward(Reward reward) { + this.reward = reward; + } + + public boolean isSuccessful() { + return this.successful; + } + + public void setSuccessfull(boolean successful) { + this.successful = successful; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/ServerSaveEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/ServerSaveEvent.java new file mode 100644 index 0000000..cbe4795 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/ServerSaveEvent.java @@ -0,0 +1,21 @@ +package net.grandtheftmc.core.events; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class ServerSaveEvent extends Event { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + public ServerSaveEvent() { + + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/TutorialEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/TutorialEvent.java new file mode 100644 index 0000000..ad06202 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/TutorialEvent.java @@ -0,0 +1,84 @@ +package net.grandtheftmc.core.events; + +import net.grandtheftmc.core.tutorials.Tutorial; +import net.grandtheftmc.core.users.User; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; + +public class TutorialEvent extends PlayerEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private Player player; + private User user; + private Tutorial tutorial; + private TutorialEventType type; + private String cancelMessage; + + public TutorialEvent(Player player, User user, Tutorial tutorial, TutorialEventType type) { + super(player); + this.user = user; + this.tutorial = tutorial; + this.type = type; + } + + public User getUser() { + return this.user; + } + + public void setUser(User user) { + this.user = user; + } + + public Tutorial getTutorial() { + return this.tutorial; + } + + public void setTutorial(Tutorial tutorial) { + this.tutorial = tutorial; + } + + public TutorialEventType getType() { + return this.type; + } + + public void setType(TutorialEventType type) { + this.type = type; + } + + public boolean isCancelled() { + return this.cancelMessage != null; + } + + public void setCancelled(String cancelMessage) { + this.cancelMessage = cancelMessage; + } + + public String getCancelMessage() { + return this.cancelMessage; + } + + public TutorialEvent call() { + Bukkit.getPluginManager().callEvent(this); + return this; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } + + public enum TutorialEventType { + PRE_START, + START, + SLIDE, + END, + QUIT + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/UpdateEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/UpdateEvent.java new file mode 100644 index 0000000..24a75e0 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/events/UpdateEvent.java @@ -0,0 +1,52 @@ +package net.grandtheftmc.core.events; + +import net.grandtheftmc.core.users.Pref; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; + +public class UpdateEvent extends PlayerEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final UpdateReason reason; + private Pref pref; + + public UpdateEvent(Player player, UpdateReason reason) { + super(player); + this.reason = reason; + } + + public UpdateEvent(Player player, Pref pref) { + super(player); + this.reason = UpdateReason.PREF; + this.pref = pref; + } + + public UpdateReason getReason() { + return this.reason; + } + + public Pref getPref() { + return this.pref; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } + + public enum UpdateReason { + BOARD, + BUCKS, + MONEY, + TOKENS, + OTHER, + RANK, + CROWBARS, + PREF + } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/giftcard/Balance.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/giftcard/Balance.java new file mode 100644 index 0000000..eb9cdb7 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/giftcard/Balance.java @@ -0,0 +1,23 @@ +package net.grandtheftmc.core.giftcard; + +/** + * Created by Timothy Lampen on 1/5/2018. + */ +public class Balance { + + private String starting; + private String remaining; + private String currency; + + public String getCurrency() { + return currency; + } + + public String getRemaining() { + return remaining; + } + + public String getStarting() { + return starting; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/giftcard/Data.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/giftcard/Data.java new file mode 100644 index 0000000..ee164d5 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/giftcard/Data.java @@ -0,0 +1,32 @@ +package net.grandtheftmc.core.giftcard; + +import com.google.gson.annotations.SerializedName; + +/** + * Created by Timothy Lampen on 1/5/2018. + */ +public class Data { + + private Double id; + private String code; + private Balance balance; + + @SerializedName("void") + private Boolean _void; + + public Balance getBalance() { + return balance; + } + + public Boolean get_void() { + return _void; + } + + public Double getId() { + return id; + } + + public String getCode() { + return code; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/giftcard/Giftcard.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/giftcard/Giftcard.java new file mode 100644 index 0000000..f816ae8 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/giftcard/Giftcard.java @@ -0,0 +1,12 @@ +package net.grandtheftmc.core.giftcard; + +/** + * Created by Timothy Lampen on 1/5/2018. + */ +public class Giftcard { + private Data data; + + public Data getData() { + return data; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/giftcard/GiftcardAPI.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/giftcard/GiftcardAPI.java new file mode 100644 index 0000000..3e9a141 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/giftcard/GiftcardAPI.java @@ -0,0 +1,138 @@ +package net.grandtheftmc.core.giftcard; + +import com.google.gson.Gson; +import net.buycraft.plugin.internal.okhttp3.FormBody; +import net.buycraft.plugin.internal.okhttp3.Request; +import net.buycraft.plugin.internal.okhttp3.Response; +import net.buycraft.plugin.internal.okhttp3.ResponseBody; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.HTTPUtil; +import net.grandtheftmc.core.util.ServerUtil; + +import java.io.IOException; + +/** + * Created by Luke Bingham on 28/08/2017. + */ +public class GiftcardAPI { + private static final Gson GSON = new Gson(); + + /** + * @param callback called when the task is completed. Returns the code of the giftcard just created. + */ + public static void postGiftCard(final double amount, net.grandtheftmc.core.util.Callback callback) { + ServerUtil.runTaskAsync(() -> { + try { + Response response = Core.getOkHttpClient().newCall( + new Request.Builder().url("https://plugin.buycraft.net/gift-cards") + .addHeader("X-Buycraft-Secret", Core.getInstance().getBuycraftSecret()) + .addHeader("Accept", "application/json") + .addHeader("User-Agent", "BuycraftX") + .post(new FormBody.Builder().add("amount", String.valueOf(amount)).build()) + .build() + ).execute(); + + try(ResponseBody responseBody = response.body()) { + if(response.isSuccessful()) { + String body = responseBody.string(); + Giftcard card = GSON.fromJson(body, Giftcard.class); + callback.call(card); + return; + } + callback.call(null); + } + } catch (IOException e) { + callback.call(null); + e.printStackTrace(); + } + }); + } + + public static void getGiftCard(final int id, net.grandtheftmc.core.util.Callback callback) { + ServerUtil.runTaskAsync(() -> { + try { + Response response = Core.getOkHttpClient().newCall( + new Request.Builder().url("https://plugin.buycraft.net/gift-cards/" + id) + .addHeader("X-Buycraft-Secret", Core.getInstance().getBuycraftSecret()) + .addHeader("Accept", "application/json") + .addHeader("User-Agent", "BuycraftX") + .get() + .build() + ).execute(); + + try (ResponseBody responseBody = response.body()) { + if (response.isSuccessful()) { + String body = responseBody.string(); + callback.call(HTTPUtil.transform(body, GiftcardAPI.class)); + return; + } + + callback.call(null); + } + } catch (IOException e) { + callback.call(null); + e.printStackTrace(); + } + }); + } + + public static void topupGiftCard(final int id, final double amount, net.grandtheftmc.core.util.Callback callback) { + ServerUtil.runTaskAsync(() -> { + try { + Response response = Core.getOkHttpClient().newCall( + new Request.Builder().url("https://plugin.buycraft.net/gift-cards/" + id) + .addHeader("X-Buycraft-Secret", Core.getInstance().getBuycraftSecret()) + .addHeader("Accept", "application/json") + .addHeader("User-Agent", "BuycraftX") + .post(new FormBody.Builder().add("amount", String.valueOf(amount)).build()) + .build() + ).execute(); + + try (ResponseBody responseBody = response.body()) { + if (response.isSuccessful()) { + String body = responseBody.string(); + callback.call(HTTPUtil.transform(body, GiftcardAPI.class)); + return; + } + + callback.call(null); + } + } catch (IOException e) { + callback.call(null); + e.printStackTrace(); + } + }); + } + + /** + * GiftCards cannot be removed from the API, + * So to 'delete' them we set them as VOID. + */ + public static void voidGiftCard(final int id, net.grandtheftmc.core.util.Callback callback) { + ServerUtil.runTaskAsync(() -> { + try { + Response response = Core.getOkHttpClient().newCall( + new Request.Builder().url("https://plugin.buycraft.net/gift-cards/" + id) + .addHeader("X-Buycraft-Secret", Core.getInstance().getBuycraftSecret()) + .addHeader("Accept", "application/json") + .addHeader("User-Agent", "BuycraftX") + .delete() + .build() + ).execute(); + + try (ResponseBody responseBody = response.body()) { + if (response.isSuccessful()) { + String body = responseBody.string(); + callback.call(HTTPUtil.transform(body, GiftcardAPI.class)); + return; + } + + callback.call(null); + } + } catch (IOException e) { + callback.call(null); + e.printStackTrace(); + } + }); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/gui/ConfirmationMenu.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/gui/ConfirmationMenu.java new file mode 100644 index 0000000..b11887c --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/gui/ConfirmationMenu.java @@ -0,0 +1,313 @@ +package net.grandtheftmc.core.gui; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.plugin.Plugin; + +public class ConfirmationMenu implements Listener { + + /** The owning plugin */ + private Plugin plugin; + /** The item that represents what the confirmation is about */ + private ItemStack infoItem; + /** The item that represents the confirm item */ + private ItemStack confirmItem; + /** The item that represents the deny item */ + private ItemStack denyItem; + /** The GUI involved */ + private Inventory gui; + + /** Whether or not this inventory has been destroyed */ + private boolean destroyed; + + /** + * Create a generic confirmation menu, where the handling of the + * confirm/deny item can be per project specific. + *

+ * Note: Typically you would want to override + * {@link #onConfirm(InventoryClickEvent, Player)} and + * {@link #onDeny(InventoryClickEvent, Player)}. + *

+ * + * @param plugin - the owning plugin + * @param infoItem - the item that holds the info + * @param confirmItem - the confirm item + * @param denyItem - the deny item + */ + public ConfirmationMenu(Plugin plugin, ItemStack infoItem, ItemStack confirmItem, ItemStack denyItem) { + this.plugin = plugin; + this.infoItem = infoItem; + this.confirmItem = confirmItem; + this.denyItem = denyItem; + this.gui = createGUI(); + + // register this as an event + Bukkit.getPluginManager().registerEvents(this, plugin); + } + + /** + * Create a generic confirmation menu, where the handling of the + * confirm/deny item can be per project specific. + *

+ * Note: Typically you would want to override + * {@link #onConfirm(InventoryClickEvent, Player)} and + * {@link #onDeny(InventoryClickEvent, Player)}. + *

+ * Wrapper around + * {@link #ConfirmationMenu(Plugin, ItemStack, ItemStack, ItemStack)}. + * + * @param plugin - the owning plugin + * @param infoItem - the item that holds the info + */ + public ConfirmationMenu(Plugin plugin, ItemStack infoItem) { + this(plugin, infoItem, getYesItem(), getNoItem()); + } + + /** + * Opens the menu for the specified player. + * + * @param p - the player viewing the menu. + */ + public void open(Player p) { + + if (gui != null) { + p.openInventory(gui); + + // optional call-back + onOpen(); + } + } + + /** + * Close the confirmation menu. + */ + public void close() { + if (gui != null) { + + List viewers = new ArrayList<>(); + viewers.addAll(gui.getViewers()); + + // close all the viewers + viewers.forEach(v -> v.closeInventory()); + } + + // optional call-back + onClose(); + + if (!destroyed) { + + // destroy the menu + destroy(); + } + } + + /** + * Destroy this menu, marking it for garbage collection, and unregistering + * it as a Listener. + */ + private void destroy() { + + // optional call-back + onDestroy(); + + plugin = null; + infoItem = null; + confirmItem = null; + denyItem = null; + gui = null; + + // unregister the event + HandlerList.unregisterAll(this); + + destroyed = true; + } + + /** + * Optional call-back to be filled by superclass. This is called when the + * menu is opened. + */ + protected void onOpen() { + } + + /** + * Optional call-back to be filled by superclass. This is called when the + * menu is closed. + */ + protected void onClose() { + } + + /** + * Optional call-back to be filled by superclass. This is called when the + * menu is destroyed. + */ + protected void onDestroy() { + } + + /** + * Optional call-back to be filled by superclass. This is called when the + * confirm button is clicked by the user. + * + * @param e - the click event + * @param p - the player who clicked + */ + protected void onConfirm(InventoryClickEvent e, Player p) { + } + + /** + * Optional call-back to be filled by superclass. This is called when the + * deny button is clicked by the user. + * + * @param e - the click event + * @param p - the player who clicked + */ + protected void onDeny(InventoryClickEvent e, Player p) { + } + + /** + * Creates the GUI for the confirmation menu. + * + * @return The GUI that was created for this menu. + */ + private Inventory createGUI() { + + Inventory gui = plugin.getServer().createInventory(null, 9 * 3, " " + ChatColor.BOLD + ChatColor.UNDERLINE + "Are you sure?"); + + // page item + gui.setItem(4, infoItem); + + // set yes items + gui.setItem(10, confirmItem); + gui.setItem(11, confirmItem); + gui.setItem(12, confirmItem); + + // set no items + gui.setItem(14, denyItem); + gui.setItem(15, denyItem); + gui.setItem(16, denyItem); + + for (int i = 0; i < gui.getSize(); i++) { + + // populate whitespace + if (gui.getItem(i) == null) { + gui.setItem(i, getMenuBorder()); + } + } + + return gui; + } + + /** + * Handles the confirmation menu interaction. + * + * @param e - the inventory click event + * @param p - the player involved in the event + * + * @return {@code true} if the menu should be closed, {@code false} + * otherwise. + */ + private boolean handleConfirmation(InventoryClickEvent e, Player p) { + + ItemStack is = e.getCurrentItem(); + + if (is != null && is.hasItemMeta() && is.getItemMeta().hasDisplayName()) { + + if (is.isSimilar(confirmItem)) { + onConfirm(e, p); + return true; + } + else if (is.isSimilar(denyItem)) { + onDeny(e, p); + return true; + } + } + + return false; + } + + /** + * Listens in on inventory clicks. + * + * @param e - the event + */ + @EventHandler + public void onInventoryInteract(InventoryClickEvent e) { + Player p = (Player) e.getWhoClicked(); + Inventory inven = e.getInventory(); + + if (inven.equals(gui)) { + e.setCancelled(true); + + if (e.isLeftClick() || e.isRightClick() || e.isShiftClick()) { + if (e.getCurrentItem() != null && e.getRawSlot() < inven.getSize()) { + + boolean success = handleConfirmation(e, p); + if (success) { + + // close the inventory + close(); + } + } + } + } + } + + /** + * Get the itemstack representation for a generic YES item. + * + * @return The itemstack representation for a generic YES item. + */ + private static ItemStack getYesItem(){ + String displayName = ChatColor.GREEN + "Yes"; + + ItemStack is = new ItemStack(Material.WOOL, 1, (short) 13); + ItemMeta im = is.getItemMeta(); + im.setDisplayName(displayName); + is.setItemMeta(im); + + return is; + } + + /** + * Get the itemstack representation for a generic NO item. + * + * @return The itemstack representation for a generic NO item. + */ + private static ItemStack getNoItem(){ + String displayName = ChatColor.RED + "No"; + + ItemStack is = new ItemStack(Material.WOOL, 1, (short) 14); + ItemMeta im = is.getItemMeta(); + im.setDisplayName(displayName); + is.setItemMeta(im); + + return is; + } + + /** + * Get the generic representation of a menu border. + * + * @return The menu border for this menu. + */ + private static ItemStack getMenuBorder() { + ItemStack is = new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 7); + ItemMeta im = is.getItemMeta(); + im.setDisplayName(""); + is.setItemMeta(im); + + return is; + } +} + diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/handlers/Handler.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/handlers/Handler.java new file mode 100644 index 0000000..49ba8ae --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/handlers/Handler.java @@ -0,0 +1,5 @@ +package net.grandtheftmc.core.handlers; + +public interface Handler { + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/handlers/chat/ChatAdHandler.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/handlers/chat/ChatAdHandler.java new file mode 100644 index 0000000..bdeb8eb --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/handlers/chat/ChatAdHandler.java @@ -0,0 +1,27 @@ +package net.grandtheftmc.core.handlers.chat; + +import java.util.regex.Pattern; + +public class ChatAdHandler { + private final String addressRegex; + private final String domainRegex; + + public ChatAdHandler() { + this.addressRegex = "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$"; + this.domainRegex = "^((?!-)[A-Za-z0-9-]{1,63}(? lastChats; + + public ChatCooldownHandler() { + this.lastChats = new HashMap<>(); + } + + public boolean canChatAgain(UUID uuid, int cooldown) { + if (!lastChats.containsKey(uuid)) return true; + if (System.currentTimeMillis() >= this.lastChats.get(uuid)) { + this.lastChats.remove(uuid); + return true; + } + return false; + } + + public void setCanChatAgain(UUID uuid, Long timestamp) { + this.lastChats.put(uuid, timestamp); + } + + protected Map getLastChats() { + return lastChats; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/handlers/chat/ChatManager.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/handlers/chat/ChatManager.java new file mode 100644 index 0000000..8fc7ed3 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/handlers/chat/ChatManager.java @@ -0,0 +1,52 @@ +package net.grandtheftmc.core.handlers.chat; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.Component; +import org.bukkit.configuration.file.YamlConfiguration; + +public class ChatManager implements Component { + private static ChatSettings chatSettings; + + private static ChatCooldownHandler cooldownHandler; + private static ChatRepeatHandler repeatHandler; + private static ChatAdHandler adHandler; + + public ChatManager(YamlConfiguration config) { + chatSettings = new ChatSettings(config); + cooldownHandler = new ChatCooldownHandler(); + repeatHandler = new ChatRepeatHandler(); + adHandler = new ChatAdHandler(); + } + + @Override + public ChatManager onDisable(Core plugin) { + chatSettings.getDomainWhitelist().clear(); + cooldownHandler.getLastChats().clear(); + repeatHandler.getRecentMessages().clear(); + return this; + } + + public static ChatSettings getSettings() { + return chatSettings; + } + + public static ChatCooldownHandler getCooldownHandler() { + return cooldownHandler; + } + + public static ChatRepeatHandler getRepeatHandler() { + return repeatHandler; + } + + public static ChatAdHandler getAdHandler() { + return adHandler; + } + + public static int getDefaultChatCooldown() { + return chatSettings.getDefaultChatCooldown(); + } + + public static int getVipChatCooldown() { + return chatSettings.getVipChatCooldown(); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/handlers/chat/ChatRepeatHandler.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/handlers/chat/ChatRepeatHandler.java new file mode 100644 index 0000000..b7b6df6 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/handlers/chat/ChatRepeatHandler.java @@ -0,0 +1,42 @@ +package net.grandtheftmc.core.handlers.chat; + +import net.grandtheftmc.core.Core; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.*; + +public class ChatRepeatHandler { + private Map> recentMessages; + + public ChatRepeatHandler() { + this.recentMessages = new HashMap<>(); + } + + public boolean canChatAgain(UUID uuid, String message) { + if (this.recentMessages.getOrDefault(uuid, new ArrayList<>()).contains(message)) { + return false; + } else { + for (String string : this.recentMessages.getOrDefault(uuid, new ArrayList<>())) { + if(message.contains(string)) return false; + } + } + return true; + } + + public void addRecentMessage(UUID uuid, String message, int cooldown) { + List messages = this.recentMessages.getOrDefault(uuid, new ArrayList<>()); + messages.add(message); + this.recentMessages.put(uuid, messages); + new BukkitRunnable() { + @Override + public void run() { + messages.remove(message); + recentMessages.put(uuid, messages); + } + }.runTaskLaterAsynchronously(Core.getInstance(), cooldown * 20); + } + + protected Map> getRecentMessages() { + return recentMessages; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/handlers/chat/ChatSettings.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/handlers/chat/ChatSettings.java new file mode 100644 index 0000000..9937b9b --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/handlers/chat/ChatSettings.java @@ -0,0 +1,52 @@ +package net.grandtheftmc.core.handlers.chat; + +import org.bukkit.configuration.file.YamlConfiguration; + +import java.util.Collection; + +public class ChatSettings { + private YamlConfiguration config; + + private Collection domainWhitelist; + private int defaultChatCooldown; + private int vipChatCooldown; + + public ChatSettings(YamlConfiguration chatSettingsConfig) { + this.config = chatSettingsConfig; + this.loadSettings(); + } + + public void loadSettings() { + this.defaultChatCooldown = this.config.getInt("default-chat-delay"); + this.vipChatCooldown = this.config.getInt("vip-chat-delay"); + this.domainWhitelist = this.config.getStringList("domain-whitelist"); + } + + public YamlConfiguration getConfig() { + return this.config; + } + + public void setConfig(YamlConfiguration config) { + this.config = config; + } + + public Collection getDomainWhitelist() { + return domainWhitelist; + } + + public int getDefaultChatCooldown() { + return defaultChatCooldown; + } + + public void setDefaultChatCooldown(int defaultChatCooldown) { + this.defaultChatCooldown = defaultChatCooldown; + } + + public int getVipChatCooldown() { + return vipChatCooldown; + } + + public void setVipChatCooldown(int vipChatCooldown) { + this.vipChatCooldown = vipChatCooldown; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/inventory/CoreMenu.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/inventory/CoreMenu.java new file mode 100644 index 0000000..460c1f1 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/inventory/CoreMenu.java @@ -0,0 +1,282 @@ +package net.grandtheftmc.core.inventory; + +import com.google.common.collect.Maps; +import net.grandtheftmc.core.inventory.button.ClickableItem; +import net.grandtheftmc.core.inventory.button.MenuItem; +import net.grandtheftmc.core.util.Utils; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; + +import java.util.HashMap; + +/** + * Created by Luke Bingham on 05/07/2017. + */ +public abstract class CoreMenu implements InventoryHolder, IMenuButtonHandler { + + private final HashMap mapItems; +// private final List items; + private Inventory inventory; + + private final int rows; + private final String title; + private CoreMenuFlag[] menuFlags; + protected boolean selfHandle = false; + + /** + * Construct a new Menu. + */ + public CoreMenu(int rows, String title, CoreMenuFlag... menuFlags) { + this(rows, title); + this.menuFlags = menuFlags; + if(hasFlag(CoreMenuFlag.PHONE_LAYOUT)) { + this.inventory = Bukkit.createInventory(this, 54, title); + setPhoneDefaults(); + } + } + + /** + * Construct a new Menu. + */ + public CoreMenu(int rows, String title) { + if(rows <= 0 || rows >= 7) { + throw new IndexOutOfBoundsException("Menu rows out of bounds, choose value between 1 - 6"); + } + + this.mapItems = Maps.newHashMap(); + + this.rows = rows; + this.title = Utils.f(title); + this.inventory = Bukkit.createInventory(this, rows * 9, title); + + } + + /** + * Construct a new Menu. + */ + public CoreMenu(String title, int rows, InventoryType type, CoreMenuFlag... menuFlags) { + this.mapItems = Maps.newHashMap(); + + this.rows = rows; + this.title = title; + this.inventory = Bukkit.createInventory(this, type, title); + this.menuFlags = menuFlags; + } + + public void setSelfHandle(boolean b) { + this.selfHandle = b; + } + + @Override + public final Inventory getInventory() { + return this.inventory; + } + + public boolean isSelfHandle() { + return selfHandle; + } + + public void selfHandle(InventoryClickEvent event) { + CoreMenu menu = (CoreMenu) event.getInventory().getHolder(); + Player player = (Player) event.getWhoClicked(); + + MenuItem item = menu.getMenuItem(event.getRawSlot()); + if(item == null) return; + + if(!item.isAllowingPickup()) + event.setCancelled(true); + + if(item instanceof ClickableItem) { + event.setCancelled(true); + ((ClickableItem) item).getClickAction().onClick(player, event.getClick()); + } + } + + private void setPhoneDefaults() { + ItemStack whiteGlass = Utils.createItem(Material.STAINED_GLASS_PANE, "&a"); + ItemStack grayGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a"); + ItemStack blackGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 15, "&a"); + ItemStack lightGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 8, "&a"); + for (int i : new int[]{1, 10, 19, 28, 37, 46, 7, 16, 25, 34, 43, 52}) addItem(new MenuItem(i, whiteGlass, false)); + for (int i : new int[]{2, 3, 4, 5, 6}) addItem(new MenuItem(i, blackGlass, false)); + for (int i : new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42, 47, 48, 49, 50, 51}) addItem(new MenuItem(i, grayGlass, false)); + for (int i : new int[]{0, 8, 9, 17, 18, 26, 27, 35, 36, 44, 45, 53}) addItem(new MenuItem(i, lightGlass, false)); + } + + /** + * Open the inventory to the specified player. + * + * @param player Specified Player + */ + public void openInventory(Player player) { + if(hasFlag(CoreMenuFlag.RESET_CURSOR_ON_OPEN)) player.closeInventory(); + player.openInventory(this.inventory); + } + + public final boolean hasFlag(CoreMenuFlag menuFlag) { + if(this.menuFlags == null || this.menuFlags.length == 0) return false; + boolean result = false; + for(int i = 0; i < this.menuFlags.length; i++) { + if(this.menuFlags[i] == menuFlag) { + result = true; + break; + } + } + return result; + } + + /** + * This should be overwritten for menus which require the usage of this. + */ + public void onClose(InventoryCloseEvent event){ + + } + + /** + * This should be overwritten for menu which require the usage of this. If selfHandle = true then this is not triggered. + * This is done before the handling of the Clickable / MenuItems. + * Cancelling this event WILLNOT cancel the handling of the Clickable / Menuitems. + */ + public void onClick(InventoryClickEvent event){ + + } + + /** + * This is called on every interaction. + * + * @param menu + */ + public void onInteract(CoreMenu menu) { + + } + + /** + * Add an item to the inventory. + * + * @param menuItem + */ + @Override + public void addItem(MenuItem menuItem) { + this.inventory.setItem(menuItem.getIndex(), menuItem.getItemStack()); +// this.items.add(menuItem); + this.mapItems.put(menuItem.getIndex(), menuItem); + } + + @Override + public void deleteItem(int index) { + this.inventory.setItem(index, null); + this.mapItems.remove(index); + } + + /** + * Check if the inventory contains a specific item. + * + * @param itemStack Item to search for + * @return true if item is found + */ + @Override + public boolean containsItem(ItemStack itemStack) { +// return this.items.stream().anyMatch(item -> item.getItemStack().equals(itemStack)); + return this.mapItems.values().stream().anyMatch(item -> item.getItemStack().equals(itemStack)); + } + + /** + * Check if the inventory slot is in use. + * + * @param index slot index + * @return found status + */ + @Override + public boolean containsItem(int index) { + return this.inventory.getItem(index) != null; + } + + /** + * Get the MenuItem from an input ItemStack. + * + * @param itemStack Item to search for + * @return MenuItem version of the found ItemStack + */ + @Override + public MenuItem getMenuItem(ItemStack itemStack) { +// return this.items.stream().filter(item -> item.getItemStack().equals(itemStack)).findFirst().orElse(null); + return this.mapItems.values().stream().filter(item -> item.getItemStack().equals(itemStack)).findFirst().orElse(null); + } + + /** + * Get the MenuItem from an index input. + * + * @param index slot to search + * @return MenuItem version of the found ItemStack + */ + @Override + public MenuItem getMenuItem(int index) { + return this.mapItems.getOrDefault(index, null); +// return this.mapItems.values().stream().filter(item -> item.getIndex() == index).findFirst().orElse(null); + } + + /** + * Get the amount of rows in the inventory. + * + * @return amount of rows + */ + public final int getRows() { + return rows; + } + + /** + * Get the display title of the inventory ui. + * + * @return display title + */ + public final String getTitle() { + return title; + } + + /** + * Get the flags assigned to said inventory. + * + * @return array of menu flags + */ + public final CoreMenuFlag[] getMenuFlags() { + return menuFlags; + } + + protected int[] getEdgeSlots(int rows) { + switch (rows) { + case 1: + return new int[] {}; + case 2: + return new int[] {}; + case 3: + return new int[] {0,1,2,3,4,5,6,7,8, 9,17, 18,19,20,21,22,23,24,25,26}; + case 4: + return new int[] {0,1,2,3,4,5,6,7,8, 9,17, 18,26, 27,28,29,30,31,32,33,34,35}; + case 5: + return new int[] {0,1,2,3,4,5,6,7,8, 9,17, 18,26, 27,35, 36,37,38,39,40,41,42,43,44}; + case 6: + return new int[] {0,1,2,3,4,5,6,7,8, 9,17, 18,26, 27,35, 36,44, 45,46,47,48,49,50,51,52,53}; + } + + return new int[]{}; + } + + public boolean isSlotBlocked(int slot) { + for (int i : this.mapItems.keySet()) { + if (i != slot) continue; + MenuItem item = this.mapItems.get(i); + if (!item.isAllowingPickup()) { + return true; + } + } + + return false; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/inventory/CoreMenuFlag.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/inventory/CoreMenuFlag.java new file mode 100644 index 0000000..58d3d30 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/inventory/CoreMenuFlag.java @@ -0,0 +1,32 @@ +package net.grandtheftmc.core.inventory; + +/** + * Created by Luke Bingham on 05/07/2017. + */ +public enum CoreMenuFlag { + + /** + * When a user clicks outside of the inventory ui, + * the menu will close. + * + * ! This does not account for empty slots. ! + */ + CLOSE_ON_NULL_CLICK, + + /** + * When a user opens the specific inventory, + * the cursor will be reset back to its + * default position. (X:Center - Y:Bottom) + * + * ! This only accounts for opening ! + */ + RESET_CURSOR_ON_OPEN, + + /** + * If you would like the inventory to have + * the same layout as the phone. + * + * This overrides the size parameter (the size can be set to anything) + */ + PHONE_LAYOUT +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/inventory/CoreMenuHandler.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/inventory/CoreMenuHandler.java new file mode 100644 index 0000000..17dcdd2 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/inventory/CoreMenuHandler.java @@ -0,0 +1,89 @@ +package net.grandtheftmc.core.inventory; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.inventory.button.ClickableItem; +import net.grandtheftmc.core.inventory.button.MenuItem; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.inventory.InventoryDragEvent; +import org.bukkit.inventory.ItemStack; + +/** + * Created by Luke Bingham on 05/07/2017. + */ +public class CoreMenuHandler implements Listener {//TODO, Implement Component + + public CoreMenuHandler(Core plugin) { + Bukkit.getPluginManager().registerEvents(this, plugin); + } + + @EventHandler + public void onDrag(InventoryDragEvent event){ + if(event.getInventory().getHolder() == null) return; + if(!(event.getInventory().getHolder() instanceof CoreMenu)) return; + if(!(event.getWhoClicked() instanceof Player)) return; + + CoreMenu menu = (CoreMenu) event.getInventory().getHolder(); + + boolean blocked = false; + for (int slot : event.getRawSlots()) { + if (menu.isSlotBlocked(slot)) { + blocked = true; + break; + } + } + + menu.onInteract(menu); + + event.setCancelled(blocked); + } + + @EventHandler + protected void onInventoryClick(InventoryClickEvent event) { + if(event.getInventory().getHolder() == null) return; + if(!(event.getInventory().getHolder() instanceof CoreMenu)) return; + if(!(event.getWhoClicked() instanceof Player)) return; + + CoreMenu menu = (CoreMenu) event.getInventory().getHolder(); + + Player player = (Player) event.getWhoClicked(); + ItemStack clicked = event.getCurrentItem(); + + if(clicked == null && menu.hasFlag(CoreMenuFlag.CLOSE_ON_NULL_CLICK)) { + player.closeInventory(); + return; + } + + menu.onInteract(menu); + + if(menu.isSelfHandle()) { + menu.selfHandle(event); + return; + } + menu.onClick(event); + MenuItem item = menu.getMenuItem(event.getRawSlot()); + if(item == null) return; + + if(!item.isAllowingPickup()) + event.setCancelled(true); + if(item instanceof ClickableItem) { + ((ClickableItem) item).getClickAction().onClick(player, event.getClick()); + } + } + + @EventHandler + protected void onInventoryClose(InventoryCloseEvent event) { + if(event.getInventory().getHolder() == null) + return; + if(!(event.getInventory().getHolder() instanceof CoreMenu)) + return; + if(!(event.getPlayer() instanceof Player)) + return; + CoreMenu menu = (CoreMenu) event.getInventory().getHolder(); + menu.onClose(event); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/inventory/IMenuButtonHandler.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/inventory/IMenuButtonHandler.java new file mode 100644 index 0000000..90f84e9 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/inventory/IMenuButtonHandler.java @@ -0,0 +1,54 @@ +package net.grandtheftmc.core.inventory; + +import net.grandtheftmc.core.inventory.button.MenuItem; +import org.bukkit.inventory.ItemStack; + +/** + * Created by Luke Bingham on 05/07/2017. + */ +public interface IMenuButtonHandler { + + /** + * Add an item to the inventory. + */ + void addItem(MenuItem menuItem); + + /** + * Delete an item from the inventory. + */ + void deleteItem(int index); + + /** + * Check if the inventory contains a specific item. + * + * @param itemStack Item to search for + * @return true if item is found + */ + boolean containsItem(ItemStack itemStack); + + /** + * Check if the inventory slot is in use. + * + * @param index slot index + * @return found status + */ + boolean containsItem(int index); + + /** + * Get the MenuItem from an input ItemStack. + * + * @param itemStack Item to search for + * @return MenuItem version of the found ItemStack + */ + MenuItem getMenuItem(ItemStack itemStack); + + /** + * Get the MenuItem from an index input. + * + * @param index slot to search + * @return MenuItem version of the found ItemStack + */ + MenuItem getMenuItem(int index); + + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/inventory/button/ClickableItem.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/inventory/button/ClickableItem.java new file mode 100644 index 0000000..dbc8732 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/inventory/button/ClickableItem.java @@ -0,0 +1,42 @@ +package net.grandtheftmc.core.inventory.button; + +import org.bukkit.inventory.ItemStack; + +/** + * Created by Luke Bingham on 05/07/2017. + */ +public class ClickableItem extends MenuItem { + + private IMenuClickAction clickAction; + + /** + * Construct a new MenuItem + * + * @param index menu slot index + * @param itemStack menu itemstack + */ + public ClickableItem(int index, ItemStack itemStack, IMenuClickAction clickAction) { + super(index, itemStack, false); + this.clickAction = clickAction; + } + + /** + * Construct a new MenuItem + * + * @param index menu slot index + * @param itemStack menu itemstack + */ + public ClickableItem(int index, ItemStack itemStack, boolean allowPickup, IMenuClickAction clickAction) { + super(index, itemStack, allowPickup); + this.clickAction = clickAction; + } + + public ClickableItem(int index, ItemStack itemStack, IMenuClickAction clickAction, boolean pickup) { + super(index, itemStack, pickup); + this.clickAction = clickAction; + } + + public IMenuClickAction getClickAction() { + return clickAction; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/inventory/button/IMenuClickAction.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/inventory/button/IMenuClickAction.java new file mode 100644 index 0000000..e2dc7fc --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/inventory/button/IMenuClickAction.java @@ -0,0 +1,18 @@ +package net.grandtheftmc.core.inventory.button; + +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; + +/** + * Created by Luke Bingham on 05/07/2017. + */ +public interface IMenuClickAction { + + /** + * This is fired when an item is interacted with. + * + * @param player Player who interacted + * @param clickType interaction type + */ + void onClick(Player player, ClickType clickType); +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/inventory/button/MenuItem.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/inventory/button/MenuItem.java new file mode 100644 index 0000000..07eef10 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/inventory/button/MenuItem.java @@ -0,0 +1,55 @@ +package net.grandtheftmc.core.inventory.button; + +import org.bukkit.inventory.ItemStack; + +/** + * Created by Luke Bingham on 05/07/2017. + */ +public class MenuItem { + + private final int index; + private final ItemStack itemStack; + + private final boolean allowPickup; + + /** + * Construct a new MenuItem + * + * @param index menu slot index + * @param itemStack menu itemstack + * @param allowPickup movable status + */ + public MenuItem(int index, ItemStack itemStack, boolean allowPickup) { + this.index = index; + this.itemStack = itemStack; + this.allowPickup = allowPickup; + } + + /** + * Get the index of the set item. + * + * @return index + */ + public final int getIndex() { + return index; + } + + /** + * Get the ItemStack of the set item. + * + * @return itemstack + */ + public final ItemStack getItemStack() { + return itemStack; + } + + /** + * If true, the item can be moved. + * If false, the item is stationary. + * + * @return movable status + */ + public final boolean isAllowingPickup() { + return allowPickup; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/inventory/example/ExampleUI.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/inventory/example/ExampleUI.java new file mode 100644 index 0000000..8fff399 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/inventory/example/ExampleUI.java @@ -0,0 +1,41 @@ +package net.grandtheftmc.core.inventory.example; + +import net.grandtheftmc.core.inventory.CoreMenu; +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import net.grandtheftmc.core.inventory.button.ClickableItem; +import net.grandtheftmc.core.inventory.button.MenuItem; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +/** + * Created by Luke Bingham on 05/07/2017. + */ +public class ExampleUI extends CoreMenu { + + /** + * Construct a new Menu. + */ + public ExampleUI() { + //Without MenuFlags + super(6, "Example Interface"); + + //With MenuFlags + //super(6, "Example Interface", CoreMenuFlag.CLOSE_ON_NULL_CLICK, CoreMenuFlag.RESET_CURSOR_ON_OPEN); + + + //new MenuItem(index, itemstack, allowPickup) + addItem(new MenuItem(0, new ItemStack(Material.APPLE), false)); + + //new ClickableItem(index, itemstack, menuClickAction) + addItem(new ClickableItem(1, new ItemStack(Material.ENDER_PEARL, 4), (player, clickType) -> { + player.sendMessage("You clicked the Ender pearl... nice! (" + clickType.name() + ")"); + })); + + //done. + } + + //How to open this menu. + //new ExampleUI().openInventory(player); +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/inventory/types/PaginationMenu.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/inventory/types/PaginationMenu.java new file mode 100644 index 0000000..82fc892 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/inventory/types/PaginationMenu.java @@ -0,0 +1,36 @@ +package net.grandtheftmc.core.inventory.types; + +import net.grandtheftmc.core.inventory.CoreMenu; +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +/** + * Created by Timothy Lampen on 1/22/2018. + * @deprecated in progress. + */ +public abstract class PaginationMenu extends CoreMenu { + + protected final ItemStack[] items = getItems(); + public PaginationMenu(String title, CoreMenuFlag... menuFlags) { + super(6, title, menuFlags); + } + + public PaginationMenu(String title){ + super(6, title); + } + + /** + * Open the inventory to the specified player. + * + * @param player Specified Player + */ + public void openInventory(Player player, int page) { + if(hasFlag(CoreMenuFlag.RESET_CURSOR_ON_OPEN)) player.closeInventory(); + + } + + protected abstract ItemStack[] getItems(); + + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/leaderboards/LeaderBoard.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/leaderboards/LeaderBoard.java new file mode 100644 index 0000000..444a7cb --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/leaderboards/LeaderBoard.java @@ -0,0 +1,118 @@ +package net.grandtheftmc.core.leaderboards; + +import com.gmail.filoghost.holographicdisplays.api.Hologram; +import com.gmail.filoghost.holographicdisplays.api.HologramsAPI; +import com.gmail.filoghost.holographicdisplays.api.line.TextLine; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.Utils; +import org.bukkit.Location; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class LeaderBoard { + + private String name; + private String displayName; + private Location location; + private final int lines; + private String table; + private String column; + + private Hologram hologram; + private final List textLines = new ArrayList<>(); + + private final Map cache; + + public LeaderBoard(String name, String displayName, String table, String column, Location location, int lines) { + this.name = name; + this.displayName = displayName; + this.location = location; + this.lines = lines; + this.cache = new HashMap<>(); + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public Location getLocation() { + return this.location; + } + + public void setLocation(Location location) { + this.location = location; + } + + public String getDisplayName() { + return this.displayName; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + public Hologram getHologram() { + return this.hologram; + } + + public void setHologram(Hologram hologram) { + this.hologram = hologram; + } + + public void create() { + this.hologram = HologramsAPI.createHologram(Core.getInstance(), this.location); + this.hologram.appendTextLine(Utils.f(this.displayName + " Leaderboard")); + this.hologram.appendTextLine(""); + this.textLines.clear(); + for (int i = 0; i < this.lines; i++) { + this.textLines.add(this.hologram.appendTextLine("")); + } + } + + protected void delete() { + this.hologram.delete(); + this.textLines.clear(); + } + + public void update() { + /* + try { + ResultSet rs = Core.getSQL().query( + "select name, " + this.column + " from " + this.table + " order by " + this.column + " desc limit " + this.lines + ';'); + this.cache.clear(); + while (rs.next()) + this.cache.put(rs.getString("name"), rs.getDouble(this.column)); + + } catch (SQLException e) { + e.printStackTrace(); + } + new BukkitRunnable() { + @Override + public void run() { + int i = 0; + for (Map.Entry stringDoubleEntry : LeaderBoard.this.cache.entrySet()) { + LeaderBoard.this.textLines.get(0).setText("&6&l#" + (i + 1) + "&7: &a&l" + stringDoubleEntry.getKey() + "&7 with &a&l" + LeaderBoard.this.cache.get(stringDoubleEntry.getKey())); + i++; + if (i >= LeaderBoard.this.lines) + break; + } + } + }.runTask(Core.getInstance());*/ + } + + public String getTable() { + return this.table; + } + + public String getColumn() { + return this.column; + } + +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/leaderboards/LeaderBoardManager.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/leaderboards/LeaderBoardManager.java new file mode 100644 index 0000000..d4d3826 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/leaderboards/LeaderBoardManager.java @@ -0,0 +1,67 @@ +package net.grandtheftmc.core.leaderboards; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.util.Component; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class LeaderBoardManager implements Component { + + private int taskId = -1; + + private final List leaderBoards = new ArrayList<>(); + + public LeaderBoardManager() { + if (!Core.getSettings().useHolographicDisplays()) + return; + //this.loadLeaderBoards(); + //this.startSchedule(); + } + + @Override + public LeaderBoardManager onDisable(Core plugin) { + if(this.leaderBoards==null || this.leaderBoards.size()==0) + return this; + this.leaderBoards.forEach(LeaderBoard::delete); + this.leaderBoards.clear(); + return this; + } + + private void startSchedule() { + /* + if (this.taskId > 0) + Bukkit.getScheduler().cancelTask(this.taskId); + this.taskId = new BukkitRunnable() { + @Override + public void run() { + LeaderBoardManager.this.leaderBoards.forEach(LeaderBoard::update); + } + }.runTaskTimerAsynchronously(Core.getInstance(), 100, 100).getTaskId();*/ + } + + public void loadLeaderBoards() { + YamlConfiguration c = Core.getSettings().getLeaderBoardsConfig(); + this.leaderBoards.addAll(c.getKeys(false).stream().map(name -> new LeaderBoard(name, c.getString(name + ".displayName"), c.getString(name + ".table"), + c.getString(name + ".column"), Utils.teleportLocationFromString(c.getString(name + ".location")), + c.getInt(name + ".lines"))).collect(Collectors.toList())); + } + + public void saveLeaderBoards(boolean shutdown) { + YamlConfiguration c = Core.getSettings().getLeaderBoardsConfig(); + for (String s : c.getKeys(false)) + c.set(s, null); + for (LeaderBoard board : this.leaderBoards) { + String name = board.getName(); + c.set(name + ".displayName", board.getDisplayName()); + c.set(name + ".table", board.getTable()); + c.set(name + ".column", board.getColumn()); + c.set(name + ".location", Utils.teleportLocationToString(board.getLocation())); + } + Utils.saveConfig(c, "leaderBoards"); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/Chat.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/Chat.java new file mode 100644 index 0000000..fb28b83 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/Chat.java @@ -0,0 +1,134 @@ +package net.grandtheftmc.core.listeners; + +import java.util.ArrayList; +import java.util.UUID; +import java.util.concurrent.TimeUnit; +import java.util.regex.Pattern; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.server.TabCompleteEvent; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.commands.GlobalMuteCommand; +import net.grandtheftmc.core.events.ChatEvent; +import net.grandtheftmc.core.handlers.chat.ChatManager; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.IconConverter; +import net.grandtheftmc.core.util.Utils; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.TextComponent; + +public class Chat implements Listener { + + private final Pattern pattern; + + public Chat() { + this.pattern = Pattern.compile("^\\\\/(?:about|bukkit:about|minecraft:about|ver|bukkit:ver|version|bukkit:version).*$"); + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onChat(AsyncPlayerChatEvent e) { + + // grab event variables + Player player = e.getPlayer(); + UUID uuid = player.getUniqueId(); + String msg = e.getMessage(); + + User u = Core.getUserManager().getUser(player.getUniqueId()).orElse(null); + if (u == null || u.isInTutorial()) { + e.setCancelled(true); + return; + } + + for (Player p : new ArrayList<>(e.getRecipients())) { + User pu = Core.getUserManager().getUser(p.getUniqueId()).orElse(null); + if (pu == null || pu.isInTutorial() || pu.isIgnored(player.getName())){ + e.getRecipients().remove(p); + } + } + if (u.isRank(UserRank.VIP)) { + for (String word : msg.split(" ")) { + if (word.startsWith(":") && word.endsWith(":")) { + msg = IconConverter.convertInput(msg); + } + } + } + if (!u.isRank(UserRank.MOD)) { + if (GlobalMuteCommand.chatMuted) { + e.setCancelled(true); + player.sendMessage(Lang.GTM.f("&7Chat has been muted! Please wait")); + return; + } + } + u.updateDisplayName(player); + TextComponent textComponent; + if (u.isSpecial()) { + e.setMessage(u.isAdmin() ? Utils.f(msg) : Utils.fColor(msg)); + e.setFormat(Utils.f("%s&f %s")); + textComponent = new TextComponent(Utils.f(player.getDisplayName() + "&f ") + e.getMessage()); + } else { + e.setFormat(Utils.f("%s&7 " + "%s")); + textComponent = new TextComponent(Utils.f(player.getDisplayName() + "&7 ") + e.getMessage()); + textComponent.setColor(ChatColor.GRAY); + } + ChatEvent chatEvent; + try { + chatEvent = new ChatEvent(player, textComponent, e.getRecipients()); + Bukkit.getPluginManager().callEvent(chatEvent); + } catch (NullPointerException exception) { + exception.printStackTrace(); + return; + } + if (chatEvent.isCancelled()) { + e.setCancelled(true); + return; + } + textComponent = chatEvent.getTextComponent(); + if (u.getUUID() != null && !u.isStaff()) { + for (String text : e.getMessage().split(" ")) { + if (ChatManager.getAdHandler().matchesAdvertisement(text)) { + player.sendMessage(Lang.GTM.f("&7URL prohibited. Please do not attempt to advertise.")); + Bukkit.getOnlinePlayers() + .stream() + .filter(target -> Core.getUserManager() + .getLoadedUser(target.getUniqueId()) + .isRank(UserRank.HELPOP)) + .forEach(target -> target.sendMessage(Lang.ANTIAD.f(u.getColoredName(player) + + " &cattempted to advertise &a''" + e.getMessage() + "''"))); + e.setCancelled(true); + return; + } + } + int cooldown = u.isSpecial() ? ChatManager.getVipChatCooldown() : ChatManager.getDefaultChatCooldown(); + if (ChatManager.getCooldownHandler().canChatAgain(uuid, cooldown)) { + ChatManager.getCooldownHandler().setCanChatAgain(uuid, System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(cooldown)); + } else { + player.sendMessage(Lang.GTM.f("&7You are sending messages too fast, please slow down.")); + e.setCancelled(true); + return; + } + cooldown = u.isSpecial() ? 3 : 5; + if (ChatManager.getRepeatHandler().canChatAgain(uuid, e.getMessage())) { + ChatManager.getRepeatHandler().addRecentMessage(uuid, e.getMessage(), cooldown); + } else { + player.sendMessage(Lang.GTM.f("&7Please wait a few seconds before repeating that message.")); + e.setCancelled(true); + return; + } + } + for (Player target : chatEvent.getRecipients()) target.spigot().sendMessage(textComponent); + e.getRecipients().clear(); + } + + @EventHandler + protected void onTabComplete(TabCompleteEvent event) { + event.setCancelled(this.pattern.matcher(ChatColor.stripColor(event.getBuffer())).find()); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/ChunkLoad.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/ChunkLoad.java new file mode 100644 index 0000000..eb819e5 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/ChunkLoad.java @@ -0,0 +1,18 @@ +package net.grandtheftmc.core.listeners; + +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.world.ChunkLoadEvent; + +import net.grandtheftmc.core.Core; + +public class ChunkLoad implements Listener { + + @SuppressWarnings("deprecation") + @EventHandler + public void onChunkLoad(ChunkLoadEvent e) { + if ((Core.getSettings().stopChunkLoad(e.getWorld().getName()) && e.isNewChunk()) || (Core.getSettings().stopLoadDefaultWorld() && "world".equals(e.getWorld().getName()))) + e.getChunk().unload(false,false); + } + +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/CommandListener.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/CommandListener.java new file mode 100644 index 0000000..b568fdb --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/CommandListener.java @@ -0,0 +1,201 @@ +package net.grandtheftmc.core.listeners; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.Server; +import org.bukkit.command.SimpleCommandMap; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerChatTabCompleteEvent; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.server.ServerCommandEvent; +import org.bukkit.plugin.SimplePluginManager; +import org.bukkit.scheduler.BukkitRunnable; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.Pref; +import net.grandtheftmc.core.users.UserManager; +import net.grandtheftmc.core.util.Utils; +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.TextComponent; + +public class CommandListener implements Listener { + private SimpleCommandMap cmdMap; + private List socialSpyCmds = new ArrayList<>(); + + public CommandListener() { + try { + this.cmdMap = this.getCommandMap(Core.getInstance().getServer()); + } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) { + e.printStackTrace(); + } + this.loadSocialSpy(); + } + + private void loadSocialSpy() { + YamlConfiguration c = Core.getSettings().getSocialSpyConfig(); + this.socialSpyCmds = c.getStringList("commands"); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onServerCommand(ServerCommandEvent event) { + String[] split = event.getCommand().split(" "); + switch (split[0].toLowerCase()){ + case "restart": + case "stop": + event.setCancelled(true); + Core.getInstance().setRestarting(true); + if(Core.getSettings().getNumber() <= 0 || (split.length>1 && split[1].equalsIgnoreCase("force"))) { + Bukkit.shutdown(); + return; + } + shutdownSequence(); + return; + } + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent e) { + Player player = e.getPlayer(); + switch (e.getMessage()) { + case "/bankcraft deposit all": + case "/bc deposit all": + case "/bank deposit all": + player.sendMessage(Utils.f("&c/bankcraft deposit ")); + return; + default: + break; + } + String[] split = e.getMessage().replaceFirst("/", "").split(" "); + String cmd = split[0].toLowerCase(); + if (this.socialSpyCmds != null && this.socialSpyCmds.contains(cmd)){ + UserManager.getInstance().getUsers().stream().filter(user -> user.getPref(Pref.SOCIALSPY)).forEach(user -> { + Player p = Bukkit.getPlayer(user.getUUID()); + if (p != null){ + p.sendMessage(Lang.SS.f("&r" + player.getName() + ": " + e.getMessage())); + } + }); + } + switch (cmd) { + case "who": { + e.setCancelled(true); + player.sendMessage(Utils.f("&7Unknown command: \"&a" + e.getMessage() + "&7\".")); + return; + } + case "me": + e.setCancelled(true); + player.sendMessage(Utils.f("&7Unknown command: \"&a" + e.getMessage() + "&7\".")); + return; + case "buy": + case "donate": + case "purchase": + e.setCancelled(true); + player.performCommand("/store"); + return; + case "restart": + case "stop": + e.setCancelled(true); + if (!player.isOp()) { + player.sendMessage(Utils.f("&cYou do not have permission to execute this command!")); + return; + } + Core.getInstance().setRestarting(true); + if(Core.getSettings().getNumber() <= 0 || (split.length>1 && split[1].equalsIgnoreCase("force"))) { + Bukkit.shutdown(); + return; + } + shutdownSequence(); + return; + case "minecraft:tell": + case "minecraft:msg": + case "minecraft:w": + case "bukkit:tell": + case "bukkit:msg": + case "bukkit:w": + case "bukkit:version": + case "version": + case "ver": + case "about": + case "bukkit:me": + case "minecraft:me": + case "plugins": + case "pl": + case "bukkit:plugins": + case "bukkit:pl": + case "?": + case "bukkit:?": + case "bukkit:help": + case "minecraft:?": + case "save-on": + case "save-all": + e.setCancelled(true); + player.sendMessage(Utils.f("&cbit.ly/FreeCookiesOn" + Core.getSettings().getServer_GTM_shortName())); + return; + default: + if (this.isCmdRegistered(cmd)) + return; + e.getPlayer().sendMessage(Utils.f("&7Unknown command: \"&a" + e.getMessage() + "&7\".")); + e.setCancelled(true); + } + } + + @EventHandler + public void onTabComplete(PlayerChatTabCompleteEvent e) { + if (!e.getChatMessage().startsWith("/")) return; + String[] args = e.getChatMessage().split(" "); + if (args.length == 1 && args[0].length() < 5) e.getTabCompletions().clear(); + } + + private SimpleCommandMap getCommandMap(Server svr) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException { + if (svr.getPluginManager() instanceof SimplePluginManager) { + Field f = SimplePluginManager.class.getDeclaredField("commandMap"); + f.setAccessible(true); + return (SimpleCommandMap) f.get(svr.getPluginManager()); + } else { + return null; + } + } + + private void shutdownSequence(){ + Core.error("[Stop] Stop sequence started..."); + Core.error("[Stop] Blocking player requests to join..."); + new BukkitRunnable() { + int counter = 60; + @Override + public void run() { + if(counter<=0) { + for(Player player : Bukkit.getOnlinePlayers()) { + player.kickPlayer(Lang.ALERTS.f("&cThe server is restarting!")); + } + Core.error("[Stop] Players have been kicked, stopping server in 20 seconds."); + new BukkitRunnable() { + @Override + public void run() { + Bukkit.shutdown(); + } + }.runTaskLater(Core.getInstance(), 400); + cancel(); + return; + } + if(counter % 5 == 0){ + Core.error("[Stop] Kicking players in " + counter + " seconds"); + } + for(Player player : Bukkit.getOnlinePlayers()) { + player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(Lang.ALERTS.f("&6The server will stop in &4" + counter + "&6s"))); + } + counter--; + } + }.runTaskTimer(Core.getInstance(), 0,20); + } + + private boolean isCmdRegistered(String name) { + return this.cmdMap.getCommand(name) != null; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/Damage.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/Damage.java new file mode 100644 index 0000000..b67d8a4 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/Damage.java @@ -0,0 +1,30 @@ +package net.grandtheftmc.core.listeners; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageEvent; + +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserManager; + +public class Damage implements Listener { + + @EventHandler + public void entityDamageEvent(EntityDamageEvent event) { + + // ignore non player entities + if (!(event.getEntity() instanceof Player)){ + return; + } + + Player player = (Player) event.getEntity(); + + User user = UserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + if (user != null){ + if (user.isInTutorial()){ + event.setCancelled(true); + } + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/HopperComponent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/HopperComponent.java new file mode 100644 index 0000000..87617a8 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/HopperComponent.java @@ -0,0 +1,36 @@ +package net.grandtheftmc.core.listeners; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.Component; +import org.bukkit.Material; +import org.bukkit.entity.Item; +import org.bukkit.event.EventHandler; +import org.bukkit.event.inventory.InventoryPickupItemEvent; +import org.bukkit.event.inventory.InventoryType; + +/** + * Created by Luke Bingham on 26/08/2017. + */ +public class HopperComponent implements Component { + + @EventHandler + protected final void onHopperPickup(InventoryPickupItemEvent event) { + if(event.getInventory() == null && event.getInventory().getType() != InventoryType.HOPPER) return; + if(event.getItem() == null && (event.getItem().getItemStack().getType() != Material.DIAMOND_SWORD && event.getItem().getItemStack().getType() != Material.FLINT_AND_STEEL)) + return; + + Item item = event.getItem(); + + if(event.getItem().getItemStack().getType() == Material.DIAMOND_SWORD) { + if(item.getItemStack().getDurability() <= 751 || item.getItemStack().getDurability() >= 800) { + event.setCancelled(true); + return; + } + } + + if(event.getItem().getItemStack().getType() == Material.FLINT_AND_STEEL) { + event.setCancelled(true); + return; + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/HungerChange.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/HungerChange.java new file mode 100644 index 0000000..e2bd881 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/HungerChange.java @@ -0,0 +1,17 @@ +package net.grandtheftmc.core.listeners; + +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.FoodLevelChangeEvent; + +import net.grandtheftmc.core.Core; + +public class HungerChange implements Listener { + + @EventHandler + public void onHungerChange(FoodLevelChangeEvent e) { + if (Core.getSettings().stopHungerChange(e.getEntity().getWorld().getName())) { + e.setFoodLevel(20); + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/InventoryClick.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/InventoryClick.java new file mode 100644 index 0000000..ff266ae --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/InventoryClick.java @@ -0,0 +1,42 @@ +package net.grandtheftmc.core.listeners; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.users.User; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +public class InventoryClick implements Listener { + + @EventHandler + public void onClick(InventoryClickEvent e) { + Player player = (Player) e.getWhoClicked(); + Inventory inv = e.getInventory(); + if(inv != null && (inv.getType() == InventoryType.CHEST || + inv.getType() == InventoryType.ENDER_CHEST || + inv.getType().name().equals("SHULKER_BOX") || + inv.getType() == InventoryType.DISPENSER || + inv.getType() == InventoryType.DROPPER || + inv.getType() == InventoryType.HOPPER)) { + ItemStack selected = e.isShiftClick() ? e.getCurrentItem() : e.getCursor(); + if(selected != null && selected.getType().toString().contains("SHULKER_BOX")){ + e.setCancelled(true); + return; + } + } + /* if (!Core.getSettings().useEditMode()) { + return; + } + User u = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (u.hasEditMode()) { + if (e.isCancelled()) { + e.setCancelled(false); + } + }*/ + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/Join.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/Join.java new file mode 100644 index 0000000..dcaf23f --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/Join.java @@ -0,0 +1,177 @@ +package net.grandtheftmc.core.listeners; + +import java.sql.Connection; +import java.sql.SQLException; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.database.dao.MutexDAO; +import net.grandtheftmc.core.database.mutex.common.LoadUserTask; +import net.grandtheftmc.core.nametags.NametagManager; +import net.grandtheftmc.core.transaction.state.user.UserStateTransaction; +import net.grandtheftmc.core.users.Pref; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserDAO; +import net.grandtheftmc.core.users.UserManager; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.NMSUtil; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; + +public class Join implements Listener { + + /** + * Listens in on player join events. + *

+ * Note: This is LOW so that events can listen in BEFORE or AFTER this event + * is called since the player will be added to the container. + *

+ * + * @param event - the event + */ + @EventHandler(priority = EventPriority.LOW) + public void onJoin(PlayerJoinEvent event) { + + // grab event variables + Player player = event.getPlayer(); + + // create a new user + User user = new User(player.getUniqueId(), player.getName()); + + // NOTE: This is called on an async thread + new LoadUserTask(Core.getInstance(), user) { + + @Override + protected boolean onLoad() { + try (Connection conn = BaseDatabase.getInstance().getConnection()) { + + // execute a data check to create new entries if needed + user.dataCheck(); + + // load the user + user.onLoad(conn); + } + catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + @Override + protected void onLoadFailure() { + // Back to main thread + Bukkit.getScheduler().runTask(getPlugin(), () -> { + player.kickPlayer("[Core] Load failure; contact staff if this issue persists."); + + // TODO this is to reset mutex issues + Bukkit.getScheduler().runTaskAsynchronously(getPlugin(), () -> { + try (Connection conn = BaseDatabase.getInstance().getConnection()){ + MutexDAO.setUserMutex(conn, player.getUniqueId(), false); + } + catch(Exception e){ + e.printStackTrace(); + } + }); + }); + } + + @Override + protected void onLoadComplete() { + + // add to the container + UserManager.getInstance().addUser(user); + + try (Connection conn = BaseDatabase.getInstance().getConnection()){ + // check for user state transactions + UserStateTransaction.process(conn, getPlugin(), player, Core.getSettings().getType().getName(), Core.getSettings().getNumber()); + } + catch (Exception e){ + e.printStackTrace(); + } + + // Back to main thread + Bukkit.getScheduler().runTask(plugin, () -> { + + // can update name or other things on thread + // like teleport them + + // make sure still online + Player player = Bukkit.getPlayer(user.getUUID()); + if (player != null) { + + // bind bukkit player object to user object + user.setPerms(player); + + // update nametag + NametagManager.updateNametag(player); + NametagManager.updateNametagsTo(player, user); + + // update display name + user.updateDisplayName(player); + + if (user.dailyStreakExpired()) + player.sendMessage(Lang.REWARDS.f("&7Your Daily Reward Streak has expired! Claim it once every 24h to build up your streak!")); + else if (user.canClaimDailyReward()) + player.sendMessage(Lang.REWARDS.f("&7Your Daily Reward is waiting for you! Claim it once every 24h to build up your streak!")); + if (user.voteStreakExpired()) + player.sendMessage(Lang.VOTE.f("&7Your Vote Streak has expired! Vote once every 24h to build up your streak!")); + else if (user.getVoteRecord().getStreak() > 0 && user.canVoteStreak()) + player.sendMessage(Lang.VOTE.f("&7Remember to vote to raise your Vote Streak! Vote on all &e5 &7sites for maximum rewards! You currently have a &a&l" + user.getDoubleVoteChance() + "&a%&7 chance to get a Double Vote&7!")); + if (user.isSpecial() && user.canClaimMonthlyReward()) + player.sendMessage(Lang.REWARDS.f("&7Thank you for being a loyal supporter of " + Core.getSettings().getServer_GTM_shortName() + "! Your monthly reward of &e&l" + user.getUserRank().getMonthlyTokens() + " Tokens&7 is waiting for you!")); + + // if trial rank, let them know they can buy it + UserRank trial = user.getTrialRank(); + if (trial != null) { + player.sendMessage(Lang.RANKS.f("&7You are currently on the &a&lfree " + trial.getColoredNameBold() + "&7 trial! You can buy it permanently for &a$&l" + trial.getPrice() + "&7 at &a&l" + Core.getSettings().getStoreLink() + "&7!")); + } + + // if at least help op, set join time + if (user.isRank(UserRank.HELPOP)) { + user.setJoinTime(System.currentTimeMillis()); + } + + if (user.getPref(Pref.ANNOUNCEMENTS)) { + + // TODO this should be loaded during the loading of + // the user + // as its being called for each login anyways + ServerUtil.runTaskAsync(() -> { + if (UserDAO.isLastMonthsVoteWinner(player.getName())) { + Bukkit.getScheduler().runTask(getPlugin(), () -> { + player.sendMessage(Lang.VOTE.f("&7You have won store credit for being a top voter! Please visit the store to claim your prize!. (You can turn this notification off by toggling the annoucements pref)")); + }); + } + }); + } + } + }); + } + }; + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onJoinMonitor(PlayerJoinEvent e) { + + // grab event variables + Player p = e.getPlayer(); + + // send join title + NMSUtil.sendTabTitle(p, Core.getSettings().getDisplayName(), Utils.f("&aCheck out our site at &6&l" + Core.getSettings().getWebsiteLink() + "&a!")); + // set join message + e.setJoinMessage(Core.getSettings().getJoinLeaveMessagesEnabled() ? Utils.f(p.getDisplayName() + " &ejoined the game!") : null); + + // for all players online, show them this player + e.getPlayer().getWorld().getEntitiesByClass(Player.class).forEach(target -> e.getPlayer().showPlayer(target)); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/Leave.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/Leave.java new file mode 100644 index 0000000..706d746 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/Leave.java @@ -0,0 +1,96 @@ +package net.grandtheftmc.core.listeners; + +import java.sql.Connection; +import java.sql.SQLException; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerQuitEvent; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.database.dao.ServerStatsDAO; +import net.grandtheftmc.core.database.mutex.common.SaveUserTask; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserManager; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.Playtime; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.util.debug.Log; + +public class Leave implements Listener { + + /** + * Listens in on player quit events. + *

+ * Note: This is HIGH so that events can listen in BEFORE or AFTER this + * event is called since the player will be removed from the container. + *

+ * + * @param event - the event + */ + @EventHandler(priority = EventPriority.HIGH) + public void onLeave(PlayerQuitEvent event) { + + // grab event variables + Player p = event.getPlayer(); + + // update Move listener + Move.logout(p.getUniqueId()); + + // grab the user + User coreUser = UserManager.getInstance().getUser(p.getUniqueId()).orElse(null); + if (coreUser != null) { + + // if they are help op + if (coreUser.isRank(UserRank.HELPOP)) { + coreUser.setLeaveTime(System.currentTimeMillis()); + Long playtime = coreUser.getLeaveTime() - coreUser.getJoinTime(); + if (Playtime.playtime.containsKey(p.getName())) { + playtime = Playtime.playtime.get(p.getName()) + coreUser.getLeaveTime() - coreUser.getJoinTime(); + } + Playtime.playtime.put(p.getName(), playtime); + } + + // if quit messages are enabled + event.setQuitMessage(Core.getSettings().getJoinLeaveMessagesEnabled() ? Utils.f(p.getDisplayName() + " &eleft the game!") : null); + coreUser.removePerms(p); + + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + ServerStatsDAO.updatePlaytimeAndFirstlogin(connection, p, coreUser); + } + catch (SQLException ex) { + ex.printStackTrace(); + } + }); + } + + // REMOVE from local container and save + User removedUser = UserManager.getInstance().removeUser(p.getUniqueId()).orElse(null); + if (removedUser != null) { + + new SaveUserTask(Core.getInstance(), removedUser) { + @Override + protected boolean onSave() { + try (Connection conn = BaseDatabase.getInstance().getConnection()) { + removedUser.onSave(conn); + } + catch (SQLException e) { + e.printStackTrace(); + } + + return true; + } + + @Override + protected void onSaveFailure() { + Log.error("Core", "Unhandled exception while saving " + removedUser.getName()); + } + }; + } + } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/Login.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/Login.java new file mode 100644 index 0000000..2651207 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/Login.java @@ -0,0 +1,221 @@ +package net.grandtheftmc.core.listeners; + +import java.sql.Connection; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerPreLoginEvent; +import org.bukkit.event.player.PlayerLoginEvent; +import org.bukkit.plugin.Plugin; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.ProtocolManager; +import com.comphenix.protocol.events.ListenerPriority; +import com.comphenix.protocol.events.PacketAdapter; +import com.comphenix.protocol.events.PacketEvent; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserDAO; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.PluginAssociated; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.whitelist.WhitelistManager; +import net.grandtheftmc.core.whitelist.WhitelistedUser; + +public class Login implements PluginAssociated, Listener { + + /** The owning plugin */ + private Plugin plugin; + /** Maps uuid to user rank */ + private Map uuidToRank; + + /** + * Construct a new Login. + *

+ * This is a listener that handles login related events. + *

+ * + * @param plugin - the owning plugin + */ + public Login(Plugin plugin) { + this.plugin = plugin; + this.uuidToRank = new HashMap<>(); + + ProtocolManager manager = ProtocolLibrary.getProtocolManager(); + manager.addPacketListener(new PacketAdapter(Core.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Client.SETTINGS) { + @Override + public void onPacketReceiving(PacketEvent event) { + String locale = event.getPacket().getStrings().read(0); + User user = Core.getUserManager().getLoadedUser(event.getPlayer().getUniqueId()); + if (user == null) + return; + + if (user.getLanguage() != null && user.getLanguage().equals(locale)) + return; + user.setLanguage(locale); + } + }); + + // every 60 secs clear the cache map + Bukkit.getScheduler().runTaskTimerAsynchronously(getPlugin(), () -> { + uuidToRank.clear(); + }, 0, 20L * 60); + } + + /** + * Listens in on the async pre login event. + * + * @param event - the event + */ + @EventHandler(priority = EventPriority.LOW) + public void onAsyncPlayerPreLogin(AsyncPlayerPreLoginEvent event) { + + // if the server is restarting + if (Core.getInstance().isRestarting()) { + event.setKickMessage(Lang.ALERTS.f("&cThe server is restarting!")); + event.disallow(org.bukkit.event.player.AsyncPlayerPreLoginEvent.Result.KICK_OTHER, "&cThe server is currently restarting!"); + return; + } + + // if the core plugin isn't enabled + if (!Core.getInstance().isEnabled()) { + event.setKickMessage(Lang.ALERTS.f("&cWaiting on core...")); + event.disallow(org.bukkit.event.player.AsyncPlayerPreLoginEvent.Result.KICK_OTHER, "&cWaiting on core..."); + return; + } + + // grab event variables + UUID uuid = event.getUniqueId(); + + // if required rank to join + if (Core.getSettings().needRankToJoin()) { + + // find the required rank to join + UserRank requiredRank = Core.getSettings().getRankToJoin(); + UserRank userRank = UserRank.DEFAULT; + + // if cached rank + if (uuidToRank.containsKey(uuid)) { + userRank = uuidToRank.get(uuid); + } + // fetch from database + else { + + // grab the user rank + try (Connection conn = BaseDatabase.getInstance().getConnection()) { + userRank = UserDAO.getHighestRank(conn, uuid); + } + catch (Exception e) { + e.printStackTrace(); + } + + // add to cache + uuidToRank.put(uuid, userRank); + } + + // if they do not have the required rank OR HIGHER + if (!userRank.isHigherThan(requiredRank) && userRank != requiredRank) { + event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_WHITELIST, Utils.f("&cSorry, this game is for " + requiredRank.getColoredNameBold() + " &c and up only! Go to " + Core.getSettings().getStoreLink() + " to purchase a rank!")); + } + } + } + + /** + * Listens in the player login event. + * + * @param event - the event + */ + @EventHandler + public void onPlayerLogin(PlayerLoginEvent event) { + + // grab event variables + Player player = event.getPlayer(); + + if (Core.getInstance().isRestarting()) { + event.setKickMessage(Lang.ALERTS.f("&cThe server is restarting!")); + event.setResult(PlayerLoginEvent.Result.KICK_OTHER); + return; + } + + // if the core plugin isn't enabled + if (!Core.getInstance().isEnabled()) { + event.setKickMessage(Lang.ALERTS.f("&cWaiting on core...")); + event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "&cWaiting on core..."); + return; + } + + // if whitelist is enabled + WhitelistManager wm = Core.getWhitelistManager(); + if (wm.isEnabled()) { + + // grab the specified user + WhitelistedUser wu = wm.getWhitelistedUser(player.getUniqueId()); + + // if not found, try by name + if (wu == null){ + wu = wm.getWhitelistedUser(player.getName()); + } + + // if we found the user, set the name/uuid + if (wu != null) { + wu.setName(player.getName()); + wu.setUuid(player.getUniqueId()); + + // allow them to join + return; + } + + // if whitelist manager exists and there is no bypass rank specified + if (wm != null && wm.getBypassRank() == null) { + event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, Utils.f("&cYou are not whitelisted on this server!")); + } + else { + + // find the required rank to join from whitelist + UserRank requiredRank = wm.getBypassRank(); + UserRank userRank = UserRank.DEFAULT; + + // if cached rank + if (uuidToRank.containsKey(player.getUniqueId())) { + userRank = uuidToRank.get(player.getUniqueId()); + } + // fetch from database + else { + + // grab the user rank + try (Connection conn = BaseDatabase.getInstance().getConnection()) { + userRank = UserDAO.getHighestRank(conn, player.getUniqueId()); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + // if higher than whitelist rank + if (userRank.hasRank(requiredRank)) { + event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, Utils.f("&cSorry, this game is for " + wm.getBypassRank().getColoredNameBold() + "&c and up only! Go to " + Core.getSettings().getStoreLink() + " to purchase a rank!")); + } + } + } + } + + /** + * Get the owning plugin for this listener. + * + * @return The owning plugin for this listener. + */ + @Override + public Plugin getPlugin() { + return plugin; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/Move.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/Move.java new file mode 100644 index 0000000..c504bb0 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/Move.java @@ -0,0 +1,169 @@ +package net.grandtheftmc.core.listeners; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.util.Vector; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.data.CompactLoc; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; + +public class Move implements Listener { + + //Used to compare locations for AFKers + private static Map playerLocations = new HashMap<>(); + + //Remove player the AFK tracker. + public static void logout(UUID u) { + playerLocations.remove(u); + } + + public Move(){ + //Run every 30 seconds + Bukkit.getScheduler().runTaskTimer(Core.getInstance(), () -> { + for (Player p : Bukkit.getOnlinePlayers()) { + CompactLoc last = playerLocations.get(p.getUniqueId()); + + if (last == null) { + //Register them + playerLocations.put(p.getUniqueId(), new CompactLoc(p.getLocation())); + } else { + //Compare the difference + CompactLoc current = new CompactLoc(p.getLocation()); + + if (current.differs(last)) { + //we can try to update the afk list as they have moved. + User u = Core.getUserManager().getLoadedUser(p.getUniqueId()); + if(!u.hasTrialRank() && !u.isRank(UserRank.VIP)){ + Core.getAntiAFK().refreshAfk(p); + } + } + + playerLocations.put(p.getUniqueId(), current); + } + } + }, 0L, 20 * 30); + } + + //Store a list of players opening crates who shouldn't be affected + private static Set excludeCrate = new HashSet<>(); + //Store a list of active crate openings to scan, use a list because it's quicker to iterate + private static List activeCrates = new ArrayList<>(); + + public static void setOpening(UUID u, Location l) { + excludeCrate.add(u); + activeCrates.add(l); + activeWorldHashcodes.add(l.getWorld().hashCode()); + //Bukkit.broadcastMessage(ChatColor.GREEN + Bukkit.getPlayer(u).getName() + " opening crate, added to exclusion list."); + } + + public static void stopOpening(UUID u, Location l) { + excludeCrate.remove(u); + activeCrates.remove(l); + + //do we need to remove it from the active hashset? + for (Location acl : activeCrates) { + if (acl.getWorld().hashCode() == l.getWorld().hashCode()) { + //there is stil lan active crate with this world stored so we can't remove it + return; + } + } + + activeWorldHashcodes.remove(l.getWorld().hashCode()); + //Bukkit.broadcastMessage(ChatColor.RED + Bukkit.getPlayer(u).getName() + " STOPPED opening crate, REMOVED from exclusion list."); + } + + //All active crates are present in this hashset + private static Set activeWorldHashcodes = new HashSet<>(); + + @EventHandler + public void onMoveOptimised(PlayerMoveEvent e) { + Location to = e.getTo(), from = e.getFrom(); + + if (to.getBlockX() == from.getBlockX() && to.getBlockY() == from.getBlockY() && to.getBlockZ() == from.getBlockZ()) { + //Player has not moved block + return; + } + + Player player = e.getPlayer(); + //Hashmap lookup so this is fast enough. + User u = Core.getUserManager().getLoadedUser(player.getUniqueId()); + + //Better ways to refresh afk than on move, this has been moved to a scheduler task above ^. + //if (!u.hasTrialRank() && !u.isRank(UserRank.VIP)) Core.getAntiAFK().refreshAfk(player); + + if (u != null && u.isInTutorial()) { + e.setTo(e.getFrom()); + //Don't allow them to move. + return; + } + + //player.sendMessage("HC (spawn/curWorld) = (" + spawnWorldHashCode + "/" + player.getWorld().hashCode() + ")"); + + if (activeWorldHashcodes.isEmpty() || !activeWorldHashcodes.contains(player.getWorld().hashCode()) || activeCrates.isEmpty()) { + //Comparing integer hashcodes is faster than strings. + //Also return if no crates are being opened. + //Crates only opened in spawn world, so if they dont match exit + return; + } + + //Crates must not be empty, a crate is being opened. Check if we can exclude the player first + if (excludeCrate.contains(player.getUniqueId())) { + //player.sendMessage("You are on the exclusion list, not checked!"); + return; + } + + //Otherwise do a scan + for (Location l : activeCrates) { + if (player.getLocation().getWorld().hashCode() != l.getWorld().hashCode()) { + //Only compare locations in the same world. + //player.sendMessage("Not in same world as crate."); + continue; + } + + /* + Now remember, that for most players they won't actually be near the crates that are being opened. + + So we can speed up the comparison by doing some quick eliminations as calculating the distance is expensive. + + Do quick checks on the x, y, z to determine if the player is nearby. + */ + if (Math.abs(l.getBlockX() - player.getLocation().getBlockX()) >= 6 || + Math.abs(l.getBlockZ() - player.getLocation().getBlockZ()) >= 6 || + Math.abs(l.getBlockY() - player.getLocation().getBlockY()) >= 6) { + //Player can't be within 5 units of the crate if distance between two is >= 5. + //Check y first as this is the least likely to differ. + //player.sendMessage("Outside of active crate range."); + return; + } + + if (player.getLocation().distance(l) < 7) { + //They must be in range, so lets push them back + //Removed .clone() it's unnecessary. + //player.sendMessage("THROWING AWAY"); + Vector ce = l.toVector(); + Vector toThrow = player.getLocation().toVector(); + double x = toThrow.getX() - ce.getX(); + double z = toThrow.getZ() - ce.getZ(); + //Multiplication by 1 achieves nothing so remove that also. + Vector v = new Vector(x, 1, z).normalize(); + player.setVelocity(v); + } + + } + + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/PetListener.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/PetListener.java new file mode 100644 index 0000000..3f85853 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/PetListener.java @@ -0,0 +1,35 @@ +package net.grandtheftmc.core.listeners; + +/*import com.dsh105.echopet.api.EchoPetAPI; +import com.dsh105.echopet.compat.api.entity.IPet; +import com.dsh105.echopet.compat.api.event.PetInteractEvent; +import net.grandtheftmc.core.Core; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority;*/ +import org.bukkit.event.Listener; + +/** + * Created by Liam on 11/09/2016. + */ +public class PetListener implements Listener { + + /*@EventHandler(priority = EventPriority.LOW) + public void onPetInteract(PetInteractEvent e) { + Player player = e.getPlayer(); + IPet pet = e.getPet(); + PetInteractEvent.Action i = e.getAction(); + if (i == PetInteractEvent.Action.LEFT_CLICK) { + if (pet.getOwner().equals(player)) { + pet.ownerRidePet(true); + e.setCancelled(true); + } else e.setCancelled(!Core.getSettings().isPetsVulnerable()); + } else if (i == PetInteractEvent.Action.RIGHT_CLICK) { + if (!pet.getOwner().equals(player)) return; + e.setCancelled(true); + if (player.isSneaking()) pet.ownerRidePet(true); + else EchoPetAPI.getAPI().openPetDataMenu(player, false); + } + }*/ + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/PlaywireRecieve.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/PlaywireRecieve.java new file mode 100644 index 0000000..8de3afd --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/PlaywireRecieve.java @@ -0,0 +1,55 @@ +package net.grandtheftmc.core.listeners; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.playwire.events.AsyncPlaywireRecieveEvent; +import net.grandtheftmc.core.users.User; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.Listener; + +import java.util.UUID; + +/** + * Created by Timothy Lampen on 2017-12-06. + */ +public class PlaywireRecieve implements Listener { + + /** + * Disabled, done through command instead. + */ + //@EventHandler + public void onRecieve(AsyncPlaywireRecieveEvent event){ + UUID uuid = event.getUUID(); + if(Bukkit.getPlayer(uuid)==null) + return;//since this event would trigger ALL cores on ALL servers, a listener should only give rewards to people on the one server. + Player player = Bukkit.getPlayer(uuid); + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + + switch (event.getType()) { + case COUNTED: {//when the player has watched the video + user.setCouponCredits(user.getCouponCredits()+2); + player.sendMessage(Lang.REWARDS.f("&7Thanks for watching the ad! Here are &a2 &7coupon credits!")); + break; + } + case UNCOUNTED: {//when the player has watched too many videos in a certain time limit (not set by us, set by playwire) + break; + } + case BLOCKED: {//when the player blocks an ad with ad block + break; + } + case UNFILLED: {//when there is no ad to show the player + break; + } + case PING: {//when the playwire server is pinged + break; + } + case CONFIRM_SUBSCRIPTION: {//when the playwire channel is subscribed to (onEnable) + break; + } + case WELCOME: {//when the player opens the webpage (a guess) + break; + } + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/Save.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/Save.java new file mode 100644 index 0000000..af018f0 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/Save.java @@ -0,0 +1,17 @@ +package net.grandtheftmc.core.listeners; + +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.events.ServerSaveEvent; +import net.grandtheftmc.core.users.UserManager; + +public class Save implements Listener { + + @EventHandler + public void serverSaveEvent(ServerSaveEvent event) { + Core.getInstance().save(false); + UserManager.getInstance().getUsers().forEach(user -> user.updateAchievements()); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/SignChange.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/SignChange.java new file mode 100644 index 0000000..744ef35 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/SignChange.java @@ -0,0 +1,41 @@ +package net.grandtheftmc.core.listeners; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.SignChangeEvent; + +import java.util.UUID; + +public class SignChange implements Listener { + + @EventHandler + public void onSignChange(SignChangeEvent e) { + Player player = e.getPlayer(); + UUID uuid = player.getUniqueId(); + User u = Core.getUserManager().getLoadedUser(uuid); + if (Core.getWorldManager().usesEditMode(player.getWorld().getName()) && !u.hasEditMode()) { + e.setCancelled(true); + return; + } + if (u.isSpecial()) + for (int i = 0; i < 4; i++) { + e.setLine(i, Utils.f(e.getLine(i))); + } + /* + if (e.getBlock().getType() != Material.WALL_SIGN) return; + String line = ChatColor.stripColor(e.getLine(0)); + if (!line.startsWith("[") || !line.endsWith("]")) return; + String serverName = ChatColor.stripColor(e.getLine(0)).replace("[", "").replace("]", "").toLowerCase(); + ServerManager sm = Core.getServerManager(); + Server server = sm.getServer(serverName); + if (server == null) { + server = new Server(serverName, null, -1, null, -1, true, 0, 0, null, null, 0, null, Collections.singletonList(e.getBlock().getLocation())); + sm.getServers().add(server); + } else server.getJoinSigns().add(e.getBlock().getLocation()); + e.getPlayer().sendMessage(Utils.f("You added a join sign for server " + server.getName() + '.'));*/ + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/SwapHandItems.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/SwapHandItems.java new file mode 100644 index 0000000..a15bc03 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/SwapHandItems.java @@ -0,0 +1,20 @@ +package net.grandtheftmc.core.listeners; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.events.PlayerFActionEvent; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerSwapHandItemsEvent; + +public class SwapHandItems implements Listener { + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = false) + public void onPlayerSwapHandItems(PlayerSwapHandItemsEvent event) { + Player player = event.getPlayer(); + PlayerFActionEvent playerFActionEvent = new PlayerFActionEvent(player); + Core.getInstance().getServer().getPluginManager().callEvent(playerFActionEvent); + if (playerFActionEvent.isCancelled()) event.setCancelled(true); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/Teleport.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/Teleport.java new file mode 100644 index 0000000..d30e057 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/Teleport.java @@ -0,0 +1,112 @@ +package net.grandtheftmc.core.listeners; + +import java.util.Objects; + +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerTeleportEvent; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.events.PlayerSwitchWorldEvent; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserManager; +import net.grandtheftmc.core.users.UserRank; + +public class Teleport implements Listener { + + + @EventHandler + public void onTeleport(PlayerTeleportEvent event) { + + // grab event variables + World fromWorld = event.getFrom().getWorld(); + World toWorld = event.getTo().getWorld(); + + if (!Objects.equals(fromWorld.getName(), toWorld.getName())) { + PlayerSwitchWorldEvent e = new PlayerSwitchWorldEvent(event.getPlayer(), event.getFrom(), event.getTo(), Core.getWorldManager().getWorldConfig(event.getTo().getWorld().getName())); + switch (e.getToWorldConfig().getType()) { + case USERRANK: + + // grab the user + User user = UserManager.getInstance().getUser(event.getPlayer().getUniqueId()).orElse(null); + if (user != null){ + UserRank requiredRank = UserRank.getUserRank(e.getToWorldConfig().getRestricted()); + + if (!user.isRank(requiredRank)){ + event.setCancelled(true); + } + } + + break; + case RESTRICTED: + e.setCancelled(true); + break; + default: + break; + } + Bukkit.getPluginManager().callEvent(e); + if (e.isCancelled()) event.setCancelled(true); + } + if (event.getCause() == PlayerTeleportEvent.TeleportCause.SPECTATE) { + event.setCancelled(true); + } + } + + /* + * // Try increasing this. May be dependent on lag. private final int + * TELEPORT_FIX_DELAY = 15; // ticks + * + * @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + * public void onPlayerTeleport(PlayerTeleportEvent event) { if + * (!Core.getSettings().getUseTeleportFix()) return; + * + * final Player player = event.getPlayer(); final int visibleDistance = + * Bukkit.getServer().getViewDistance() * 16; + * Bukkit.getScheduler().scheduleSyncDelayedTask(Core.getInstance(), new + * Runnable() { + * + * @Override public void run() { updateEntities(getPlayersWithin(player, + * visibleDistance)); } }, TELEPORT_FIX_DELAY); } + * + * public void updateEntities(List observers) { // Refresh every + * single player for (Player player : observers) updateEntity(player, + * observers); + * + * } + * + * public void updateEntity(Entity entity, List observers) { + * + * World world = entity.getWorld(); WorldServer worldServer = + * ReflectionAPI.getHandle(world); + * + * EntityTracker tracker = worldServer.tracker; EntityTrackerEntry entry = + * (EntityTrackerEntry) tracker.trackedEntities.get(entity.getEntityId()); + * + * List nmsPlayers = getNmsPlayers(observers); + * + * // Force Minecraft to resend packets to the affected clients + * entry.trackedPlayers.removeAll(nmsPlayers); + * entry.scanPlayers(nmsPlayers); } + * + * private List getNmsPlayers(List players) { + * List nsmPlayers = new ArrayList(); + * + * for (Player bukkitPlayer : players) { CraftPlayer craftPlayer = + * (CraftPlayer) bukkitPlayer; nsmPlayers.add(craftPlayer.getHandle()); } + * + * return nsmPlayers; } + * + * private List getPlayersWithin(Player player, int distance) { + * List res = new ArrayList(); int d2 = distance * distance; + * + * for (Player p : Bukkit.getOnlinePlayers()) { if (p.getWorld() == + * player.getWorld() && + * p.getLocation().distanceSquared(player.getLocation()) <= d2) { + * res.add(p); } } + * + * return res; } + */ + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/UpdateListener.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/UpdateListener.java new file mode 100644 index 0000000..6f1635c --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/UpdateListener.java @@ -0,0 +1,7 @@ +package net.grandtheftmc.core.listeners; + +/** + * Created by Liam on 16/10/2016. + */ +public class UpdateListener { +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/UserStateTransactionListener.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/UserStateTransactionListener.java new file mode 100644 index 0000000..6f0d85d --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/UserStateTransactionListener.java @@ -0,0 +1,83 @@ +package net.grandtheftmc.core.listeners; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.plugin.Plugin; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.currency.Currency; +import net.grandtheftmc.core.currency.component.CurrencySource; +import net.grandtheftmc.core.transaction.state.user.UserStateTransactionEvent; +import net.grandtheftmc.core.users.Pref; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserManager; +import net.grandtheftmc.core.util.PluginAssociated; +import net.grandtheftmc.core.util.json.JSONParser; + +public class UserStateTransactionListener implements Listener, PluginAssociated { + + /** The owning plugin */ + private final Plugin plugin; + + /** + * Create a UserStateTransactionListener that will listen and handle all user state transaction events. + * + * @param plugin - the owning plugin + */ + public UserStateTransactionListener(Plugin plugin){ + this.plugin = plugin; + } + + /** + * Listens in on user state transaction events. + * + * @param event - the event + */ + @EventHandler + public void onUserStateTransaction(UserStateTransactionEvent event){ + + Player player = event.getPlayer(); + JSONParser parser = new JSONParser(event.getTransaction().getPayload()); + + // get the type of the payload + if (parser.hasKey("type")){ + String type = parser.getString("type"); + + switch(type.toLowerCase()){ + case "currency": + Currency curr = Currency.fromID(parser.getString("currency")).orElse(null); + int amount = parser.getInt("amount"); + + if (curr != null && amount != 0){ + User coreUser = UserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + if (coreUser != null){ + + // custom source unless vote token + CurrencySource source = CurrencySource.CUSTOM; + if (curr == Currency.VOTE_TOKEN){ + source = CurrencySource.VOTE; + } + + int result = coreUser.getPurse().deposit(source, curr, amount); + event.setProcessed(true); + + // if autoclaim votes + if (curr == Currency.VOTE_TOKEN && coreUser.getPref(Pref.AUTO_CLAIM_VOTE_REWARD)){ + Core.getVoteManager().spendAllVotes(player, coreUser); + } + } + } + break; + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public Plugin getPlugin() { + return plugin; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/WeatherChange.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/WeatherChange.java new file mode 100644 index 0000000..d0505a8 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/listeners/WeatherChange.java @@ -0,0 +1,19 @@ +package net.grandtheftmc.core.listeners; + +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.weather.WeatherChangeEvent; + +import net.grandtheftmc.core.Core; + +public class WeatherChange implements Listener { + @EventHandler + public void onWeatherChange(WeatherChangeEvent e) { + if (Core.getSettings().stopWeatherChange(e.getWorld().getName())) { + if (e.toWeatherState()) { + e.setCancelled(true); + } + } + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/menus/Menu.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/menus/Menu.java new file mode 100644 index 0000000..6ec2e6d --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/menus/Menu.java @@ -0,0 +1,55 @@ +package net.grandtheftmc.core.menus; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.Listener; +import org.bukkit.inventory.Inventory; + +import net.grandtheftmc.core.util.Utils; + +public class Menu implements Listener { + + private final String name; + private final String displayName; + private final int size; + private Inventory inventory; + + public Menu(String name, int size, String displayName) { + this.name = name; + this.displayName = displayName; + this.size = size; + } + + public String getName() { + return this.name; + } + + public String getDisplayName() { + return this.displayName; + } + + public int getSize() { + return this.size; + } + + public void openFor(Player player) { + MenuOpenEvent event = new MenuOpenEvent(player, this); + Bukkit.getPluginManager().callEvent(event); + if(!event.isCancelled()) { + Inventory inv = Bukkit.createInventory(null, size, Utils.f(this.displayName)); + inv.setContents(event.getContents()); + player.openInventory(inv); + this.inventory = inv; + } + } + + public Inventory getInventory() { + return this.inventory; + } + + public void openFor(Player... p) { + for (Player player : p) { + this.openFor(player); + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/menus/MenuClickEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/menus/MenuClickEvent.java new file mode 100644 index 0000000..d95c813 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/menus/MenuClickEvent.java @@ -0,0 +1,62 @@ +package net.grandtheftmc.core.menus; + + +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +public class MenuClickEvent extends PlayerEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final Menu menu; + private final Inventory inv; + private final int slot; + private final ItemStack item; + private final InventoryClickEvent event; + + public MenuClickEvent(Player player, Menu menu, Inventory inv, int slot, ItemStack item, InventoryClickEvent event) { + super(player); + this.menu = menu; + this.inv = inv; + this.slot = slot; + this.item = item; + this.event = event; + } + + public Menu getMenu() { + return this.menu; + } + + public int getSlot() { + return this.slot; + } + + public ItemStack getItem() { + return this.item; + } + + public Inventory getInv() { + return this.inv; + } + + public InventoryClickEvent getInventoryClickEvent() { + return this.event; + } + + public ClickType getClickType() { + return this.event.getClick(); + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/menus/MenuCloseEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/menus/MenuCloseEvent.java new file mode 100644 index 0000000..07b01b9 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/menus/MenuCloseEvent.java @@ -0,0 +1,29 @@ +package net.grandtheftmc.core.menus; + +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; + +public class MenuCloseEvent extends PlayerEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final Menu menu; + + public MenuCloseEvent(Player player, Menu menu) { + super(player); + this.menu = menu; + } + + public Menu getMenu() { + return this.menu; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/menus/MenuListener.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/menus/MenuListener.java new file mode 100644 index 0000000..210e418 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/menus/MenuListener.java @@ -0,0 +1,1561 @@ +package net.grandtheftmc.core.menus; + +import java.math.RoundingMode; +import java.text.DecimalFormat; +import java.time.YearMonth; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.UUID; +import java.util.stream.Collectors; + +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; + +import net.grandtheftmc.ServerTypeId; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.database.dao.VoteDAO; +import net.grandtheftmc.core.giftcard.GiftcardAPI; +import net.grandtheftmc.core.nametags.NametagManager; +import net.grandtheftmc.core.playwire.PlaywireManager; +import net.grandtheftmc.core.servers.Server; +import net.grandtheftmc.core.servers.ServerManager; +import net.grandtheftmc.core.servers.ServerType; +import net.grandtheftmc.core.users.Pref; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.users.eventtag.EventTag; +import net.grandtheftmc.core.users.eventtag.EventTagDAO; +import net.grandtheftmc.core.users.eventtag.TagVisibility; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.voting.Reward; +import net.grandtheftmc.core.voting.RewardPack; +import net.grandtheftmc.core.voting.ShopItem; +import net.grandtheftmc.core.voting.VoteManager; +import net.grandtheftmc.core.voting.VoteReward; +import net.grandtheftmc.core.voting.crates.Crate; +import net.grandtheftmc.core.voting.crates.CrateReward; +import net.grandtheftmc.jedis.JedisChannel; +import net.grandtheftmc.jedis.JedisModule; +import net.grandtheftmc.jedis.message.ServerQueueMessage; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.TextComponent; + +@SuppressWarnings("NestedSwitchStatement") +public class MenuListener implements Listener { + + @EventHandler + public void onOpenMenu(MenuOpenEvent e) { + Menu menu = e.getMenu(); + Player player = e.getPlayer(); + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); +// CosmeticType cosmeticType = CosmeticType.getType(menu.getName()); + /*if (Core.getSettings().loadCosmetics() && cosmeticType != null && cosmeticType.isEnabled(Core.getSettings().getType())) { + this.setPhoneDefaults(e); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + List cosmetics = cosmeticType.getCosmetics(user); + for (int i = 0; i < slots.length && i < cosmetics.size(); i++) { + Cosmetic cos = cosmetics.get(i); + e.setItem(slots[i], cos.getMenuItem(user)); + } + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the cosmetics menu!")); + e.setItem(49, Utils.createItem(cosmeticType.getMaterial(), "&6&lCosmetics: " + cosmeticType.getDisplayName(), "&7Page 1")); + if (cosmetics.size() > 20) + e.setItem(50, Utils.createItem(Material.ARROW, "&6&lNext Page", "&7Page 2")); + e.setItem(51, Utils.createItem(Material.WEB, "&c&lRemove Cosmetic", "&7Click to remove your current " + cosmeticType.toString().charAt(0) + cosmeticType.toString().substring(1).toLowerCase())); + return; + }*/ + switch (menu.getName()) { + case "freecoupons": { + this.setPhoneDefaults(e); + DecimalFormat df = new DecimalFormat("#.##"); + df.setRoundingMode(RoundingMode.FLOOR); + ItemStack is = new ItemStack(Material.PAPER); + is.addUnsafeEnchantment(Enchantment.ARROW_DAMAGE, 1); + ItemMeta im = is.getItemMeta(); + im.addItemFlags(ItemFlag.HIDE_ENCHANTS); + im.setDisplayName(ChatColor.translateAlternateColorCodes('&', "&6Your Ad Credits:&b " + user.getCouponCredits())); + im.setLore(Arrays.asList(ChatColor.translateAlternateColorCodes('&', "&7Click to get the credit link"))); + is.setItemMeta(im); + + e.setItem(13, is); + e.setItem(21, Utils.createItem(Material.GOLD_NUGGET, "&6Convert &b50 &6Credits:", "&a$0.10")); + e.setItem(22, Utils.createItem(Material.GOLD_INGOT, "&6Convert &b100 &6Credits:", "&a$0.20")); + e.setItem(23, Utils.createItem(Material.GOLD_BLOCK, "&6Convert &b500 &6Credits:", "&a$1.00")); + e.setItem(31, Utils.createItem(Material.DIAMOND, "&6Convert &bAll &6Credits:", "&a$" + (df.format(user.getCouponCredits()/500.0)))); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Click to return to the rewards menu!")); + break; + } + case "chooseeventtag": { + this.setPhoneDefaults(e); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24,29,30,31,32,33}; + int selector = 0; + for(EventTag t : EventTag.values()) { + TagVisibility v = EventTagDAO.getTagVisibility(t); + if(v==TagVisibility.NO_ONE) + continue; + boolean unlocked = user.getUnlockedTags().contains(t); + if(v==TagVisibility.THOSE_WHO_HAVE_IT_UNLOCKED && !unlocked) + continue; + + int slot = slots[selector]; + boolean activated = user.getEquipedTag() == t; + if(unlocked) { + e.setItem(slot, Utils.createItem(Material.NAME_TAG, t.getBoldName(), "&6&lStatus: " + (activated ? "&a&lOn" : "&c&lOff"))); + } + else + e.setItem(slot, Utils.createItem(Material.NAME_TAG, t.getBoldName(), "&6&lStatus: &4&lLOCKED")); + selector++; + } + + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Click to return to your account!")); + return; + } + case "topvoters": { + this.setPhoneDefaults(e); + + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Click to return to the vote menu!")); + + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24}; + + ServerUtil.runTaskAsync(() -> { + VoteDAO.VoteUser[] topVoters = Core.getInstance().getVoteManager().getTopVoters(); + if (topVoters == null) return; + + List items = new ArrayList<>(); + + for (VoteDAO.VoteUser voteUser : topVoters) { + ItemStack is = Utils.createItem(Material.SKULL_ITEM, 3, "&7#&6" + voteUser.getPossition() + "&7 " + voteUser.getName()); + SkullMeta im = (SkullMeta) is.getItemMeta(); + im.setOwner(voteUser.getName()); + List lore = new ArrayList<>(); + lore.add(Utils.f("&6Votes: &a&l" + voteUser.getVotes())); + String reward = null; + switch (voteUser.getPossition()) { + case 1: + reward = "&6Expected Prize: &a$&l100 Store Credit"; + break; + case 2: + case 3: + reward = "&6Expected Prize: &a$&l50 Store Credit"; + break; + case 4: + case 5: + reward = "&6Expected Prize: &a$&l25 Store Credit"; + break; + } + if (reward != null) lore.add(Utils.f(reward)); + im.setLore(lore); + is.setItemMeta(im); + items.add(is); + } + + ServerUtil.runTask(() -> { + for (int i = 0; i < items.size(); i++) + e.getMenu().getInventory().setItem(slots[i], items.get(i)); + + player.updateInventory(); + }); + }); + +// new BukkitRunnable() { +// @Override +// public void run() { +// try { +// ResultSet rs = Core.sql.prepareStatement("SELECT * FROM votes ORDER BY `votes`.`monthlyVotes` DESC LIMIT 10;").executeQuery(); +// int counter = 1; +// List items = new ArrayList<>(); +// while (rs.next()) { +// String name = rs.getString("name"); +// int votes = rs.getInt("monthlyVotes"); +// ItemStack is = Utils.createItem(Material.SKULL_ITEM, 3, "&7#&6" + counter + "&7 " + name); +// SkullMeta im = (SkullMeta)is.getItemMeta(); +// im.setOwner(name); +// List lore = new ArrayList<>(); +// lore.add(Utils.f("&6Votes: &a&l" + votes)); +// String reward = null; +// switch (counter) { +// case 1: +// reward = "&6Expected Prize: &a$&l100 Store Credit"; +// break; +// case 2: +// case 3: +// reward = "&6Expected Prize: &a$&l50 Store Credit"; +// break; +// case 4: +// case 5: +// reward = "&6Expected Prize: &a$&l25 Store Credit"; +// break; +// } +// if(reward!=null) { +// lore.add(Utils.f(reward)); +// } +// im.setLore(lore); +// is.setItemMeta(im); +// items.add(is); +// counter++; +// } +// new BukkitRunnable() { +// @Override +// public void run() { +// for(int i = 0; i < items.size(); i++) { +// e.getMenu().getInventory().setItem(slots[i], items.get(i)); +// } +// player.updateInventory(); +// } +// }.runTask(Core.getInstance()); +// } catch (SQLException e1) { +// e1.printStackTrace(); +// } +// } +// }.runTaskAsynchronously(Core.getInstance()); + } + case "confirmcratereward": { + Crate crate = user.getSelectedCrate(); + CrateReward reward = user.getConfirmingCrateReward(); + if (crate == null || reward == null) { + player.closeInventory(); + return; + } + List confirmLore = new ArrayList<>(reward.getRewardPack().get().stream().map(Reward::getDisplayName).collect(Collectors.toList())); + this.setConfirmDefaults(e, "&a&lClick to accept this reward:", "&c&lClick to cancel this reward and get refunded: &9&l" + crate.getCrateStars().getStars() + " crowbars&c&l.", confirmLore, null); + return; + } + case "confirmexpensivecrate": + Crate crate = user.getSelectedCrate(); + this.setConfirmDefaults(e, "&a&lClick to spend &9&l" + crate.getCrateStars().getCrowbars() + " Crowbar" + (crate.getCrateStars().getCrowbars() == 1 ? "" : "s") + "&a&l to open this " + crate.getCrateStars().getDisplayName() + "&7.", "&c&lCancel opening this " + crate.getCrateStars().getType() + "&7."); + return; + case "cosmetics": + return; + /*if (!Core.getSettings().loadCosmetics()) return; + this.setPhoneDefaults(e); + List types = Arrays.stream(new CosmeticType[]{CosmeticType.BLOCK, CosmeticType.HAT, CosmeticType.MORPH, CosmeticType.PARTICLE, CosmeticType.PET}).filter(t -> t.isEnabled(Core.getSettings().getType())).collect(Collectors.toList()); + int[] slots = types.size() > 6 ? new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42} : new int[]{11, 13, 15, 29, 31, 33}; + for (int i = 0; i < types.size(); i++) { + CosmeticType t = types.get(i); + e.setItem(slots[i], Utils.createItem(t.getMaterial(), t.getColoredDisplayName(), t.getDescription())); + } + e.setItem(49, Utils.createItem(Material.ENDER_CHEST, "&6&lCosmetics", "&7Click to select a cosmetic type!")); + //e.setItem(51, Utils.createItem(Material.NAME_TAG, "&a&lNametags", "&7Click to apply nametags!")); + return;*/ + case "buycosmetic": + return; + /*Cosmetic c = user.getBuyingCosmetic(); + if (c == null || user.hasCosmetic(c) || c.getTokens() < 0 || !user.hasTokens(c.getTokens())) return; + this.setConfirmDefaults(e, "&a&lBuy " + c.getColoredDisplayName() + ' ' + c.getType().toString().charAt(0) + c.getType().toString().substring(1).toLowerCase() + " &a&lfor &e&l" + c.getTokens() + " Tokens", "&c&lCancel"); + return;*/ + case "petinfo": + this.setPhoneDefaults(e); + e.setItem(11, Utils.createItem(Material.CHEST, 3, "&c&lPet Data", "&7Click customize your pet!")); + e.setItem(15, Utils.createItem(Material.BANNER, "&c&lPet Name", "&7Click to change your pet's name!")); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Click to return to the pet menu!")); + e.setItem(49, Utils.createItem(Material.LEASH, "&c&lGuard Pet Customizer", "&7Customize your friendly follower!")); + return; + /*case "petdata": { + this.setPhoneDefaults(e); + IPet pet = EchoPetAPI.getAPI().getPet(player); + if (pet == null) { + player.closeInventory(); + return; + } + List list = pet.getPetType().getAllowedDataTypes(); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + Iterator it = list.iterator(); + for (int i = 0; i < 20; i++) { + if (!it.hasNext()) break; + PetData data = it.next(); + String name = "&c&l"; + for (String s : data.toString().split("_")) + name += s.charAt(0) + s.substring(1).toLowerCase() + ' '; + if (name.endsWith(" ")) name = name.substring(0, name.length() - 1); + e.setItem(slots[i], Utils.createItem(Material.INK_SACK, pet.getPetData().contains(data) ? 10 : 8, name)); + } + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Click to return to the pet customizer!")); + e.setItem(49, Utils.createItem(Material.CHEST, "&c&lGuard Pet Data", "&7Customize your friendly follower!")); + return; + }*/ +// case "bannervariant": +// this.setPhoneDefaults(e); +// e.setItem(11, Utils.createItem(Material.SKULL_ITEM, 3, "&4&lBanner Hat", "&7Click to put the banner on your head!")); +// e.setItem(15, Utils.createItem(Material.BANNER, "&4&lBanner Cape", "&7Click to wear the banner on your back!")); +// e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Click to return to the banner menu!")); +// e.setItem(49, Utils.createItem(CosmeticType.BANNER.getMaterial(), CosmeticType.BANNER.getDisplayName() + " Hat or Cape", "&7Click to select where to equip the banner!")); +// return; +// case "blockvariant": +// this.setPhoneDefaults(e); +// e.setItem(11, Utils.createItem(Material.LEASH, "&2&lBalloon", "&7Click to get the block on a piece of string!")); +// e.setItem(15, Utils.createItem(Material.MONSTER_EGG, 3, "&2&lBlock Pet", "&7Click to get the block to follow you as a pet!")); +// e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Click to return to the blocks menu!")); +// e.setItem(49, Utils.createItem(CosmeticType.BANNER.getMaterial(), "&2&lBalloon or Block Pet", "&7Click to select how the block should follow you!")); +// return; +// case "particleshape": { +// this.setPhoneDefaults(e); +// int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; +// Cosmetic.ParticleShape[] a = Cosmetic.ParticleShape.values(); +// for (int i = 0; i < slots.length && i < a.length; i++) { +// Cosmetic.ParticleShape shape = a[i]; +// e.setItem(slots[i], Utils.createItem(Material.INK_SACK, i, "&a&l" + shape.getDisplayName(), "&7Click to select this shape!")); +// } +// e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Click to return to the particles menu!")); +// e.setItem(49, Utils.createItem(CosmeticType.PARTICLE.getMaterial(), "&a&lParticle Shape", "&7Click to select the particles' shape!")); +// return; +// } +// case "nametags": { +// this.setPhoneDefaults(e); +// List list = Core.getNametagManager().getNametags(user); +// int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; +// Iterator it = list.iterator(); +// for (int i = 0; i < 20; i++) { +// if (!it.hasNext()) break; +// Nametag tag = it.next(); +// e.setItem(slots[i], Utils.createItem(Material.NAME_TAG, tag.getDisplayName(), user.hasNametag(tag) ? "&7Click to apply this nametag!" : "&7Price: &e&l" + tag.getPrice() + " Tokens")); +// } +// e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the cosmetics menu!")); +// e.setItem(49, Utils.createItem(Material.CHEST, "&a&lNametags", "&7Select a nametag to apply to a pet!", "&7Soon, you will be able to apply nametags to", "&7your player character, vehicles and weapons.", "&7Page 1")); +// if (list.size() > 20) +// e.setItem(50, Utils.createItem(Material.ARROW, "&a&lNext Page", "&7Page 2")); +// +// e.setItem(51, Utils.createItem(Material.WEB, "&c&lRemove Nametag", "&7Click to remove a nametag from a pet.")); +// return; +// } +// case "buynametag": { +// Nametag tag = user.getBuyingNametag(); +// if (tag == null || !user.hasTokens(tag.getPrice())) return; +// this.setConfirmDefaults(e, "&a&lBuy " + tag.getDisplayName() + "&a&l for &e&l" + tag.getPrice() + " Token" + (tag.getPrice() == 1 ? "" : "s"), "&c&lCancel"); +// return; +// } +// case "applynametag": +// this.setPhoneDefaults(e); +// Nametag tag = user.getActivatingNametag(); +// if (tag == null || !user.hasNametag(tag)) return; +// Cosmetic pet = user.getLastPet(player); +// if (pet == null) +// e.setItem(11, Utils.createItem(Material.LEASH, "&c&lGuard Pet", "&7You have no pet to name!")); +// else e.setItem(11, pet.getMenuItem(user)); +// e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lCancel", "&7Return to the nametags menu!")); +// e.setItem(49, Utils.createItem(Material.NAME_TAG, tag.getDisplayName(), "&7Please select what you would like to name.")); +// return; + case "prefs": { + this.setPhoneDefaults(e); + User u = Core.getUserManager().getLoadedUser(player.getUniqueId()); + ServerType type = Core.getSettings().getType(); + int[] slots = new int[]{11, 12, 13, 14, 15, 29, 30, 31, 32, 33}; + + int i = 0; + for (Pref pref : Pref.values()) + if (pref.isEnabled(player, u, type)) { + boolean b = u.getPref(pref); + ItemStack achievementItem = Utils.createItem(pref.getMaterial(), pref.getMaterialData(), + (b ? "&a" : "&c") + "&l" + pref.getDisplayName(), "&7Click to " + (b ? "disable." : "enable.")); + Utils.applyItemFlags(achievementItem, ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE); + e.setItem(slots[i], achievementItem); + e.setItem(slots[i] + 9, Utils.createItem(Material.INK_SACK, b ? 10 : 8, (b ? "&a" : "&c") + "&l" + pref.getDisplayName(), "&7Click to " + (b ? "disable." : "enable."))); + i++; + } + e.setItem(49, Utils.createItem(Material.REDSTONE_COMPARATOR, "&5&lPreferences", "&7Toggle your " + (Core.getSettings().isSister() ? "stuff" : "shit") + "!")); + return; + } + case "rewards": { + this.setPhoneDefaults(e); + + if(!Core.getSettings().isSister()) { + e.setItem(11, Utils.createItem(Material.DOUBLE_PLANT, "&e&lVote", user.getVotes(), "&7Earn awesome rewards!", "", "&7Total Votes: &e&l" + user.getVotes(), "", "&7Vote to get more rewards!")); + e.setItem(20, Utils.createItem(Material.INK_SACK, user.getVotes() > 0 ? 10 : 8, "&e&lVote Streak", user.getVoteRecord().getStreak() > 64 ? 64 : user.getVoteRecord().getStreak(), + "&7Vote at least once a day to", "&7increase your streak! ", "&7Every day gives you an extra 5%", "&7chance to get a double reward!", "&7Vote on all &e4 &7sites for maximum rewards!", + "", "&7Current Streak: &a&l" + user.getVoteRecord().getStreak(), "&7Double Reward Chance: &a&l" + user.getDoubleVoteChance() + '%', "", + user.canVoteStreak() ? "&7Vote &a&lnow&7 to raise your streak!" : "&7Time Left: &c&l" + Utils.timeInMillisToText(user.getTimeUntilVoteStreak().isPresent() ? user.getTimeUntilVoteStreak().get().getTime() : 0))); + + e.setItem(22, Utils.createItem(Material.PAPER, "&a&lFree Store Giftcards", "&7Earn free store giftcards by", "&7watching ads! ")); + } + + UserRank rank = user.getUserRankNonTrial().isHigherThan(UserRank.SUPREME) ? UserRank.SUPREME : user.getUserRankNonTrial(); + boolean canClaimMonthly = user.canClaimMonthlyReward(); + if (rank == UserRank.DEFAULT) { + List lore = new ArrayList<>(Arrays.asList("&7Buy a &6&lDonor Rank&7 at", "&a&n" + Core.getSettings().getStoreLink(), "", "&7to get monthly &e&lTokens&7!", "")); + for (UserRank r : new UserRank[]{UserRank.VIP, UserRank.PREMIUM, UserRank.ELITE, UserRank.SPONSOR, UserRank.SUPREME}) + lore.add(r.getColoredNameBold() + "&7: &e&l" + r.getMonthlyTokens() + " Tokens"); + Map> monthly = Core.getVoteManager().getMonthlyRewards(); + if (!monthly.isEmpty()) { + lore.add(""); + lore.add("&7Extra rewards:"); + for (Map.Entry> userRankListEntry : monthly.entrySet()) { + lore.addAll(userRankListEntry.getValue().stream().map(r -> rank.getColoredNameBold() + "&7: " + r.getDisplayName()).collect(Collectors.toList())); + } + } + e.setItem(13, Utils.createItem(Material.COAL, "&c&lDonor Reward", lore)); + } else { + List lore = new ArrayList<>(Arrays.asList("&7As a donator you are entitled to", "&e&l" + rank.getMonthlyTokens() + " Tokens&7 every month!", "&7Upgrade your rank for more!", "", + canClaimMonthly ? "&aClick to claim!" : "&7Next Reward: &c&l" + Utils.timeInMillisToText(user.getTimeUntilMonthlyReward()))); + Map> monthly = Core.getVoteManager().getMonthlyRewards(); + if (monthly.containsKey(rank)) { + lore.add(""); + lore.add("&7Extra rewards:"); + lore.addAll(monthly.get(rank).stream().map(RewardPack::getDisplayName).collect(Collectors.toList())); + } + e.setItem(13, Utils.createItem(canClaimMonthly ? rank.getMaterial() : Material.COAL, rank.getColoredNameBold() + " Reward", + lore)); + } + List lore = new ArrayList<>(Arrays.asList("&7Come back every day to claim:", "&e&l2 Tokens")); + lore.addAll(Core.getVoteManager().getDailyRewards().stream().map(RewardPack::getDisplayName).collect(Collectors.toList())); + lore.add(""); + lore.add(user.canClaimDailyReward() ? "&aClick to claim!" : "&7Next Reward: &c&l" + Utils.timeInMillisToText(user.getTimeUntilDailyReward())); + e.setItem(15, Utils.createItem(Material.NETHER_STAR, "&a&lDaily Reward", lore)); + lore = new ArrayList<>(Arrays.asList("&7Claim your reward daily to", "&7increase your streak! ", "&7Every day gives you an extra 5%", "&7chance to increase your reward to:", "&e&l5 Tokens")); + lore.addAll(Core.getVoteManager().getLuckyDailyRewards().stream().map(RewardPack::getDisplayName).collect(Collectors.toList())); + lore.add(""); + lore.add("&7Current Streak: &a&l" + user.getDailyStreak()); + lore.add("&7Lucky Chance: &a&l" + user.getLuckyDailyChance() + '%'); + lore.add(""); + lore.add(user.canClaimDailyReward() ? "&7Claim &a&lnow&7 to raise your streak!" : "&7Next Reward: &c&l" + Utils.timeInMillisToText(user.getTimeUntilDailyReward())); + e.setItem(24, Utils.createItem(Material.INK_SACK, user.canClaimDailyReward() ? 10 : 8, "&a&lDaily Reward Streak", lore, user.getDailyStreak() > 64 ? 64 : user.getDailyStreak())); + e.setItem(49, Utils.createItem(Material.EXP_BOTTLE, "&a&lRewards", "&7Click to claim your rewards!")); + return; + } + case "vote": { + this.setPhoneDefaults(e); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33}; + VoteManager vm = Core.getVoteManager(); + int i = 0; + for (VoteReward reward : vm.getChanceVoteRewards()) { + List l = new ArrayList<>(); + l.add(""); + l.add(Utils.f("&7Chance: &a&l" + reward.getChance() + "&a%")); + if (reward.getRewardPack().get().size() > 1) { + l.add(Utils.f("&7Contains rewards:")); + l.addAll(reward.getRewardPack().get().stream().map(r -> Utils.f(r.getDisplayName())).collect(Collectors.toList())); + } + l.add(""); + ItemStack item = reward.getItem(); + ItemMeta meta = item.getItemMeta(); + meta.setDisplayName(Utils.f(reward.getDisplayName())); + meta.setLore(l); + item.setItemMeta(meta); + Utils.applyItemFlags(item, ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE); + e.setItem(slots[i], item); + i++; + } + // + +// new BukkitRunnable() { +// @Override +// public void run() { +// Optional voteUser = VoteDAO.getTopVoter(); +// if(!voteUser.isPresent()) return; +// +// ItemStack is = Utils.createItem(Material.SKULL_ITEM, 3, "&e&lThis Month's Top Voters", "&7The top voters of the month can win up to &a$&l100 Store Credit&7!"); +// SkullMeta meta = (SkullMeta) is.getItemMeta(); +// meta.setOwner(voteUser.get().getName()); +// is.setItemMeta(meta); +// +// ServerUtil.runTask(() -> { +// e.getMenu().getInventory().setItem(39, is); +// player.updateInventory(); +// }); +// +// ItemStack item = Utils.createItem(Material.SKULL_ITEM, 3, "&e&lLast Month's Top Voters"); +// SkullMeta im = (SkullMeta) item.getItemMeta(); +// List lore = new ArrayList<>(); +// +// Optional optional = VoteDAO.getLastMonthsVoters(); +// if(!optional.isPresent()) return; +// +// for(VoteDAO.VoteUser voter : optional.get()) { +// im.setOwner(voter.getName()); +// lore.add(Utils.f("&7#&6" + voter.getPossition() + "&7 " + voter.getName())); +// } +// +// im.setLore(lore); +// item.setItemMeta(im); +// +// ServerUtil.runTask(() -> { +// e.getMenu().getInventory().setItem(41, item); +// player.updateInventory(); +// }); +// } +// }.runTaskAsynchronously(Core.getInstance()); + + ServerUtil.runTaskAsync(() -> { + VoteDAO.VoteUser[] topVoters = Core.getInstance().getVoteManager().getTopVoters(); + if(topVoters == null || topVoters.length == 0) return; + + // get the first place guy + VoteDAO.VoteUser topVoter = topVoters[0]; + + ItemStack is = Utils.createItem(Material.SKULL_ITEM, 3, "&e&lThis Month's Top Voters", "&7The top voters of the month can win up to &a$&l100 Store Credit&7!"); + SkullMeta meta = (SkullMeta) is.getItemMeta(); + meta.setOwner(topVoter.getName()); + is.setItemMeta(meta); + + ServerUtil.runTask(() -> { + e.getMenu().getInventory().setItem(39, is); + player.updateInventory(); + }); + + ItemStack item = Utils.createItem(Material.SKULL_ITEM, 3, "&e&lLast Month's Top Voters"); + SkullMeta im = (SkullMeta) item.getItemMeta(); + List lore = new ArrayList<>(); + + VoteDAO.VoteUser[] lastMonthsVoters = Core.getInstance().getVoteManager().getLastTopVoters(); + if(lastMonthsVoters == null || lastMonthsVoters.length == 1) return; + + for(VoteDAO.VoteUser voter : lastMonthsVoters) { + if (voter != null){ + im.setOwner(voter.getName()); + lore.add(Utils.f("&7#&6" + voter.getPossition() + "&7 " + voter.getName())); + } + } + + im.setLore(lore); + item.setItemMeta(im); + + ServerUtil.runTask(() -> { + e.getMenu().getInventory().setItem(41, item); + player.updateInventory(); + }); + }); + + // + + ItemStack is = new ItemStack(Material.SKULL_ITEM, 1, (short) 3); + SkullMeta im = (SkullMeta) is.getItemMeta(); + YearMonth lastMonthStr = YearMonth.now(); + DateTimeFormatter monthFormatter = DateTimeFormatter.ofPattern("MMMM"); + im.setDisplayName(Utils.f("&e&lYour Votes")); + im.setLore(Arrays.asList(Utils.f("&eTotal Votes Ever: &7" + lastMonthStr.format(monthFormatter)), Utils.f("&eVotes: &7" + user.getVoteRecord().getTotalVotes()))); + im.setOwner(player.getName()); + is.setItemMeta(im); + e.setItem(40, is); + + + e.setItem(i > 9 ? 38 : 29, Utils.createItem(Material.EMPTY_MAP, + "&e&lVote Link", "&7Click to go to the voting webpage!", "", "&a&nvote.grandtheftmc.net")); + List lore = new ArrayList<>(Arrays.asList("&7With every vote you are guaranteed", + "&7to receive these items:")); + lore.addAll(vm.getGuaranteedVoteRewards().stream().map(r -> "&7" + r.getDisplayName()).collect(Collectors.toList())); + lore.addAll(Arrays.asList("&7Get lucky and receive extra rare rewards!", "", "&7Votes: &e&l" + user.getVotes(), "")); + + if (user.getVotes() > 1) + lore.addAll(Arrays.asList("&aRight click to claim all votes!", "&aLeft click to claim 1 vote!")); + else lore.add(user.getVotes() == 1 ? "&aClick to claim your rewards!" : "&7Vote on all &e4 &7sites for maximum rewards!"); + e.setItem(i > 9 ? 40 : 31, Utils.createItem(Material.CHEST, "&e&lVoting Rewards", lore)); + e.setItem(i > 9 ? 42 : 33, Utils.addItemFlags(Utils.createItem(Material.FLINT_AND_STEEL, 45, + "&9&lCrowbars: " + user.getCrowbars(), "&7Crowbars are used to open crates.", "", + "&7&oFind crates at spawn near the teleporter!"), ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE)); + // TODO figure out if this removes durability bar + + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the rewards menu!")); + lore = new ArrayList<>(Arrays.asList("&7Earn awesome rewards!", "", "&7Votes: &e&l" + user.getVotes(), "")); + if (user.getVotes() > 1) + lore.addAll(Arrays.asList("&aRight click to claim all votes!", "&aLeft click to claim 1 vote!")); + else lore.add(user.getVotes() == 1 ? "&aClick to claim your rewards!" : "&7Vote on all &e4 &7sites for maximum rewards!"); + e.setItem(49, Utils.createItem(Material.DOUBLE_PLANT, "&e&lVote", lore, user.getVotes())); + e.setItem(51, + Utils.createItem(Material.BOOK_AND_QUILL, "&e&lToken Shop", "&7Buy amazing items with your tokens!")); + return; + } + case "tokenshop": { + this.setPhoneDefaults(e); + List items = Core.getVoteManager().getShopItems(); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + Iterator it = items.iterator(); + for (int i = 0; i < 20; i++) { + if (!it.hasNext()) + break; + ShopItem item = it.next(); + ItemStack stack = item.getItem().clone(); + ItemMeta meta = stack.getItemMeta(); + meta.setDisplayName(Utils.f("&3&l" + item.getName())); + meta.setLore(Arrays.asList("", + Utils.f("&7Price: &" + (user.hasTokens(item.getPrice()) ? "e" : "c") + "&l" + item.getPrice() + (item.getPrice() == 1 ? " Token" : " Tokens")))); + stack.setItemMeta(meta); + e.setItem(slots[i], stack); + } + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the voting menu!")); + e.setItem(49, Utils.createItem(Material.BOOK_AND_QUILL, "&e&lToken Shop", "&7Page 1")); + if (items.size() > 20) + e.setItem(50, Utils.createItem(Material.ARROW, "&e&lNext Page", "&7Page 2")); + return; + } + case "buyshopitem": + ShopItem item = user.getBuyingShopItem(); + if (item == null || !user.hasTokens(item.getPrice())) return; + this.setConfirmDefaults(e, "&a&lBuy " + item.getName() + "&a&l for &e&l" + item.getPrice() + " Token" + (item.getPrice() == 1 ? "" : "s"), "&c&lCancel"); + return; + case "serverwarper": + if (!Core.getSettings().serverWarperEnabled()) + return; + this.setPhoneDefaults(e); + List lore = Arrays.stream(new String[]{"gtm1", "gtm2", "gtm3", "gtm4", "gtm5", "gtm6"}).map(st -> Core.getServerManager().getServer(st)).filter(Objects::nonNull).map(s -> Utils.f("&7&lGTM &a&l" + s.getNumber() + "&7: " + (s.isOffline() ? "&c&lOffline" : "&a" + s.getOnlinePlayers() + "&7/&a" + s.getMaxPlayers()))).collect(Collectors.toList()); + lore.add(Utils.f("&0")); + lore.add(ServerType.GTM.getDescription()); + e.setItem(11, Utils.createItem(ServerType.GTM.getIcon(), ServerType.GTM.getDisplayName(), lore)); + + if (!Core.getSettings().isSister()) { + this.addServerIcon(e, "creative1", 15); + // this.addServerIcon(e, "hub1", 47); + this.addServerIcon(e, "vice1", 13); + } + + e.setItem(49, Utils.createItem(Material.COMPASS, "&e&lServer Warper", "&7Click to join a server!")); + break; + case "gtmservers": + if (!Core.getSettings().serverWarperEnabled()) + return; + this.setPhoneDefaults(e); + int[] slots = new int[]{11, 13, 15, 29, 31, 33}; + List gtmServers = Core.getServerManager().getServers(ServerType.GTM); + Iterator it = gtmServers.iterator(); + for (int i = 0; i < slots.length && it.hasNext(); i++) { + Server server = it.next(); + this.addServerIcon(e, server, server.getType(), slots[i]); + } + e.setItem(49, Utils.createItem(Material.COMPASS, "&e&lServer Warper", "&7Click to join a server!")); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Go back to the server warper!")); + break; + + case "hubservers": + + if (!Core.getSettings().serverWarperEnabled()) + return; + + this.setPhoneDefaults(e); + int[] hubSlots = new int[]{11, 13, 15, 20, 22, 24, 29, 31, 33, 38, 40, 42}; + List gtmHubServers = Core.getServerManager().getServers(ServerType.HUB); + Iterator serverIterator = gtmHubServers.iterator(); + for (int i = 0; i < hubSlots.length && serverIterator.hasNext(); i++) { + Server server = serverIterator.next(); + this.addServerIcon(e, server, server.getType(), hubSlots[i]); + } + e.setItem(49, Utils.createItem(Material.COMPASS, "&e&lHub Warper", "&7Click to join a server!")); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Go back to the server warper!")); + return; + } + + } + + public void addServerIcon(MenuOpenEvent e, String server, int slot) { + Server s = Core.getServerManager().getServer(server); + this.addServerIcon(e, s, s == null ? ServerType.NONE : s.getType(), slot); + } + + public void addServerIcon(MenuOpenEvent e, Server s, ServerType type, int slot) { + String lore = ""; + if (type == ServerType.GTM && s.getNumber() == 4) + lore = "&8&lEpicStun &4&lCommunity &e&lServer &8&l(German/Deutsch)"; + e.setItem(slot, Utils.createItem(type.getIcon(), + type.getDisplayName() + (s == null ? "" : " &a&l" + s.getNumber()), + s == null || s.isOffline() ? "&c&lOffline!" + : "&a" + s.getOnlinePlayers() + "&7/&a" + s.getMaxPlayers(), + "", Utils.f(lore), type.getDescription())); + } + + @EventHandler + public void onClickMenu(MenuClickEvent e) { + Menu menu = e.getMenu(); + Player player = e.getPlayer(); + UUID uuid = player.getUniqueId(); + ItemStack item = e.getItem(); + Inventory inv = e.getInv(); + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (item == null) return; +// CosmeticType cosmeticType = CosmeticType.getType(menu.getName()); +// if (Core.getSettings().loadCosmetics() && cosmeticType != null) { +// switch (item.getType()) { +// case ARROW: +// int page = Integer.parseInt(ChatColor.stripColor(item.getItemMeta().getLore().get(0)).replace("Page ", "")); +// this.setPhoneDefaults(inv); +// int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; +// List cosmetics = cosmeticType.getCosmetics(user); +// for (int i = 0; i < slots.length && (page - 1) * 20 + i < cosmetics.size(); i++) { +// Cosmetic cos = cosmetics.get((page - 1) * 20 + i); +// inv.setItem(slots[i], cos.getMenuItem(user)); +// } +// inv.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the cosmetics menu!")); +// if (page > 1) +// inv.setItem(48, Utils.createItem(Material.ARROW, "&6&lPrevious Page", "&7Page " + (page - 1))); +// inv.setItem(49, Utils.createItem(cosmeticType.getMaterial(), "&6&lCosmetics: " + cosmeticType.getDisplayName(), "&7Page " + page)); +// if (cosmetics.size() > (20 * page)) +// inv.setItem(50, Utils.createItem(Material.ARROW, "&6&lNext Page", "&7Page " + (page + 1))); +// inv.setItem(51, Utils.createItem(Material.WEB, "&c&lRemove Cosmetic", "&7Click to remove your current " + cosmeticType.toString().charAt(0) + cosmeticType.toString().substring(1).toLowerCase())); +// return; +// case REDSTONE: +// MenuManager.openMenu(player, "cosmetics"); +// return; +// case WEB: +// switch (cosmeticType) { +// /*case PET: +// IPet pet = EchoPetAPI.getAPI().getPet(player); +// if (pet != null) { +// player.sendMessage(Lang.GUARDPETS.f("&7You removed your " + pet.getPetName() + "&7!")); +// EchoPetAPI.getAPI().removePet(player, false, false); +// Core.getUserManager().getLoadedUser(uuid).removeLastCosmetic(cosmeticType); +// return; +// } +// user.removeLastCosmetic(cosmeticType); +// player.sendMessage(Lang.GUARDPETS.f("&7You currently do not have a Pet activated!")); +// return;*/ +// default: +// Set set = Core.getUltimateCosmetics().getApi().getCosmetics(player); +// Iterator it = set.iterator(); +// for (int i = 0; i < set.size() && it.hasNext(); i++) { +// com.j0ach1mmall3.ultimatecosmetics.api.Cosmetic c = it.next(); +// if ((cosmeticType == CosmeticType.GADGET && Cosmetic.getGadgetByIdentifier(c.getCosmeticStorage().getIdentifier()) != null) || c.getCosmeticStorage().getIdentifier().startsWith(cosmeticType.toString().toLowerCase())) +// c.remove(Core.getUltimateCosmetics()); +// } +// user.removeLastCosmetic(cosmeticType); +// player.sendMessage(Lang.COSMETICS.f("&7You removed all cosmetics from the category " + cosmeticType.getDisplayName() + "&7!")); +// return; +// } +// default: +// Cosmetic cos = item.hasItemMeta() && item.getItemMeta().hasDisplayName() ? cosmeticType.getCosmeticFromDisplayName(item.getItemMeta().getDisplayName()) : null; +// if (cos == null) return; +// if (!user.hasCosmetic(cos)) { +// if (cos.getTokens() < 0 || !user.hasTokens(cos.getTokens())) { +// player.sendMessage(Lang.COSMETICS.f("&7You don't have access to this cosmetic! Buy cosmetics at &a&lstore.grandtheftmc.net&7!")); +// return; +// } +// user.setBuyingCosmetic(cos); +// MenuManager.openMenu(player, "buycosmetic"); +// return; +// } +// switch (cosmeticType) { +// case BANNER: +// case BLOCK: +// case PARTICLE: +// user.setActivatingCosmetic(cos); +// MenuManager.openMenu(player, cosmeticType == CosmeticType.BANNER ? "bannervariant" : cosmeticType == CosmeticType.BLOCK ? "blockvariant" : "particleshape"); +// return; +// case PET: +// player.closeInventory(); +// cos.activate(user, player); +// MenuManager.openMenu(player, "petinfo"); +// return; +// default: +// player.closeInventory(); +// cos.activate(user, player); +// return; +// } +// } +// } + switch (menu.getName()) { + case "freecoupons": { + int credits = 0; + switch (item.getType()) { + case PAPER: { + TextComponent m0 = new TextComponent(); + m0.addExtra(Lang.REWARDS.f("")); + + TextComponent m1 = new TextComponent("[Click Here For Free Credits]"); + m1.setColor(ChatColor.BLUE); + m1.setBold(true); + m1.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, PlaywireManager.getPlaywireLink(player.getUniqueId()))); + + + player.spigot().sendMessage(m0, m1); + player.closeInventory(); + return; + } + case GOLD_NUGGET: { + credits = 50; + break; + } + case GOLD_INGOT: { + credits = 100; + break; + } + case GOLD_BLOCK: { + credits = 500; + break; + } + case DIAMOND: { + credits = user.getCouponCredits(); + break; + } + case REDSTONE: { + MenuManager.openMenu(player, "rewards"); + return; + } + } + + if(user.getCouponCredits() { + if(obj==null || user.getCouponCredits() list = Core.getNametagManager().getNametags(user); +// int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; +// Iterator it = list.iterator(); +// for (int i = (page - 1) * 20; i < 20 * page; i++) { +// if (!it.hasNext()) +// break; +// Nametag tag = it.next(); +// inv.setItem(slots[i], Utils.createItem(Material.NAME_TAG, tag.getDisplayName(), user.hasNametag(tag) ? "&7Click to apply this nametag!" : "&7Price: &e&l" + tag.getPrice() + " Tokens")); +// } +// inv.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the cosmetics menu!")); +// if (page > 1) +// inv.setItem(48, Utils.createItem(Material.ARROW, "&a&lPrevious Page", "&7Page " + (page - 1))); +// inv.setItem(49, Utils.createItem(Material.CHEST, "&a&lNametags", "&7Select a nametag to apply to a pet!", "&7Soon, you will be able to apply nametags to", "&7your player character, vehicles and weapons.", "&7Page " + page)); +// if (list.size() > (20 * page)) +// inv.setItem(50, Utils.createItem(Material.ARROW, "&a&lNext Page", "&7Page " + (page + 1))); +// inv.setItem(51, Utils.createItem(Material.WEB, "&c&lRemove Nametag", "&7Click to remove a nametag from a pet.")); +// return; +// case REDSTONE: +// MenuManager.openMenu(player, "cosmetics"); +// return; +// default: +// Nametag tag = item.hasItemMeta() && item.getItemMeta().hasDisplayName() ? Core.getNametagManager().getNametagFromDisplayName(item.getItemMeta().getDisplayName()) : null; +// if (tag == null) return; +// if (user.hasNametag(tag)) { +// user.setActivatingNametag(tag); +// MenuManager.openMenu(player, "applynametag"); +// return; +// } +// if (!user.hasTokens(tag.getPrice())) { +// player.sendMessage(Lang.NAMETAGS.f("&7You do not have the &e&l" + tag.getPrice() + " Token " + (tag.getPrice() == 1 ? "" : "s") + "&7!")); +// return; +// } +// user.setBuyingNametag(tag); +// MenuManager.openMenu(player, "buynametag"); +// return; +// } +// case "buynametag": +// switch (item.getType()) { +// case STAINED_GLASS_PANE: +// switch (item.getDurability()) { +// case 5: +// User u = Core.getUserManager().getLoadedUser(uuid); +// Nametag tag = u.getBuyingNametag(); +// u.setBuyingNametag(null); +// if (tag == null) { +// player.closeInventory(); +// player.sendMessage(Lang.NAMETAGS.f("&7You are not buying a nametag!")); +// return; +// } +// player.closeInventory(); +// if (tag.getPrice() > 0 && !u.hasTokens(tag.getPrice())) { +// player.sendMessage( +// Lang.TOKEN_SHOP.f("&7You do not have the &e&l" + tag.getPrice() + " Tokens&7 to pay for this nametag!")); +// +// return; +// } +// player.sendMessage( +// Lang.TOKEN_SHOP.f("&7You bought &a" + tag.getDisplayName() + "&7 for &e&l" + tag.getPrice() + " Token" + (tag.getPrice() == 1 ? "" : "s") + "&7!")); +// u.takeTokens(tag.getPrice()); +// u.giveNametag(tag); +// u.insertLog(player, "buyNametag", Reward.RewardType.NAMETAG.toString(), tag.getName(), 1, tag.getPrice()); +// UpdateEvent ev = new UpdateEvent(player, UpdateEvent.UpdateReason.TOKENS); +// Bukkit.getPluginManager().callEvent(ev); +// return; +// case 14: +// Core.getUserManager().getLoadedUser(uuid).setBuyingShopItem(null); +// MenuManager.openMenu(player, "nametags"); +// return; +// default: +// return; +// } +// default: +// return; +// } +// case "applynametag": +// switch (item.getType()) { +// case REDSTONE: +// MenuManager.openMenu(player, "nametags"); +// return; +// default: +// Nametag tag = user.getActivatingNametag(); +// if (tag == null) { +// MenuManager.openMenu(player, "nametags"); +// return; +// } +// +// if (item.hasItemMeta() && item.getItemMeta().hasDisplayName()) { +// Cosmetic pet = user.getLastPet(player); +// if (pet != null && CosmeticType.PET.getCosmeticFromDisplayName(item.getItemMeta().getDisplayName()) == pet) { +// user.setPetNametag(player, pet, tag); +// player.sendMessage(Lang.NAMETAGS.f("&7You have renamed your pet to " + tag.getDisplayName() + "&7!")); +// player.closeInventory(); +// return; +// } +// } +// return; +// } + case "rewards": + switch (item.getType()) { + case PAPER: { + if(Core.getSettings().isSister()) + return; + MenuManager.openMenu(player, "freecoupons"); + return; + } + case DOUBLE_PLANT: + MenuManager.openMenu(player, "vote"); + return; + case NETHER_STAR: + Core.getVoteManager().claimDaily(player, Core.getUserManager().getLoadedUser(uuid)); + return; + case INK_SACK: + switch (ChatColor.stripColor(item.getItemMeta().getDisplayName())) { + case "Vote Streak": + MenuManager.openMenu(player, "vote"); + return; + case "Daily Reward Streak": + Core.getVoteManager().claimDaily(player, Core.getUserManager().getLoadedUser(uuid)); + return; + default: + return; + } + case EXP_BOTTLE: + if (user.canClaimDailyReward()) + Core.getVoteManager().claimDaily(player, user); + if (user.canClaimMonthlyReward()) + Core.getVoteManager().claimMonthly(player, user); + if (user.getVotes() > 0) + Core.getVoteManager().spendVote(player, user); + default: + if (item.getType() == Material.COAL || UserRank.getUserRank(item.getType()) != null) + Core.getVoteManager().claimMonthly(player, Core.getUserManager().getLoadedUser(uuid)); + return; + } + case "prefs": + switch (item.getType()) { + case REDSTONE: + MenuManager.openMenu(player, "account"); + return; + default: + if (!item.hasItemMeta() || !item.getItemMeta().hasDisplayName()) + return; + User u = Core.getUserManager().getLoadedUser(uuid);// + Pref pref = Pref.getPrefByDisplayName(ChatColor.stripColor(item.getItemMeta().getDisplayName())); + if (pref == null) return; + if (!pref.isEnabled(player, u, Core.getSettings().getType())) { + player.sendMessage(Lang.PREFS.f("&7You can't use this pref!")); + return; + } + u.togglePref(player, pref); + player.sendMessage(Lang.PREFS + .f("&7You turned " + (u.getPref(pref) ? "&a&lon" : "&c&loff") + "&7 " + pref.getDisplayName() + '!')); + MenuManager.updateMenu(player, "prefs"); + return; + } + case "topvoters": { + switch (item.getType()) { + case REDSTONE: + MenuManager.openMenu(player, "vote"); + return; + } + } + case "vote": + switch (item.getType()) { + case SKULL_ITEM: + if (e.getSlot() == 39) + MenuManager.openMenu(player, "topvoters"); + return; + case CHEST: + case EMPTY_MAP: + player.closeInventory(); + player.sendMessage(Utils.f(Lang.VOTE + "&7Vote for the server at &a&n" + Core.getVoteManager().getVoteLink() + "&7!")); + return; + case BOOK_AND_QUILL: + MenuManager.openMenu(player, "tokenshop"); + return; + case DOUBLE_PLANT: + if (user.getVotes() == 0) { + player.closeInventory(); + player.sendMessage(Utils.f(Lang.VOTE + "&7Vote for the server at &a&n" + Core.getVoteManager().getVoteLink() + "&7 to claim rewards!")); + return; + } + if (user.getVotes() > 1 && (e.getClickType() == ClickType.RIGHT || e.getClickType() == ClickType.SHIFT_RIGHT)) + Core.getVoteManager().spendAllVotes(player, user); + else + Core.getVoteManager().spendVote(player, user); + return; + case REDSTONE: + MenuManager.openMenu(player, "rewards"); + return; + default: + return; + } + case "tokenshop": + switch (item.getType()) { + case ARROW: + int page = Integer + .parseInt(ChatColor.stripColor(item.getItemMeta().getLore().get(0)).replace("Page ", "")); + this.setPhoneDefaults(inv); + List items = Core.getVoteManager().getShopItems(); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, + 42}; + Iterator it = items.iterator(); + for (int i = (page - 1) * 20; i < 20 * page; i++) { + if (!it.hasNext()) + break; + ShopItem shopItem = it.next(); + ItemStack stack = shopItem.getItem().clone(); + ItemMeta meta = stack.getItemMeta(); + meta.setDisplayName(Utils.f(shopItem.getName())); + meta.setLore(Arrays.asList("", + Utils.f("&7Price: &" + (Core.getUserManager().getLoadedUser(uuid).hasTokens(shopItem.getPrice()) ? "e" : "c") + "&l" + shopItem.getPrice() + (shopItem.getPrice() == 1 ? " Token" : " Tokens")))); + stack.setItemMeta(meta); + inv.setItem(slots[i], stack); + } + inv.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the voting menu!")); + if (page > 1) + inv.setItem(48, Utils.createItem(Material.ARROW, "&e&lPrevious Page", "&7Page " + (page - 1))); + inv.setItem(49, Utils.createItem(Material.BOOK_AND_QUILL, "&e&lToken Shop", "&7Page " + page)); + if (items.size() > (20 * page)) + inv.setItem(50, Utils.createItem(Material.ARROW, "&e&lNext Page", "&7Page " + (page + 1))); + return; + case REDSTONE: + MenuManager.openMenu(player, "vote"); + return; + default: + ShopItem shopItem = Core.getVoteManager().getShopItem(item.getItemMeta().getDisplayName()); + if (shopItem != null) { + if (!user.hasTokens(shopItem.getPrice())) { + player.sendMessage(Lang.TOKEN_SHOP.f("&7You do not have &e&l" + shopItem.getPrice() + " Token" + (shopItem.getPrice() == 1 ? "" : "s") + "&7!")); + return; + } + user.setBuyingShopItem(shopItem); + MenuManager.openMenu(player, "buyshopitem"); + return; + } + return; + } + case "buyshopitem": + switch (item.getType()) { + case STAINED_GLASS_PANE: + switch (item.getDurability()) { + case 5: + User u = Core.getUserManager().getLoadedUser(uuid); + ShopItem shopItem = u.getBuyingShopItem(); + u.setBuyingShopItem(null); + if (shopItem == null) { + player.closeInventory(); + player.sendMessage(Lang.TOKEN_SHOP.f("&7You are not buying a token shop item!")); + return; + } + player.closeInventory(); + shopItem.buy(player, Core.getUserManager().getLoadedUser(uuid)); + return; + case 14: + Core.getUserManager().getLoadedUser(uuid).setBuyingShopItem(null); + MenuManager.openMenu(player, "tokenshop"); + return; + default: + return; + } + default: + return; + } + case "serverwarper": + if (!Core.getSettings().serverWarperEnabled()) + return; + ServerManager sm = Core.getServerManager(); + switch (item.getType()) { + case REDSTONE: + sm.sendToServer(player, "hub1"); +// Core.getJedisManager().getModule(JedisChannel.SERVER_QUEUE).sendMessage( +// new ServerQueueMessage(player.getUniqueId(), user.getUserRank().name(), new ServerTypeId(net.grandtheftmc.ServerType.HUB, 1)), +// new ServerTypeId(net.grandtheftmc.ServerType.OPERATOR, -1) +// ); + return; + + case MINECART: + MenuManager.openMenu(player, "gtmservers"); + MenuManager.openMenu(player, "gtmservers"); + return; + + case GOLD_BLOCK: +// sm.sendToServer(player, "creative1"); + Core.getJedisManager().getModule(JedisChannel.SERVER_QUEUE).sendMessage( + new ServerQueueMessage(player.getUniqueId(), user.getUserRank().name(), new ServerTypeId(net.grandtheftmc.ServerType.CREATIVE, 1)), + new ServerTypeId(net.grandtheftmc.ServerType.OPERATOR, -1) + ); + return; + + case ELYTRA: + sm.sendToServer(player, "gliders1"); + return; + + case CHEST: + sm.sendToServer(player, "legacygtm"); + return; + + case SUGAR: +// sm.sendToServer(player, "vice1"); + Core.getJedisManager().getModule(JedisChannel.SERVER_QUEUE).sendMessage( + new ServerQueueMessage(player.getUniqueId(), user.getUserRank().name(), new ServerTypeId(net.grandtheftmc.ServerType.VICE, 1)), + new ServerTypeId(net.grandtheftmc.ServerType.OPERATOR, -1) + ); + default: + break; + } + case "gtmservers": + if (!Core.getSettings().serverWarperEnabled()) return; + + switch (item.getType()) { + case REDSTONE: + MenuManager.openMenu(player, "serverwarper"); + return; + + case MINECART: + String name = item.hasItemMeta() ? item.getItemMeta().hasDisplayName() ? ChatColor.stripColor(item.getItemMeta().getDisplayName()).replace(Core.getSettings().getServer_GTM_name() + " ", "") : null : null; + if (name == null) return; + int number; + try { + number = Integer.parseInt(name); + } catch (NumberFormatException ex) { + return; + } + + JedisModule module = Core.getJedisManager().getModule(JedisChannel.SERVER_QUEUE); + if (module == null) { + Core.getServerManager().sendToServer(player, "gtm" + number); + return; + } + + module.sendMessage( + new ServerQueueMessage(player.getUniqueId(), user.getUserRank().name(), new ServerTypeId(net.grandtheftmc.ServerType.GTM, number)), + new ServerTypeId(net.grandtheftmc.ServerType.OPERATOR, -1) + ); + return; + + default: + break; + } + + + case "hubservers": + if (!Core.getSettings().serverWarperEnabled()) + return; + switch (item.getType()) { + case REDSTONE: + + if (ChatColor.stripColor(item.getItemMeta().getDisplayName()).equalsIgnoreCase("Back")) { + MenuManager.openMenu(player, "serverwarper"); + } else { + String name = item.hasItemMeta() ? item.getItemMeta().hasDisplayName() ? ChatColor.stripColor(item.getItemMeta().getDisplayName()).replace("Hub ", "") : null : null; + if (name == null) + return; + + int number; + try { + number = Integer.parseInt(name); + } catch (NumberFormatException ex) { + return; + } + +// Core.getServerManager().sendToServer(player, "hub" + number); + Core.getJedisManager().getModule(JedisChannel.SERVER_QUEUE).sendMessage( + new ServerQueueMessage(player.getUniqueId(), user.getUserRank().name(), new ServerTypeId(net.grandtheftmc.ServerType.HUB, number)), + new ServerTypeId(net.grandtheftmc.ServerType.OPERATOR, -1) + ); + } + return; + } + } + } + + @EventHandler + public void onClose(MenuCloseEvent e) { + Player player = e.getPlayer(); + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + Crate crate = user.getSelectedCrate(); + String s = e.getMenu().getName().toLowerCase(); + if (Objects.equals(s, "confirmcratereward") && user.getSelectedCrate() != null) { + user.setConfirmingCrateReward(null); + user.setSelectedCrate(null); + user.addCrowbars(crate.getCrateStars().getCrowbars()); + player.sendMessage(Lang.CRATES.f("&7You have opted to not recieve the crate rewards.")); + } + } + + + public void setPhoneDefaults(MenuOpenEvent e) { + ItemStack whiteGlass = Utils.createItem(Material.STAINED_GLASS_PANE, "&a"); + ItemStack grayGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a"); + ItemStack blackGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 15, "&a"); + ItemStack lightGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 8, "&a"); + for (int i : new int[]{1, 10, 19, 28, 37, 46, 7, 16, 25, 34, 43, 52}) e.setItem(i, whiteGlass); + for (int i : new int[]{2, 3, 4, 5, 6}) e.setItem(i, blackGlass); + for (int i : new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42, 47, 48, + 49, 50, 51}) + e.setItem(i, grayGlass); + for (int i : new int[]{0, 8, 9, 17, 18, 26, 27, 35, 36, 44, 45, 53}) e.setItem(i, lightGlass); + } + + public void setPhoneDefaults(Inventory inv) { + ItemStack whiteGlass = Utils.createItem(Material.STAINED_GLASS_PANE, "&a"); + ItemStack grayGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a"); + ItemStack blackGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 15, "&a"); + ItemStack lightGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 8, "&a"); + for (int i : new int[]{1, 10, 19, 28, 37, 46, 7, 16, 25, 34, 43, 52}) inv.setItem(i, whiteGlass); + for (int i : new int[]{2, 3, 4, 5, 6}) inv.setItem(i, blackGlass); + for (int i : new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42, 47, 48, + 49, 50, 51}) + inv.setItem(i, grayGlass); + for (int i : new int[]{0, 8, 9, 17, 18, 26, 27, 35, 36, 44, 45, 53}) inv.setItem(i, lightGlass); + } + + public void setGPSDefaults(MenuOpenEvent e) { + ItemStack whiteGlass = Utils.createItem(Material.STAINED_GLASS_PANE, "&a"); + ItemStack grayGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a"); + ItemStack blackGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 15, "&a"); + ItemStack lightGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 8, "&a"); + + for (int i : new int[]{0, 8, 9, 17, 18, 26, 27, 35, 36, 44, 45, 53}) e.setItem(i, lightGlass); + for (int i : new int[]{0, 9, 18, 27, 36, 45, 8, 17, 26, 35, 44, 53}) e.setItem(i, whiteGlass); + for (int i : new int[]{1, 2, 3, 4, 5, 6, 7}) e.setItem(i, blackGlass); + for (int i : new int[]{10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, 33, 34, 37, + 38, 39, 40, 41, 42, 43, 46, 47, 48, 49, 50, 51, 52}) + e.setItem(i, grayGlass); + } + + public void setGPSDefaults(Inventory inv) { + ItemStack whiteGlass = Utils.createItem(Material.STAINED_GLASS_PANE, "&a"); + ItemStack grayGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a"); + ItemStack blackGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 15, "&a"); + ItemStack lightGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 8, "&a"); + + for (int i : new int[]{0, 8, 9, 17, 18, 26, 27, 35, 36, 44, 45, 53}) inv.setItem(i, lightGlass); + for (int i : new int[]{0, 9, 18, 27, 36, 45, 8, 17, 26, 35, 44, 53}) + inv.setItem(i, whiteGlass); + for (int i : new int[]{1, 2, 3, 4, 5, 6, 7}) + inv.setItem(i, blackGlass); + for (int i : new int[]{10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, 33, 34, 37, + 38, 39, 40, 41, 42, 43, 46, 47, 48, 49, 50, 51, 52}) + inv.setItem(i, grayGlass); + } + + private void setConfirmDefaults(MenuOpenEvent e) { + this.setConfirmDefaults(e, "&a&lConfirm", "&c&lCancel"); + } + + private void setConfirmDefaults(MenuOpenEvent e, String confirmMessage, String cancelMessage) { + ItemStack whiteGlass = Utils.createItem(Material.STAINED_GLASS_PANE, "&a"); + ItemStack grayGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a"); + ItemStack blackGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 15, "&a"); + ItemStack lightGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 8, "&a"); + ItemStack greenGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 5, confirmMessage); + ItemStack redGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 14, cancelMessage); + for (int i : new int[]{1, 10, 19, 28, 37, 46, 7, 16, 25, 34, 43, 52}) e.setItem(i, whiteGlass); + for (int i : new int[]{2, 3, 4, 5, 6}) e.setItem(i, blackGlass); + for (int i : new int[]{13, 22, 31, 40, 49,}) e.setItem(i, grayGlass); + for (int i : new int[]{0, 8, 9, 17, 18, 26, 27, 35, 36, 44, 45, 53}) e.setItem(i, lightGlass); + for (int i : new int[]{11, 12, 20, 21, 29, 30, 38, 39, 47, 48}) e.setItem(i, greenGlass); + for (int i : new int[]{14, 15, 23, 24, 32, 33, 41, 42, 50, 51}) e.setItem(i, redGlass); + } + + private void setConfirmDefaults(MenuOpenEvent e, String confirmMessage, String cancelMessage, List confirmLore, List cancelLore) { + ItemStack whiteGlass = Utils.createItem(Material.STAINED_GLASS_PANE, "&a"); + ItemStack grayGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a"); + ItemStack lightGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 8, "&a"); + ItemStack blackGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 15, "&a"); + ItemStack greenGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 5, confirmMessage, confirmLore == null ? new ArrayList<>() : confirmLore); + ItemStack redGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 14, cancelMessage, cancelLore == null ? new ArrayList<>() : cancelLore); + for (int i : new int[]{1, 10, 19, 28, 37, 46, 7, 16, 25, 34, 43, 52}) e.setItem(i, whiteGlass); + for (int i : new int[]{2, 3, 4, 5, 6}) e.setItem(i, blackGlass); + for (int i : new int[]{13, 22, 31, 40, 49,}) e.setItem(i, grayGlass); + for (int i : new int[]{0, 8, 9, 17, 18, 26, 27, 35, 36, 44, 45, 53}) e.setItem(i, lightGlass); + for (int i : new int[]{11, 12, 20, 21, 29, 30, 38, 39, 47, 48}) e.setItem(i, greenGlass); + for (int i : new int[]{14, 15, 23, 24, 32, 33, 41, 42, 50, 51}) e.setItem(i, redGlass); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/menus/MenuManager.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/menus/MenuManager.java new file mode 100644 index 0000000..240b859 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/menus/MenuManager.java @@ -0,0 +1,93 @@ +package net.grandtheftmc.core.menus; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.util.Component; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.inventory.InventoryView; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public class MenuManager implements Component { + private static final List MENUS = new ArrayList<>(); + + public static void openMenu(Player player, String menuName) { + Menu menu = getMenu(menuName); + if (menu == null) + return; + menu.openFor(player); + } + + @Override + public MenuManager onDisable(Core plugin) { + MENUS.clear(); + return this; + } + + public static void updateMenu(Player player, String menuName) { + InventoryView view = player.getOpenInventory(); + if (view == null) + return; + Menu menu = getMenu(menuName); + if (menu == null || !Objects.equals(Utils.f(menu.getDisplayName()), view.getTitle())) + return; + MenuOpenEvent event = new MenuOpenEvent(player, menu); + Bukkit.getPluginManager().callEvent(event); + if (!event.isCancelled()) { + view.getTopInventory().setContents(event.getContents()); + player.updateInventory(); + } + } + + public static void updateMenu(String menuName) { + for (Player player : Bukkit.getOnlinePlayers()) + updateMenu(player, menuName); + } + + public static Menu getMenu(String menuName) { + return MENUS.stream().filter(menu -> menu.getName().equalsIgnoreCase(menuName)).findFirst().orElse(null); + } + + public static Menu getMenuFromTitle(String title) { + return MENUS.stream().filter(menu -> Utils.f(menu.getDisplayName()).equalsIgnoreCase(title)).findFirst().orElse(null); + } + + public static List getMenus() { + return MENUS; + } + + public static void addMenu(Menu menu) { + MENUS.add(menu); + } + + public static void addMenu(String name, int size, String title) { + MENUS.add(new Menu(name, size, title)); + } + + @EventHandler + public void onInventoryClick(InventoryClickEvent e) { + Menu menu = getMenuFromTitle(e.getInventory().getTitle()); + if (menu == null || e.getClickedInventory() == null || !Objects.equals(e.getClickedInventory(), e.getInventory())) + return; + e.setCancelled(true); + Player p = (Player) e.getWhoClicked(); + if (Core.getUserManager().getLoadedUser(p.getUniqueId()).isInTutorial()) return; + MenuClickEvent event = new MenuClickEvent(p, menu, e.getClickedInventory(), e.getSlot(), e.getCurrentItem(), e); + Bukkit.getPluginManager().callEvent(event); + } + + @EventHandler + public void onInventoryClose(InventoryCloseEvent e) { + Menu menu = getMenuFromTitle(e.getInventory().getTitle()); + if (menu == null) return; + Player player = (Player) e.getPlayer(); + MenuCloseEvent event = new MenuCloseEvent(player, menu); + Bukkit.getPluginManager().callEvent(event); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/menus/MenuOpenEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/menus/MenuOpenEvent.java new file mode 100644 index 0000000..aeefb2a --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/menus/MenuOpenEvent.java @@ -0,0 +1,57 @@ +package net.grandtheftmc.core.menus; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.bukkit.inventory.ItemStack; + +public class MenuOpenEvent extends PlayerEvent implements Cancellable{ + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final Menu menu; + private ItemStack[] contents; + private boolean cancelled = false; + + public MenuOpenEvent(Player player, Menu menu) { + super(player); + this.menu = menu; + this.contents = new ItemStack[menu.getSize()]; + } + + public Menu getMenu() { + return this.menu; + } + + public ItemStack[] getContents() { + return this.contents; + } + + public void setContents(ItemStack[] contents) { + this.contents = contents; + } + + public Menu setItem(int i, ItemStack item) { + if (i >= 0 && i < this.contents.length) + this.contents[i] = item; + return this.menu; + } + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean b) { + this.cancelled = b; + } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/nametags/Nametag.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/nametags/Nametag.java new file mode 100644 index 0000000..8e13cf2 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/nametags/Nametag.java @@ -0,0 +1,37 @@ +package net.grandtheftmc.core.nametags; + +import net.grandtheftmc.core.util.Utils; + +/** + * Created by Liam on 17/11/2016. + */ +public class Nametag { + + private final String name; + private final String displayName; + private final int price; + + Nametag(String name, String displayName, int price) { + this.name = name; + this.displayName = displayName; + this.price = price; + } + + public String getName() { + return this.name; + } + + public String getDisplayName() { + return Utils.f(this.displayName); + } + + public int getPrice() { + return this.price; + } + + @Override + public String toString() { + return this.name; + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/nametags/NametagCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/nametags/NametagCommand.java new file mode 100644 index 0000000..110863f --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/nametags/NametagCommand.java @@ -0,0 +1,103 @@ +package net.grandtheftmc.core.nametags; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.users.User; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + + +/** + * Created by Liam on 17/11/2016. + */ +public class NametagCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command cmd, String lbl, String[] args) { + if (Core.getSettings().loadCosmetics() && args.length == 0 && s instanceof Player) { + MenuManager.openMenu((Player) s, "nametags"); + return true; + } + if (!s.hasPermission("command.nametag")) { + s.sendMessage(Lang.NOPERM.s()); + return true; + } + if (args.length == 0) { + s.sendMessage(Lang.NAMETAGS.f("&7/nametag list")); + s.sendMessage(Lang.NAMETAGS.f("&7/nametag give ")); + s.sendMessage(Lang.NAMETAGS.f("&7/nametag remove ")); + s.sendMessage(Lang.NAMETAGS.f("&7/nametag reload")); + return true; + } + switch (args[0].toLowerCase()) { + case "list": { + String msg = ""; + for (Nametag t : Core.getNametagManager().getNametags()) + msg += "&a" + t.toString().toLowerCase() + "&7, "; + if (msg.endsWith("&7, ")) + msg.substring(0, msg.length() - 4); + s.sendMessage(Lang.NAMETAGS.f("&7List of &e&lNametags&7:")); + s.sendMessage(Utils.f(msg)); + return true; + } + case "give": { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/nametag give ")); + return true; + } + Nametag tag = Core.getNametagManager().getNametag(args[2]); + if (tag == null) { + s.sendMessage(Lang.NAMETAGS.f("&7That is not a nametag! Do &a/nametag list&7 to see a list!")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player == null) { +// Core.sql.updateAsyncLater("update nametags set `" + tag + "`=true where name='" + args[1] + "';"); + s.sendMessage(Lang.NAMETAGS.f("&7That player is not online, so his nametags have been updated directly in the database!")); + return true; + } + User u = Core.getUserManager().getLoadedUser(player.getUniqueId()); + u.giveNametag(tag); + s.sendMessage(Lang.NAMETAGS.f("&7You gave nametag &a" + tag.getDisplayName() + "&7 to player " + u.getColoredName(player) + "&7!")); + return true; + } + case "remove": + if (args.length != 3) { + s.sendMessage(Utils.f("&c/nametag remove ")); + return true; + } + Nametag tag = Core.getNametagManager().getNametag(args[2]); + if (tag == null) { + s.sendMessage(Lang.NAMETAGS.f("&7That is not a nametag! Do &a/nametag list&7 to see a list!")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player == null) { +// Core.sql.updateAsyncLater("update nametags set `" + tag + "`=false where name='" + args[1] + "';"); + s.sendMessage(Lang.NAMETAGS.f("&7That player is not online, so his nametags have been updated directly in the database!")); + return true; + } + User u = Core.getUserManager().getLoadedUser(player.getUniqueId()); + u.takeNametag(tag); + s.sendMessage(Lang.NAMETAGS.f("&7You removed nametag &a" + tag.getDisplayName() + "&7 from player " + u.getColoredName(player) + "&7!")); + return true; + case "reload": + Core.getSettings().setNametagsConfig(Utils.loadConfigFromMaster("nametags")); + Core.getNametagManager().loadNametags(); + s.sendMessage(Utils.f("&7The nametags config was reloaded!")); + return true; + default: + s.sendMessage(Lang.NAMETAGS.f("&7/nametag list")); + s.sendMessage(Lang.NAMETAGS.f("&7/nametag give ")); + s.sendMessage(Lang.NAMETAGS.f("&7/nametag remove ")); + s.sendMessage(Lang.NAMETAGS.f("&7/nametag reload")); + return true; + } + + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/nametags/NametagManager.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/nametags/NametagManager.java new file mode 100644 index 0000000..43143e1 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/nametags/NametagManager.java @@ -0,0 +1,173 @@ +package net.grandtheftmc.core.nametags; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.scoreboard.Scoreboard; +import org.bukkit.scoreboard.Team; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.events.NametagUpdateEvent; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserManager; +import net.grandtheftmc.core.util.Component; +import net.grandtheftmc.core.util.Utils; + +public class NametagManager implements Component { + + private final List nametags = new ArrayList<>(); + + public NametagManager() { + this.loadNametags(); + } + + @Override + public NametagManager onDisable(Core plugin) { + this.nametags.clear(); + return this; + } + + public static void updateNametag(Player player) { + + // if invalid player + if (player == null || !player.isOnline()){ + return; + } + // create nametag update event + NametagUpdateEvent event = new NametagUpdateEvent(player); + + User user = UserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + if (user != null){ + + if (user.isSpecial()){ + event.setPrefix(user.getUserRank().getTabPrefix()); + } + + // call nametag update event + Bukkit.getPluginManager().callEvent(event); + + String prefix = event.getPrefix() == null ? "&r" : event.getPrefix() + (event.getNameColor() == null ? " &r" : ' ' + event.getNameColor()); + String suffix = event.getSuffix() == null ? "" : ' ' + event.getSuffix(); + + for (Player p : Bukkit.getOnlinePlayers()) { + User u = UserManager.getInstance().getUser(p.getUniqueId()).orElse(null); + if (u != null){ + + Scoreboard board = u.getScoreboard(); + Team team = board.getTeam(player.getName()); + if (team == null) + team = board.registerNewTeam(player.getName()); + team.setPrefix(Utils.f(prefix)); + team.setSuffix(Utils.f(suffix.length() > 16 ? suffix.substring(0,16) : suffix)); + team.addEntry(player.getName()); + /*if (event.getBelowName() != null) { + Objective obj = board.getObjective(event.getBelowName()); + if (obj == null) + obj = board.registerNewObjective(event.getBelowName(), "dummy"); + obj.setDisplaySlot(DisplaySlot.BELOW_NAME); + obj.setDisplayName(event.getBelowName()); + obj.getScore(player.getName()).setScore(event.getValue()); + }*/ + p.setScoreboard(board); + } + } + } + } + + public static void updateNametagsTo(Player player, User user) { + if (player == null || !player.isOnline() || user == null){ + return; + } + + // grab scoreboard + Scoreboard board = user.getScoreboard(); + + // for all other players + for (Player p : Bukkit.getOnlinePlayers()) { + + // create nametag update event + NametagUpdateEvent event = new NametagUpdateEvent(p); + + // grab user object + User u = UserManager.getInstance().getUser(p.getUniqueId()).orElse(null); + if (u != null){ + + if (u.isSpecial()){ + event.setPrefix(u.getUserRank().getTabPrefix()); + } + + + // call event + Bukkit.getPluginManager().callEvent(event); + + String prefix = event.getPrefix() == null ? "&r" : event.getPrefix() + (event.getNameColor() == null ? " &r" : ' ' + event.getNameColor()); + String suffix = event.getSuffix() == null ? "" : ' ' + event.getSuffix(); + + Team team = board.getTeam(p.getName()); + if (team == null){ + team = board.registerNewTeam(p.getName()); + } + team.setPrefix(Utils.f(prefix)); + team.setSuffix(Utils.f(suffix.length() > 16 ? suffix.substring(0,16) : suffix)); + team.addEntry(p.getName()); + /*if (event.getBelowName() != null) { + Objective obj = board.getObjective(event.getBelowName()); + if (obj == null) + obj = board.registerNewObjective(event.getBelowName(), "dummy"); + obj.setDisplaySlot(DisplaySlot.BELOW_NAME); + obj.setDisplayName(event.getBelowName()); + obj.getScore(p.getName()).setScore(event.getValue()); + }*/ + } + } + player.setScoreboard(board); + } + + public void loadNametags() { + YamlConfiguration c = Core.getSettings().getNametagsConfig(); + this.nametags.clear(); + for (String s : c.getKeys(false)) { + try { + String displayName = c.getString(s + ".displayName"); + int price = c.getInt(s + ".price"); + this.nametags.add(new Nametag(s, displayName, price)); + } catch (Exception e) { + Core.log("Error loading nametag: " + s); + e.printStackTrace(); + } + } + } + + public List getNametags() { + return this.nametags; + } + + public List getNametags(User user) { + List list = new ArrayList<>(); + List list2 = new ArrayList<>(); + for (Nametag tag : this.nametags) + if (user.hasNametag(tag)) list.add(tag); + else list2.add(tag); + list.addAll(list2); + return list; + + } + + public Nametag getNametag(String s) { + for (Nametag t : this.nametags) + if (t.getName().equalsIgnoreCase(s)) + return t; + return null; + } + + public Nametag getNametagFromDisplayName(String s) { + for (Nametag t : this.nametags) + if (t.getDisplayName().equalsIgnoreCase(s)) + return t; + return null; + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/neural/NeuralNetTools.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/neural/NeuralNetTools.java new file mode 100644 index 0000000..9f99a16 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/neural/NeuralNetTools.java @@ -0,0 +1,73 @@ +package net.grandtheftmc.core.neural; + +public class NeuralNetTools { + public static double[] createArray(int size, double init_value) { + if (size < 1) { + return null; + } + double[] ar = new double[size]; + for (int i = 0; i < size; i++) { + ar[i] = init_value; + } + return ar; + } + + public static double[] createRandomArray(int size, double lower_bound, double upper_bound) { + if (size < 1) { + return null; + } + double[] ar = new double[size]; + for (int i = 0; i < size; i++) { + ar[i] = randomValue(lower_bound, upper_bound); + } + return ar; + } + + public static double[][] createRandomArray(int sizeX, int sizeY, double lower_bound, double upper_bound) { + if (sizeX < 1 || sizeY < 1) { + return null; + } + double[][] ar = new double[sizeX][sizeY]; + for (int i = 0; i < sizeX; i++) { + ar[i] = createRandomArray(sizeY, lower_bound, upper_bound); + } + return ar; + } + + public static double randomValue(double lower_bound, double upper_bound) { + return Math.random() * (upper_bound - lower_bound) + lower_bound; + } + + public static Integer[] randomValues(int lowerBound, int upperBound, int amount) { + lowerBound--; + if (amount > (upperBound - lowerBound)) return null; + + Integer[] values = new Integer[amount]; + for (int i = 0; i < amount; i++) { + int n = (int) (Math.random() * (upperBound - lowerBound + 1) + lowerBound); + while (containsValue(values, n)) + n = (int) (Math.random() * (upperBound - lowerBound + 1) + lowerBound); + values[i] = n; + } + return values; + } + + public static > boolean containsValue(T[] ar, T value) { + for (T anAr : ar) { + if (anAr != null && value.compareTo(anAr) == 0) { + return true; + } + } + return false; + } + + public static int indexOfHighestValue(double[] values) { + int index = 0; + for (int i = 1; i < values.length; i++) { + if (values[i] > values[index]) { + index = i; + } + } + return index; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/neural/NeuralNetwork.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/neural/NeuralNetwork.java new file mode 100644 index 0000000..56db226 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/neural/NeuralNetwork.java @@ -0,0 +1,221 @@ +package net.grandtheftmc.core.neural; + +import net.grandtheftmc.core.neural.parser.NeuralAttribute; +import net.grandtheftmc.core.neural.parser.NeuralNode; +import net.grandtheftmc.core.neural.parser.NeuralParser; +import net.grandtheftmc.core.neural.parser.NeuralParserTools; + +import java.io.*; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class NeuralNetwork { + + private double[][] output; + private double[][][] weights; + private double[][] bias; + + private double[][] errorSignal; + private double[][] outputDerivative; + + /** + * Neurons in a layer + */ + private final int[] layerSizes; + + private final int inputSize, outputSize, networkSize; + + public NeuralNetwork(int... layerSizes) { + this.layerSizes = layerSizes; + this.inputSize = layerSizes[0]; + this.networkSize = layerSizes.length; + this.outputSize = layerSizes[this.networkSize - 1]; + + this.output = new double[this.networkSize][]; + this.weights = new double[this.networkSize][][]; + this.bias = new double[this.networkSize][]; + + this.errorSignal = new double[this.networkSize][]; + this.outputDerivative = new double[this.networkSize][]; + + for (int i = 0; i < this.networkSize; i++) { + this.output[i] = new double[layerSizes[i]]; + this.errorSignal[i] = new double[layerSizes[i]]; + this.outputDerivative[i] = new double[layerSizes[i]]; + this.bias[i] = NeuralNetTools.createRandomArray(layerSizes[i], -0.5, 0.7); + if (i > 0) this.weights[i] = NeuralNetTools.createRandomArray(layerSizes[i], layerSizes[i - 1], -1, 1); + } + } + + public double[] calculate(double... input) { + if (input.length != this.inputSize) return null; + this.output[0] = input; + for (int layer = 1; layer < this.networkSize; layer++) { + for (int neuron = 0; neuron < this.layerSizes[layer]; neuron++) { + double x = this.bias[layer][neuron]; + for (int prevNeuron = 0; prevNeuron < this.layerSizes[layer - 1]; prevNeuron++) + x += this.output[layer - 1][prevNeuron] * this.weights[layer][neuron][prevNeuron]; + this.output[layer][neuron] = sigmoid(x); + this.outputDerivative[layer][neuron] = this.output[layer][neuron] * (1 - this.output[layer][neuron]); + } + } + return this.output[this.networkSize - 1]; + } + + public void train(NeuralTrainSet set, int loops, int batchSize) { + if (set.INPUT_SIZE != this.inputSize || set.OUTPUT_SIZE != this.outputSize) return; + for (int i = 0; i < loops; i++) { + NeuralTrainSet batch = set.extractBatch(batchSize); + for (int x = 0; x < batchSize; x++) + this.train(batch.getInput(x), batch.getOutput(x), 0.3); + System.out.println(MSE(batch)); + } + } + + private double sigmoid(double x) { + return 1d / (1 + Math.exp(-x)); + } + + public void train(double[] input, double[] target, double eta) { + if (input.length != this.inputSize || target.length != this.outputSize) return; + calculate(input); + backpropError(target); + updateWeights(eta); + } + + public void backpropError(double[] target) { + for (int neuron = 0; neuron < this.layerSizes[this.networkSize - 1]; neuron++) + this.errorSignal[this.networkSize - 1][neuron] = (this.output[this.networkSize - 1][neuron] - target[neuron]) * this.outputDerivative[this.networkSize - 1][neuron]; + + for (int layer = this.networkSize - 2; layer > 0; layer--) { + for (int neuron = 0; neuron < this.layerSizes[layer]; neuron++) { + double x = 0; + for (int nextNeuron = 0; nextNeuron < this.layerSizes[layer + 1]; nextNeuron++) + x += this.weights[layer + 1][nextNeuron][neuron] * this.errorSignal[layer + 1][nextNeuron]; + this.errorSignal[layer][neuron] = x * this.outputDerivative[layer][neuron]; + } + } + } + + public void updateWeights(double eta) { + for (int layer = 1; layer < this.networkSize; layer++) { + for (int neuron = 0; neuron < this.layerSizes[layer]; neuron++) { + double delta = -eta * this.errorSignal[layer][neuron]; + this.bias[layer][neuron] += delta; + + for (int prevNeuron = 0; prevNeuron < this.layerSizes[layer - 1]; prevNeuron++) + this.weights[layer][neuron][prevNeuron] += delta * this.output[layer - 1][prevNeuron]; + } + } + } + + public double MSE(double[] input, double[] target) { + if (input.length != this.inputSize || target.length != this.outputSize) return 0; + calculate(input); + double v = 0; + for (int i = 0; i < target.length; i++) + v += (target[i] - this.output[this.networkSize - 1][i]) * (target[i] - this.output[this.networkSize - 1][i]); + return v / (2d * target.length); + } + + public double MSE(NeuralTrainSet set) { + double v = 0; + for (int i = 0; i < set.size(); i++) + v += MSE(set.getInput(i), set.getOutput(i)); + return v / set.size(); + } + + public static void main1(String[] args) { + NeuralNetwork network = new NeuralNetwork(4, 3, 3, 2); + + +// double[] input = new double[] { 0.1, 0.2, 0.3, 0.4 }; +// double[] target = new double[] { 0.9, 0.1 }; +// +// for(int i = 0; i < 1000; i++) { +// network.train(input, target, 0.3); +// } +// +// System.out.println(Arrays.toString(network.calculate(input))); + + + NeuralTrainSet trainSet = new NeuralTrainSet(4, 2); + trainSet.addData(new double[]{0.1, 0.2, 0.3, 0.4}, new double[]{0.9, 0.1}); + trainSet.addData(new double[]{0.9, 0.8, 0.7, 0.6}, new double[]{0.1, 0.9}); + trainSet.addData(new double[]{0.3, 0.8, 0.1, 0.4}, new double[]{0.3, 0.7}); + trainSet.addData(new double[]{0.9, 0.8, 0.1, 0.2}, new double[]{0.7, 0.3}); + + network.train(trainSet, 10000, 4); + + for (int i = 0; i < 4; i++) { + double[] result = network.calculate(trainSet.getInput(i)); + System.out.println(Arrays.toString(result)); + for (int x = 0; x < result.length; x++) { + System.out.println("Goal(" + i + "," + x + "): " + trainSet.getOutput(i)[x]); + System.out.println("Result(" + i + "," + x + "): " + result[x]); + System.out.println("Percent: " + network.getPercentDifference(trainSet.getOutput(i)[x], result[x]) + "%"); + System.out.println(); + } + System.out.println(); + System.out.println(); + } + } + + public static void main(String[] args) { +// NeuralNetwork network = new NeuralNetwork(4,3,2); +// network.save("res/test.txt"); + + NeuralNetwork network = NeuralNetwork.load("res/test.txt"); + System.out.println(Arrays.toString(network.layerSizes)); + } + + public double getPercentDifference(double goal, double result) { + return 100 - Math.abs(((goal - result) / goal) * 100d); + } + + public void save(String fileName) { + NeuralParser parser = new NeuralParser(); + parser.create(fileName); + NeuralNode root = parser.getContent(); + NeuralNode network = new NeuralNode("network"); + NeuralNode layers = new NeuralNode("layers"); + network.addAttribute(new NeuralAttribute("sizes", Arrays.toString(this.layerSizes))); + network.addChild(layers); + root.addChild(network); + + for (int layer = 1; layer < this.networkSize; layer++) { + NeuralNode node = new NeuralNode("" + layer); + layers.addChild(node); + NeuralNode nodeWeights = new NeuralNode("weights"); + NeuralNode nodeBiases = new NeuralNode("biases"); + node.addChild(nodeWeights); + node.addChild(nodeBiases); + nodeBiases.addAttribute("values", Arrays.toString(this.bias[layer])); + + for (int we = 0; we < this.weights[layer].length; we++) + nodeWeights.addAttribute("" + we, Arrays.toString(this.weights[layer][we])); + } + + parser.close(); + } + + public static NeuralNetwork load(String fileName) { + NeuralParser parser = new NeuralParser(); + parser.load(fileName); + String sizes = parser.getValue(new String[]{"network"}, "sizes"); + int[] si = NeuralParserTools.parseIntArray(sizes); + NeuralNetwork network = new NeuralNetwork(si); + + for (int i = 1; i < network.networkSize; i++) { + network.bias[i] = NeuralParserTools.parseDoubleArray(parser.getValue(new String[]{"network", "layers", (i + ""), "biases"}, "values")); + + for (int n = 0; n < network.layerSizes[i]; n++) + network.weights[i][n] = NeuralParserTools.parseDoubleArray(parser.getValue(new String[]{"network", "layers", (i + ""), "weights"}, "" + n)); + } + + parser.close(); + return network; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/neural/NeuralTrainSet.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/neural/NeuralTrainSet.java new file mode 100644 index 0000000..17ab12a --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/neural/NeuralTrainSet.java @@ -0,0 +1,90 @@ +package net.grandtheftmc.core.neural; + +import java.util.ArrayList; +import java.util.Arrays; + +public class NeuralTrainSet { + + public final int INPUT_SIZE; + public final int OUTPUT_SIZE; + + //double[][] <- index1: 0 = input, 1 = output || index2: index of element + private ArrayList data = new ArrayList<>(); + + public NeuralTrainSet(int INPUT_SIZE, int OUTPUT_SIZE) { + this.INPUT_SIZE = INPUT_SIZE; + this.OUTPUT_SIZE = OUTPUT_SIZE; + } + + public void addData(double[] in, double[] expected) { + if (in.length != INPUT_SIZE || expected.length != OUTPUT_SIZE) return; + data.add(new double[][]{in, expected}); + } + + public NeuralTrainSet extractBatch(int size) { + if (size > 0 && size <= this.size()) { + NeuralTrainSet set = new NeuralTrainSet(INPUT_SIZE, OUTPUT_SIZE); + Integer[] ids = NeuralNetTools.randomValues(0, this.size() - 1, size); + for (Integer i : ids) set.addData(this.getInput(i), this.getOutput(i)); + return set; + } else return this; + } + + public static void main(String[] args) { + NeuralTrainSet set = new NeuralTrainSet(3, 2); + + for (int i = 0; i < 8; i++) { + double[] a = new double[3]; + double[] b = new double[2]; + for (int k = 0; k < 3; k++) { + a[k] = (double) ((int) (Math.random() * 10)) / (double) 10; + if (k < 2) b[k] = (double) ((int) (Math.random() * 10)) / (double) 10; + } + set.addData(a, b); + } + + System.out.println(set); + System.out.println(set.extractBatch(3)); + } + + public String toString() { + StringBuilder s = new StringBuilder("TrainSet [" + INPUT_SIZE + " ; " + OUTPUT_SIZE + "]\n"); + int index = 0; + for (double[][] r : data) { + s.append(index) + .append(": ") + .append(Arrays.toString(r[0])) + .append(" | ") + .append(Arrays.toString(r[1])) + .append("\n"); + index++; + } + return s.toString(); + } + + public int size() { + return data.size(); + } + + public double[] getInput(int index) { + return index >= 0 && index < size() ? data.get(index)[0] : null; +// if (index >= 0 && index < size()) +// return data.get(index)[0]; +// else return null; + } + + public double[] getOutput(int index) { + return index >= 0 && index < size() ? data.get(index)[1] : null; +// if (index >= 0 && index < size()) +// return data.get(index)[1]; +// else return null; + } + + public int getINPUT_SIZE() { + return INPUT_SIZE; + } + + public int getOUTPUT_SIZE() { + return OUTPUT_SIZE; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/neural/mnist/Mnist.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/neural/mnist/Mnist.java new file mode 100644 index 0000000..dad3fd6 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/neural/mnist/Mnist.java @@ -0,0 +1,77 @@ +package net.grandtheftmc.core.neural.mnist; + +import net.grandtheftmc.core.neural.NeuralNetTools; +import net.grandtheftmc.core.neural.NeuralNetwork; +import net.grandtheftmc.core.neural.NeuralTrainSet; + +import java.io.File; + +/** + * Created by Luecx on 10.08.2017. + */ +public class Mnist { + + public static void main(String[] args) { +// NeuralNetwork network = new NeuralNetwork(784, 50, 10); +// trainData(network, createTrainSet(0,100), 1000, 100, 100, "res/mnist1.txt"); + + NeuralNetwork network = NeuralNetwork.load("res/mnist1.txt"); + testTrainSet(network, createTrainSet(0,50000), 1000); + } + + public static NeuralTrainSet createTrainSet(int start, int end) { + NeuralTrainSet set = new NeuralTrainSet(28 * 28, 10); + try { + String path = new File("").getAbsolutePath(); + MnistImageFile m = new MnistImageFile(path + "/res/trainImage.idx3-ubyte", "rw"); + MnistLabelFile l = new MnistLabelFile(path + "/res/trainLabel.idx1-ubyte", "rw"); + for(int i = start; i <= end; i++) { + if(i % 100 == 0){ + System.out.println("prepared: " + i); + } + + double[] input = new double[28 * 28]; + double[] output = new double[10]; + + output[l.readLabel()] = 1d; + for(int j = 0; j < 28*28; j++){ + input[j] = (double)m.read() / (double)256; + } + + set.addData(input, output); + m.next(); + l.next(); + } + } catch (Exception e) { + e.printStackTrace(); + } + + return set; + } + + public static void trainData(NeuralNetwork net,NeuralTrainSet set, int epochs, int loops, int batch_size, String outputFile) { + for(int e = 0; e < epochs;e++) { + net.train(set, loops, batch_size); + System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>> "+ e+ " <<<<<<<<<<<<<<<<<<<<<<<<<<"); + + net.save(outputFile); + } + } + + public static void testTrainSet(NeuralNetwork net, NeuralTrainSet set, int printSteps) { + int correct = 0; + for(int i = 0; i < set.size(); i++) { + + double highest = NeuralNetTools.indexOfHighestValue(net.calculate(set.getInput(i))); + double actualHighest = NeuralNetTools.indexOfHighestValue(set.getOutput(i)); + if(highest == actualHighest) { + + correct ++ ; + } + if(i % printSteps == 0) { + System.out.println(i + ": " + (double)correct / (double) (i + 1)); + } + } + System.out.println("Testing finished, RESULT: " + correct + " / " + set.size()+ " -> " + (double)correct / (double)set.size() +" %"); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/neural/mnist/MnistDbFile.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/neural/mnist/MnistDbFile.java new file mode 100644 index 0000000..590afad --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/neural/mnist/MnistDbFile.java @@ -0,0 +1,112 @@ +package net.grandtheftmc.core.neural.mnist; + + + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; + +/** + * MNIST database file containing entries that can represent image or label + * data. Extends the standard random access file with methods for navigating + * over the entries. The file format is basically idx with specific header + * information. This includes a magic number for determining the type of stored + * entries, count of entries. + */ +public abstract class MnistDbFile extends RandomAccessFile { + private int count; + + + /** + * Creates new instance and reads the header information. + * + * @param name + * the system-dependent filename + * @param mode + * the access mode + * @throws IOException + * @throws FileNotFoundException + * @see RandomAccessFile + */ + public MnistDbFile(String name, String mode) throws IOException { + super(name, mode); + if (getMagicNumber() != readInt()) { + throw new RuntimeException("This MNIST DB file " + name + " should start with the number " + getMagicNumber() + "."); + } + count = readInt(); + } + + /** + * MNIST DB files start with unique integer number. + * + * @return integer number that should be found in the beginning of the file. + */ + protected abstract int getMagicNumber(); + + /** + * The current entry index. + * + * @return long + * @throws IOException + */ + public long getCurrentIndex() throws IOException { + return (getFilePointer() - getHeaderSize()) / getEntryLength() + 1; + } + + /** + * Set the required current entry index. + * + * @param curr + * the entry index + */ + public void setCurrentIndex(long curr) { + try { + if (curr < 0 || curr > count) { + throw new RuntimeException(curr + " is not in the range 0 to " + count); + } + seek(getHeaderSize() + (curr - 1) * getEntryLength()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public int getHeaderSize() { + return 8; // two integers + } + + /** + * Number of bytes for each entry. + * Defaults to 1. + * + * @return int + */ + public int getEntryLength() { + return 1; + } + + /** + * Move to the next entry. + * + * @throws IOException + */ + public void next() throws IOException { + if (getCurrentIndex() < count) { + skipBytes(getEntryLength()); + } + } + + /** + * Move to the previous entry. + * + * @throws IOException + */ + public void prev() throws IOException { + if (getCurrentIndex() > 0) { + seek(getFilePointer() - getEntryLength()); + } + } + + public int getCount() { + return count; + } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/neural/mnist/MnistImageFile.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/neural/mnist/MnistImageFile.java new file mode 100644 index 0000000..492e05f --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/neural/mnist/MnistImageFile.java @@ -0,0 +1,101 @@ +package net.grandtheftmc.core.neural.mnist; + + +import java.io.FileNotFoundException; +import java.io.IOException; + +/** + * + * MNIST database image file. Contains additional header information for the + * number of rows and columns per each entry. + * + */ +public class MnistImageFile extends MnistDbFile { + private int rows; + private int cols; + + /** + * Creates new MNIST database image file ready for reading. + * + * @param name + * the system-dependent filename + * @param mode + * the access mode + * @throws IOException + * @throws FileNotFoundException + */ + public MnistImageFile(String name, String mode) throws FileNotFoundException, IOException { + super(name, mode); + + // read header information + rows = readInt(); + cols = readInt(); + } + + /** + * Reads the image at the current position. + * + * @return matrix representing the image + * @throws IOException + */ + public int[][] readImage() throws IOException { + int[][] dat = new int[getRows()][getCols()]; + for (int i = 0; i < getCols(); i++) { + for (int j = 0; j < getRows(); j++) { + dat[i][j] = readUnsignedByte(); + } + } + return dat; + } + + /** + * Move the cursor to the next image. + * + * @throws IOException + */ + public void nextImage() throws IOException { + super.next(); + } + + /** + * Move the cursor to the previous image. + * + * @throws IOException + */ + public void prevImage() throws IOException { + super.prev(); + } + + @Override + protected int getMagicNumber() { + return 2051; + } + + /** + * Number of rows per image. + * + * @return int + */ + public int getRows() { + return rows; + } + + /** + * Number of columns per image. + * + * @return int + */ + public int getCols() { + return cols; + } + + @Override + public int getEntryLength() { + return cols * rows; + } + + @Override + public int getHeaderSize() { + return super.getHeaderSize() + 8; // to more integers - rows and columns + } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/neural/mnist/MnistImageLoader.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/neural/mnist/MnistImageLoader.java new file mode 100644 index 0000000..1b3411f --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/neural/mnist/MnistImageLoader.java @@ -0,0 +1,67 @@ +package net.grandtheftmc.core.neural.mnist; + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.RenderingHints; +import java.awt.image.BufferedImage; +import java.io.File; + +import javax.imageio.ImageIO; + +public class MnistImageLoader { + + public static BufferedImage loadImage(String path) throws Exception{ + return resize(ImageIO.read(new File(path)),28,28); + } + + public static BufferedImage resize(BufferedImage img, int newW, int newH) { + Image tmp = img.getScaledInstance(newW, newH, Image.SCALE_SMOOTH); + BufferedImage dimg = new BufferedImage(newW, newH, BufferedImage.TYPE_INT_ARGB); + + Graphics2D g2d = dimg.createGraphics(); + g2d.drawImage(tmp, 0, 0, null); + g2d.dispose(); + + return dimg; +} + + public static int[][] bufferedImageToArray(BufferedImage img) { + int[][] arr = new int[img.getWidth()][img.getHeight()]; + + for(int i = 0; i < img.getWidth(); i++) + for(int j = 0; j < img.getHeight(); j++) + arr[i][j] = img.getRGB(i, j); + + return arr; + } + + public static int[][] bufferedImageRedToArray(BufferedImage img) { + int[][] arr = new int[img.getWidth()][img.getHeight()]; + + for(int i = 0; i < img.getWidth(); i++) + for(int j = 0; j < img.getHeight(); j++) + arr[i][j] = new Color(img.getRGB(i, j)).getRed(); + + return arr; + } + + public static double[] intArrayToDoubleArray(int[][] i) { + double[] ar = new double[i.length * i[0].length]; + for(int j = 0 ; j < i.length; j ++){ + for(int n = 0; n < i[0].length; n++){ + ar[j * i.length + n] = (double)i[n][j] / (double)256; + } + } + return ar; + } + + public static double[] invert(double[] ar) { + for(int j = 0 ; j < ar.length; j ++){ + ar[j] = 0.9999-ar[j]; + } + return ar; + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/neural/mnist/MnistLabelFile.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/neural/mnist/MnistLabelFile.java new file mode 100644 index 0000000..0d76aa1 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/neural/mnist/MnistLabelFile.java @@ -0,0 +1,49 @@ +package net.grandtheftmc.core.neural.mnist; + +import java.io.FileNotFoundException; +import java.io.IOException; + + +/** + * + * MNIST database label file. + * + */ +public class MnistLabelFile extends MnistDbFile { + + /** + * Creates new MNIST database label file ready for reading. + * + * @param name + * the system-dependent filename + * @param mode + * the access mode + * @throws IOException + * @throws FileNotFoundException + */ + public MnistLabelFile(String name, String mode) throws IOException { + super(name, mode); + } + + /** + * Reads the integer at the current position. + * + * @return integer representing the label + * @throws IOException + */ + public int readLabel() throws IOException { + return readUnsignedByte(); + } + + /** Read the specified number of labels from the current position*/ + public int[] readLabels(int num) throws IOException { + int[] out = new int[num]; + for( int i=0; i childs = new ArrayList<>(); + private ArrayList attributes = new ArrayList<>(); + + public NeuralNode(String name) { + this.name = name; + } + + public boolean addAttribute(NeuralAttribute att) { + if (att != null) { + if (this.containsAttribute(att)) return false; + attributes.add(att); + return true; + } + return false; + } + + public boolean addAttribute(String att, String value) { + return this.addAttribute(new NeuralAttribute(att, value)); + } + + public boolean addChild(String name) { + return this.addChild(new NeuralNode(name)); + } + + public boolean addChild(NeuralNode n) { + if (n != null) { + if (this.containsChild(n)) return false; + childs.add(n); + return true; + } + return false; + } + + public NeuralNode getChild(String child) { + for (NeuralNode r : childs) { + if (r.getName().equals(child)) { + return r; + } + } + return null; + } + + public NeuralAttribute getAttribute(String key) { + for (NeuralAttribute r : attributes) { + if (r.getName().equals(key)) return r; + } + return null; + } + + public void setAttribute(String att, String value) { + if (this.getAttribute(att) != null) { + this.getAttribute(att).setValue(value); + } + } + + public boolean removeAttribute(String att) { + return this.removeAttribute(new NeuralAttribute(att, "")); + } + + public boolean removeChild(String child) { + return this.removeChild(new NeuralNode(child)); + } + + public boolean removeAttribute(NeuralAttribute att) { + int index = 0; + for (NeuralAttribute r : attributes) { + if (r.equals(att)) { + childs.remove(index); + return true; + } + index++; + } + return false; + } + + public boolean removeChild(NeuralNode child) { + int index = 0; + for (NeuralNode r : childs) { + if (child.equals(r)) { + childs.remove(index); + return true; + } + index++; + } + return false; + } + + public boolean containsAttribute(NeuralAttribute s) { + for (NeuralAttribute r : attributes) { + if (r.equalAttribute(s)) { + return true; + } + } + return false; + } + + public boolean containsChild(NeuralNode s) { + for (NeuralNode r : childs) { + if (s.equals(r)) { + return true; + } + } + return false; + } + + public static NeuralNode parse(String c) { + String[] lines = c.split("[;>]"); + NeuralNode n = new NeuralNode(lines[0].substring(1, lines[0].length())); + + int i = 1; + while (i < lines.length - 1) { + String currentLine = lines[i].trim(); + + String nodeName = ""; + if (currentLine.startsWith("<")) { + nodeName = currentLine.substring(1); + String batch = ""; + while (!lines[i].trim().startsWith("" + "\n"; + + for (NeuralAttribute at : attributes) + res += at.toParse(spacesLeft + 4) + "\n"; + + for (NeuralNode n : childs) + res += n.toParse(spacesLeft + 4); + + res += NeuralParserTools.createSpaces(spacesLeft) + "" + "\n"; + return res; + } + + public String getName() { + return this.name; + } + + public ArrayList getChilds() { + return this.childs; + } + + public boolean equals(Object o) { + if (o.getClass() != this.getClass()) return false; + if (!Objects.equals(((NeuralNode) o).getName(), this.getName())) return false; + return true; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/neural/parser/NeuralParser.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/neural/parser/NeuralParser.java new file mode 100644 index 0000000..3e5aa17 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/neural/parser/NeuralParser.java @@ -0,0 +1,86 @@ +package net.grandtheftmc.core.neural.parser; + +import java.io.*; + +public class NeuralParser { + + private NeuralNode mainContent; + private String fileName; + + public void load(String file) { + this.fileName = file; + StringBuilder data = new StringBuilder(""); + try (BufferedReader reader = new BufferedReader(new FileReader(file))) { + String line; + while ((line = reader.readLine()) != null) + if (!line.trim().equals("")) data.append(line); + + data.append(""); + this.generateNodes(data.toString()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void create(String fileName) { + this.fileName = fileName; + this.mainContent = new NeuralNode("mainContent"); + } + + private void generateNodes(String data) { + mainContent = NeuralNode.parse(data); + } + + public NeuralNode getContent() { + return mainContent; + } + + public String getValue(String[] keys, String attr) { + NeuralNode curr = mainContent; + for (String k : keys) { + curr = curr.getChild(k); + if (curr == null) { + return null; + } + } + return curr.getAttribute(attr).getValue(); + } + + public void setValue(String[] keys, String attr, String value) { + NeuralNode curr = mainContent; + for (String k : keys) { + curr = curr.getChild(k); + if (curr == null) return; + } + if (curr.containsAttribute(new NeuralAttribute(attr, ""))) + curr.setAttribute(attr, value); + else curr.addAttribute(attr, value); + } + + public void addNode(String[] keys, NeuralNode n) { + NeuralNode curr = mainContent; + for (String k : keys) { + curr = curr.getChild(k); + if (curr == null) return; + } + curr.addChild(n); + } + + public void addNode(String[] keys, String node) { + NeuralNode curr = mainContent; + for (String k : keys) { + curr = curr.getChild(k); + if (curr == null) return; + } + curr.addChild(new NeuralNode(node)); + } + + public void close() { + try (PrintWriter out = new PrintWriter(fileName)) { + for (NeuralNode n : mainContent.getChilds()) + out.print(n.toParse(0)); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/neural/parser/NeuralParserTools.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/neural/parser/NeuralParserTools.java new file mode 100644 index 0000000..91b344e --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/neural/parser/NeuralParserTools.java @@ -0,0 +1,52 @@ +package net.grandtheftmc.core.neural.parser; + +public class NeuralParserTools { + + public static int parseInt(String code) { + return Integer.parseInt(code); + } + + public static float parseFloat(String code) { + return Float.parseFloat(code); + } + + public static double parseDouble(String code) { + return Double.parseDouble(code); + } + + public static int[] parseIntArray(String code) { + code = code.substring(1, code.length() - 1); + String[] data = code.split(","); + int[] d = new int[data.length]; + for (int i = 0; i < d.length; i++) + d[i] = Integer.parseInt(data[i].trim()); + return d; + } + + public static double[] parseDoubleArray(String code) { + code = code.substring(1, code.length() - 1); + String[] data = code.split(","); + double[] d = new double[data.length]; + for (int i = 0; i < d.length; i++) + d[i] = Double.parseDouble(data[i].trim()); + return d; + } + + public static float[] parseFloatArray(String code) { + code = code.substring(1, code.length() - 1); + String[] data = code.split(","); + float[] d = new float[data.length]; + for (int i = 0; i < d.length; i++) + d[i] = Float.parseFloat(data[i].trim()); + return d; + } + + public static String createSpaces(int amount) { + StringBuilder res = new StringBuilder(); + for (int i = 0; i < amount; i++) + res.append(" "); + return res.toString(); + } + + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/npc/CoreNPC.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/npc/CoreNPC.java new file mode 100644 index 0000000..390c9e6 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/npc/CoreNPC.java @@ -0,0 +1,312 @@ +package net.grandtheftmc.core.npc; + +import java.util.List; + +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.entity.Ageable; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.entity.Zombie; + +import com.gmail.filoghost.holographicdisplays.api.Hologram; +import com.gmail.filoghost.holographicdisplays.api.HologramsAPI; +import com.google.common.collect.Lists; +import com.mojang.authlib.properties.Property; + +import net.citizensnpcs.api.CitizensAPI; +import net.citizensnpcs.api.event.DespawnReason; +import net.citizensnpcs.api.npc.NPC; +import net.citizensnpcs.npc.skin.SkinnableEntity; +import net.citizensnpcs.trait.Age; +import net.citizensnpcs.trait.Controllable; +import net.citizensnpcs.trait.Gravity; +import net.citizensnpcs.trait.LookClose; +import net.citizensnpcs.trait.SkinLayers; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.ServerUtil; + +/** + * Created by Timothy Lampen on 1/13/2018. + * + * @apiNote When you implements one of the interfaces you still have to set the targetable / damageable / collidable / etc traits using this class. + * @apiNote When making changes to the NPC entity such as it's location, rather do NPC#teleport than Entity#teleport. + */ +public abstract class CoreNPC { + + private final NPC npc; + private final int id; + private final Location startingLoc; + private final Hologram hologram; + private final EntityType type; + + /** + * @apiNote default constructor for the CoreNPC, does generateNewNPC after it is completed. + */ + public CoreNPC(Location loc, EntityType type, String displayName) { + this(loc, type, displayName, null); + } + + /** + * @apiNote if you use this constructor, you cannot TP the entity expect for the first, original location. If functionality is required, talk to teddeh to implement negative slime shit. + */ + public CoreNPC(Location loc, EntityType type, String... lines) { + this.type = type; + + if (!loc.getChunk().isLoaded()) + loc.getChunk().load(); + + //Remove left over NPC's if any. + List toRemove = Lists.newArrayList(); + CitizensAPI.getNPCRegistry().forEach(citizensNPC -> { + if (citizensNPC.getEntity() != null && citizensNPC.getEntity().getLocation() != null) { + if (citizensNPC.getEntity().getLocation().distance(loc) < 1) { + toRemove.add(citizensNPC); + } + } + }); + + for (NPC remove : toRemove) { + try { remove.despawn(); } catch (Exception e) {} + try { remove.destroy(); } catch (Exception e) {} + } + + if (lines.length == 1) { + this.npc = CitizensAPI.getNPCRegistry().createNPC(type, ChatColor.translateAlternateColorCodes('&', lines[0])); + this.hologram = null; + } + else { + this.npc = CitizensAPI.getNPCRegistry().createNPC(type, ""); + this.hologram = HologramsAPI.createHologram(Core.getInstance(), loc.clone().add(0, 2.575, 0)); + for (String s : lines) + this.hologram.appendTextLine(ChatColor.translateAlternateColorCodes('&', s)); + } + + this.startingLoc = loc.clone(); + this.id = this.npc.getId(); + this.npc.spawn(loc); + + generateNewNPC(); + Core.getNPCManager().registerCoreNPC(this); + } + + public Location getStartingLoc() { + return this.startingLoc; + } + + public int getID() { + return this.id; + } + + /** + * @apiNote delete the dispStand and NPC (not clear from MySQL) + */ + public void delete() { + if (hologram != null) + hologram.delete(); + + if (this.npc != null) { + this.npc.despawn(DespawnReason.PLUGIN); + this.npc.destroy(); + + if (npc != null && npc.getEntity() != null){ + this.npc.getEntity().remove(); + } + } + } + + /** + * @param damageable whether or not the entity can be damaged + * @apiNote default state is false + */ + protected void setDamageable(boolean damageable) { + this.npc.data().setPersistent(NPC.DEFAULT_PROTECTED_METADATA, !damageable); + } + + /** + * @param targetable whether or not other mobs will target this entity. + * @apiNote default is true + */ + protected void setTargetable(boolean targetable) { + this.npc.data().setPersistent(NPC.TARGETABLE_METADATA, targetable); + } + + /** + * @param layer the layer that will be set on the entity. + * @param turnedOn whether or not the layer is turned on or off. + * @return if the method was successful. + * @apiNote default all true. + */ + protected boolean setSkinLayer(SkinLayers.Layer layer, boolean turnedOn) { + if (!(this.npc.getEntity() instanceof Player)) + return false; + + SkinLayers trait = this.npc.getTrait(SkinLayers.class); + trait.setVisible(layer, turnedOn); + return true; + } + + + /** + * @param option the path finding option. (AVOID_WATER = boolean, others are integers) + * @param o the object of the option (boolean or int) + */ + protected void setPathfindingOption(PathfindOption option, Object o) { + switch (option) { + case AVOID_WATER: + npc.getNavigator().getDefaultParameters().avoidWater((boolean) o); + break; + case ATTACK_RANGE: + npc.getNavigator().getDefaultParameters().attackRange((int) o); + break; + case DISTANCE_MARGIN: + npc.getNavigator().getDefaultParameters().distanceMargin((int) o); + break; + case STATIONARY_TICKS: + npc.getNavigator().getDefaultParameters().stationaryTicks((int) o); + break; + } + } + + /** + * @param passive if the player should (true) or not attack nearby entities. + * @apiNote default stat is true + */ + protected void setPassive(boolean passive) { + this.npc.data().setPersistent(NPC.DAMAGE_OTHERS_METADATA, !passive); + } + + /** + * @param lookClose whether or not the entity should look at nearby players. + * @return true if changes were made. + * @apiNote default state is false + */ + protected boolean setLookClose(boolean lookClose) { + LookClose trait = npc.getTrait(LookClose.class); + + while (trait.toggle() != lookClose) + trait.toggle(); + return true; + } + + /** + * @param gravity whether or not the entity should have gravity. + * @return true if changes were made to the entity. + * @apiNote default state is true + */ + protected boolean setGravity(boolean gravity) { + Gravity trait = this.npc.getTrait(Gravity.class); + + if (trait.hasGravity() == gravity) + return false; + trait.toggle(); + return true; + } + + /** + * @param color the color that you want to surround the entity (player). + * @return true if the method was successful. + * @apiNote default state is not glowing + * @deprecated seems not to be able to change color from white. + */ + @Deprecated + protected boolean setGlowing(ChatColor color) { + if (!(this.npc.getEntity() instanceof Player)) + return false; + if (color == null) { + this.npc.data().remove(NPC.GLOWING_COLOR_METADATA); + this.npc.data().remove(NPC.GLOWING_METADATA); + return true; + } + + this.npc.data().setPersistent(NPC.GLOWING_METADATA, true); + this.npc.data().setPersistent(NPC.GLOWING_COLOR_METADATA, color.name()); + + return true; + } + + /** + * @param rideable whether or not the npc is rideable + * @apiNote default state is false. + */ + protected void setRideable(boolean rideable) { + if (!this.npc.hasTrait(Controllable.class)) + npc.addTrait(Controllable.class); + Controllable trait = this.npc.getTrait(Controllable.class); + + trait.setEnabled(rideable); + } + + /** + * @param collideable whether or not the entity is collideable + * @apiNote default state is false. + * @apiNote sets the collidability of the entity + */ + protected void setCollideable(boolean collideable) { + this.npc.data().setPersistent(NPC.COLLIDABLE_METADATA, collideable); + } + + /** + * @param age the tick age of the entity, 0 = adult, -24000 = baby. + * @param passiveAging whether or not the npc will age over time (true = it will age). + * @return true if it was successful. + * @apiNote default state is adult (0). + * @apiNote the npc must implement Ageable or be a Zombie + */ + protected boolean setAge(int age, boolean passiveAging) { + if (!this.npc.isSpawned() || (!(npc.getEntity() instanceof Ageable) && !(npc.getEntity() instanceof Zombie))) + return false; + + Age trait = this.npc.getTrait(Age.class); + trait.setAge(age); + + while (trait.toggle() == passiveAging) + trait.toggle();//there is no set state method :( + return true; + } + + /** + * @param textureValue the base64 encoded value of the image. + * @param textureSignature the base64 encoded signature of the image. + * @apiNote allows the ability to set a player's skin to one that is not linked to a specific player. Use mineskin.org + */ + protected boolean setSkin(String textureValue, String textureSignature) { + if (this.npc.getEntity().getType() != EntityType.PLAYER) { + return false; + } + ((SkinnableEntity) getNPC().getEntity()).getProfile().getProperties().removeAll("textures"); + ((SkinnableEntity) getNPC().getEntity()).getProfile().getProperties().put("textures", new Property("textures", textureValue, textureSignature)); + return true; + } + + /** + * @param playerName the name of the player whose skin you want to set the NPC to + * @param snapshot if the skin should update if the player selected changes their skin (snapshot = true means no update) + * @apiNote the entity type has to be implementing SkinnableEntity (ex. player) + */ + protected boolean setSkin(String playerName, boolean snapshot) { + if (this.type != EntityType.PLAYER) { + ServerUtil.debug("not skinnable"); + return false; + } + this.npc.data().setPersistent(NPC.PLAYER_SKIN_UUID_METADATA, playerName); + this.npc.data().setPersistent(NPC.PLAYER_SKIN_USE_LATEST, !snapshot); + + if (this.npc.isSpawned()) + ((SkinnableEntity) this.npc.getEntity()).setSkinName(playerName); + return true; + } + + /** + * @apiNote used to add the clothes and such of the npc; + */ + protected abstract void generateNewNPC(); + + /** + * @return the npc entity of this class. + */ + public NPC getNPC() { + return npc; + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/npc/NPCDAO.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/npc/NPCDAO.java new file mode 100644 index 0000000..6b68aff --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/npc/NPCDAO.java @@ -0,0 +1,69 @@ +package net.grandtheftmc.core.npc; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.database.BaseDatabase; +import org.bukkit.Location; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +/** + * Created by Timothy Lampen on 1/14/2018. + */ +public class NPCDAO { + + public static boolean loadNPCs() { + String query = "SELECT * FROM npc_record WHERE server_key = ?;"; + try (Connection c = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement s = c.prepareStatement(query)) { + s.setString(1, Core.name()); + try (ResultSet set = s.executeQuery()) { + while (set.next()) { + String reference = set.getString("reference"); + String serializedLoc = set.getString("location"); + ServerUtil.runTask(() -> Core.getNPCManager().load(reference, Utils.teleportLocationFromString(serializedLoc))); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + return true; + } + + public static boolean clearRecords(){ + String delete = "DELETE FROM npc_record WHERE server_key = ?";//incase an npc was deleted from the list, you don't want to load it in again. + try (Connection c = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement s = c.prepareStatement(delete)){ + s.setString(1, Core.name()); + s.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + return true; + } + + public static boolean saveNPC(String reference, Location loc) { + + String add = "INSERT INTO npc_record(server_key, reference, location) VALUES (?,?,?);"; + try (Connection c = BaseDatabase.getInstance().getConnection()){ + try(PreparedStatement s = c.prepareStatement(add)) { + s.setString(1, Core.name()); + s.setString(2, reference); + s.setString(3, Utils.teleportLocationToString(loc)); + s.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + return true; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/npc/NPCManager.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/npc/NPCManager.java new file mode 100644 index 0000000..a947969 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/npc/NPCManager.java @@ -0,0 +1,182 @@ +package net.grandtheftmc.core.npc; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.HashSet; +import java.util.Set; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.world.ChunkUnloadEvent; +import org.bukkit.scheduler.BukkitRunnable; + +import net.citizensnpcs.api.event.NPCCollisionEvent; +import net.citizensnpcs.api.event.NPCCombustByBlockEvent; +import net.citizensnpcs.api.event.NPCCombustByEntityEvent; +import net.citizensnpcs.api.event.NPCDamageByBlockEvent; +import net.citizensnpcs.api.event.NPCDamageByEntityEvent; +import net.citizensnpcs.api.event.NPCDeathEvent; +import net.citizensnpcs.api.event.NPCLeftClickEvent; +import net.citizensnpcs.api.event.NPCPushEvent; +import net.citizensnpcs.api.event.NPCRightClickEvent; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.npc.interfaces.ClickableNPC; +import net.grandtheftmc.core.npc.interfaces.CollideableNPC; +import net.grandtheftmc.core.npc.interfaces.CombustableNPC; +import net.grandtheftmc.core.npc.interfaces.DamageableNPC; +import net.grandtheftmc.core.util.Component; +import net.grandtheftmc.core.voting.crates.events.CrateNearbyPlayerEvent; + +/** + * Created by Timothy Lampen on 1/13/2018. + */ +public class NPCManager implements Component { + + private final Set npcs = new HashSet<>(); + + @Override + public NPCManager onEnable(Core plugin) { + Bukkit.getPluginManager().registerEvents(this, plugin); + +// ServerUtil.runTaskLaterAsync(NPCDAO::loadNPCs, 20 * 10); + + new BukkitRunnable() { + @Override + public void run() { + + npcs.forEach(npc -> { + + for (Entity nearby : npc.getStartingLoc().getWorld().getNearbyEntities(npc.getStartingLoc(), 0.4, 1, 0.4)) { + + if (nearby instanceof Player) { + Player nearbyPlayer = (Player) nearby; + if (!Bukkit.getOnlinePlayers().contains(nearby)) continue; + + CrateNearbyPlayerEvent event = new CrateNearbyPlayerEvent(nearbyPlayer, null); + + if (event.isCancelled()) { + return; + } + + Bukkit.getPluginManager().callEvent(event); + } + } + }); + } + }.runTaskTimerAsynchronously(Core.getInstance(), 0L, 5); + return this; + } + + @Override + public NPCManager onDisable(Core plugin) { + NPCDAO.clearRecords(); + + for (CoreNPC npc : npcs){ + + try{ + // sync so it must run (before server shutdown), attempt to save + NPCDAO.saveNPC(npc.getClass().getName(), npc.getStartingLoc()); + System.out.println("NPC Removed! " + npc.getID()); + npc.delete(); + } + catch(Exception e){ + e.printStackTrace(); + } + } + return this; + } + + /** + * @param e the entity of the npc that you wish to delete. + */ + public void deleteNPC(Entity e) { + Set copy = new HashSet<>(this.npcs); + copy.stream().filter(npc -> npc.getNPC().isSpawned() && npc.getNPC().getEntity().equals(e)).forEach(npc -> { + npc.delete(); + this.npcs.remove(npc); + }); + } + + /** + * @param referenceName the class name of the entity at the location @param loc + * @param loc the location of the reference. + */ + public void load(String referenceName, Location loc) { + + if (!loc.getChunk().isLoaded()) + loc.getChunk().load(); + + try { + Class c = Class.forName(referenceName); + Constructor con = c.getConstructor(Location.class); + Object o = con.newInstance(loc); + Core.log("Successfully loaded " + referenceName + " at" + loc); + } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | InvocationTargetException | IllegalAccessException e) { + Core.log("Unable to load " + referenceName + " at " + loc); + e.printStackTrace(); + } + } + + /** + * @param npc the npc that is being added. + */ + public void registerCoreNPC(CoreNPC npc) { + this.npcs.add(npc); + } + + @EventHandler + public void onChunkUnload(ChunkUnloadEvent event) { + if (this.npcs.stream().anyMatch(npc -> npc.getNPC().isSpawned() && npc.getStartingLoc().getChunk().equals(event.getChunk()))) { + event.setCancelled(true); + } + } + + + @EventHandler + public void onPush(NPCPushEvent event) { + this.npcs.stream().filter(npc -> npc instanceof CollideableNPC).filter(npc -> npc.getID() == event.getNPC().getId()).forEach(npc -> ((CollideableNPC) npc).onPush(event)); + } + + @EventHandler + public void onCollide(NPCCollisionEvent event) { + this.npcs.stream().filter(npc -> npc instanceof CollideableNPC).filter(npc -> npc.getID() == event.getNPC().getId()).forEach(npc -> ((CollideableNPC) npc).onCollide(event)); + } + + @EventHandler + public void onDeath(NPCDeathEvent event) { + this.npcs.stream().filter(npc -> npc instanceof DamageableNPC).filter(npc -> npc.getID() == event.getNPC().getId()).forEach(npc -> ((DamageableNPC) npc).onDeath(event)); + } + + @EventHandler + public void onDamageBlock(NPCDamageByBlockEvent event) { + this.npcs.stream().filter(npc -> npc instanceof DamageableNPC).filter(npc -> npc.getID() == event.getNPC().getId()).forEach(npc -> ((DamageableNPC) npc).onDamageByBlock(event)); + } + + @EventHandler + public void onDamageEntity(NPCDamageByEntityEvent event) { + this.npcs.stream().filter(npc -> npc instanceof DamageableNPC).filter(npc -> npc.getID() == event.getNPC().getId()).forEach(npc -> ((DamageableNPC) npc).onDamageByEntity(event)); + } + + @EventHandler + public void onCombustBlock(NPCCombustByBlockEvent event) { + this.npcs.stream().filter(npc -> npc instanceof CombustableNPC).filter(npc -> npc.getID() == event.getNPC().getId()).forEach(npc -> ((CombustableNPC) npc).onCombustByBlock(event)); + } + + @EventHandler + public void onCombustEntity(NPCCombustByEntityEvent event) { + this.npcs.stream().filter(npc -> npc instanceof CombustableNPC).filter(npc -> npc.getID() == event.getNPC().getId()).forEach(npc -> ((CombustableNPC) npc).onCombustByEntity(event)); + } + + @EventHandler + public void onRightClick(NPCRightClickEvent event) { + this.npcs.stream().filter(npc -> npc instanceof ClickableNPC).filter(npc -> npc.getID() == event.getNPC().getId()).forEach(npc -> ((ClickableNPC) npc).onRightClick(event)); + } + + @EventHandler + public void onLeftClick(NPCLeftClickEvent event) { + this.npcs.stream().filter(npc -> npc instanceof ClickableNPC).filter(npc -> npc.getID() == event.getNPC().getId()).forEach(npc -> ((ClickableNPC) npc).onLeftClick(event)); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/npc/PathfindOption.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/npc/PathfindOption.java new file mode 100644 index 0000000..18098ad --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/npc/PathfindOption.java @@ -0,0 +1,11 @@ +package net.grandtheftmc.core.npc; + +/** + * Created by Timothy Lampen on 1/14/2018. + */ +public enum PathfindOption { + AVOID_WATER, + ATTACK_RANGE, + DISTANCE_MARGIN, + STATIONARY_TICKS +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/npc/example/ExampleNPC.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/npc/example/ExampleNPC.java new file mode 100644 index 0000000..0080a61 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/npc/example/ExampleNPC.java @@ -0,0 +1,40 @@ +package net.grandtheftmc.core.npc.example; + +import net.citizensnpcs.api.event.NPCLeftClickEvent; +import net.citizensnpcs.api.event.NPCRightClickEvent; +import net.grandtheftmc.core.npc.CoreNPC; +import net.grandtheftmc.core.npc.interfaces.ClickableNPC; +import net.grandtheftmc.core.util.ServerUtil; +import org.bukkit.Location; +import org.bukkit.entity.EntityType; + +/** + * Created by Timothy Lampen on 1/14/2018. + */ +public class ExampleNPC extends CoreNPC implements ClickableNPC { + /** + * @param loc + * @apiNote default constructor for the CoreNPC, does generateNewNPC after it is completed. + */ + public ExampleNPC(Location loc) { + super(loc, EntityType.PLAYER, "Example"); + } + + + @Override + protected void generateNewNPC() { + ServerUtil.debug("overriden method"); + setSkin("TimLampen", true); + setLookClose(true); + } + + @Override + public void onRightClick(NPCRightClickEvent event) { + event.getClicker().sendMessage("hey dud"); + } + + @Override + public void onLeftClick(NPCLeftClickEvent event) { + + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/npc/interfaces/ClickableNPC.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/npc/interfaces/ClickableNPC.java new file mode 100644 index 0000000..4279b34 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/npc/interfaces/ClickableNPC.java @@ -0,0 +1,15 @@ +package net.grandtheftmc.core.npc.interfaces; + +import net.citizensnpcs.api.event.NPCLeftClickEvent; +import net.citizensnpcs.api.event.NPCRightClickEvent; + +/** + * Created by Timothy Lampen on 1/13/2018. + */ +public interface ClickableNPC { + + void onRightClick(NPCRightClickEvent event); + + void onLeftClick(NPCLeftClickEvent event); + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/npc/interfaces/CollideableNPC.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/npc/interfaces/CollideableNPC.java new file mode 100644 index 0000000..e56ec18 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/npc/interfaces/CollideableNPC.java @@ -0,0 +1,14 @@ +package net.grandtheftmc.core.npc.interfaces; + +import net.citizensnpcs.api.event.NPCCollisionEvent; +import net.citizensnpcs.api.event.NPCPushEvent; + +/** + * Created by Timothy Lampen on 1/14/2018. + */ +public interface CollideableNPC { + + void onCollide(NPCCollisionEvent event); + + void onPush(NPCPushEvent event); +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/npc/interfaces/CombustableNPC.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/npc/interfaces/CombustableNPC.java new file mode 100644 index 0000000..8e8df58 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/npc/interfaces/CombustableNPC.java @@ -0,0 +1,14 @@ +package net.grandtheftmc.core.npc.interfaces; + +import net.citizensnpcs.api.event.NPCCombustByBlockEvent; +import net.citizensnpcs.api.event.NPCCombustByEntityEvent; + +/** + * Created by Timothy Lampen on 1/14/2018. + */ +public interface CombustableNPC { + + void onCombustByBlock(NPCCombustByBlockEvent event); + + void onCombustByEntity(NPCCombustByEntityEvent event); +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/npc/interfaces/DamageableNPC.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/npc/interfaces/DamageableNPC.java new file mode 100644 index 0000000..f4674e8 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/npc/interfaces/DamageableNPC.java @@ -0,0 +1,17 @@ +package net.grandtheftmc.core.npc.interfaces; + +import net.citizensnpcs.api.event.NPCDamageByBlockEvent; +import net.citizensnpcs.api.event.NPCDamageByEntityEvent; +import net.citizensnpcs.api.event.NPCDeathEvent; + +/** + * Created by Timothy Lampen on 1/13/2018. + */ +public interface DamageableNPC { + + void onDeath(NPCDeathEvent event); + + void onDamageByEntity(NPCDamageByEntityEvent event); + + void onDamageByBlock(NPCDamageByBlockEvent event); +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/perms/PermsManager.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/perms/PermsManager.java new file mode 100644 index 0000000..4a15366 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/perms/PermsManager.java @@ -0,0 +1,158 @@ +package net.grandtheftmc.core.perms; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.events.GetPermsEvent; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserManager; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.Component; +import org.bukkit.Bukkit; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +public class PermsManager implements Component { + + private final List userPerms = new ArrayList<>(); + private List rankPerms = new ArrayList<>(); + + public PermsManager() { + this.loadPerms(); + } + + @Override + public PermsManager onDisable(Core plugin) { + this.userPerms.forEach(e -> e.onDisable(plugin)); + this.rankPerms.forEach(e -> e.onDisable(plugin)); + + this.userPerms.clear(); + this.rankPerms.clear(); + return this; + } + + public RankPerms getRankPerms(UserRank rank) { + for (RankPerms p : this.rankPerms) + if (p.getRank() == rank) + return p; + return null; + } + + public UserPerms getUserPerms(UUID uuid) { + for (UserPerms u : this.userPerms) + if (u.getUUID().equals(uuid)) + return u; + return null; + } + + public List getPerms(UUID uuid) { + List perms = new ArrayList<>(); + UserPerms u = this.getUserPerms(uuid); + if (u != null) + perms.addAll(u.getPerms()); + GetPermsEvent e = new GetPermsEvent(uuid); + Bukkit.getPluginManager().callEvent(e); + perms.addAll(e.getPerms()); + return perms; + } + + public List getAllPerms(UserRank ur, UUID uuid) { + List perms = new ArrayList<>(); + for (UserRank r : UserRank.getUserRanks()) { + perms.addAll(this.getRankPerms(r).getPerms()); + if (r == ur) + break; + } + perms.addAll(this.getPerms(uuid)); + return perms; + + } + + public void loadPerms() { + this.rankPerms = new ArrayList<>(); + FileConfiguration c = Core.getSettings().getPermsConfig(); + if (c == null) + return; + for (UserRank rank : UserRank.getUserRanks()) { + List ls = c.getStringList("ranks." + rank.getName().toLowerCase()); + RankPerms perms = new RankPerms(rank, ls == null ? new ArrayList<>() : ls); + this.rankPerms.add(perms); + + } + if (c.getConfigurationSection("players") != null) + for (String s : c.getConfigurationSection("players").getKeys(false)) { + UUID uuid = UUID.fromString(s); + if (uuid == null) + break; + List ls = c.getStringList("players." + s); + UserPerms perms = new UserPerms(uuid, ls); + this.userPerms.add(perms); + } + for (Player p : Bukkit.getOnlinePlayers()) + this.updatePerms(p.getUniqueId()); + + } + + public void savePerms(boolean shutdown) { + YamlConfiguration c = Core.getSettings().getPermsConfig(); + for (String s : c.getKeys(false)) c.set(s, null); + for (RankPerms rank : this.rankPerms) + c.set("ranks." + rank.getRank().getName().toLowerCase(), rank.getPerms()); + for (UserPerms user : this.userPerms) + c.set("players." + user.getUUID(), this.getPerms(user.getUUID())); + Utils.saveConfig(c, "perms"); + } + + public boolean hasPerm(UserRank ur, String perm) { + for (String p : this.getRankPerms(ur).getPerms()) + if (p.equalsIgnoreCase(perm)) + return true; + return false; + + } + + public boolean hasPerm(UUID uuid, String perm) { + return this.getPerms(uuid).stream().anyMatch(p -> p.equalsIgnoreCase(perm)); + } + + public void addPerm(UUID uuid, String perm) { + UserPerms user = this.getUserPerms(uuid); + if (user == null) { + user = new UserPerms(uuid); + this.userPerms.add(user); + } + user.addPerm(perm); + this.savePerms(false); + } + + public void removePerm(UUID uuid, String perm) { + UserPerms user = this.getUserPerms(uuid); + if (user != null) + user.removePerm(perm); + this.savePerms(false); + } + + public void updatePerms(UserRank ur) { + UserManager um = Core.getUserManager(); + for (Player p : Bukkit.getOnlinePlayers()) { + User u = um.getLoadedUser(p.getUniqueId()); + if (u != null) + if (ur == u.getUserRank()) + u.setPerms(p); + } + this.savePerms(false); + } + + public void updatePerms(UUID uuid) { + Player player = Bukkit.getPlayer(uuid); + if (player == null) + return; + User u = Core.getUserManager().getLoadedUser(uuid); + u.setPerms(player); + this.savePerms(false); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/perms/RankPerms.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/perms/RankPerms.java new file mode 100644 index 0000000..1829c18 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/perms/RankPerms.java @@ -0,0 +1,59 @@ +package net.grandtheftmc.core.perms; + +import java.util.ArrayList; +import java.util.List; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.Component; + +public class RankPerms implements Component { + + private UserRank rank; + private List perms = new ArrayList<>(); + + public RankPerms(UserRank rank, List perms) { + this.rank = rank; + if (perms != null) + this.perms = perms; + } + + @Override + public RankPerms onDisable(Core plugin) { + this.perms.clear(); + return this; + } + + public RankPerms(UserRank rank) { + this.rank = rank; + } + + public UserRank getRank() { + return this.rank; + } + + public void setRank(UserRank rank) { + this.rank = rank; + } + + public List getPerms() { + return this.perms; + } + + public void setPerms(List perms) { + this.perms = perms; + Core.getPermsManager().updatePerms(this.rank); + } + + public void addPerm(String perm) { + if (!this.perms.contains(perm)) + this.perms.add(perm.toLowerCase()); + Core.getPermsManager().updatePerms(this.rank); + } + + public void removePerm(String perm) { + this.perms.remove(perm); + Core.getPermsManager().updatePerms(this.rank); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/perms/UserPerms.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/perms/UserPerms.java new file mode 100644 index 0000000..7051905 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/perms/UserPerms.java @@ -0,0 +1,59 @@ +package net.grandtheftmc.core.perms; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.Component; + +public class UserPerms implements Component { + + private UUID uuid; + private List perms; + + public UserPerms(UUID uuid, List perms) { + this.uuid = uuid; + this.perms = perms; + } + + public UserPerms(UUID uuid) { + this.uuid = uuid; + this.perms = new ArrayList<>(); + } + + @Override + public UserPerms onDisable(Core plugin) { + this.perms.clear(); + return this; + } + + public UUID getUUID() { + return this.uuid; + } + + public void setUUID(UUID uuid) { + this.uuid = uuid; + } + + public List getPerms() { + return this.perms; + } + + public void setPerms(List perms) { + this.perms = perms; + Core.getPermsManager().updatePerms(this.uuid); + } + + public void addPerm(String perm) { + if (!this.perms.contains(perm)) + this.perms.add(perm.toLowerCase()); + Core.getPermsManager().updatePerms(this.uuid); + } + + public void removePerm(String perm) { + this.perms.remove(perm); + Core.getPermsManager().updatePerms(this.uuid); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/playwire/PlaywireManager.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/playwire/PlaywireManager.java new file mode 100644 index 0000000..7f5ab07 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/playwire/PlaywireManager.java @@ -0,0 +1,63 @@ +package net.grandtheftmc.core.playwire; + +import com.neovisionaries.ws.client.WebSocket; +import com.neovisionaries.ws.client.WebSocketFactory; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.playwire.listeners.WSListener; +import net.grandtheftmc.core.util.Component; +import org.bukkit.scheduler.BukkitRunnable; +import org.json.JSONObject; + +import java.util.UUID; + +/** + * Created by Timothy Lampen on 2017-12-07. + */ +public class PlaywireManager implements Component{ +/** + * This package has been disabled for now. + */ + + private WebSocket websocket; + private static String URI = "rewards.grandtheftmc.net"; + private static String TOKEN = "NotAToken", ID = "70"; + + @Override + public PlaywireManager onEnable(Core plugin) { + new BukkitRunnable() { + public void run() { + if(websocket==null || !websocket.isOpen()) { + openWebSocket(URI, TOKEN); + registerChannel("ServerNotificationChannel"); + } + } + }.runTaskTimerAsynchronously(Core.getInstance(), 0, 1000); + return this; + } + + private void openWebSocket(String uri, String serverToken) { + String endpoint = "wss://" + uri + "/cable?token=" + serverToken; + try { + websocket = new WebSocketFactory().createSocket(endpoint); + websocket.addListener(new WSListener()); + websocket.connect(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void registerChannel(String channelName) { + JSONObject channelSubscribe = new JSONObject(); + channelSubscribe.put("command", "subscribe"); + channelSubscribe.put("identifier", new JSONObject().put("channel", channelName).toString()); + websocket.sendText(channelSubscribe.toString()); + } + + /** + * @param uuid the uuid of the player. + * @return the link that the player goes to to watch the ad. + */ + public static String getPlaywireLink(UUID uuid) { + return "http://" + URI + "/?server_id=" + ID + "&player_uuid=" + uuid; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/playwire/SocketMessage.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/playwire/SocketMessage.java new file mode 100644 index 0000000..b87e6f9 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/playwire/SocketMessage.java @@ -0,0 +1,49 @@ +package net.grandtheftmc.core.playwire; + + +import org.json.JSONArray; +import org.json.JSONObject; + +import java.util.UUID; + +/** + * Created by Timothy Lampen on 2017-12-06. + */ +public class SocketMessage extends JSONObject { + + public SocketMessage(String message) { + super(message); + } + + public String getState() { + return getMessage().getJSONObject("data").getJSONObject("attributes").getString("aasm-state"); + } + + public UUID getPlayerUUID() { + return UUID.fromString(getJSONObjectBy(getMessage().getJSONArray("included"), "type", "players").getJSONObject("attributes").getString("uuid")); + } + + public boolean hasType() { + return has("type"); + } + + public String getType() { + return getString("type"); + } + + private JSONObject getMessage() + { + return getJSONObject("message"); + } + + private JSONObject getJSONObjectBy(JSONArray jsonArray, String key, String value) { + for(int i = 0; i> map) throws Exception { + System.out.println("[playwire-ads] Websocket Connected"); + } + + public void onDisconnected(WebSocket webSocket, WebSocketFrame webSocketFrame, WebSocketFrame webSocketFrame1, boolean b) throws Exception { + System.out.println("[playwire-ads] Websocket Disconnected!"); + } + + public void onTextMessage(WebSocket webSocket, String text) throws Exception { + SocketMessage message = new SocketMessage(text); + String compare = message.hasType() ? message.getType().toUpperCase() : message.getState().toUpperCase(); + SocketMessageType type = SocketMessageType.valueOf(compare); + + AsyncPlaywireRecieveEvent event = new AsyncPlaywireRecieveEvent(message.getPlayerUUID(), type); + Bukkit.getPluginManager().callEvent(event); + } + + public void onError(WebSocket webSocket, WebSocketException e) throws Exception { + System.out.println("[playwire-ads] ========================================"); + System.out.println("[playwire-ads] WebsocketException: " + e); + System.out.println("[playwire-ads] ========================================"); + } + + public void onFrame(WebSocket webSocket, WebSocketFrame webSocketFrame) throws Exception { + + } + + public void onContinuationFrame(WebSocket webSocket, WebSocketFrame webSocketFrame) throws Exception { + + } + + public void onTextFrame(WebSocket webSocket, WebSocketFrame webSocketFrame) throws Exception { + + } + + public void onBinaryFrame(WebSocket webSocket, WebSocketFrame webSocketFrame) throws Exception { + + } + + public void onCloseFrame(WebSocket webSocket, WebSocketFrame webSocketFrame) throws Exception { + + } + + public void onPingFrame(WebSocket webSocket, WebSocketFrame webSocketFrame) throws Exception { + + } + + public void onPongFrame(WebSocket webSocket, WebSocketFrame webSocketFrame) throws Exception { + + } + + public void onBinaryMessage(WebSocket webSocket, byte[] bytes) throws Exception { + + } + + public void onSendingFrame(WebSocket webSocket, WebSocketFrame webSocketFrame) throws Exception { + + } + + public void onFrameSent(WebSocket webSocket, WebSocketFrame webSocketFrame) throws Exception { + + } + + public void onFrameUnsent(WebSocket webSocket, WebSocketFrame webSocketFrame) throws Exception { + + } + + public void onThreadCreated(WebSocket webSocket, ThreadType threadType, Thread thread) throws Exception { + + } + + public void onThreadStarted(WebSocket webSocket, ThreadType threadType, Thread thread) throws Exception { + + } + + public void onThreadStopping(WebSocket webSocket, ThreadType threadType, Thread thread) throws Exception { + + } + + public void onFrameError(WebSocket webSocket, WebSocketException e, WebSocketFrame webSocketFrame) throws Exception { + + } + + public void onMessageError(WebSocket webSocket, WebSocketException e, List list) throws Exception { + + } + + public void onMessageDecompressionError(WebSocket webSocket, WebSocketException e, byte[] bytes) throws Exception { + + } + + public void onTextMessageError(WebSocket webSocket, WebSocketException e, byte[] bytes) throws Exception { + + } + + public void onSendError(WebSocket webSocket, WebSocketException e, WebSocketFrame webSocketFrame) throws Exception { + + } + + public void onUnexpectedError(WebSocket webSocket, WebSocketException e) throws Exception { + + } + + public void handleCallbackError(WebSocket webSocket, Throwable throwable) throws Exception { + + } + + public void onSendingHandshake(WebSocket webSocket, String s, List list) throws Exception { + + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/redis/RedisFactory.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/redis/RedisFactory.java new file mode 100644 index 0000000..7dc0190 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/redis/RedisFactory.java @@ -0,0 +1,31 @@ +package net.grandtheftmc.core.redis; + +import net.grandtheftmc.core.Core; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPoolConfig; + +/** + * Created by Adam on 16/06/2017. + */ +public class RedisFactory { + + private static JedisPool pool; + + public RedisFactory(String server, String passwd, int port, Runnable onCreate){ + JedisPoolConfig config = new JedisPoolConfig(); + config.setMaxTotal(8); + config.setMinIdle(2); + config.setMaxIdle(4); + config.setBlockWhenExhausted(false); + this.pool = new JedisPool(config, server, port, 0, passwd); + + //Callback + onCreate.run(); + } + + public static JedisPool getPool(){ + return pool; + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/redis/RedisListener.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/redis/RedisListener.java new file mode 100644 index 0000000..045a04c --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/redis/RedisListener.java @@ -0,0 +1,129 @@ +package net.grandtheftmc.core.redis; + +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.json.JSONObject; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.redis.data.DataType; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.voting.Reward; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPubSub; +import redis.clients.jedis.exceptions.JedisConnectionException; + +/** + * Created by Adam on 14/06/2017. + */ +public class RedisListener { + + public RedisListener() { + try { + //Jedis e = Core.getInstance().getJedis(); + Jedis e = RedisFactory.getPool().getResource(); + + e.subscribe(new JedisPubSub() { + @Override + public void onMessage(String channel, String message) { + super.onMessage(channel, message); + + if (!channel.equalsIgnoreCase(RedisManager.channel)) { + //Only listen for messages on our channel. + return; + } + + JSONObject serialized = new JSONObject(message); + String dt = serialized.getString("datatype"); + DataType type = DataType.valueOf(dt); + + if (type == null) { + Core.log("Unknown datatype (" + dt + ") received on channel=" + RedisManager.channel + ", ignoring."); + return; + } + + if (type.equals(DataType.REWARD_NOTIFY)) { + + String targetPlayer = serialized.getString("target"); + + Player target = null; + + //Check for player from their UUID + if ((target = Bukkit.getPlayer(UUID.fromString(targetPlayer))) == null) { + //target is not on this server + return; + } + + //Notify them of the rewards they have waiting + target.sendMessage(Utils.f("&aYou have rewards waiting to be claimed! /rewards")); + } + } + }, RedisManager.channel); + } catch (JedisConnectionException e) { + Core.log("Unable to connect to Jedis!!"); + e.printStackTrace(); + } + } + + private String getDisplayName(Reward.RewardType type, String val) { + switch (type) { + case ITEMS: + break; + case BUCKS: + return "&a&l" + val + " Bucks"; + case MONEY: + return "&a$&l" + val; + case TOKENS: + int i = Integer.parseInt(val); + return "&a&l" + i + "&e&l Token" + (i > 1 ? "s" : ""); + case NAMETAG: + return "&e&l" + val; + case RANK: + UserRank rank = UserRank.valueOf(val); + return rank.getColor() + "&lPermanent " + rank.getColoredNameBold(); + case TRIAL_RANK: + String[] args = val.split(","); + rank = UserRank.valueOf(args[0]); + i = Integer.parseInt(args[1]); + return "&a&l" + i + " day" + (i > 1 ? "s " : " ") + rank.getColoredNameBold() + "&a&l Trial"; + case CUSTOM: + break; +// case COSMETIC: +// if (val.equalsIgnoreCase("random-any")) { +// args = val.split(","); +// int minTokens = Integer.parseInt(args[0]), maxTokens = Integer.parseInt(args[1]); +// return "&e&lRandom Cosmetic " + +// "&7(&e" + (maxTokens > 0 ? minTokens + '-' + maxTokens : "min " + minTokens) + " tokens&7)"; +// } else if (val.equalsIgnoreCase("random-specific")) { +// +// args = val.split(","); +// int minTokens = Integer.parseInt(args[0]), maxTokens = Integer.parseInt(args[1]); +// CosmeticType ct = CosmeticType.valueOf(args[2]); +// return '&' + ct.getColor() + "&lRandom " + ct.getColoredDisplayNameSingle() +// + " &7(&e" + (maxTokens > 0 ? minTokens + '-' + maxTokens : "min " + minTokens) + " tokens&7)"; +// } else { +// +// CosmeticType ct = CosmeticType.valueOf(val); +// return ct.getColoredDisplayName(); +// } + /* return this.cosmetic == null ? this.cosmeticType == null ? "&e&lRandom Cosmetic " + + "&7(&e" + (this.maxTokens > 0 ? this.minTokens + '-' + this.maxTokens : "min " + this.minTokens) + " tokens&7)" : + '&' + this.cosmeticType.getColor() + "&lRandom " + this.cosmeticType.getColoredDisplayNameSingle() + + " &7(&e" + (this.maxTokens > 0 ? this.minTokens + '-' + this.maxTokens : "min " + this.minTokens) + " tokens&7)" : + this.cosmetic.getColoredDisplayName();*/ + case PERMISSION: + return val; + case CROWBARS: + i = Integer.parseInt(val); + return "&9&l" + i + " Crowbar" + (i > 1 ? "s" : ""); + case COMMAND: + break; + case ACHIEVEMENT: + return val; + + } + return val; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/redis/RedisManager.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/redis/RedisManager.java new file mode 100644 index 0000000..fc68869 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/redis/RedisManager.java @@ -0,0 +1,43 @@ +package net.grandtheftmc.core.redis; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.redis.data.DataType; +import org.json.JSONObject; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.exceptions.JedisConnectionException; + +import java.util.Map; + +/** + * Created by Adam on 14/06/2017. + */ +public class RedisManager { + + public static final String channel = "gtmcore_msgs"; + + public static boolean publishMessage(DataType type, Map data) { + + try { + //Jedis e = Core.getInstance().getJedis(); + //Core.log("Publishing channel=" + channel + ". msg=" + serialized); + + JSONObject obj = new JSONObject(); + obj.put("datatype", type.name()); + data.keySet().forEach(key -> obj.put(key, data.get(key))); + + Jedis jedis = RedisFactory.getPool().getResource(); + jedis.publish(channel, obj.toString()); + jedis.close(); + return true; + } catch (JedisConnectionException e) { + Core.log("Unable to connect to Jedis!!"); + e.printStackTrace(); + } + + return false; + } + + public static boolean redisEnabled(){ + return RedisFactory.getPool() != null; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/redis/data/DataType.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/redis/data/DataType.java new file mode 100644 index 0000000..8586a0e --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/redis/data/DataType.java @@ -0,0 +1,15 @@ +package net.grandtheftmc.core.redis.data; + +public enum DataType { + + //Declares when a player has received some rewards (if live on the server to notify them) + //Can contain multiple reward notifications, checks are done on MySQL + REWARD_NOTIFY("rewards"), + VOTE_NOTIFY("vote_notify"); + + private final String identifier; + + DataType(String identifier) { + this.identifier = identifier; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/redis/listener/QueueListener.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/redis/listener/QueueListener.java new file mode 100644 index 0000000..836ed6a --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/redis/listener/QueueListener.java @@ -0,0 +1,24 @@ +package net.grandtheftmc.core.redis.listener; + +import net.grandtheftmc.ServerTypeId; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.jedis.JMessageListener; +import net.grandtheftmc.jedis.message.ServerQueueNotifyMessage; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +public class QueueListener implements JMessageListener { + + @Override + public void onReceive(ServerTypeId serverTypeId, ServerQueueNotifyMessage serverQueueNotifyMessage) { + if(!Core.isCoreEnabled()) return; + ServerUtil.runTask(() -> { + Player player = Bukkit.getPlayer(serverQueueNotifyMessage.getUniqueId()); + if (player == null) return; + + player.sendMessage(Lang.QUEUE.f("&7You're #" + serverQueueNotifyMessage.getPossition() + " in the Queue for joining, " + serverQueueNotifyMessage.getTargetServer().getServerType().name() + "-" + serverQueueNotifyMessage.getTargetServer().getId())); + }); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/redis/listener/UserStateTransactionCheckListener.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/redis/listener/UserStateTransactionCheckListener.java new file mode 100644 index 0000000..4f783d1 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/redis/listener/UserStateTransactionCheckListener.java @@ -0,0 +1,64 @@ +package net.grandtheftmc.core.redis.listener; + +import java.sql.Connection; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import net.grandtheftmc.ServerTypeId; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.transaction.state.user.UserStateTransaction; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserManager; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.jedis.JMessageListener; +import net.grandtheftmc.jedis.message.UserStateTransactionCheck; + +public class UserStateTransactionCheckListener implements JMessageListener { + + @Override + public void onReceive(ServerTypeId serverTypeId, UserStateTransactionCheck userStateMessage) { + + // ignore if core is not setup + if (!Core.isCoreEnabled()) + return; + + // run on sync + ServerUtil.runTask(() -> { + + // grab the player + Player player = Bukkit.getPlayer(userStateMessage.getUUID()); + + // if no player online, skip, user state transactions will be + // handled + if (player == null) { + return; + } + + // grab the core user + User coreUser = UserManager.getInstance().getUser(userStateMessage.getUUID()).orElse(null); + if (coreUser != null) { + + // make sure they are mutex locked + if (coreUser.isLocked()) { + + // async fetch + Bukkit.getScheduler().runTaskAsynchronously(Core.getInstance(), () -> { + + try (Connection conn = BaseDatabase.getInstance().getConnection()) { + // check for user state transactions + UserStateTransaction.process(conn, Core.getInstance(), player, Core.getSettings().getType().getName(), Core.getSettings().getNumber()); + } + catch (Exception e) { + e.printStackTrace(); + } + }); + } + } + + // TODO test remove + Core.log("[UserStateTransactionCheckListener][DEBUG] Received user state transaction check for " + userStateMessage.getUUID().toString()); + }); + } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/redis/listener/VoteNotificationListener.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/redis/listener/VoteNotificationListener.java new file mode 100644 index 0000000..5baaa47 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/redis/listener/VoteNotificationListener.java @@ -0,0 +1,52 @@ +package net.grandtheftmc.core.redis.listener; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import net.grandtheftmc.ServerTypeId; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.voting.events.PlayerVoteEvent; +import net.grandtheftmc.jedis.JMessageListener; +import net.grandtheftmc.jedis.message.VoteNotificationMessage; + +public class VoteNotificationListener implements JMessageListener { + + @Override + public void onReceive(ServerTypeId serverTypeId, VoteNotificationMessage voteMessage) { + + // ignore if core is not setup + if (!Core.isCoreEnabled()) + return; + + // run on sync + ServerUtil.runTask(() -> { + + // TODO remove as its a test + Core.log("[VoteNotificationListener][DEBUG] Received vote notification for " + voteMessage.getUUID().toString()); + + // grab the player + Player player = Bukkit.getPlayer(voteMessage.getUUID()); + + // if no player online, skip, user state transactions will be + // handled + if (player == null) { + return; + } + + // create the voter in the vote manager + Core.getVoteManager().createVoter(player.getName()); + + // fire vote event, null params for legacy purposes + PlayerVoteEvent voteEvent = new PlayerVoteEvent(player.getUniqueId(), null, null, null); + Bukkit.getPluginManager().callEvent(voteEvent); + + player.sendMessage(Lang.VOTE.f("&7Thank you for &e&lvoting&7 for the server! Open the &e&lVote&7 menu to claim your prize!")); + + if (voteMessage != null) { + player.sendMessage(voteMessage.getMessage().replaceAll("&", "§")); + } + }); + } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/resourcepack/RSPack_1_12.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/resourcepack/RSPack_1_12.java new file mode 100644 index 0000000..9a7931a --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/resourcepack/RSPack_1_12.java @@ -0,0 +1,57 @@ +package net.grandtheftmc.core.resourcepack; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; + +import net.grandtheftmc.core.Core; + +/** + * Created by Luke Bingham on 07/08/2017. + */ +public class RSPack_1_12 implements ResourcePackReceiving { + + /** + * {@inheritDoc} + */ + @Override + public void onReceiving(ResourcePackManager manager, PacketContainer packet, Player player) { + + if (packet.getType().equals(PacketType.Play.Client.RESOURCE_PACK_STATUS)) { + + ResourcePackEvent.ResourceStatus[] resourceStatus = { ResourcePackEvent.ResourceStatus.NO_RESPONSE }; + net.minecraft.server.v1_12_R1.PacketPlayInResourcePackStatus.EnumResourcePackStatus status = packet.getSpecificModifier(net.minecraft.server.v1_12_R1.PacketPlayInResourcePackStatus.EnumResourcePackStatus.class).read(0); + + switch (status) { + case SUCCESSFULLY_LOADED: + // manager.sendLoaded(player); + resourceStatus[0] = ResourcePackEvent.ResourceStatus.SUCCESSFULLY_LOADED; + break; + case DECLINED: + manager.sendDeclined(player); + resourceStatus[0] = ResourcePackEvent.ResourceStatus.DECLINED; + break; + case FAILED_DOWNLOAD: + manager.sendFailed(player); + resourceStatus[0] = ResourcePackEvent.ResourceStatus.FAILED_DOWNLOAD; + break; + case ACCEPTED: + // manager.sendLoading(player); + resourceStatus[0] = ResourcePackEvent.ResourceStatus.ACCEPTED; + break; + } + + // run notification event 3 seconds later + new BukkitRunnable() { + @Override + public void run() { + ResourcePackEvent event = new ResourcePackEvent(player, resourceStatus[0]); + Bukkit.getPluginManager().callEvent(event); + } + }.runTaskLater(Core.getInstance(), 3 * 20); + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/resourcepack/ResourcePack.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/resourcepack/ResourcePack.java new file mode 100644 index 0000000..c09775c --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/resourcepack/ResourcePack.java @@ -0,0 +1,42 @@ +package net.grandtheftmc.core.resourcepack; + +/** + * Created by Luke Bingham on 06/08/2017. + */ +public class ResourcePack { + + /** The URL for the pack */ + private final String pack; + /** The 20 byte hash that identifies the pack */ + private final String hash; + + /** + * Create a new ResourcePack. + * + * @param pack - the pack url + * @param hash - the hash associated with the pack + */ + public ResourcePack(String pack, String hash) { + this.pack = pack; + this.hash = hash; + } + + /** + * Get the url for the pack. + * + * @return The URL for the pack. + */ + public String getPack() { + return pack; + } + + /** + * Get the id hash in US-ASCII characters and should be encoded as per RFC + * 1738. + * + * @return The hash for the pack. + */ + public String getHash() { + return hash; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/resourcepack/ResourcePackEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/resourcepack/ResourcePackEvent.java new file mode 100644 index 0000000..b53f4d7 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/resourcepack/ResourcePackEvent.java @@ -0,0 +1,50 @@ +package net.grandtheftmc.core.resourcepack; + +import org.bukkit.entity.Player; + +import net.grandtheftmc.core.events.CoreEvent; + +/** + * Created by Luke Bingham on 07/08/2017. + */ +public class ResourcePackEvent extends CoreEvent { + + /** The player involved in the event */ + private final Player player; + /** The resource status constant associated with the event */ + private final ResourceStatus status; + + /** + * Construct a new Event + */ + public ResourcePackEvent(Player player, ResourceStatus status) { + super(false); + this.player = player; + this.status = status; + } + + /** + * Get the player involved in the event. + * + * @return The player involved in the event. + */ + public Player getPlayer() { + return player; + } + + /** + * Get the status of the resource pack involved in the event/ + * + * @return The status of the resource pack. + */ + public ResourceStatus getStatus() { + return this.status; + } + + /** + * Enum constant payloads that are received by the player client. + */ + public enum ResourceStatus { + SUCCESSFULLY_LOADED, DECLINED, FAILED_DOWNLOAD, ACCEPTED, NO_RESPONSE; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/resourcepack/ResourcePackManager.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/resourcepack/ResourcePackManager.java new file mode 100644 index 0000000..1dce929 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/resourcepack/ResourcePackManager.java @@ -0,0 +1,227 @@ +package net.grandtheftmc.core.resourcepack; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashMap; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.java.JavaPlugin; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.events.ListeningWhitelist; +import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.events.PacketListener; +import com.comphenix.protocol.injector.GamePhase; +import com.google.common.collect.Maps; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.util.Callback; +import net.grandtheftmc.core.util.Component; +import net.grandtheftmc.core.util.NMSVersion; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.util.title.NMSTitle; + +/** + * Created by Luke Bingham on 06/08/2017. + */ +public class ResourcePackManager implements Component, PacketListener { + + /** Mapping of versions to associated resource packs */ + private final HashMap resourcePacks; + /** Interface implementation of receiving client handling per version */ + private final ResourcePackReceiving recoursePackReceiving; + /** NMS title to display to user */ + private final NMSTitle nmsTitle; + + /** + * Construct a new ResourcePackManager. + * + * @param plugin - the owning plugin + * @param resourcePackReceiving - the interface handler for handling of the + * resource pack + * @param nmsTitle - the title object to send + */ + public ResourcePackManager(final JavaPlugin plugin, final ResourcePackReceiving recoursePackReceiving, final NMSTitle nmsTitle) { + this.resourcePacks = Maps.newHashMap(); + this.recoursePackReceiving = recoursePackReceiving; + this.nmsTitle = nmsTitle; + + Bukkit.getPluginManager().registerEvents(this, plugin); + ProtocolLibrary.getProtocolManager().addPacketListener(this); + } + + /** + * {@inheritDoc} + */ + @Override + public ResourcePackManager onDisable(Core plugin) { + this.resourcePacks.clear(); + return this; + } + + /** + * Get the resource pack with the associated version. + * + * @param version - the client version + * + * @return The resource pack that is associated with the specified version. + */ + public ResourcePack getResourcePack(NMSVersion version) { + return this.resourcePacks.getOrDefault(version, null); + } + + /** + * Set the resource pack and version key/pair. + * + * @param version - the version key + * @param resourcePack - the resource pack value + */ + public void setResourcePack(NMSVersion version, ResourcePack resourcePack) { + this.resourcePacks.put(version, resourcePack); + } + + /** + * Get whether or not, via the callback, if we can send the resource pack to + * the specified player. + * + * @param player - the player in question + * @param callback - the callback object + */ + public void canSendPack(Player player, Callback callback) { + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT last_pack FROM user_respack WHERE uuid=UNHEX(?);")) { + statement.setString(1, player.getUniqueId().toString().replaceAll("-", "")); + + try (ResultSet result = statement.executeQuery()) { + if (result.next()) { + String pack = result.getString(1); + if (!pack.equals(Core.getSettings().getType().name())) { + callback.call(true); + + try (PreparedStatement update = connection.prepareStatement("UPDATE user_respack SET last_pack=? WHERE uuid=UNHEX(?);")) { + update.setString(1, Core.getSettings().getType().name()); + update.setString(2, player.getUniqueId().toString().replaceAll("-", "")); + + update.execute(); + } + return; + } + } + else { + callback.call(true); + try (PreparedStatement insert = connection.prepareStatement("INSERT INTO user_respack (uuid, last_pack) VALUES (UNHEX(?), ?);")) { + insert.setString(1, player.getUniqueId().toString().replaceAll("-", "")); + insert.setString(2, Core.getSettings().getType().name()); + + insert.execute(); + } + return; + } + } + } + } + catch (SQLException e) { + e.printStackTrace(); + } + + callback.call(false); + }); + } + + /** + * Display a declined message. + * + * @param player - the player getting the message + */ + protected void sendDeclined(Player player) { + player.sendMessage(""); + player.sendMessage(""); + player.sendMessage(Utils.f("&4▀&c▔&4▀&c▔&4▀&c▔&4▀&c▔&4▀&c▔&4▀&c▔&4▀&c▔&4▀&c▔&4▀&c▔&4▀&c▔&4▀&c▔&4▀&c▔&4▀&c▔&4▀&c▔&4▀&c▔&4▀&c▔&4▀&c▔&4▀")); + player.sendMessage(""); + player.sendMessage(Utils.f(" &c&lRESPACK&4&l> &7Please go into your client's server list and make sure &aServer Resource Packs&7 is set to &aenabled&7.")); + player.sendMessage(""); + player.sendMessage(Utils.f("&4▀&c▔&4▀&c▔&4▀&c▔&4▀&c▔&4▀&c▔&4▀&c▔&4▀&c▔&4▀&c▔&4▀&c▔&4▀&c▔&4▀&c▔&4▀&c▔&4▀&c▔&4▀&c▔&4▀&c▔&4▀&c▔&4▀&c▔&4▀")); + +// player.sendMessage(Lang.VICE.f("&7Download the server resource pack here: &a" + url)); +// player.sendMessage(Lang.VICE.f("&7or automatically apply it later using &a/respack")); + NMSTitle.sendTitle(player, Utils.f("&c&lDownload denied!"), Utils.f("&7Please check your server resourcepack settings."), 0, 2 * 20, 1 * 20); + } + + /** + * Display a failed message. + * + * @param player - the player getting the message + */ + protected void sendFailed(Player player) { + player.sendMessage(Utils.f(" &a&lRESPACK&8&l> &cThe Resource Pack Failed to download..")); + player.sendMessage(Utils.f(" &a&lRESPACK&8&l> &cMake sure you're using an official minecraft build.")); +// player.sendMessage(Lang.VICE.f("&7Download the server resource pack here: &a" + url)); +// player.sendMessage(Lang.VICE.f("&7or automatically apply it later using &a/respack")); + NMSTitle.sendTitle(player, Utils.f("&4&lRESOURCE PACK"), Utils.f("&cThe Resource Pack Failed to download!"), 0, 2 * 20, 1 * 20); + } + + /** + * Display a loading title. + * + * @param player - the player getting the title + */ + protected void sendLoading(Player player) { + NMSTitle.sendTitle(player, Utils.f("&4&lRESOURCE PACK"), Utils.f("&fThis could freeze your client for a few seconds."), 0, 2 * 20, 1 * 20); + } + + /** + * Display a loading complete title. + * + * @param player - the player getting the title + */ + protected void sendLoaded(Player player) { + NMSTitle.sendTitle(player, Utils.f("&4&lRESOURCE PACK"), Utils.f("&fLoading complete!"), 0, 2 * 20, 1 * 20); + } + + /** + * {@inheritDoc} + */ + @Override + public void onPacketSending(PacketEvent packetEvent) { + } + + /** + * {@inheritDoc} + */ + @Override + public void onPacketReceiving(PacketEvent packetEvent) { + recoursePackReceiving.onReceiving(this, packetEvent.getPacket(), packetEvent.getPlayer()); + } + + /** + * {@inheritDoc} + */ + @Override + public ListeningWhitelist getSendingWhitelist() { + return ListeningWhitelist.EMPTY_WHITELIST; + } + + /** + * {@inheritDoc} + */ + @Override + public ListeningWhitelist getReceivingWhitelist() { + return ListeningWhitelist.newBuilder().normal().gamePhase(GamePhase.PLAYING).types(PacketType.Play.Client.RESOURCE_PACK_STATUS).build(); + } + + /** + * {@inheritDoc} + */ + @Override + public Plugin getPlugin() { + return Core.getInstance(); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/resourcepack/ResourcePackReceiving.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/resourcepack/ResourcePackReceiving.java new file mode 100644 index 0000000..d41ad4d --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/resourcepack/ResourcePackReceiving.java @@ -0,0 +1,20 @@ +package net.grandtheftmc.core.resourcepack; + +import org.bukkit.entity.Player; + +import com.comphenix.protocol.events.PacketContainer; + +/** + * Created by Luke Bingham on 07/08/2017. + */ +public interface ResourcePackReceiving { + + /** + * Callback for when a packet is received. + * + * @param manager - the resource pack manager container + * @param packet - the packet container being sent + * @param player - the player involved in the event + */ + void onReceiving(ResourcePackManager manager, PacketContainer packet, Player player); +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/sentry/CustomExceptionHandler.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/sentry/CustomExceptionHandler.java new file mode 100644 index 0000000..4304b1e --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/sentry/CustomExceptionHandler.java @@ -0,0 +1,27 @@ +package net.grandtheftmc.core.sentry; + +import io.sentry.Sentry; +import io.sentry.event.EventBuilder; +import net.grandtheftmc.core.Core; + +import java.io.*; + +/** + * Created by Luke Bingham on 31/08/2017. + */ +public class CustomExceptionHandler implements Thread.UncaughtExceptionHandler { + +// private Thread.UncaughtExceptionHandler defaultUEH; + + public CustomExceptionHandler() { +// this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler(); + } + + public void uncaughtException(Thread t, Throwable e) { + System.out.println(t.getName() + " threw an exception: " + e.getLocalizedMessage()); + Core.getInstance().getSentryClient().sendEvent(new EventBuilder()); + +// Sentry.capture(e.getMessage()); +// defaultUEH.uncaughtException(t, e); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/servers/PingHandler.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/servers/PingHandler.java new file mode 100644 index 0000000..d6ce27e --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/servers/PingHandler.java @@ -0,0 +1,51 @@ +package net.grandtheftmc.core.servers; + +import com.j0ach1mmall3.jlib.integration.pinger.PingResponse; +import com.j0ach1mmall3.jlib.integration.pinger.PingResponse.Players; +import com.j0ach1mmall3.jlib.storage.database.CallbackHandler; + +public class PingHandler implements CallbackHandler { + + private final Server server; + + public PingHandler(Server server) { + this.server = server; + } + + @Override + public void callback(PingResponse resp) { + this.server.setLastUpdate(System.currentTimeMillis()); + if (resp == null) { + // Utils.b("Updating OFFLINE server " + this.server.getName() + " with ip " + this.server.getIp() + ':' + this.server.getPort()); + this.server.setOffline(true); + return; + } + this.server.setOffline(false); + Players players = resp.getPlayers(); + this.server.setOnlinePlayers(players.getOnline()); + this.server.setMaxPlayers(players.getMax()); + String desc = resp.getDescription().getText(); + String[] a = desc.split(","); + if (a.length > 0) + for (String s : a) { + String[] array = s.split(":"); + if (array.length != 2) + continue; + switch (array[0]) { + case "map": + this.server.setMap(array[1]); + break; + case "gameState": + this.server.setGameState(array[1]); + break; + case "round": + this.server.setRound(Integer.parseInt(array[1])); + break; + default: + break; + } + } + this.server.updateJoinSigns(); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/servers/Server.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/servers/Server.java new file mode 100644 index 0000000..725e239 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/servers/Server.java @@ -0,0 +1,244 @@ +package net.grandtheftmc.core.servers; + +import com.j0ach1mmall3.jlib.integration.pinger.Pinger; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.users.UserRank; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.BlockState; +import org.bukkit.block.Sign; + +import java.util.ArrayList; +import java.util.List; + +public class Server { + private String name; + private ServerType type; + private int number; + private int onlinePlayers; + private int maxPlayers; + private String map; + private String gameState; + private List joinSigns = new ArrayList<>(); + private int round; + private UserRank rankToJoin; + private boolean offline; + private String ip; + private int port; + private long lastUpdate; + + public Server(String name, ServerType type, int number, String ip, int port, UserRank rankToJoin) { + this.name = name; + this.type = type; + this.number = number; + this.ip = ip; + this.port = port; + this.rankToJoin = rankToJoin; + } + + public Server(String name, ServerType type, int number, String ip, int port, boolean offline, int onlinePlayers, + int maxPlayers, String map, String gameState, int round, UserRank rankToJoin, List joinSigns) { + this.name = name; + this.type = type; + this.number = number; + this.ip = ip; + this.port = port; + this.offline = offline; + this.onlinePlayers = onlinePlayers; + this.maxPlayers = maxPlayers; + this.map = map; + this.gameState = gameState; + this.round = round; + this.rankToJoin = rankToJoin; + this.joinSigns = joinSigns; + this.lastUpdate = System.currentTimeMillis(); + } + + public void ping() { + if (this.ip == null || this.port <= 0) { + Core.log("Server '" + this.name + "' does not have an ip/port configured in the database!"); + return; + } + Pinger pinger = new Pinger(this.ip, this.port); + pinger.ping(Core.getInstance(), new PingHandler(this)); + } + + public void updateJoinSigns() { + if (this.joinSigns.isEmpty()) + return; + String line0 = null; + String line1 = null; + String line2 = null; + String line3 = null; + if (this.offline) { + line0 = "&4&l█████████"; + line1 = "&cRestarting..."; + line2 = "&c&l" + this.name.toUpperCase(); + line3 = "&4&l█████████"; + } else if (this.gameState == null) { + line0 = (this.isFull() ? "&c&l" : "&a&l") + '[' + this.name.toUpperCase() + ']'; + line1 = this.map == null ? "" : "&7" + this.map; + line2 = (this.isFull() ? "&c" : "&7") + this.onlinePlayers + " / " + this.maxPlayers; + line3 = "&a&lLobby"; + } else + switch (this.gameState.toLowerCase()) { + case "none": + case "lobby": + line0 = (this.isFull() ? "&c&l" : "&a&l") + '[' + this.name.toUpperCase() + ']'; + line1 = this.map == null ? "" : "&7" + this.map; + line2 = (this.isFull() ? "&c" : "&7") + this.onlinePlayers + " / " + this.maxPlayers; + line3 = "&a&lLobby"; + break; + case "ingame": + line0 = (this.isFull() ? "&c&l" : "&8&l") + '[' + this.name.toUpperCase() + ']'; + line1 = this.map == null ? "" : "&7" + this.map; + line2 = (this.isFull() ? "&c" : "&7") + this.onlinePlayers + " / " + this.maxPlayers; + line3 = "&8&lRound " + this.round; + break; + + case "end": + line0 = "&c&l[" + this.name.toUpperCase() + ']'; + line1 = this.map == null ? "" : "&7" + this.map; + line2 = (this.isFull() ? "&c" : "&7") + this.onlinePlayers + " / " + this.maxPlayers; + line3 = "&c&lEnding"; + break; + } + for (Location loc : new ArrayList<>(this.joinSigns)) { + BlockState state = loc.getBlock().getState(); + if (state.getType() == Material.SIGN_POST || state.getType() == Material.WALL_SIGN) { + Sign sign = (Sign) state; + sign.setLine(0, line0); + sign.setLine(1, line1); + sign.setLine(2, line2); + sign.setLine(3, line3); + } + } + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public int getOnlinePlayers() { + return this.onlinePlayers; + } + + public void setOnlinePlayers(int onlinePlayers) { + this.onlinePlayers = onlinePlayers; + + } + + public int getMaxPlayers() { + return this.maxPlayers; + } + + public void setMaxPlayers(int maxPlayers) { + this.maxPlayers = maxPlayers; + } + + public String getMap() { + return this.map; + } + + public void setMap(String map) { + this.map = map; + + } + + public String getGameState() { + return this.gameState; + } + + public void setGameState(String gameState) { + this.gameState = gameState; + + } + + public List getJoinSigns() { + return this.joinSigns; + } + + public void setJoinSigns(List joinSigns) { + this.joinSigns = joinSigns; + } + + public int getRound() { + return this.round; + } + + public void setRound(int round) { + this.round = round; + + } + + public boolean isOffline() { + return this.offline; + } + + public void setOffline(boolean offline) { + this.offline = offline; + + } + + public boolean isFull() { + return this.onlinePlayers >= this.maxPlayers; + } + + public String getIp() { + return this.ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public int getPort() { + return this.port; + } + + public void setPort(int port) { + this.port = port; + } + + public ServerType getType() { + return this.type; + } + + public void setType(ServerType type) { + this.type = type; + } + + public int getNumber() { + return this.number; + } + + public void setNumber(int number) { + this.number = number; + + } + + public UserRank getRankToJoin() { + return this.rankToJoin; + } + + public void setRankToJoin(UserRank rankToJoin) { + this.rankToJoin = rankToJoin; + } + + public boolean needsRankToJoin() { + return this.rankToJoin != null; + } + + public void setLastUpdate(long l) { + this.lastUpdate = l; + } + + public long getLastUpdate() { + return this.lastUpdate; + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/servers/ServerManager.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/servers/ServerManager.java new file mode 100644 index 0000000..953c69e --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/servers/ServerManager.java @@ -0,0 +1,165 @@ +package net.grandtheftmc.core.servers; + +import com.google.common.io.ByteArrayDataOutput; +import com.google.common.io.ByteStreams; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Settings; +import net.grandtheftmc.core.database.dao.ServerInfoDAO; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +public class ServerManager { + public List servers = new ArrayList<>(); + + private String map; + private String gameState; + private int round; + + public ServerManager() { + this.loadServers(); + this.loadJoinSigns(); + this.updateThisServer(); + this.startSchedule(); + } + + private int taskId = -1; + + public void sendToServer(Player player, String server) { + ByteArrayDataOutput out = ByteStreams.newDataOutput(); + out.writeUTF("Connect"); + out.writeUTF(server); + player.sendPluginMessage(Core.getInstance(), "BungeeCord", out.toByteArray()); + + } + + public void updateThisServer() { + Settings settings = Core.getSettings(); +// Core.getSQL().updateAsyncLater("update servers set type='" + settings.getType() + "',number=" +// + settings.getNumber() + ",onlinePlayers=" + Bukkit.getOnlinePlayers().size() + ",maxPlayers=" +// + Bukkit.getMaxPlayers() + ",map='" + this.map + "',gameState='" + this.gameState + "',round=" + this.round +// + ",rankToJoin='" + (settings.getRankToJoin() == null ? null : settings.getRankToJoin().toString()) +// + "',lastCheck=" + System.currentTimeMillis() + " where name='" + Core.name() + "';"); + ServerUtil.runTaskAsync(() -> ServerInfoDAO.updateServerInfo(Core.name(), settings.getType(), settings.getNumber(), Bukkit.getOnlinePlayers().size(), Bukkit.getMaxPlayers(), this.map, this.gameState, this.round, settings.getRankToJoin())); + + Server server = this.getServer(Core.name()); + if (server == null) + return; + server.setMap(this.map); + server.setGameState(this.gameState); + server.setRound(this.round); + server.setOnlinePlayers(Bukkit.getOnlinePlayers().size()); + server.setMaxPlayers(Bukkit.getMaxPlayers()); + server.setOffline(false); + server.updateJoinSigns(); + } + + public void loadServers() { + ServerUtil.runTaskAsync(() -> { + Optional> optional = ServerInfoDAO.fetchAllServers(); + if(!optional.isPresent()) return; + ServerUtil.runTask(() -> ServerManager.this.servers = new ArrayList<>(optional.get())); + }); + } + + public void startSchedule() { + if (this.taskId != -1) + Bukkit.getScheduler().cancelTask(this.taskId); + this.taskId = new BukkitRunnable() { + @Override + public void run() { + ServerManager.this.updateThisServer(); + Core.getServerManager().getServers().stream().filter(server -> !server.getName().equals(Core.name())).forEach(Server::ping); + if (Core.getSettings().serverWarperEnabled()) + MenuManager.updateMenu("serverwarper"); + } + }.runTaskTimer(Core.getInstance(), 100, 100).getTaskId(); + + } + + public List getServers() { + return this.servers; + } + + public List getServers(ServerType type) { + return this.servers.stream().filter(server -> server.getType() == type).collect(Collectors.toList()); + } + + public Server getServer(String name) { + for (Server server : this.servers) + if (server.getName().equalsIgnoreCase(name)) + return server; + return null; + } + + public Server getServer(String ip, int port) { + for (Server server : this.servers) + if (server.getIp().equals(ip) && server.getPort() == port) + return server; + return null; + } + + public void loadJoinSigns() { + YamlConfiguration c = Core.getSettings().getJoinSignsConfig(); + for (String s : c.getKeys(false)) { + Server server = this.getServer(s); + if (server == null) + break; + List locs = new ArrayList<>(); + for (String l : c.getStringList(s)) { + Location loc = Utils.blockLocationFromString(l); + if (l != null) + locs.add(loc); + } + server.setJoinSigns(locs); + } + } + + public void saveJoinSigns(boolean shutdown) { + YamlConfiguration c = Core.getSettings().getJoinSignsConfig(); + for (String key : c.getKeys(false)) + c.set(key, null); + this.servers.stream().filter(server -> !server.getJoinSigns().isEmpty()).forEach(server -> c.set(server.getName(), server.getJoinSigns().stream().map(Utils::blockLocationToString).collect(Collectors.toList()))); + Utils.saveConfig(c, "joinSigns"); + } + + public void removeJoinSign(Location location) { + this.servers.stream().filter(server -> server.getJoinSigns().contains(location)).forEach(server -> server.getJoinSigns().remove(location)); + } + + public String getMap() { + return this.map; + } + + public void setMap(String map) { + this.map = map; + } + + public String getGameState() { + return this.gameState; + } + + public void setGameState(String gameState) { + this.gameState = gameState; + } + + public int getRound() { + return this.round; + } + + public void setRound(int round) { + this.round = round; + } + + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/servers/ServerPingListener.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/servers/ServerPingListener.java new file mode 100644 index 0000000..069127d --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/servers/ServerPingListener.java @@ -0,0 +1,16 @@ +package net.grandtheftmc.core.servers; + +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.server.ServerListPingEvent; + +import net.grandtheftmc.core.Core; + +public class ServerPingListener implements Listener { + + @EventHandler + public void onPing(ServerListPingEvent e) { + ServerManager sm = Core.getServerManager(); + e.setMotd("map=" + sm.getMap() + ",gameState=" + sm.getGameState() + ",round=" + sm.getRound()); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/servers/ServerType.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/servers/ServerType.java new file mode 100644 index 0000000..a13b542 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/servers/ServerType.java @@ -0,0 +1,59 @@ +package net.grandtheftmc.core.servers; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.Utils; +import org.bukkit.Material; + +import java.util.Arrays; + +public enum ServerType { + + NONE("&c&lERROR", " &c&lERROR ", Material.REDSTONE_BLOCK, "&7Error"), + HUB("&6&lHub", " &7&l" + Core.getSettings().getNetworkShortName() + " &6&lHub ", Material.REDSTONE, "&7Go back to the lobby!"), + GTM("&7&l" + Core.getSettings().getServer_GTM_name(), " &7&l" + Core.getSettings().getServer_GTM_name() + " ", Material.MINECART, "&7GTA in Minecraft!"), + LEGACY("&7&l" + Core.getSettings().getServer_GTM_name() + " &c&lLegacy", "&7&l" + Core.getSettings().getServer_GTM_shortName() + " &c&lLegacy", Material.CHEST, "&7To the good old days!"), + CREATIVE("&6&lCreative", " &6&lCreative ", Material.GOLD_BLOCK, "&7Infinite plots to build anything you want!"), + GLIDERS("&c&lGlider Assault", " &c&lGlider Assault ", Material.ELYTRA, "&7Free for All with weapons and gliders!"), + VICE("&d&lVice&7&lMC", "&d&lVice&7&lMC", Material.SUGAR, "&7Drug Cartels in Minecraft!"); + + private final String displayName; + private final String scoreboardHeader; + private final Material icon; + private final String description; + + ServerType(String displayName, String scoreboardHeader, Material icon, String description) { + this.scoreboardHeader = scoreboardHeader; + this.displayName = displayName; + this.icon = icon; + this.description = description; + } + + public static ServerType getType(String string) { + return Arrays.stream(getAll()).filter(type -> type.toString().equalsIgnoreCase(string)).findFirst().orElse(NONE); + } + + private static ServerType[] getAll() { + return ServerType.class.getEnumConstants(); + } + + public String getName() { + return this.toString().toLowerCase(); + } + + public String getScoreboardHeader() { + return this.scoreboardHeader; + } + + public String getDisplayName() { + return this.displayName; + } + + public Material getIcon() { + return this.icon; + } + + public String getDescription() { + return this.description; + } +} + diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/servers/menu/GTMTranzitMenu.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/servers/menu/GTMTranzitMenu.java new file mode 100644 index 0000000..c6b2dca --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/servers/menu/GTMTranzitMenu.java @@ -0,0 +1,140 @@ +package net.grandtheftmc.core.servers.menu; + +import org.bukkit.Material; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; + +import net.grandtheftmc.ServerTypeId; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.inventory.CoreMenu; +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import net.grandtheftmc.core.inventory.button.ClickableItem; +import net.grandtheftmc.core.inventory.button.MenuItem; +import net.grandtheftmc.core.servers.Server; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.StringUtil; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.core.wrapper.packet.out.WrapperPlayServerSetCooldown; +import net.grandtheftmc.jedis.JedisChannel; +import net.grandtheftmc.jedis.JedisModule; +import net.grandtheftmc.jedis.message.ServerQueueMessage; + +public class GTMTranzitMenu extends CoreMenu { + + private int[] edgeInOrder = null; + private int[] colours = null; + + /** + * Construct a new Menu. + */ + public GTMTranzitMenu() { + super(6, StringUtil.getCenteredMenuText(Core.getSettings().getServer_GTM_shortName() + " Server Travel"), CoreMenuFlag.CLOSE_ON_NULL_CLICK, CoreMenuFlag.RESET_CURSOR_ON_OPEN); + + this.edgeInOrder = new int[]{0, 9, 18, 27, 36, 45, 46, 47, 48, 49, 50, 51, 52, 53, 44, 35, 26, 17, 8, 7, 6, 5, 4, 3, 2, 1}; + this.colours = new int[]{13, 4, 1, 14, 6, 2, 10, -1, -1, 11, 9, 3, 5, 13, 4, 1, 14, 6, 2, 10, -1, -1, 11, 9, 3, 5}; + + this.refreshEdge(); + this.refreshButtons(); + } + + public void refreshEdge() { + for (int i = 0; i < this.edgeInOrder.length; i++) { + if (this.colours[i] < 0) { + super.deleteItem(this.edgeInOrder[i]); + continue; + } + +// super.addItem(new MenuItem(this.edgeInOrder[i], new ItemStack(Material.STAINED_GLASS_PANE, 1, (byte) this.colours[i]), false)); + super.addItem(new MenuItem(this.edgeInOrder[i], new ItemFactory(Material.STAINED_GLASS_PANE, (byte) this.colours[i]).setName(C.WHITE).build(), false)); + } + + ServerUtil.runTaskAsync(() -> { + WrapperPlayServerSetCooldown cooldown = new WrapperPlayServerSetCooldown(); + cooldown.setItem(Material.STAINED_GLASS_PANE); + cooldown.setTicks(500); + try { + HumanEntity[] viewers = this.getInventory().getViewers().toArray(new HumanEntity[this.getInventory().getViewers().size()]); + for (HumanEntity player : viewers) + cooldown.sendPacket((Player) player); + } catch (Exception e) { + } + }); + } + + public void rotate() { + int[] arr = new int[this.colours.length]; + for (int i = 0; i < this.colours.length; i++) { + if (i == this.colours.length - 1) { + arr[0] = this.colours[i]; + continue; + } + + arr[i + 1] = this.colours[i]; + } + + this.colours = arr; + } + + public void refreshButtons() { + int[] slots = {20, 24, 29, 22, 31, 33}; + for (int i = 1; i < (Core.getSettings().isSister() ? 3 : 7); i++) { + Server gtm = Core.getServerManager().getServer("gtm" + i); + boolean online = gtm != null && !gtm.isOffline(); + + Material material = !online ? Material.EXPLOSIVE_MINECART : Material.MINECART; + String displayName = " " + C.RESET + C.WHITE + C.BOLD + (gtm != null ? gtm.getNumber() : 0) + C.RESET + C.GRAY + " v" + Core.GTM_VERSION; + if (Core.getSettings().isSister()) { + if (i == 1) displayName = (!online ? C.RED : C.GREEN) + C.BOLD + "Capital City" + displayName; + else if (i == 2) displayName = (!online ? C.RED : C.GREEN) + C.BOLD + "Sandy Shores" + displayName; + } else { + if (i == 1) + displayName = (!online ? C.RED : C.GREEN) + C.BOLD + "GTM" + C.WHITE + C.BOLD + " MineSantos" + C.RESET + C.GRAY + " v" + Core.GTM_VERSION; + else if (i == 4) + displayName = (!online ? C.RED : C.GREEN) + C.BOLD + "GTM" + C.WHITE + C.BOLD + " Sanktburg" + C.RESET + C.GRAY + " v" + Core.GTM_VERSION; + else + displayName = (!online ? C.RED : C.GREEN) + C.BOLD + "GTM" + displayName; + } + + ItemFactory item = new ItemFactory(material).setName(displayName).setLore(getGtmLore(gtm)); + addItem(new ClickableItem(slots[i - 1], item.build(), (player, clickType) -> { + if (!online) return; + + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + + JedisModule module = Core.getJedisManager().getModule(JedisChannel.SERVER_QUEUE); + if (module == null) { + Core.getServerManager().sendToServer(player, "gtm" + gtm.getNumber()); + return; + } + + module.sendMessage( + new ServerQueueMessage(player.getUniqueId(), user.getUserRank().name(), new ServerTypeId(net.grandtheftmc.ServerType.GTM, gtm.getNumber())), + new ServerTypeId(net.grandtheftmc.ServerType.OPERATOR, -1) + ); + })); + } + } + + protected String[] getGtmLore(Server server) { + boolean online = server != null && !server.isOffline(); + if (server!=null&&(server.getNumber() == 1 || server.getNumber() == 4)) { + String[] description = {C.DARK_GRAY + "Shoot enemies, drive tanks,", C.DARK_GRAY + "and buy penthouses in the", C.DARK_GRAY + "epic city!"}; + String id = C.GRAY + "Server Number " + C.LIGHT_PURPLE + C.BOLD + (server != null ? server.getNumber() : 0); + String playersOnline = C.GRAY + "Players online " + (!online ? C.RED + C.BOLD + "0" + C.GRAY + " / " + C.RED + C.BOLD + "0" + C.RESET : C.GREEN + C.BOLD + server.getOnlinePlayers() + C.GRAY + " / " + C.GREEN + C.BOLD + server.getMaxPlayers() + C.RESET); +// String onlineServers = C.GRAY + "Servers online " + (allOffline ? C.RED : C.GREEN) + C.BOLD + totalUsers[2]; + String[] language = {C.GRAY + "Favored Language", " " + (online && server.getNumber() == 4 ? C.YELLOW + C.BOLD + "GERMAN" : C.AQUA + C.BOLD + "ENGLISH")}; + String[][] version = { + {C.GRAY + "Recommended versions", C.GREEN + " 1.12" + C.WHITE + ", " + C.GREEN + "1.12.1" + C.WHITE + ", " + C.GREEN + "1.12.2"}, + {C.GRAY + "Supported versions", C.YELLOW + " 1.8.*" + C.WHITE + ", " + C.YELLOW + "1.9.*" + C.WHITE + ", " + C.YELLOW + "1.10.*" + C.WHITE + ", " + C.YELLOW + "1.11.*" + C.WHITE + ", " + C.YELLOW + "1.12.*"} + }; + String clickInfo = !online ? C.RED + C.ITALIC + "\u27A3 Offline for maintenance!" : C.WHITE + C.ITALIC + "\u27A3 Click to join server!"; +// String secret = C.DARK_GRAY + C.ITALIC + "/gtmlog to view updates"; + + return new String[]{description[0], description[1], description[2], "", id, "", playersOnline, "", language[0], language[1], "", version[0][0], version[0][1], "", version[1][0], version[1][1], "", clickInfo/*, "", secret*/}; + } else { + return new String[]{C.RED+ "This server will be",C.RED+"closed on September 20.",C.RED+"If you are a new player,",C.RED+"please choose a different server.",C.RED+"",C.RED+"If you are an existing player,",C.RED+"please read our post at",C.RED+"grandtheftmc.net",C.RED+"to transfer some of your",C.RED+"progress to another server."}; + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/servers/menu/TranzitMenu.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/servers/menu/TranzitMenu.java new file mode 100644 index 0000000..edad767 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/servers/menu/TranzitMenu.java @@ -0,0 +1,220 @@ +package net.grandtheftmc.core.servers.menu; + +import net.grandtheftmc.ServerType; +import net.grandtheftmc.ServerTypeId; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.inventory.CoreMenu; +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import net.grandtheftmc.core.inventory.button.ClickableItem; +import net.grandtheftmc.core.inventory.button.MenuItem; +import net.grandtheftmc.core.servers.Server; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.StringUtil; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.core.wrapper.packet.out.WrapperPlayServerSetCooldown; +import net.grandtheftmc.jedis.JedisChannel; +import net.grandtheftmc.jedis.message.ServerQueueMessage; +import org.bukkit.Material; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import java.util.*; +import java.util.stream.Collectors; + +public class TranzitMenu extends CoreMenu { + + private int[] edgeInOrder = null; + private int[] colours = null; + + private GTMTranzitMenu gtmMenu; + + /** + * Construct a new Menu. + */ + public TranzitMenu(GTMTranzitMenu gtmMenu) { + super(6, StringUtil.getCenteredMenuText("Server Travel"), CoreMenuFlag.CLOSE_ON_NULL_CLICK, CoreMenuFlag.RESET_CURSOR_ON_OPEN); + this.gtmMenu = gtmMenu; + + this.edgeInOrder = new int[]{0, 9, 18, 27, 36, 45, 46, 47, 48, 49, 50, 51, 52, 53, 44, 35, 26, 17, 8, 7, 6, 5, 4, 3, 2, 1}; + this.colours = new int[]{13, 4, 1, 14, 6, 2, 10, -1, -1, 11, 9, 3, 5, 13, 4, 1, 14, 6, 2, 10, -1, -1, 11, 9, 3, 5}; + + this.refreshEdge(); + this.refreshButtons(); + } + + public void rotate() { + int[] arr = new int[this.colours.length]; + for (int i = 0; i < this.colours.length; i++) { + if (i == this.colours.length - 1) { + arr[0] = this.colours[i]; + continue; + } + + arr[i + 1] = this.colours[i]; + } + + this.colours = arr; + } + + public void refreshEdge() { + for (int i = 0; i < this.edgeInOrder.length; i++) { + if (this.colours[i] < 0) { + super.deleteItem(this.edgeInOrder[i]); + continue; + } + +// super.addItem(new MenuItem(this.edgeInOrder[i], new ItemStack(Material.STAINED_GLASS_PANE, 1, (byte) this.colours[i]), false)); + super.addItem(new MenuItem(this.edgeInOrder[i], new ItemFactory(Material.STAINED_GLASS_PANE, (byte) this.colours[i]).setName(C.WHITE).build(), false)); + } + + ServerUtil.runTaskAsync(() -> { + WrapperPlayServerSetCooldown cooldown = new WrapperPlayServerSetCooldown(); + cooldown.setItem(Material.STAINED_GLASS_PANE); + cooldown.setTicks(500); + try { + HumanEntity[] viewers = this.getInventory().getViewers().toArray(new HumanEntity[this.getInventory().getViewers().size()]); + for (HumanEntity player : viewers) + cooldown.sendPacket((Player) player); + } + catch (Exception e) {} + }); + } + + public void refreshButtons() { + refreshGTM(); + +// System.out.println(Core.getSettings().isSister()); + if (!Core.getSettings().isSister()) { +// System.out.println("RAN"); + refreshVice(); + refreshCreative(); + } + } + + private void refreshGTM() { + List gtmServers = Arrays.stream(Core.getSettings().isSister() ? new String[]{"gtm1","gtm2"} : new String[]{"gtm1", "gtm4","gtm2", "gtm3", "gtm5", "gtm6"}).map(st -> Core.getServerManager().getServer(st)).collect(Collectors.toList()); + boolean allOffline; + try { + allOffline = gtmServers.stream().filter(Server::isOffline).count() >= gtmServers.size(); + } catch (Exception e) { + allOffline = true; + } + + Material material = allOffline ? Material.EXPLOSIVE_MINECART : Material.MINECART; + String displayName = (allOffline ? C.RED : C.GREEN) + C.BOLD + Core.getSettings().getServer_GTM_name() + C.RESET + C.GRAY + " v" + Core.GTM_VERSION; + + ItemFactory item = new ItemFactory(material).setName(displayName).setLore(getGtmServersLore(gtmServers, allOffline)); + super.addItem(new ClickableItem(Core.getSettings().isSister() ? 22 : 31, item.build(), (player, clickType) -> { + player.closeInventory(); + gtmMenu.openInventory(player); + })); + } + + private void refreshVice() { + Server vice = Core.getServerManager().getServer("vice2"); + boolean Coffline = vice == null || vice.isOffline(); + + Material Cmaterial = Coffline ? Material.REDSTONE : Material.SUGAR; + String CdisplayName = (Coffline ? C.RED + C.BOLD + "ViceMC" : C.LIGHT_PURPLE + C.BOLD + "Vice" + C.WHITE + C.BOLD + "MC") + C.RESET + C.GRAY + " season " + Core.VICE_VERSION; + + ItemFactory Citem = new ItemFactory(Cmaterial).setName(CdisplayName).setLore(getViceLore(vice)); + addItem(new ClickableItem(24, Citem.build(), (player, clickType) -> { + if (Coffline) return; + + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + Core.getJedisManager().getModule(JedisChannel.SERVER_QUEUE).sendMessage( + new ServerQueueMessage(player.getUniqueId(), user.getUserRank().name(), new ServerTypeId(net.grandtheftmc.ServerType.VICE, 1)), + new ServerTypeId(net.grandtheftmc.ServerType.OPERATOR, -1) + ); + })); + } + + private void refreshCreative() { + Server creative = Core.getServerManager().getServer("creative1"); + boolean Coffline = creative == null || creative.isOffline(); + + Material Cmaterial = Coffline ? Material.REDSTONE_BLOCK : Material.GOLD_BLOCK; + String displayName = (Coffline ? C.RED + C.BOLD + "Creative" : C.GOLD + C.BOLD + "Creative") + C.RESET + C.GRAY + " v" + Core.CREATIVE_VERSION; + + ItemFactory item = new ItemFactory(Cmaterial).setName(displayName).setLore(getCreativeLore(creative)); + super.addItem(new ClickableItem(20, item.build(), (player, clickType) -> { + if (Coffline) return; + + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + Core.getJedisManager().getModule(JedisChannel.SERVER_QUEUE).sendMessage( + new ServerQueueMessage(player.getUniqueId(), user.getUserRank().name(), new ServerTypeId(ServerType.CREATIVE, 1)), + new ServerTypeId(net.grandtheftmc.ServerType.OPERATOR, -1) + ); + })); + } + +// public static void main(String[] args) { +// edgeInOrder = new int[]{0, 9, 18, 27, 36, 45, 46, 47, 48, 49, 50, 51, 52, 53, 44, 35, 26, 17, 8, 7, 6, 5, 4, 3, 2, 1}; +// colours = new int[]{13, 4, 1, 14, 6, 2, 10, -1, -1, 11, 9, 3, 5, 13, 4, 1, 14, 6, 2, 10, -1, -1, 11, 9, 3, 5}; +// +// System.out.println("#" + 0 + Arrays.toString(colours)); +// +// for (int i = 0; i < colours.length; i++) { +// rotate(); +// System.out.println("#" + (i+1) + Arrays.toString(colours)); +// } +// } + + private String[] getGtmServersLore(List gtmServers, boolean allOffline) { + int[] totalUsers = {0, 0, 0}; + if (!allOffline) { + gtmServers.stream().filter(server -> !server.isOffline()).forEach(server -> { + totalUsers[0] += server.getOnlinePlayers(); + totalUsers[1] += server.getMaxPlayers(); + totalUsers[2]++; + }); + } + + String[] description = {C.DARK_GRAY + "Shoot enemies, drive tanks,", C.DARK_GRAY + "and buy penthouses in the", C.DARK_GRAY + "epic city!"}; + String playersOnline = C.GRAY + "Players online " + (allOffline ? C.RED + C.BOLD + "0" + C.GRAY + " / " + C.RED + C.BOLD + "0" + C.RESET : C.GREEN + C.BOLD + totalUsers[0] + C.GRAY + " / " + C.GREEN + C.BOLD + totalUsers[1] + C.RESET); + String onlineServers = C.GRAY + "Servers online " + (allOffline ? C.RED : C.GREEN) + C.BOLD + totalUsers[2]; + String[][] version = { + {C.GRAY + "Recommended versions", C.GREEN + " 1.12" + C.WHITE + ", " + C.GREEN + "1.12.1" + C.WHITE + ", " + C.GREEN + "1.12.2"}, + {C.GRAY + "Supported versions", C.YELLOW + " 1.8.*" + C.WHITE + ", " + C.YELLOW + "1.9.*" + C.WHITE + ", " + C.YELLOW + "1.10.*" + C.WHITE + ", " + C.YELLOW + "1.11.*" + C.WHITE + ", " + C.YELLOW + "1.12.*"} + }; + String clickInfo = allOffline ? C.RED + C.ITALIC + "\u27A3 Offline for maintenance!" : C.WHITE + C.ITALIC + "\u27A3 Click to join a server!"; + String secret = C.DARK_GRAY + C.ITALIC + "/gtalog to view updates"; + + return new String[] {description[0], description[1], description[2], "", playersOnline, onlineServers, "", version[0][0], version[0][1], "", version[1][0], version[1][1], "", clickInfo, /*, "", secret*/}; + } + + private String[] getViceLore(Server server) { + boolean online = server != null && !server.isOffline(); + + String[] description = {C.DARK_GRAY + "Grow drugs, form cartels,", C.DARK_GRAY + "and become the next", C.DARK_GRAY + "Pablo Escabar!"}; + String playersOnline = C.GRAY + "Players online " + (!online ? C.RED + C.BOLD + "0" + C.GRAY + " / " + C.RED + C.BOLD + "0" + C.RESET : C.GREEN + C.BOLD + server.getOnlinePlayers() + C.GRAY + " / " + C.GREEN + C.BOLD + server.getMaxPlayers() + C.RESET); +// String onlineServers = C.GRAY + "Servers online " + (allOffline ? C.RED : C.GREEN) + C.BOLD + totalUsers[2]; + String[][] version = { + {C.GRAY + "Recommended versions", C.GREEN + " 1.12" + C.WHITE + ", " + C.GREEN + "1.12.1" + C.WHITE + ", " + C.GREEN + "1.12.2"}, + {C.GRAY + "Supported versions", C.YELLOW + " 1.8.*" + C.WHITE + ", " + C.YELLOW + "1.9.*" + C.WHITE + ", " + C.YELLOW + "1.10.*" + C.WHITE + ", " + C.YELLOW + "1.11.*" + C.WHITE + ", " + C.YELLOW + "1.12.*"} + }; + String clickInfo = !online ? C.RED + C.ITALIC + "\u27A3 Offline for maintenance!" : C.WHITE + C.ITALIC + "\u27A3 Click to join server!"; + String secret = C.DARK_GRAY + C.ITALIC + "/vicelog to view updates"; + + return new String[] {description[0], description[1], description[2], "", playersOnline, "", version[0][0], version[0][1], "", version[1][0], version[1][1], "", clickInfo, /*, "", secret*/}; + } + + private String[] getCreativeLore(Server server) { + boolean online = server != null && !server.isOffline(); + + String[] description = {C.DARK_GRAY + "Build to your hearts", C.DARK_GRAY + "content and help inspire", C.DARK_GRAY + "new updates to the network"}; + String playersOnline = C.GRAY + "Players online " + (!online ? C.RED + C.BOLD + "0" + C.GRAY + " / " + C.RED + C.BOLD + "0" + C.RESET : C.GREEN + C.BOLD + server.getOnlinePlayers() + C.GRAY + " / " + C.GREEN + C.BOLD + server.getMaxPlayers() + C.RESET); +// String onlineServers = C.GRAY + "Servers online " + (allOffline ? C.RED : C.GREEN) + C.BOLD + totalUsers[2]; + String[][] version = { + {C.GRAY + "Recommended versions", C.GREEN + " 1.10.*" + C.WHITE + ", " + C.GREEN + "1.11.*" + C.WHITE + ", " + C.GREEN + "1.12.*"}, + {C.GRAY + "Supported versions", C.YELLOW + " 1.8.*" + C.WHITE + ", " + C.YELLOW + "1.9.*" + C.WHITE + ", " + C.YELLOW + "1.10.*" + C.WHITE + ", " + C.YELLOW + "1.11.*" + C.WHITE + ", " + C.YELLOW + "1.12.*"} + }; + String clickInfo = !online ? C.RED + C.ITALIC + "\u27A3 Offline for maintenance!" : C.WHITE + C.ITALIC + "\u27A3 Click to join server!"; + String secret = C.DARK_GRAY + C.ITALIC + "/buildlog to view updates"; + + return new String[] {description[0], description[1], description[2], "", playersOnline, "", version[0][0], version[0][1], "", version[1][0], version[1][1], "", clickInfo, /*, "", secret*/}; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/stat/StatDAO.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/stat/StatDAO.java new file mode 100644 index 0000000..a04f053 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/stat/StatDAO.java @@ -0,0 +1,71 @@ +package net.grandtheftmc.core.stat; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.util.Optional; +import java.util.UUID; + +public class StatDAO { + + /** + * Create user join info record in the database. + * + * @param conn - the database connection thread + * @param uuid - the uuid of the user to create the record for + * @param serverJoinAddress - the server address they joined with + * + * @return {@code} true if the record was created, {@code false} otherwise. + */ + public static boolean createUserJoinInfo(Connection conn, UUID uuid, String serverJoinAddress) { + + // note: look at initial record is 2x serverJoinAddress, as it can be updated later + // with on update query + String query = "INSERT IGNORE INTO user_join_info (uuid, initial_server_address, last_server_address) VALUES (UNHEX(?), ?, ?) ON DUPLICATE KEY UPDATE last_server_address=VALUES(last_server_address), last_login=VALUES(last_login);"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setString(1, uuid.toString().replaceAll("-", "")); + ps.setString(2, serverJoinAddress); + ps.setString(3, serverJoinAddress); + + ps.executeUpdate(); + return true; + } + catch (Exception e) { + System.out.println("[StatDAO] An error occurred for createUserStat() for uuid=" + uuid + ", serverJoinAddress=" + serverJoinAddress); + e.printStackTrace(); + } + + return false; + } + + /** + * Get the join address the user. + * + * @param conn - the database connection thread + * @param uuid - the uuid of the user to lookup + * + * @return The string representation of the join address the user used to connect wtih, i.e. 'dev.mc-gtm.net', if one exists. + */ + public static Optional getUserJoinAddress(Connection conn, UUID uuid) { + + //String query = "SELECT last_server_address FROM user_join_info WHERE uuid=UNHEX(?);"; + String query = "SELECT initial_server_address FROM user_join_info WHERE uuid=UNHEX(?);"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setString(1, uuid.toString().replaceAll("-", "")); + + try (ResultSet result = ps.executeQuery()){ + if (result.next()){ + return Optional.of(result.getString("initial_server_address")); + } + } + } + catch (Exception e) { + System.out.println("[StatDAO] An error occurred for getUserJoinAddress() for uuid=" + uuid); + e.printStackTrace(); + } + + return Optional.empty(); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/stat/StatFactory.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/stat/StatFactory.java new file mode 100644 index 0000000..90b416d --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/stat/StatFactory.java @@ -0,0 +1,183 @@ +package net.grandtheftmc.core.stat; + +import java.sql.Connection; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolManager; +import com.comphenix.protocol.events.ListenerPriority; +import com.comphenix.protocol.events.PacketAdapter; +import com.comphenix.protocol.events.PacketEvent; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.util.UUIDUtil; +import net.minecraft.server.v1_12_R1.PacketHandshakingInSetProtocol; + +public class StatFactory { + + /** The instance of this factory */ + private static StatFactory instance; + /** Whether or not the stat factory was initialized */ + private static boolean initialized; + + /** The owning plugin */ + private Plugin plugin; + + /** + * Construct a new StatFactory. + *

+ * This represents a data structure that will collate and save statistical + * information. + * + * @param plugin - the owning plugin + */ + private StatFactory(Plugin plugin) { + this.plugin = plugin; + } + + /** + * Get the instance of this factory. + * + * @return The singleton instance for this factory. + * + * @throws IllegalStateException if the factory was never initialized with + * {@link #init(Plugin)}. + */ + public static StatFactory getInstance() throws IllegalStateException { + if (instance == null) { + if (!initialized) { + throw new IllegalStateException("The StatFactory was never initialized by the owning plugin! This is a severe error and should be fixed. Please call StatFactory.init() first!"); + } + } + + return instance; + } + + /** + * Initialize the manager. + * + * @param plugin - the owning plugin + */ + public static void init(Plugin plugin) { + + System.out.println("[StatFactory] Initializing stat factory..."); + + // create singleton instance + instance = new StatFactory(plugin); + initialized = true; + } + + /** + * Register the client connection stat listener. + *

+ * This is used to keep track of what IP players are connecting through. + *

+ * + * @param protocolManager - the protocol lib manager. + * + * @return {@code true} if the client was registered, {@code false} + * otherwise. + */ + public boolean registerClientConnectionStat(ProtocolManager protocolManager) { + if (!initialized) { + return false; + } + + System.out.println("[StatFactory] Registering client connection stat..."); + + protocolManager.addPacketListener(new PacketAdapter(plugin, ListenerPriority.NORMAL, PacketType.Handshake.Client.SET_PROTOCOL) { + + @Override + public void onPacketReceiving(PacketEvent event) { + + // confirm correct packet + if (event.getPacketType() == PacketType.Handshake.Client.SET_PROTOCOL) { + + Player p = event.getPlayer(); + if (p != null) { + + // get the handshake packet + PacketHandshakingInSetProtocol packet = (PacketHandshakingInSetProtocol) event.getPacket().getHandle(); + + // hostname field from packet is 255 bytes long + // in form of hostname: + // dev.mc-gtm.net24.101.17.184b50fd86cbcc642d0a5f87e975f5a817c + // THEN SOME RANDOM ASS JSON + String hostname = packet.hostname; + + // drop the JSON attached info + String[] parts = hostname.split("\\["); + if (parts.length > 1) { + + // in form of + // dev.mc-gtm.net24.100.10.100b50fd86cbcc642d0a5f87e975f5a817c + String playerInfo = parts[0]; + + // split on a regex of IP format + String[] playerParts = playerInfo.split("[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}"); + + if (playerParts.length > 1) { + + // IP the player CONNECTED TO + String connectedIP = playerParts[0]; + // player uuid + String trimmedUUID = playerParts[1]; + + // TODO remove debug + Core.log("[StatFactory][DEBUG] uuid=" + trimmedUUID + " conn using " + connectedIP); + + // if we correctly parsed the connected ip + if (connectedIP != null && !connectedIP.isEmpty()) { + + // if this is because of SRV records + if (connectedIP.contains("gtm-prox1") || connectedIP.contains("gtm-prox2")){ + connectedIP = "mc-gtm.net"; + } + if (connectedIP.contains("gtm-dream") || connectedIP.contains("dream.mc-gtm")){ + connectedIP = "dream.mc-gtm.net"; + } + if (connectedIP.contains("gtm-vicemc") || connectedIP.contains("vicemc.net")){ + connectedIP = "play.vicemc.net"; + } + + // if uuid is correctly parsed + if (trimmedUUID != null && !trimmedUUID.isEmpty()) { + + // remove escapes and whitespace + trimmedUUID = trimmedUUID.replace("\\", ""); + trimmedUUID = trimmedUUID.trim(); + + UUID userUUID = UUIDUtil.createUUID(trimmedUUID).orElse(null); + if (userUUID != null){ + + String finalConnectedIP = connectedIP; + + // TODO remove debug + Core.log("[StatFactory][DEBUG] Adding to db uuid=" + trimmedUUID + " conn using " + finalConnectedIP); + + Bukkit.getScheduler().runTaskAsynchronously(getPlugin(), () -> { + try (Connection conn = BaseDatabase.getInstance().getConnection()){ + StatDAO.createUserJoinInfo(conn, userUUID, finalConnectedIP); + } + catch(Exception e){ + e.printStackTrace(); + } + }); + } + } + } + } + } + } + } + } + }); + + return true; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/task/ExpirableTask.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/task/ExpirableTask.java new file mode 100644 index 0000000..86261de --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/task/ExpirableTask.java @@ -0,0 +1,161 @@ +package net.grandtheftmc.core.task; + +import org.bukkit.plugin.Plugin; + +/** + * Representation of an expirable {@link Task}. It will expire after a set + * length. Optionally can be dynamic or set-in-stone via locking the handler. + */ +public abstract class ExpirableTask extends RepeatingTask { + + /** Whether or not the task's time/length is locked. */ + private final boolean locked; + /** Overall length of the task in seconds. */ + private double length; + /** Current time in seconds left until the task expires. */ + private double timeLeft; + /** Whether or not this task has expired. */ + private boolean expired; + + /** + * Constructs a new ExpirableTask. Defaults to making multiExecution 'false' + * and locked to 'true'. + * + * @param plugin - Plugin handling the task. + * @param delay - Delay in seconds until the task begins execution. + * @param interval - Interval in seconds between executions. + * @param length - Overall length of the task in seconds (how long until + * expiration). + */ + public ExpirableTask(Plugin plugin, double delay, double interval, double length) { + this(plugin, false, delay, interval, length, true); + } + + /** + * Constructs a new ExpirableTask. Defaults to making multiExecution + * 'false'. + * + * @param plugin - Plugin handling the task. + * @param delay - Delay in seconds until the task begins execution. + * @param interval - Interval in seconds between executions. + * @param length - Overall length of the task in seconds (how long until + * expiration). + * @param locked - Whether or not to lock the tasks' time and length. + */ + public ExpirableTask(Plugin plugin, double delay, double interval, double length, boolean locked) { + this(plugin, false, delay, interval, length, locked); + } + + /** + * Constructs a new ExpirableTask. + * + * @param plugin - Plugin handling the task. + * @param multiExecution - Whether or not the task can be executed multiple + * times. + * @param delay - Delay in seconds until the task begins execution. + * @param interval - Interval in seconds between executions. + * @param length - Overall length of the task in seconds (how long until + * expiration). + * @param locked - Whether or not to lock the tasks' time and length. + */ + public ExpirableTask(Plugin plugin, boolean multiExecution, double delay, double interval, double length, boolean locked) { + super(plugin, multiExecution, delay, interval); + this.length = length; + this.timeLeft = length; + this.locked = locked; + } + + /** + * {@inheritDoc} + */ + @Override + protected final void onInterval() { + if (timeLeft > 0) { + onInterval(timeLeft); + timeLeft = timeLeft - interval; + return; + } + + cancel(); + expired = true; + onExpire(); + } + + /** + * Check to see if the TaskHandler's time/length is currently locked. + * + * @return {@code true} if the TaskHandler is locked, otherwise + * {@code false}. + */ + public boolean isLocked() { + return locked; + } + + /** + * Get the overall length of the task. + * + * @return {@code double} representing the task's overall length in seconds. + */ + public double getLength() { + return length; + } + + /** + * Set the length of the task. + * + * @param length - {@code double} to be set as the task's new length. + */ + public void setLength(double length) { + this.length = length; + } + + /** + * Get the current time left until the task expires. + * + * @return {@code double} representing the time left in seconds until + * expiration. + */ + public double getTimeLeft() { + return timeLeft; + } + + /** + * Set the time left until the task expires. + * + * @param timeLeft - {@code double}, in seconds, to be set as the task's new + * time left. + */ + public void setTimeLeft(double timeLeft) { + this.timeLeft = timeLeft; + } + + /** + * Checks to see if the task has expired. This differs from + * {@link #isCancelled()} since this checks for whether or not the time has + * actually depleted- properly expiring instead of possibly being cancelled + * somewhere during the task's execution. + * + * @return {@code true} if the time left for the task until expiration is 0, + * marking it as expired. Otherwise, if it is not, {@code false}. + */ + public boolean hasExpired() { + return expired; + } + + /** + * Optional call-back for when the task ends execution. + */ + protected void onExpire() { + } + + /** + * Call-back for when the task is run. This allows you to execute code + * according to its execution interval and it also supplies the current + * time-left. This is called by {@link #onInterval()}. + * + * @param timeLeft - {@code double} representing the time left, in seconds, + * until the task expires + */ + protected abstract void onInterval(double timeLeft); + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/task/RepeatingTask.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/task/RepeatingTask.java new file mode 100644 index 0000000..8a9a1ae --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/task/RepeatingTask.java @@ -0,0 +1,213 @@ +package net.grandtheftmc.core.task; + +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; + +/** + * Representation of a repeating {@link Task}. A task that repeats over + * and over infinitely at a set interval and optional initial delay. + */ +public abstract class RepeatingTask extends Task { + + /** The interval in seconds at which the task executes. */ + protected final double interval; + /** The initial delay in seconds until the task begins execution. */ + protected final double delay; + /** Whether or not the task is cancelled. */ + protected boolean cancelled; + /** Whether the task has begun execution */ + private boolean started; + /** Whether or not the delay has been completed if there was one. */ + private boolean delayCompleted; + /** Whether or not the task is currently paused. */ + private boolean paused; + /** The task's system epoch time in milliseconds. */ + private long epoch; + + /** + * Construct a new RepeatingTask, which is used to repeatedly run code. + * + * @param plugin - the owning plugin + * @param delay - the delay, in seconds, until the task executes + * @param interval - the interval, in seconds, between running the task + */ + public RepeatingTask(Plugin plugin, double delay, double interval) { + this(plugin, false, delay, interval); + } + + /** + * Construct a new RepeatingTask, which is used to repeatedly run code. + * + * @param plugin - the owning plugin + * @param multiExecution - whether this task can be stopped/ran multiple times + * @param delay - the delay, in seconds, until the task executes + * @param interval - the interval, in seconds, between running the task + */ + public RepeatingTask(Plugin plugin, boolean multiExecution, double delay, double interval) { + super(plugin, multiExecution); + this.delay = delay; + this.interval = interval; + this.epoch = System.currentTimeMillis(); + } + + /** + * {@inheritDoc} + */ + @Override + public void execute() { + execute(false); + } + + /** + * {@inheritDoc} + */ + @Override + public void execute(boolean runAsynchronously) { + if(!started || multiExecution) { + if(runAsynchronously) { + async = true; + id = Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, this, 0L, 1L).getTaskId(); + } else { + id = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, this, 0L, 1L); + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public void run() { + if (cancelled) { + Bukkit.getScheduler().cancelTask(id); + onCancel(); + return; + } + + if (paused) { + return; + } + + if (!started) { + onStart(); + started = true; + } + + // The task's current system time in milliseconds. + long current = System.currentTimeMillis(); + + if (delay > 0) { + if (!delayCompleted) { + if (current >= epoch + (delay * 1000)) { + delayCompleted = true; + onDelayComplete(); + } + + return; + } + } + + if (current >= epoch + (interval * 1000)) { + epoch = current; + onInterval(); + } + } + + /** + * Check to see whether or not the task has started execution. + * + * @return {@code true} if it has started execution, otherwise {@code false} . + */ + public boolean hasStarted() { + return started; + } + + /** + * Check to see if the task's execution is currently paused. + * + * @return {@code true} if the task is paused, otherwise {@code false}. + */ + public boolean isPaused() { + return paused; + } + + /** + * Pause the task's execution if it already isn't. + */ + public void pause() { + if (!paused) { + paused = true; + onPause(); + } + } + + /** + * Resume the task if it is currently paused. + */ + public void resume() { + if (paused) { + paused = false; + onResume(); + } + } + + /** + * Check to see whether or not the task is cancelled. + * + * @return {@code true} if the task has been cancelled, otherwise + * {@code false}. + */ + public boolean isCancelled() { + return cancelled; + } + + /** + * Cancel the task's execution. + */ + public void cancel() { + cancelled = true; + } + + /** + * Get the interval in seconds between executions. + * + * @return {@code double} representing the interval between executions. + */ + public double getInterval() { + return interval; + } + + /** + * Optional call-back for when the task starts executing. + */ + protected void onStart() {} + + /** + * Optional call-back for when the task's execution has been delayed and the + * first interval begins. + */ + protected void onDelayComplete() {} + + /** + * Optional call-back for when the task's execution is paused. + */ + protected void onPause() {} + + /** + * Optional call-back for when the task's execution is resumed. + */ + protected void onResume() {} + + /** + * Optional call-back for when the task's execution is cancelled. + */ + protected void onCancel() {} + + /** + * Call-back for when the task is run at the appropriate interval. + */ + protected abstract void onInterval(); + +} + + diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/task/Task.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/task/Task.java new file mode 100644 index 0000000..f5b1aa3 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/task/Task.java @@ -0,0 +1,96 @@ +package net.grandtheftmc.core.task; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; + +import net.grandtheftmc.core.util.PluginAssociated; + +/** + * Representation of a basic once off task. + */ +public abstract class Task implements PluginAssociated, Runnable { + + /** Plugin handling the task. */ + protected final Plugin plugin; + /** Can this task be executed multiple times */ + protected final boolean multiExecution; + /** Whether or not the task is asynchronous. */ + protected boolean async; + /** The task's id. */ + protected int id = -1; + /** Whether this task has {@link #execute()} */ + private boolean executed; + + /** + * Constructs a new Task. + * + * @param plugin - Plugin handling the task. + */ + public Task(Plugin plugin) { + this(plugin, false); + } + + /** + * Constructs a new Task. + * + * @param plugin - Plugin handling the task + * @param multiExecution - ability for it to be executed multiple times + */ + public Task(Plugin plugin, boolean multiExecution) { + Validate.notNull(plugin, "Plugin cannot be null!"); + this.plugin = plugin; + this.multiExecution = multiExecution; + } + + @Override + public Plugin getPlugin() { + return plugin; + } + + /** + * Check to see whether or not this task is asynchronous. This will + * always return {@code false} if the task has not been executed. + * + * @return {@code true} if the task is running asynchronously, otherwise + * {@code false}. + */ + public boolean isAsynchronous() { + return async; + } + + /** Starts the synchronous execution of the task. */ + public void execute() { + execute(false); + } + + /** + * Starts the specified (sync/async) execution of the task. + * + * @param runAsynchronously - whether or not to run this task asynchronously + */ + public void execute(boolean runAsynchronously) { + if (!executed || multiExecution) { + if (runAsynchronously) { + async = true; + id = Bukkit.getScheduler().runTaskAsynchronously(plugin, this).getTaskId(); + } + else { + id = Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, this); + } + + executed = true; + } + } + + /** + * Get the task's id. This is by default initialized to -1, so if it returns + * -1 it means the task has not been executed yet. + * + * @return Task id in the form of a {@code int}. + */ + protected int getTaskId() { + return id; + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/task/common/AntiAFK.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/task/common/AntiAFK.java new file mode 100644 index 0000000..03e6aab --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/task/common/AntiAFK.java @@ -0,0 +1,74 @@ +package net.grandtheftmc.core.task.common; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.Component; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerLoginEvent; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.TimeUnit; + +public class AntiAFK implements Component { + private final ConcurrentMap afk; + private static final int AFK_MINUTES = 5; + + public AntiAFK() { + this.afk = new ConcurrentHashMap<>(); + Core.getInstance().getServer().getPluginManager().registerEvents(this, Core.getInstance()); + } + + @Override + public AntiAFK onDisable(Core plugin) { + this.afk.clear(); + return this; + } + + public void refreshAfk(Player player) { + afk.put(player.getUniqueId(), System.currentTimeMillis()); + } + + @EventHandler + public void on(PlayerLoginEvent event) { + + + User joining = Core.getUserManager().getLoadedUser(event.getPlayer().getUniqueId()); + if (Core.getInstance().getServer().getOnlinePlayers().size() >= Core.getInstance().getServer().getMaxPlayers()) { + Set toBeRemoved = new HashSet<>(); + boolean kick = false; + for (Map.Entry afkPlayers : afk.entrySet()) { + if (System.currentTimeMillis() > (afkPlayers.getValue() + TimeUnit.MINUTES.toMillis(AFK_MINUTES))) { + toBeRemoved.add(afkPlayers.getKey()); + } + } + for (UUID uuid : toBeRemoved) { + Player player = Bukkit.getPlayer(uuid); + if (player != null) { + User user = Core.getUserManager().getLoadedUser(uuid); + if (!user.isRank(UserRank.HELPOP) && user.isRank(UserRank.VIP) && !user.hasTrialRank()) continue; + kick = true; + afk.remove(uuid); + player.kickPlayer(Lang.GTM.f("&cYou were kicked for being afk!")); + } else { + if (afk.containsKey(uuid)) afk.remove(uuid); + } + } + toBeRemoved.clear(); + if (kick || joining.isRank(UserRank.PREMIUM)) { + event.allow(); + } else { + event.setKickMessage(Utils.f("&cSorry, this server is full! You must be &a&lPREMIUM+ &cto join full games!")); + } + } + } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/task/common/BossBarTask.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/task/common/BossBarTask.java new file mode 100644 index 0000000..1131b22 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/task/common/BossBarTask.java @@ -0,0 +1,74 @@ +package net.grandtheftmc.core.task.common; + +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserManager; + +public class BossBarTask { + + /** Whether or not the task is enabled */ + private boolean enabled; + /** The task object held */ + private BukkitTask task; + + /** + * Construct a new BossBar task that will update boss bar info for all + * users. + */ + public BossBarTask() { + this.enabled = true; + constructTask(); + } + + /** + * Construct the runnable task and assign it. + */ + public void constructTask() { + this.task = new BukkitRunnable() { + @Override + public void run() { + for (User user : UserManager.getInstance().getUsers()) { + user.refreshBossBar(); + } + } + }.runTaskTimerAsynchronously(Core.getInstance(), 0, 1); + } + + /** + * Get whether or not the boss bar task is enabled. + * + * @return {@code true} if the boss bar task is enabled. + */ + public boolean isEnabled() { + return enabled; + } + + /** + * Set whether or not the boss bar task is enabled. + * + * @param enabled - {@code true} if the task is enabled. + */ + public void setEnabled(boolean enabled) { + this.enabled = enabled; + + // if disabling, cancel the task + if (!enabled) { + if (task != null) { + task.cancel(); + } + } + else { + + // if enabling and task exists, cancel + if (task != null) { + task.cancel(); + } + + // construct new task + constructTask(); + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/trading/TradeManager.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/trading/TradeManager.java new file mode 100644 index 0000000..2d2259b --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/trading/TradeManager.java @@ -0,0 +1,227 @@ +package net.grandtheftmc.core.trading; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.ItemStack; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.Component; +import net.grandtheftmc.core.util.ServerUtil; + +/** + * Created by Timothy Lampen on 11/1/2017. + */ +public class TradeManager implements Component, Listener{ + + /** Whether trading is enabled */ + private boolean enabled; + + @Override + public TradeManager onEnable(Core plugin) { + this.enabled = true; + Bukkit.getPluginManager().registerEvents(this, plugin); + return this; + } + + private final ArrayList activeTrades = new ArrayList<>(); + private final HashMap pendingTrades = new HashMap<>(); + + @EventHandler + public void onLeave(PlayerQuitEvent event) { + Player player = event.getPlayer(); + Optional tradeMenu = getTrade(player); + if(!tradeMenu.isPresent()) + return; + endTrade(tradeMenu.get(), false, true); + } + + @EventHandler + public void onChat(AsyncPlayerChatEvent event) { + Player player = event.getPlayer(); + Optional tradeMenu = getTrade(player); + String msg = event.getMessage(); + if(!tradeMenu.isPresent()) + return; + event.setCancelled(true); + if(msg.equalsIgnoreCase("cancel")) { + tradeMenu.get().updatePlayerSettingCustomAmt(player, false); + tradeMenu.get().openInventory(player); + return; + } + int amt; + try { + amt =Integer.parseInt(event.getMessage()); + }catch (NumberFormatException nfe) { + player.sendMessage(Lang.TRADE.f("&6" + msg + " &7is not a number. Please type a number or type '&ccancel&7' to return to the trade menu.")); + return; + } + if(amt <= 0) { + player.sendMessage(Lang.TRADE.f("&6" + msg + " &7 is not greater than 0. Please type a positive number or type '&ccancel&7' to return to the trade menu.")); + return; + } + tradeMenu.get().updatePlayerSettingCustomAmt(player, false); + tradeMenu.get().openInventory(player); + if(tradeMenu.get().getTrader().equals(player)) { + tradeMenu.get().setTraderMoney(TradingSlotType.SET_CUSTOM_AMOUNT, amt); + return; + } + tradeMenu.get().setTradeeMoney(TradingSlotType.SET_CUSTOM_AMOUNT, amt); + } + + /** + * @param player the player who is in the trade (the tradee or trader) + * @return the trademenu that is currently active. + */ + public Optional getTrade(Player player) { + return activeTrades.stream().filter(trade -> trade.getTrader().equals(player) || trade.getTradee().equals(player)).findFirst(); + } + + /** + * @param tradee the player being traded (the person who accepts the trade) + * @param trader the player who initiated the trade + */ + public void startTrade(Player trader, Player tradee){ + activeTrades.add(new TradeMenu(trader, tradee)); + } + + /** + * @param tradeMenu the trademenu that you want to end + * @param successful if the trade was done successfully + * Note that the player's inventories cannot be closed here because a loop could be made with the onClose event. + */ + public void endTrade(TradeMenu tradeMenu, boolean successful, boolean closeInventories) { + if(!successful) { + tradeMenu.getSlotPairs().get(TradingSlotType.TRADER_ITEM).forEach(slot -> { + ItemStack is = tradeMenu.getInventory().getItem(slot); + if(is==null || is.getType()==Material.AIR || is.getType()== Material.STAINED_GLASS_PANE) + return; + Utils.giveItems(tradeMenu.getTrader(), tradeMenu.getInventory().getItem(slot)); + }); + tradeMenu.getSlotPairs().get(TradingSlotType.TRADEE_ITEM).forEach(slot -> { + ItemStack is = tradeMenu.getInventory().getItem(slot); + if(is==null || is.getType()==Material.AIR || is.getType()== Material.STAINED_GLASS_PANE) + return; + Utils.giveItems(tradeMenu.getTradee(), tradeMenu.getInventory().getItem(slot)); + }); + tradeMenu.getTrader().getInventory().addItem(tradeMenu.getTrader().getItemOnCursor()); + tradeMenu.getTrader().setItemOnCursor(null); + tradeMenu.getTrader().sendMessage(Lang.TRADE.f("&7The trade has been cancelled.")); + + tradeMenu.getTradee().getInventory().addItem(tradeMenu.getTradee().getItemOnCursor()); + tradeMenu.getTradee().setItemOnCursor(null); + tradeMenu.getTradee().sendMessage(Lang.TRADE.f("&7The trade has been cancelled.")); + + ServerUtil.runTaskLater(() -> { + tradeMenu.getTradee().updateInventory(); + tradeMenu.getTrader().updateInventory(); + }, 1); + } + else{ + String fault = ""; + User traderUser = Core.getUserManager().getLoadedUser(tradeMenu.getTrader().getUniqueId()); + User tradeeUser = Core.getUserManager().getLoadedUser(tradeMenu.getTradee().getUniqueId()); + if(!(traderUser.getMoney() >= tradeMenu.getMoneyTrader())) { + fault = tradeMenu.getTrader().getName(); + } + if(!(tradeeUser.getMoney() >= tradeMenu.getMoneyTradee())) { + fault = tradeMenu.getTradee().getName(); + } + if(!fault.equals("")) {//it cancelled somehow + tradeMenu.getTradee().sendMessage(Lang.TRADE.f("&6" + fault + " &7does not have enough money to complete this trade,")); + return; + } + tradeMenu.getSlotPairs().get(TradingSlotType.TRADER_ITEM).forEach(slot -> { + ItemStack is = tradeMenu.getInventory().getItem(slot); + if(is==null || is.getType()==Material.AIR || is.getType()== Material.STAINED_GLASS_PANE) + return; + Utils.giveItems(tradeMenu.getTradee(), tradeMenu.getInventory().getItem(slot)); + }); + tradeMenu.getSlotPairs().get(TradingSlotType.TRADEE_ITEM).forEach(slot -> { + ItemStack is = tradeMenu.getInventory().getItem(slot); + if(is==null || is.getType()==Material.AIR || is.getType()== Material.STAINED_GLASS_PANE) + return; + Utils.giveItems(tradeMenu.getTrader(), tradeMenu.getInventory().getItem(slot)); + }); + if(tradeMenu.getMoneyTrader()>0) { + tradeeUser.addMoney(tradeMenu.getMoneyTrader()); + traderUser.takeMoney(tradeMenu.getMoneyTrader()); + Utils.insertLog(tradeeUser.getUUID(), tradeMenu.getTradee().getName(), "getTradeMoney", "TRADEMENU", "MONEY", tradeMenu.getMoneyTrader(), -1); + Utils.insertLog(traderUser.getUUID(), tradeMenu.getTrader().getName(), "giveTradeMoney", "TRADEMENU", "MONEY", tradeMenu.getMoneyTrader(), -1); + } + if(tradeMenu.getMoneyTradee()>0) { + traderUser.addMoney(tradeMenu.getMoneyTradee()); + tradeeUser.takeMoney(tradeMenu.getMoneyTradee()); + Utils.insertLog(tradeeUser.getUUID(), tradeMenu.getTradee().getName(), "giveTradeMoney", "TRADEMENU", "MONEY", tradeMenu.getMoneyTradee(), -1); + Utils.insertLog(traderUser.getUUID(), tradeMenu.getTrader().getName(), "getTradeMoney", "TRADEMENU", "MONEY", tradeMenu.getMoneyTradee(), -1); + } + tradeMenu.getTradee().playSound(tradeMenu.getTradee().getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 10, 10); + tradeMenu.getTrader().playSound(tradeMenu.getTrader().getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 10, 10); + } + this.activeTrades.remove(tradeMenu); + if(closeInventories) { + tradeMenu.getTradee().closeInventory(); + tradeMenu.getTrader().closeInventory(); + } + } + + /** + * @param origin the player who sent the request + * @param target the target player who was sent the request + */ + public void addPendingTrade(UUID origin, UUID target) { + this.pendingTrades.put(target, origin); + } + + /** + * @param target the target player who was sent the request + * @return the entry of the pending trade with sender (value) and target (key) + */ + public Optional> getPendingTrade(UUID target){ + return this.pendingTrades.entrySet().stream().filter(entry -> entry.getKey().equals(target)).findFirst(); + } + + /** + * @param target the target who was sent the request + */ + public void removePendingTrade(UUID target) { + if(this.pendingTrades.containsKey(target)) + this.pendingTrades.remove(target); + } + + public ArrayList getActiveTrades() { + return activeTrades; + } + + /** + * Get whether or not the trade manager is enabled. + * + * @return {@code true} if the trade manager is enabled, {@code false} otherwise. + */ + public boolean isEnabled() { + return enabled; + } + + /** + * Set whether the trade manager is enabled. + * + * @param enabled - {@code true} if the trade manager is enabled, {@code false} otherwise. + */ + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/trading/TradeMenu.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/trading/TradeMenu.java new file mode 100644 index 0000000..bde387a --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/trading/TradeMenu.java @@ -0,0 +1,505 @@ +package net.grandtheftmc.core.trading; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.inventory.CoreMenu; +import net.grandtheftmc.core.inventory.button.ClickableItem; +import net.grandtheftmc.core.inventory.button.MenuItem; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.factory.ItemFactory; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedList; + +/** + * Created by Timothy Lampen on 11/1/2017. + */ +public class TradeMenu extends CoreMenu{ + private final HashMap> slotPairs = new HashMap<>(); + private final Player trader, tradee; + private double moneyTrader = 0, moneyTradee = 0; + private TradingStatus status = TradingStatus.WAITING; + private boolean traderSettingCustomAmt = false, tradeeSettingCustomAmt = false; + + public TradeMenu(Player trader, Player tradee) { + super(6, generateTitle(trader.getName(), tradee.getName())); + loadSlotPairs(); + this.tradee = tradee; + this.trader = trader; + + this.slotPairs.get(TradingSlotType.NOTHING).forEach(slot -> { + addItem(generateDefaultItem(TradingSlotType.NOTHING, slot)); + }); + + this.slotPairs.get(TradingSlotType.ACCEPT).forEach(slot -> { + addItem(generateDefaultItem(TradingSlotType.ACCEPT, slot)); + }); + + this.slotPairs.get(TradingSlotType.DECLINE).forEach(slot -> { + addItem(generateDefaultItem(TradingSlotType.DECLINE, slot)); + }); + + addItem(generateDefaultItem(TradingSlotType.TRADER_MONEY)); + addItem(generateDefaultItem(TradingSlotType.TRADEE_MONEY)); + addItem(generateDefaultItem(TradingSlotType.ADD_HUNDRED)); + addItem(generateDefaultItem(TradingSlotType.ADD_THOUSAND)); + addItem(generateDefaultItem(TradingSlotType.ADD_TEN_THOUSAND)); + addItem(generateDefaultItem(TradingSlotType.SET_CUSTOM_AMOUNT)); + openInventory(trader); + openInventory(tradee); + } + + @Override + public void onClick(InventoryClickEvent event){ + ItemStack cursor = event.getCursor(); + ItemStack item = event.getCurrentItem(); + Player player = (Player)event.getWhoClicked(); + int slot = event.getSlot(); + + if(!Core.getTradeManager().getActiveTrades().contains(this)) + return; + if(!(event.getClick().toString().contains("LEFT") || event.getClick().toString().contains("RIGHT"))) { + event.setCancelled(true); + return; + } + if(cursor.getType()==Material.AIR && item.getType()==Material.AIR) + return; + if(event.getClickedInventory()==null) { + event.setCancelled(true); + return; + } + if(event.getClickedInventory().equals(player.getInventory())) { + if(!event.getClick().isShiftClick()) + return; + if(item==null|| item.getType()==Material.COMPASS || item.getType()== Material.WATCH || item.getType()==Material.CHEST) { + event.setCancelled(true); + return; + } + + if(player.equals(this.trader)) { + for(Integer i : this.slotPairs.get(TradingSlotType.TRADER_ITEM)) { + ItemStack is = event.getInventory().getItem(i); + if(is==null || is.getType()==Material.AIR) { + event.getInventory().setItem(i, item); + event.setCurrentItem(new ItemStack(Material.AIR)); + if(this.status == TradingStatus.ONE_ACCEPT) { + this.status = TradingStatus.WAITING; + int[] slots = new int[]{31,40,49}; + for(int ia : slots) + addItem(generateDefaultItem(TradingSlotType.NOTHING, ia)); + } + break; + } + } + this.trader.updateInventory(); + this.tradee.updateInventory(); + event.setCancelled(true); + } + else{ + for(Integer i : this.slotPairs.get(TradingSlotType.TRADEE_ITEM)) { + ItemStack is = event.getInventory().getItem(i); + if(is==null || is.getType()==Material.AIR) { + event.getInventory().setItem(i, item); + event.setCurrentItem(new ItemStack(Material.AIR)); + if(this.status == TradingStatus.ONE_ACCEPT) { + this.status = TradingStatus.WAITING; + int[] slots = new int[]{4,13,22}; + for(int ia : slots) + addItem(generateDefaultItem(TradingSlotType.NOTHING, ia)); + } + break; + } + } + this.trader.updateInventory(); + this.tradee.updateInventory(); + event.setCancelled(true); + } + } + else if(this.slotPairs.get(TradingSlotType.TRADER_ITEM).contains(slot)) { + Core.error("2"); + if(player.equals(this.trader)) { + if(this.status == TradingStatus.ONE_ACCEPT) { + this.status = TradingStatus.WAITING; + int[] slots = new int[]{31,40,49}; + for(int i : slots) + addItem(generateDefaultItem(TradingSlotType.NOTHING, i)); + ServerUtil.runTaskLater(() -> { + this.tradee.updateInventory(); + this.trader.updateInventory(); + }, 1); + } + } + else { + event.setCancelled(true); + } + } + else if(this.slotPairs.get(TradingSlotType.TRADEE_ITEM).contains(slot)) { + if(player.equals(this.tradee)) { + if(this.status == TradingStatus.ONE_ACCEPT) { + this.status = TradingStatus.WAITING; + int[] slots = new int[]{4,13,22}; + for(int i : slots) + addItem(generateDefaultItem(TradingSlotType.NOTHING, i)); + ServerUtil.runTaskLater(() -> { + this.tradee.updateInventory(); + this.trader.updateInventory(); + }, 1); + + } + } + else { + event.setCancelled(true); + + } + } + } + + @Override + public void onClose(InventoryCloseEvent event){ + Player player = (Player)event.getPlayer(); + if(!Core.getTradeManager().getActiveTrades().contains(this)) + return; + if(player.equals(trader)) { + if (!this.traderSettingCustomAmt) { + Core.getTradeManager().endTrade(this, false, false); + this.tradee.closeInventory(); + } + } + else { + if (!this.tradeeSettingCustomAmt) { + Core.getTradeManager().endTrade(this, false, false); + this.trader.closeInventory(); + } + } + } + + /** + * @param type the type of item in the inventory that was clicked + * @param amt the amount to set the trader's money to. + */ + public boolean setTraderMoney(TradingSlotType type, double amt){ + User user = Core.getUserManager().getLoadedUser(this.trader.getUniqueId()); + if(!user.hasMoney(amt)) { + addItem(new ClickableItem(this.slotPairs.get(type).get(0), new ItemFactory(Material.WOOL).setDurability((short)14).setName(Utils.f("&cYou do not have enough money!")).setLore(Utils.f("&7Click to try again")).build(), (player, clickType)-> { + addItem(generateDefaultItem(type)); + })); + return false; + } + this.moneyTrader = amt; + MenuItem menuItem = generateDefaultItem(TradingSlotType.TRADER_MONEY); + ItemStack is = menuItem.getItemStack().clone(); + ItemMeta im = is.getItemMeta(); + im.setDisplayName(Utils.f("&7+ &a" + Utils.formatMoney(amt))); + is.setItemMeta(im); + getInventory().setItem(menuItem.getIndex(), is); + tradee.updateInventory(); + trader.updateInventory(); + resetStatus(); + return true; + } + + /** + * @param type the type of item in the inventory that was clicked + * @param amt the amount to set the tradee's money to. + */ + public boolean setTradeeMoney(TradingSlotType type, double amt){ + User user = Core.getUserManager().getLoadedUser(this.tradee.getUniqueId()); + if(!user.hasMoney(amt)) { + addItem(new ClickableItem(this.slotPairs.get(type).get(0), new ItemFactory(Material.WOOL).setDurability((short)14).setName(Utils.f("&cYou do not have enough money!)")).setLore(Utils.f("&7Click to try again")).build(), (player, clickType)-> { + addItem(generateDefaultItem(type)); + })); + return false; + } + this.moneyTradee = amt; + MenuItem menuItem = generateDefaultItem(TradingSlotType.TRADEE_MONEY); + ItemStack is = menuItem.getItemStack().clone(); + ItemMeta im = is.getItemMeta(); + im.setDisplayName(Utils.f("&7+ &a" + Utils.formatMoney(amt))); + is.setItemMeta(im); + getInventory().setItem(menuItem.getIndex(), is); + resetStatus(); + return true; + } + + /** + * Used when a player edits the trade. + */ + private static final int[] DIVIDER_SLOTS = new int[]{4,13,22,31,40,49}; + public void resetStatus(){ + if(this.status == TradingStatus.ONE_ACCEPT) { + this.status = TradingStatus.WAITING; + for(int i : DIVIDER_SLOTS) + addItem(generateDefaultItem(TradingSlotType.NOTHING, i)); + this.tradee.updateInventory(); + this.trader.updateInventory(); + } + } + + /** + * @return a hashmap with the type of item in the inventory, and the slot(s) that correspond to that type of item. + */ + public HashMap> getSlotPairs() { + return this.slotPairs; + } + + /** + * @return the money the tradee has offered + */ + public double getMoneyTradee() { + return moneyTradee; + } + + /** + * @return the money the trader has offered + */ + public double getMoneyTrader() { + return moneyTrader; + } + + private MenuItem generateDefaultItem(TradingSlotType type){ + return generateDefaultItem(type, this.slotPairs.get(type).size()>1 ? -1: this.slotPairs.get(type).get(0)); + } + + private MenuItem generateStackableItem(ItemStack is, TradingSlotType type, int slot){ + switch (type) { + case TRADEE_ITEM: + return new ClickableItem(slot, is, (playerA, clickTypeA) -> { + new BukkitRunnable() { + @Override + public void run() { + if(!playerA.equals(tradee)) + return; + ServerUtil.debug("is tradee"); + ItemStack cursor = tradee.getItemOnCursor().clone(); + MenuItem item = getMenuItem(slot); + if(cursor==null || cursor.getType() == Material.AIR) { + ServerUtil.debug("cursor null, should put item in hand."); + playerA.setItemOnCursor(item.getItemStack()); + addItem(generateDefaultItem(TradingSlotType.TRADEE_EMPTY_ITEM, slot)); + } + else { + ServerUtil.debug("cursor not null, should stack / switch the items"); + stackItemsInTrade(cursor, item, playerA, type, slot); + } + ServerUtil.debug("updated the player's inventory."); + playerA.updateInventory(); + resetStatus(); + } + }.runTaskLater(Core.getInstance(), 1); + }); + case TRADER_ITEM: + return new ClickableItem(slot, is, (playerA, clickTypeA) -> { + new BukkitRunnable() { + @Override + public void run() { + if(!playerA.equals(trader)) + return; + ServerUtil.debug("is tradee"); + ItemStack cursor = trader.getItemOnCursor().clone(); + MenuItem item = getMenuItem(slot); + if(cursor==null || cursor.getType() == Material.AIR) { + ServerUtil.debug("cursor null, should put item in hand."); + playerA.setItemOnCursor(item.getItemStack()); + addItem(generateDefaultItem(TradingSlotType.TRADER_EMPTY_ITEM, slot)); + } + else { + ServerUtil.debug("cursor not null, should stack / switch the items"); + stackItemsInTrade(cursor, item, playerA, type, slot); + } + ServerUtil.debug("updated the player's inventory."); + playerA.updateInventory(); + resetStatus(); + } + }.runTaskLater(Core.getInstance(), 1); + }); + } + return null; + } + + private void stackItemsInTrade(ItemStack cursor, MenuItem item, Player playerA, TradingSlotType type, int slot) { + if(cursor.isSimilar(item.getItemStack())) { + ServerUtil.debug("they are similar"); + if(cursor.getAmount() + item.getItemStack().getAmount() <= 64) { + ServerUtil.debug("less than 64, just put them together"); + item.getItemStack().setAmount(item.getItemStack().getAmount() + cursor.getAmount()); + addItem(item); + playerA.setItemOnCursor(new ItemStack(Material.AIR)); + } + else { + ServerUtil.debug("more than 64, so just make the item 64, remove that amount from cursor"); + int needed = 64 - item.getItemStack().getAmount(); + cursor.setAmount(cursor.getAmount() - needed); + item.getItemStack().setAmount(64); + addItem(item); + playerA.setItemOnCursor(cursor); + } + } + else { + ServerUtil.debug("player is trying to pick the item up."); + playerA.setItemOnCursor(item.getItemStack()); + addItem(generateStackableItem(cursor, type, slot)); + } + } + + + /** + * @param type the type of item that is going to be generated + * @param slot the slot that the item will be placed into + */ + private MenuItem generateDefaultItem(TradingSlotType type, int slot){ + switch (type) { + /*case TRADER_ITEM: + return new ClickableItem(slot, new ItemFactory(Material.STAINED_GLASS_PANE).setDurability((short)8).setName(Utils.f("&6" + this.trader.getName() + "&7's side")).build(), (player, clickType) -> { + if(player.equals(this.trader)) { + if(this.trader.getItemOnCursor()==null || this.trader.getItemOnCursor().getType()==Material.AIR) + return; + ServerUtil.debug(player.getItemOnCursor().getType() + "/ " + getMenuItem(slot).getItemStack().getType() + " / 1"); + addItem(generateStackableItem(player.getItemOnCursor(), TradingSlotType.TRADER_ITEM, slot)); + this.trader.setItemOnCursor(new ItemStack(Material.AIR)); + resetStatus(); + player.updateInventory(); + } + }); + case TRADEE_EMPTY_ITEM: + return new ClickableItem(slot, new ItemFactory(Material.STAINED_GLASS_PANE).setDurability((short)8).setName(Utils.f("&6" + this.tradee.getName() + "&7's side")).build(), (player, clickType) -> { + if(player.equals(this.tradee)) { + if(this.tradee.getItemOnCursor()==null || this.tradee.getItemOnCursor().getType()==Material.AIR) + return; + ServerUtil.debug(player.getItemOnCursor().getType() + "/ " + getMenuItem(slot).getItemStack().getType() + " / 2"); + addItem(generateStackableItem(player.getItemOnCursor(), TradingSlotType.TRADEE_ITEM, slot)); + this.tradee.setItemOnCursor(new ItemStack(Material.AIR)); + resetStatus(); + player.updateInventory(); + } + });*/ + case NOTHING: + return new MenuItem(slot, new ItemFactory(Material.STAINED_GLASS_PANE).setDurability((short)15).setName(" ").setLore(Utils.f("&a< &6" + trader.getName() + " &b&l| &6" + tradee.getName() + " &a>")).build(), false); + case TRADEE_MONEY: + return new MenuItem(slot, new ItemFactory(Material.PAPER).setUnsafeEnchantment(Enchantment.LURE, 0).addFlags(ItemFlag.HIDE_ENCHANTS).setName(Utils.f("&7+ &a$0")).build(), false); + case TRADER_MONEY: + return new MenuItem(slot, new ItemFactory(Material.PAPER).setUnsafeEnchantment(Enchantment.LURE, 0).addFlags(ItemFlag.HIDE_ENCHANTS).setName(Utils.f("&7+ &a$0")).build(), false); + case ADD_HUNDRED: + return new ClickableItem(slot, new ItemFactory(Material.IRON_NUGGET).setName(Utils.f("&7Add &a$100")).build(), (player, clickType)-> { + if(player.equals(this.trader)) { + setTraderMoney(type, this.moneyTrader + 100); + return; + } + setTradeeMoney(type, this.moneyTradee + 100); + }); + case ADD_THOUSAND: + return new ClickableItem(slot, new ItemFactory(Material.GOLD_INGOT).setName(Utils.f("&7Add &a$1,000")).build(), (player, clickType)-> { + if(player.equals(this.trader)) { + setTraderMoney(type, this.moneyTrader + 1000); + return; + } + setTradeeMoney(type, this.moneyTradee + 1000); + }); + case ADD_TEN_THOUSAND: + return new ClickableItem(slot, new ItemFactory(Material.GOLD_BLOCK).setName(Utils.f("&7Add &a$10,000")).build(), (player, clickType)-> { + if(player.equals(this.trader)) { + setTraderMoney(type, this.moneyTrader + 10000); + return; + } + setTradeeMoney(type, this.moneyTradee + 10000); + }); + case SET_CUSTOM_AMOUNT: + return new ClickableItem(slot, new ItemFactory(Material.DIAMOND).setName(Utils.f("&6Custom Amount")).build(), (player, clickType)->{ + updatePlayerSettingCustomAmt(player, true); + player.closeInventory(); + player.sendMessage(Lang.TRADE.f("&7Please insert the amount of money you would like to add to the trade. Or type '&ccancel&7' to return to the trade screen.")); + }); + case DECLINE: + return new ClickableItem(slot, new ItemFactory(Material.WOOL).setDurability((short)14).setName(Utils.f("&cDecline the trade")).build(), (player, clickType) -> { + this.status = TradingStatus.DECLINED; + Core.getTradeManager().endTrade(this, false, true); + }); + case ACCEPT: + return new ClickableItem(slot, new ItemFactory(Material.WOOL).setDurability((short)5).setName(Utils.f("&aAccept the trade")).build(), (player, clickType)-> { + ItemStack newDivider = generateDefaultItem(TradingSlotType.NOTHING).getItemStack(); + newDivider.setDurability((short)5); + int[] slots = player.equals(trader) ? new int[]{4,13,22} : new int[]{31,40,49}; + for(int i : slots) + addItem(new MenuItem(i, newDivider, false)); + boolean fullyComplete = true; + for(int i : new int[]{4,13,22,31,40,49}) + if(getInventory().getItem(i).getDurability()==15) { + fullyComplete = false; + break; + } + if(fullyComplete) { + this.status = TradingStatus.ACCPETED; + Core.getTradeManager().endTrade(this, true, true); + } + else + this.status = TradingStatus.ONE_ACCEPT; + }); + } + return null; + } + + + + private void loadSlotPairs(){ + slotPairs.put(TradingSlotType.TRADER_ITEM, new LinkedList<>(Arrays.asList(0,1,2,3,9,10,11,12,18,19,20,21,27,28,29,30,36,37,38))); + slotPairs.put(TradingSlotType.TRADEE_ITEM, new LinkedList<>(Arrays.asList(5,6,7,8,14,15,16,17,23,24,25,26,32,33,34,35,41,42,43))); + slotPairs.put(TradingSlotType.TRADER_MONEY, new LinkedList<>(Collections.singletonList(39))); + slotPairs.put(TradingSlotType.TRADEE_MONEY,new LinkedList<>( Collections.singletonList(44))); + slotPairs.put(TradingSlotType.ADD_TEN_THOUSAND, new LinkedList<>(Collections.singletonList(47))); + slotPairs.put(TradingSlotType.ADD_HUNDRED, new LinkedList<>(Collections.singletonList(45))); + slotPairs.put(TradingSlotType.ADD_THOUSAND, new LinkedList<>(Collections.singletonList(46))); + slotPairs.put(TradingSlotType.SET_CUSTOM_AMOUNT, new LinkedList<>(Collections.singletonList(48))); + slotPairs.put(TradingSlotType.NOTHING, new LinkedList<>(Arrays.asList(4,13,22,31,40,49))); + slotPairs.put(TradingSlotType.ACCEPT, new LinkedList<>(Arrays.asList(50,51))); + slotPairs.put(TradingSlotType.DECLINE, new LinkedList<>(Arrays.asList(52,53))); + } + + /** + * @return the tradee in the trade + */ + public Player getTradee() { + return this.tradee; + } + + /** + * @return the trader in the trade + */ + public Player getTrader() { + return this.trader; + } + + /** + * @param player the player that is using the chat function + * @param bool if they are using the chat custom ammount function. + */ + public void updatePlayerSettingCustomAmt(Player player, boolean bool) { + if(player.equals(trader)) + this.traderSettingCustomAmt = bool; + else + this.tradeeSettingCustomAmt = bool; + } + + private static String generateTitle(String origin, String target){ + origin = origin.length() >= 13 ? origin.substring(0, 13) : origin; + StringBuilder sb = new StringBuilder(origin); + for(int i = origin.length() ; i<=13; i++){ + sb.append(" "); + } + sb.append(" | "); + target = target.length() >= 12 ? target.substring(0, 12) : target; + sb.append(target); + return sb.toString(); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/trading/TradingSlotType.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/trading/TradingSlotType.java new file mode 100644 index 0000000..83e71b0 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/trading/TradingSlotType.java @@ -0,0 +1,20 @@ +package net.grandtheftmc.core.trading; + +/** + * Created by Timothy Lampen on 11/1/2017. + */ +public enum TradingSlotType { + NOTHING, + TRADER_EMPTY_ITEM, + ADD_HUNDRED, + ADD_THOUSAND, + ADD_TEN_THOUSAND, + SET_CUSTOM_AMOUNT, + TRADEE_EMPTY_ITEM, + ACCEPT, + DECLINE, + TRADER_MONEY, + TRADEE_MONEY, + TRADEE_ITEM, + TRADER_ITEM +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/trading/TradingStatus.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/trading/TradingStatus.java new file mode 100644 index 0000000..4496116 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/trading/TradingStatus.java @@ -0,0 +1,11 @@ +package net.grandtheftmc.core.trading; + +/** + * Created by Timothy Lampen on 11/4/2017. + */ +public enum TradingStatus { + WAITING, + ONE_ACCEPT, + ACCPETED, + DECLINED +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/transaction/Transaction.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/transaction/Transaction.java new file mode 100644 index 0000000..713de58 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/transaction/Transaction.java @@ -0,0 +1,72 @@ +package net.grandtheftmc.core.transaction; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +public abstract class Transaction { + + /** The ID of the transaction */ + private final int id; + /** The creation of the transaction */ + private final long creation; + + /** + * Create a new Transaction. + * + * @param id - the id of the transaction + * @param creation - the timestamp in millis for the transaction + */ + public Transaction(int id, long creation) { + this.id = id; + this.creation = creation; + } + + /** + * Get the id of the transaction. + * + * @return The id of the transaction. + */ + public int getId() { + return id; + } + + /** + * Get the creation, in milliseconds, or the timestamp, for the transaction. + * + * @return The timestamp, in milliseconds, for this transaction. + */ + public long getCreation() { + return creation; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object o) { + if (this == o) + return true; + + if (o == null || getClass() != o.getClass()) + return false; + + Transaction that = (Transaction) o; + + return new EqualsBuilder() + .append(id, that.id) + .isEquals(); + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + return new HashCodeBuilder(17, 37) + .append(id) + .toHashCode(); + } +} + + + diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/transaction/TransactionEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/transaction/TransactionEvent.java new file mode 100644 index 0000000..5ffb845 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/transaction/TransactionEvent.java @@ -0,0 +1,48 @@ +package net.grandtheftmc.core.transaction; + +import org.bukkit.event.Event; + +public abstract class TransactionEvent extends Event { + + /** The transaction assigned to this event */ + private final T transaction; + /** Whether or not the transaction has been processed */ + private boolean processed = false; + + /** + * Construct a new TransactionEvent. + * + * @param transaction - the transaction to process + */ + public TransactionEvent(T transaction) { + this.transaction = transaction; + } + + /** + * Get the transaction involved in this event. + * + * @return The transaction involved in this event. + */ + public T getTransaction() { + return transaction; + } + + /** + * Get whether or not this transaction was processed. + * + * @return {@code true} if transaction was processed, {@code false} + * otherwise. + */ + public boolean isProcessed() { + return processed; + } + + /** + * Set whether or not the transaction has been processed. + * + * @param processed - {@code true} if it was processed + */ + public void setProcessed(boolean processed) { + this.processed = processed; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/transaction/state/StateTransaction.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/transaction/state/StateTransaction.java new file mode 100644 index 0000000..c8514ec --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/transaction/state/StateTransaction.java @@ -0,0 +1,71 @@ +package net.grandtheftmc.core.transaction.state; + +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.json.simple.JSONObject; + +import net.grandtheftmc.core.transaction.Transaction; + +public abstract class StateTransaction extends Transaction { + + /** The payload involved in this transaction */ + private final JSONObject payload; + /** The time to process the transaction at */ + private final long processAt; + + /** + * Create a new StateTransaction. + *

+ * This is used to represent a JSON object that be parsed to do something + * with. + * + * @param id - the id of the transaction + * @param payload - the payload json involved in this transaction + * @param creation - the creation timestamp + * @param processAt - the process timestamp + */ + public StateTransaction(int id, JSONObject payload, long creation, long processAt) { + super(id, creation); + this.payload = payload; + this.processAt = processAt; + } + + /** + * Get the payload involved in this transaction. + * + * @return The payload involved in this transaction. + */ + public JSONObject getPayload() { + return payload; + } + + /** + * Get the time, in milliseconds, to process the transaction. + * + * @return The time to process the transaction. + */ + public long getProcessAt() { + return processAt; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object o) { + if (this == o) + return true; + + if (o == null || getClass() != o.getClass()) + return false; + + return super.equals(o); + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + return new HashCodeBuilder(19, 37).append(getId()).toHashCode(); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/transaction/state/StateTransactionEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/transaction/state/StateTransactionEvent.java new file mode 100644 index 0000000..d13e7c1 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/transaction/state/StateTransactionEvent.java @@ -0,0 +1,15 @@ +package net.grandtheftmc.core.transaction.state; + +import net.grandtheftmc.core.transaction.TransactionEvent; + +public abstract class StateTransactionEvent extends TransactionEvent { + + /** + * Create a new StateTransactionEvent. + * + * @param transaction - the transaction involved in the event + */ + public StateTransactionEvent(T transaction) { + super(transaction); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/transaction/state/user/UserStateTransaction.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/transaction/state/user/UserStateTransaction.java new file mode 100644 index 0000000..125de6a --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/transaction/state/user/UserStateTransaction.java @@ -0,0 +1,163 @@ +package net.grandtheftmc.core.transaction.state.user; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.UUID; + +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; +import org.json.simple.JSONObject; + +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.transaction.state.StateTransaction; +import net.grandtheftmc.core.util.debug.Log; +import net.grandtheftmc.core.util.json.JSONParser; + +public class UserStateTransaction extends StateTransaction { + + /** The owner of the transaction */ + private final UUID uuid; + + /** + * Construct a new UserStateTransaction. + *

+ * This is a way of scheduling new state changes for a user at a different + * time. Specific examples would be allow us to give a currency/rank in the + * future for the specified player. + * + * @param id - the ID of the transaction + * @param uuid - the UUID of the user for this transaction + * @param payload - the payload contents for this transaction + * @param creation - the time that this transaction was created + * @param processAt - the time that this transaction should be processed + */ + public UserStateTransaction(int id, UUID uuid, JSONObject payload, long creation, long processAt) { + super(id, payload, creation, processAt); + this.uuid = uuid; + } + + /** + * Get the UUID of player that owns this transaction. + * + * @return The UUID of the player that owns this transaction. + */ + public UUID getUUID() { + return uuid; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + + if (o == null || getClass() != o.getClass()) + return false; + + return super.equals(o); + } + + @Override + public int hashCode() { + return new HashCodeBuilder(13, 37).append(getId()).toHashCode(); + } + + /** + * Process the specified transactions for the given player. + *

+ * This will collect all the transactions for that player, regardless of + * server type/id, and filter them to call only the correct ones. + *

+ * This will remove transactions if they were successfully processed. + *

+ * Note: Please call this method on an async thread! For more details see + * {@link #process(Connection, Plugin, Player, ServerType, int)}; + * + * @param plugin - the owning plugin + * @param player - the player to check transactions for + * @param serverType - the type of server we are checking the transactions + * for + * @param serverNum - the ID of the server we are checking the transactions + * for + */ + public static void process(Plugin plugin, Player player, String serverType, int serverNum) { + try (Connection conn = BaseDatabase.getInstance().getConnection()) { + process(conn, plugin, player, serverType, serverNum); + } + catch (SQLException e) { + e.printStackTrace(); + } + } + + /** + * Process the specified transactions for the given player. + *

+ * This will collect all the transactions for that player, regardless of + * server type/id, and filter them to call only the correct ones. + *

+ * This will remove transactions if they were successfully processed. + *

+ * Note: Please call this method on an async thread! + * + * @param conn - the database connection thread + * @param plugin - the owning plugin + * @param player - the player we are processing the transactions for + * @param serverType - the type of server we are checking the transactions + * for + * @param serverNum - the ID of the server we are checking the transactions + * for + */ + public static void process(Connection conn, Plugin plugin, Player player, String serverType, int serverNum) { + + UserStateTransactionDAO.getUserStateTransactions(conn, player.getUniqueId()).forEach((id, transaction) -> { + JSONParser payload = new JSONParser(transaction.getPayload()); + + // Only run on correct server + JSONParser server = payload.parseObject("server"); + if (server.hasKey("type")) { + + // Validate correct server type + if (!serverType.equalsIgnoreCase(server.getString("type"))) { + return; + } + + // Validate correct server number + if (server.hasKey("id")) { + if (serverNum != server.getInt("id")) { + return; + } + } + } + + // make sure we're on sync thread + Bukkit.getScheduler().runTaskLater(plugin, () -> { + + // call the processing of the event + UserStateTransactionEvent event = new UserStateTransactionEvent(player, transaction); + Bukkit.getPluginManager().callEvent(event); + + // Remove from transactions as processed + if (event.isProcessed()) { + + // async update + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { + try (Connection deleteConn = BaseDatabase.getInstance().getConnection()) { + boolean removed = UserStateTransactionDAO.removeUserStateTransaction(deleteConn, id); + if (removed){ + UserStateTransactionDAO.createLogUserStateTransaction(deleteConn, id, transaction); + } + } + catch (Exception e) { + Log.error("Core", "We were unable to delete a user state transaction id=" + id); + e.printStackTrace(); + } + }); + + Log.info("Core", "Successfully processed UserStateTransaction for name=" + player.getName() + ", payload=" + transaction.getPayload().toJSONString()); + } + }, 20L); + }); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/transaction/state/user/UserStateTransactionDAO.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/transaction/state/user/UserStateTransactionDAO.java new file mode 100644 index 0000000..f4c45a6 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/transaction/state/user/UserStateTransactionDAO.java @@ -0,0 +1,248 @@ +package net.grandtheftmc.core.transaction.state.user; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +import net.grandtheftmc.core.util.debug.Log; + +public class UserStateTransactionDAO { + + /** + * Get a mapping of (transaction id, transaction) for the specified user. + *

+ * Wrapper around + * {@link #getUserStateTransactions(Connection, UUID, boolean)}, only + * getting the active transactions to process. + * + * @param conn - the database connection thread + * @param uuid - the UUID of the user + * + * @return A mapping of (transaction id, transaction) where each is a state + * change that needs to be handled. + * + * @see UserStateTransactionDAO#getUserStateTransactions(Connection, UUID, + * boolean) + */ + public static Map getUserStateTransactions(Connection conn, UUID uuid) { + return getUserStateTransactions(conn, uuid, false); + } + + /** + * Get a mapping of (transaction id, transaction) for the specified user. + *

+ * Wrapper around + * {@link #getUserStateTransactions(Connection, UUID, boolean, boolean)}, + * only getting transactions that have not already been processed. + * + * @param conn - the database connection thread + * @param uuid - the UUID of the user + * @param includeDelayed - {@code true} if we should get all transactions, + * {@code false} if we should get only the ones that have + * exceeded the process time + * + * @return A mapping of (transaction id, transaction) where each is a state + * change that needs to be handled. + * + * @see UserStateTransactionDAO#getUserStateTransactions(Connection, UUID, + * boolean, boolean) + */ + public static Map getUserStateTransactions(Connection conn, UUID uuid, boolean includeDelayed) { + return getUserStateTransactions(conn, uuid, includeDelayed, false); + } + + /** + * Get a mapping of (transaction id, transaction) for the specified user. + * + * @param conn - the database connection thread + * @param uuid - the UUID of the user + * @param includeDelayed - {@code true} if we should get all transactions, + * {@code false} if we should get only the ones that have + * exceeded the process time + * @param alreadyProcessed - {@code true} if we should get already processed + * transactions as well, otherwise {@code false} + * + * @return A mapping of (transaction id, transaction) where each is a state + * change that needs to be handled. + */ + public static Map getUserStateTransactions(Connection conn, UUID uuid, boolean includeDelayed, boolean alreadyProcessed) { + Map transactions = new HashMap<>(); + + String query = "SELECT id, payload, creation, process_at FROM user_state_transaction WHERE uuid = UNHEX(?)"; + if (!includeDelayed) { + query += " AND process_at <= CURRENT_TIMESTAMP"; + } + + if (!alreadyProcessed) { + query += " AND processed = 0"; + } + + query += " ORDER BY creation ASC, process_at ASC;"; + + try (PreparedStatement statement = conn.prepareStatement(query)) { + statement.setString(1, uuid.toString().replaceAll("-", "")); + + try (ResultSet resultSet = statement.executeQuery()) { + while (resultSet.next()) { + int id = resultSet.getInt("id"); + + JSONObject payload; + try { + payload = (JSONObject) new JSONParser().parse(resultSet.getString("payload")); + } + catch (ParseException e) { + Log.error("UserStateTransaction", "Failed to load transaction: " + id); + e.printStackTrace(); + continue; + } + + long creation = resultSet.getTimestamp("creation").getTime(); + long processAt = resultSet.getTimestamp("process_at").getTime(); + + transactions.put(id, new UserStateTransaction(id, uuid, payload, creation, processAt)); + } + } + } + catch (SQLException e) { + Log.error("Core", "Unable to getUserStateTransactions() for uuid=" + uuid.toString() + ", includeDelayed=" + includeDelayed + ", alreadyProcessed=" + alreadyProcessed); + e.printStackTrace(); + } + + return transactions; + } + + /** + * Creates a user state transaction in the database. + * + * @param conn - the database connection thread + * @param uuid - the UUID of the user to create the transaction for + * @param payload - the payload information that should be parsed + * + * @return {@code true} if the transaction was successfully added, + * {@code false} otherwise. + */ + public static boolean addUserStateTransaction(Connection conn, UUID uuid, JSONObject payload) { + + String query = "INSERT INTO user_state_transaction (uuid, payload) VALUES (UNHEX(?), ?);"; + + try (PreparedStatement statement = conn.prepareStatement(query)) { + statement.setString(1, uuid.toString().replaceAll("-", "")); + statement.setString(2, payload.toJSONString()); + + statement.executeUpdate(); + return true; + } + catch (SQLException e) { + Log.error("Core", "Unable to addUserStateTransaction() for uuid=" + uuid.toString() + ", payload=" + payload.toJSONString()); + e.printStackTrace(); + } + + return false; + } + + /** + * Creates the required statement to put a user state transaction in the + * database + * + * @param conn - the database connection thread + * @param uuid - the UUID of the user to create the transaction for + * @param payload - the payload information that should be parsed + * + * @return An {@link ArrayList} containing the statements required to put a + * user state transaction in the database + */ + public static List collateSaveUserStateTransaction(Connection conn, UUID uuid, JSONObject payload) { + + String query = "INSERT INTO user_state_transaction (uuid, payload) VALUES (UNHEX(?), ?);"; + + // result set + List statements = new ArrayList<>(); + + try { + PreparedStatement statement = conn.prepareStatement(query); + + statement.setString(1, uuid.toString().replaceAll("-", "")); + statement.setString(2, payload.toJSONString()); + + statements.add(statement); + } + catch (SQLException e) { + Log.error("Core", "Unable to collateSaveUserStateTransaction() for uuid=" + uuid.toString() + ", payload=" + payload.toJSONString()); + e.printStackTrace(); + } + + return statements; + } + + /** + * Removes the specified transaction ID from the user state transaction + * table. + * + * @param conn - the database connection thread + * @param id - the ID of the transaction to remove + * + * @return {@code true} if the transaction was removed, {@code false} + * otherwise. + */ + public static boolean removeUserStateTransaction(Connection conn, int id) { + + String query = "DELETE FROM user_state_transaction WHERE id = ? LIMIT 1;"; + + try (PreparedStatement statement = conn.prepareStatement(query)) { + statement.setInt(1, id); + + statement.executeUpdate(); + return true; + } + catch (SQLException e) { + Log.error("Core", "Unable to removeUserStateTransaction() for id=" + id); + e.printStackTrace(); + } + + return false; + } + + /** + * Creates a log for the user state transaction. + *

+ * This is so that we know which logs were parsed. + * + * @param conn - the database connection thread + * @param id - the id of the transaction + * @param transaction - the transaction object + * + * @return {@code true} if the query was created, {@code false} otherwise. + */ + public static boolean createLogUserStateTransaction(Connection conn, int id, UserStateTransaction transaction) { + + String query = "INSERT INTO log_user_state_transaction (id, uuid, payload, creation, process_at) VALUES (?, UNHEX(?), ?, ?, ?);"; + + try (PreparedStatement statement = conn.prepareStatement(query)) { + statement.setInt(1, id); + statement.setString(2, transaction.getUUID().toString().replaceAll("-", "")); + statement.setString(3, transaction.getPayload().toJSONString()); + statement.setTimestamp(4, new Timestamp(transaction.getCreation())); + statement.setTimestamp(5, new Timestamp(transaction.getProcessAt())); + + statement.executeUpdate(); + return true; + } + catch (SQLException e) { + Log.error("UserStateTransaction", "Unable to createLogUserStateTransaction() for uuid=" + transaction.getUUID().toString() + ", payload=" + transaction.getPayload().toJSONString()); + e.printStackTrace(); + } + + return false; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/transaction/state/user/UserStateTransactionEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/transaction/state/user/UserStateTransactionEvent.java new file mode 100644 index 0000000..6a89d2e --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/transaction/state/user/UserStateTransactionEvent.java @@ -0,0 +1,51 @@ +package net.grandtheftmc.core.transaction.state.user; + +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +import net.grandtheftmc.core.transaction.state.StateTransactionEvent; + +public class UserStateTransactionEvent extends StateTransactionEvent { + + /** List of handlers for this event */ + private static final HandlerList HANDLERS = new HandlerList(); + /** The player to run the event for */ + private final Player player; + + /** + * Create a new UserStateTransaction event. + * + * @param player - the player involved in the event + * @param transaction - the transaction + */ + public UserStateTransactionEvent(Player player, UserStateTransaction transaction) { + super(transaction); + this.player = player; + } + + /** + * Get the player involved in the event. + * + * @return The player involved in the event. + */ + public Player getPlayer() { + return player; + } + + /** + * {@inheritDoc} + */ + @Override + public HandlerList getHandlers() { + return HANDLERS; + } + + /** + * Get the handlers involved in this event. + * + * @return The handlers involved in this event. + */ + public static HandlerList getHandlerList() { + return HANDLERS; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/tutorials/Help.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/tutorials/Help.java new file mode 100644 index 0000000..5d822db --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/tutorials/Help.java @@ -0,0 +1,29 @@ +package net.grandtheftmc.core.tutorials; + +import net.grandtheftmc.core.Core; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +public class Help { + private static Map> helpData = new HashMap<>(); + private static YamlConfiguration helpConfig = Core.getSettings().getHelpConfig(); + + public static void loadHelpData() { + helpData.clear(); + for(String key : helpConfig.getConfigurationSection("help").getKeys(true)) { + helpData.put(key.toLowerCase(), helpConfig.getStringList("help." + key)); + } + } + + public static Optional> getHelpMessage(String key) { + return Optional.ofNullable(helpData.get(key.toLowerCase())); + } + + public static Map> getHelpData() { + return helpData; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/tutorials/NextCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/tutorials/NextCommand.java new file mode 100644 index 0000000..b71c865 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/tutorials/NextCommand.java @@ -0,0 +1,37 @@ +package net.grandtheftmc.core.tutorials; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.UUID; + +public class NextCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String label, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Utils.f("&cYou are not a player!")); + return true; + } + Player player = (Player) s; + UUID uuid = player.getUniqueId(); + User user = Core.getUserManager().getLoadedUser(uuid); + Tutorial tut = Core.getTutorialManager().getTutorial(user.getTutorial()); + if (tut == null) { + s.sendMessage(Lang.TUTORIALS.f("&7You are not in a tutorial!")); + return true; + } + if (tut.getSlide(user.getTutorialSlide()) != null && !tut.getSlide(user.getTutorialSlide()).isCanConfirm()) { + s.sendMessage(Lang.TUTORIALS.f("&7You can not skip this slide!")); + return true; + } + tut.playNextSlide(player, user); + return true; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/tutorials/Slide.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/tutorials/Slide.java new file mode 100644 index 0000000..57cb658 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/tutorials/Slide.java @@ -0,0 +1,222 @@ +package net.grandtheftmc.core.tutorials; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.util.SoundEffect; +import net.grandtheftmc.core.util.Title; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ClickEvent.Action; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.entity.Player; + +import java.util.List; + +public class Slide { + + private boolean canConfirm; + private int delay; + private Location location; + private GameMode gameMode; + private String[] messages; + private boolean headerAndFooter; + private String actionBarMessage; + private Title title; + private List sounds; + private int slot; + private String menu; + + public Slide() { + } + + public Slide(boolean canConfirm, int delay, Location location, GameMode gameMode, String[] messages, boolean headerAndFooter, String actionBarMessage, Title title, List sounds, int slot, String menu) { + this.canConfirm = canConfirm; + this.delay = delay; + this.location = location; + this.gameMode = gameMode; + this.messages = messages; + this.headerAndFooter = headerAndFooter; + this.actionBarMessage = actionBarMessage; + this.title = title; + this.sounds = sounds; + this.slot = slot; + this.menu = menu; + } + + public void play(Player player) { + this.teleport(player); + this.sendSoundEffects(player); + this.sendMessages(player); + this.sendActionBarMessage(player); + this.sendTitle(player); + this.setGameMode(player); + if (this.menu != null) + MenuManager.openMenu(player, this.menu); + } + + public void teleport(Player player) { + if (this.location != null) + player.teleport(this.location); + if (this.slot >= 0 && this.slot <= 8) + player.getInventory().setHeldItemSlot(this.slot); + } + + public void sendMessages(Player player) { + if (this.headerAndFooter) { + player.sendMessage(new String[]{"", "", "", "", "", "", "", "",}); + player.sendMessage(Utils.f(Core.getAnnouncer().getHeader())); + } + if (this.messages != null && this.messages.length > 0) + player.sendMessage(Utils.fc(this.messages)); + if (this.canConfirm) { + TextComponent comp = new TextComponent(Utils.fc("&nClick to continue...")); + comp.setClickEvent(new ClickEvent(Action.RUN_COMMAND, "/next")); + player.spigot().sendMessage(comp); + } else + player.sendMessage(Utils.fc("Continuing in &a&l" + (this.delay / 20) + "&r seconds...")); + + if (this.headerAndFooter) + player.sendMessage(Utils.f(Core.getAnnouncer().getFooter())); + } + + public void sendActionBarMessage(Player player) { + if (this.actionBarMessage != null) + Utils.sendActionBar(player, this.actionBarMessage); + } + + public void sendTitle(Player player) { + if (this.title != null) + Utils.sendTitle(player, this.title); + } + + public void sendSoundEffects(Player player) { + if (this.sounds != null) + for (SoundEffect sound : this.sounds) + sound.play(player); + } + + public void setGameMode(Player player) { + if (this.gameMode != null) + player.setGameMode(this.gameMode); + } + + public Location getLocation() { + return this.location; + } + + public void setLocation(Location location) { + this.location = location; + } + + public String[] getMessages() { + return this.messages; + } + + public void setMessages(String[] messages) { + this.messages = messages; + } + + public void addMessage(String message) { + List msges = Utils.toList(this.messages); + msges.add(message); + this.messages = msges.toArray(new String[msges.size()]); + } + + public void addMessage(String message, int id) { + List msges = Utils.toList(this.messages); + msges.add(id, message); + this.messages = msges.toArray(new String[msges.size()]); + } + + public void removeMessage(int id) { + List msges = Utils.toList(this.messages); + msges.remove(id); + this.messages = msges.toArray(new String[msges.size()]); + } + + public String getActionBarMessage() { + return this.actionBarMessage; + } + + public void setActionBarMessage(String actionBarMessage) { + this.actionBarMessage = actionBarMessage; + } + + public Title getTitle() { + return this.title; + } + + public void setTitle(Title title) { + this.title = title; + } + + public boolean isCanConfirm() { + return this.canConfirm; + } + + public void setCanConfirm(boolean canConfirm) { + this.canConfirm = canConfirm; + } + + public int getDelay() { + return this.delay; + } + + public void setDelay(int delay) { + this.delay = delay; + } + + public List getSounds() { + return this.sounds; + } + + public void setSounds(List sounds) { + this.sounds = sounds; + } + + public SoundEffect getSound(int id) { + return this.sounds.get(id); + } + + public void addSound(SoundEffect e) { + this.sounds.add(e); + } + + public void removeSound(int id) { + this.sounds.remove(this.getSound(id)); + } + + public GameMode getGameMode() { + return this.gameMode; + } + + public void setGameMode(GameMode gameMode) { + this.gameMode = gameMode; + } + + public int getSlot() { + return this.slot; + } + + public void setSlot(int i) { + this.slot = i; + } + + public void setHeaderAndFooter(boolean headerAndFooter) { + this.headerAndFooter = headerAndFooter; + } + + public boolean getHeaderAndFooter() { + return this.headerAndFooter; + } + + public void setMenu(String menu) { + this.menu = menu; + } + + public String getMenu() { + return this.menu; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/tutorials/Tutorial.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/tutorials/Tutorial.java new file mode 100644 index 0000000..88ae3af --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/tutorials/Tutorial.java @@ -0,0 +1,175 @@ +package net.grandtheftmc.core.tutorials; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.events.TutorialEvent; +import net.grandtheftmc.core.events.TutorialEvent.TutorialEventType; +import net.grandtheftmc.core.users.User; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +public class Tutorial { + + private String name; + private List slides; + private boolean invisible; + private boolean playersInvisible; + + public Tutorial(String name, List slides, boolean invisible, boolean playersInvisible) { + this.name = name; + this.slides = slides; + this.invisible = invisible; + this.playersInvisible = playersInvisible; + } + + public Tutorial(String name) { + this.name = name; + this.slides = new ArrayList<>(); + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public List getSlides() { + return this.slides; + } + + public void setSlides(List slides) { + this.slides = slides; + } + + public Slide getSlide(int id) { + if (this.slides.size() <= id) + return null; + return this.slides.get(id); + } + + public int addSlide(int id) { + Slide slide = new Slide(); + int i = id > this.slides.size() ? this.slides.size() : id; + this.slides.add(i, slide); + return i; + } + + public Slide addSlide() { + Slide slide = new Slide(); + this.slides.add(slide); + return slide; + } + + public void removeSlide(Slide slide) { + this.slides.remove(slide); + } + + public boolean isInvisible() { + return this.invisible; + } + + public void setInvisible(boolean invisible) { + this.invisible = invisible; + } + + public boolean isPlayersInvisible() { + return this.playersInvisible; + } + + public void setPlayersInvisible(boolean playersInvisible) { + this.playersInvisible = playersInvisible; + } + + public void setInvisible(Player player) { + if (this.invisible) + for (Player p : Bukkit.getOnlinePlayers()) { + p.hidePlayer(player); + if (this.playersInvisible) + player.hidePlayer(p); + } + } + + public void setVisible(Player player) { + if (this.invisible) + for (Player p : Bukkit.getOnlinePlayers()) { + p.showPlayer(player); + if (this.playersInvisible) + player.showPlayer(p); + } + } + + public void start(Player player, User user) { + TutorialEvent event = new TutorialEvent(player, user, this, TutorialEventType.PRE_START).call(); + if (event.isCancelled()) { + player.sendMessage(Lang.TUTORIALS.f(event.getCancelMessage())); + return; + } + if (user.isInTutorial()) { + player.sendMessage(Lang.TUTORIALS.f("&7You are in a tutorial already!")); + return; + } + event = new TutorialEvent(player, user, this, TutorialEventType.START).call(); + if (event.isCancelled()) { + player.sendMessage(Lang.TUTORIALS.f(event.getCancelMessage())); + return; + } + if (this.invisible || this.playersInvisible) { + for (Player p : Bukkit.getOnlinePlayers()) { + p.hidePlayer(player); + if (this.playersInvisible) player.hidePlayer(p); + } + } + user.setTutorial(this.name); + this.playNextSlide(player, user); + } + + public void playNextSlide(Player player, User user) { + user.setTutorialSlide(user.getTutorialSlide() + 1); + Slide slide = this.getSlide(user.getTutorialSlide()); + if (slide == null) { + new TutorialEvent(player, user, this, TutorialEventType.END).call(); + user.setTutorialSlide(-1); + user.setTutorial(null); + if (this.invisible || this.playersInvisible) { + for (Player p : Bukkit.getOnlinePlayers()) { + p.showPlayer(player); + if (this.playersInvisible) player.showPlayer(p); + } + } + player.sendMessage(Lang.TUTORIALS.f("&7Tutorial &a" + this.name + "&7 has ended!")); + return; + } + TutorialEvent event = new TutorialEvent(player, user, this, TutorialEventType.SLIDE).call(); + if (event.isCancelled()) { + player.sendMessage(Lang.TUTORIALS.f(event.getCancelMessage())); + user.setTutorialSlide(-1); + user.setTutorial(null); + return; + } + UUID uuid = player.getUniqueId(); + slide.play(player); + if (slide.getDelay() <= 0) { + slide.setCanConfirm(true); + return; + } + new BukkitRunnable() { + @Override + public void run() { + Player player = Bukkit.getPlayer(uuid); + if (player == null) return; + User user = Core.getUserManager().getLoadedUser(uuid); + Tutorial tutorial = Core.getTutorialManager().getTutorial(user.getTutorial()); + if (tutorial == null) return; + tutorial.playNextSlide(player, user); + } + }.runTaskLater(Core.getInstance(), slide.getDelay()); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/tutorials/TutorialCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/tutorials/TutorialCommand.java new file mode 100644 index 0000000..d9718c2 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/tutorials/TutorialCommand.java @@ -0,0 +1,987 @@ +package net.grandtheftmc.core.tutorials; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.menus.Menu; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.SoundEffect; +import net.grandtheftmc.core.util.Title; +import org.bukkit.GameMode; +import org.bukkit.Sound; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.List; +import java.util.UUID; + +public class TutorialCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Utils.f("&cYou are not a player!")); + return true; + } + Player player = (Player) s; + UUID uuid = player.getUniqueId(); + User user = Core.getUserManager().getLoadedUser(uuid); + if (args.length == 0) { + if (!s.hasPermission("tutorials.admin")) { + if (Core.getTutorialManager().getTutorials().isEmpty()) { + s.sendMessage(Lang.TUTORIALS.f("&7There are no tutorials!")); + return true; + } + Tutorial t = Core.getTutorialManager().getTutorials().get(0); + if (t == null) { + s.sendMessage(Lang.TUTORIALS.f("&7There are no tutorials!")); + return true; + } + t.start(player, user); + return true; + } + s.sendMessage(Lang.TUTORIALS.f("&2&lHelp Command")); + s.sendMessage(Utils.f("&2/tutorial&7 start &a")); + s.sendMessage(Utils.f("&2/tutorial&7 nextslide")); + + s.sendMessage(Utils.f("&2/tutorial&7 info/add/remove/edit &a")); + s.sendMessage(Utils.f("&2/tutorial&7 list/stop")); + s.sendMessage(Utils.f("&2/tutorial&7 set name &a")); + s.sendMessage(Utils.f("&2/tutorial&7 set invisible &a")); + s.sendMessage(Utils.f("&2/tutorial&7 set playersInvisible &a")); + s.sendMessage(Utils.f("&2/tutorial&7 slide info &a")); + s.sendMessage(Utils.f("&2/tutorial&7 slide play &a")); + s.sendMessage(Utils.f("&2/tutorial&7 slide add &a[id]")); + s.sendMessage(Utils.f("&2/tutorial&7 slide remove &a")); + s.sendMessage(Utils.f("&2/tutorial&7 slide edit &a")); + s.sendMessage(Utils.f("&2/tutorial&7 slide canConfirm &a")); + s.sendMessage(Utils.f("&2/tutorial&7 slide delay &a")); + s.sendMessage(Utils.f("&2/tutorial&7 slide location")); + s.sendMessage(Utils.f("&2/tutorial&7 slide actionBarMessage &a")); + s.sendMessage(Utils.f("&2/tutorial&7 slide title &a")); + s.sendMessage(Utils.f("&2/tutorial&7 slide subtitle &a<subTitle>")); + s.sendMessage(Utils.f("&2/tutorial&7 slide timings &a<fadeIn> <stay> <fadeOut> ")); + s.sendMessage(Utils.f("&2/tutorial&7 slide gamemode &a<gameM-mode> ")); + s.sendMessage(Utils.f("&2/tutorial&7 slide message add &a<message> &a[id]")); + s.sendMessage(Utils.f("&2/tutorial&7 slide message remove &a<id>")); + s.sendMessage(Utils.f("&2/tutorial&7 slide headerAndFooter &a<boolean>")); + s.sendMessage(Utils.f("&2/tutorial&7 slide sound add &a<sound> [volume] [pitch] [delay]")); + s.sendMessage(Utils.f("&2/tutorial&7 slide sound remove &a<id>")); + s.sendMessage(Utils.f("&2/tutorial&7 slide slot &a<slot>")); + s.sendMessage(Utils.f("&2/tutorial&7 slide menu &a<menu>")); + s.sendMessage(Utils.f("&2/tutorial&7 load")); + s.sendMessage(Utils.f("&2/tutorial&7 save")); + return true; + } + switch (args[0].toLowerCase()) { + case "start": + if (args.length != 2) { + s.sendMessage(Utils.f("&c/tutorial start <name>")); + return true; + } + Tutorial tutorial = Core.getTutorialManager().getTutorial(args[1]); + if (tutorial == null) { + s.sendMessage(Utils.f(Lang.TUTORIALS + "&7That tutorial does not exist!")); + return true; + } + tutorial.start(player, Core.getUserManager().getLoadedUser(uuid)); + return true; + case "nextslide": + Tutorial tut = Core.getTutorialManager().getTutorial(user.getTutorial()); + if (tut == null) { + s.sendMessage(Lang.TUTORIALS.f("&7You are not in a tutorial!")); + return true; + } + if (tut.getSlide(user.getTutorialSlide()) != null && !tut.getSlide(user.getTutorialSlide()).isCanConfirm()) { + s.sendMessage(Lang.TUTORIALS.f("&7You can not skip this slide!")); + return true; + } + tut.playNextSlide(player, user); + return true; + } + if (!s.hasPermission("tutorials.admin")) + return true; + switch (args[0].toLowerCase()) { + case "load": + Core.getSettings().setTutorialsConfig(Utils.loadConfig("tutorials")); + Core.getTutorialManager().load(); + s.sendMessage(Lang.TUTORIALS.f("&7The tutorials config was reloaded!")); + return true; + case "save": + Core.getTutorialManager().save(false); + s.sendMessage(Lang.TUTORIALS.f("&7The tutorials config was saved!")); + return true; + case "info": { + if (args.length != 2) { + s.sendMessage(Utils.f("&c/tutorial info <name>")); + return true; + } + Tutorial tutorial = Core.getTutorialManager().getTutorial(args[1]); + if (tutorial == null) { + s.sendMessage(Utils.f(Lang.TUTORIALS + "&7That tutorial does not exist!")); + return true; + } + s.sendMessage(Lang.TUTORIALS.f("&2&lTutorial Info &a" + tutorial.getName())); + s.sendMessage(Utils.f("&2Invisible: &a" + tutorial.isInvisible())); + s.sendMessage(Utils.f("&2Players Invisible: &a" + tutorial.isPlayersInvisible())); + s.sendMessage(Utils.f("&2Slides: &a" + tutorial.getSlides().size())); + return true; + } + case "list": + int page = 1; + if (args.length > 1) + try { + page = Integer.parseInt(args[1]); + } catch (NumberFormatException ignored) { + } + int start = (page << 3) - 8; + int end = (page << 3) - 1; + List<Tutorial> tutorials = Core.getTutorialManager().getTutorials(start, end); + s.sendMessage(Lang.TUTORIALS.f("&2&lPage " + page + " &2&lTotal Tutorials: &a" + Core.getTutorialManager().getTutorials().size())); + for (Tutorial tut : tutorials) + s.sendMessage(Utils.f("&2&lTutorial: &a" + tut.getName() + " &2&lSlides: &a" + tut.getSlides().size())); + return true; + case "add": { + if (args.length != 2) { + s.sendMessage(Utils.f("&c/tutorial add <name>")); + return true; + } + if (Core.getTutorialManager().getTutorial(args[1]) != null) { + s.sendMessage(Lang.TUTORIALS.f("&7A tutorial with that name already exists!")); + return true; + } + Tutorial tut = new Tutorial(args[1]); + Core.getTutorialManager().addTutorial(tut); + user.setEditingTutorial(true); + user.setTutorial(tut.getName()); + user.setTutorialSlide(0); + s.sendMessage(Lang.TUTORIALS.f("&7You have added a tutorial with the name &a" + tut.getName() + "&7! You are now editing this tutorial.")); + return true; + } + case "remove": { + if (args.length != 2) { + s.sendMessage(Utils.f("&c/tutorial remove <name>")); + return true; + } + Tutorial tutorial = Core.getTutorialManager().getTutorial(args[1]); + if (tutorial == null) { + s.sendMessage(Utils.f(Lang.TUTORIALS + "&7That tutorial does not exist!")); + return true; + } + Core.getTutorialManager().removeTutorial(tutorial); + s.sendMessage(Lang.TUTORIALS.f("&7You have removed a tutorial with the name &a" + tutorial.getName() + "&7!")); + return true; + } + case "edit": { + if (args.length != 2) { + s.sendMessage(Utils.f("&c/tutorial info <name>")); + return true; + } + Tutorial tutorial = Core.getTutorialManager().getTutorial(args[1]); + if (tutorial == null) { + s.sendMessage(Utils.f(Lang.TUTORIALS + "&7That tutorial does not exist!")); + return true; + } + user.setEditingTutorial(true); + user.setTutorial(tutorial.getName()); + user.setTutorialSlide(0); + s.sendMessage(Lang.TUTORIALS.f("&7You are now editing tutorial &a" + tutorial.getName() + "&7!")); + return true; + } + case "stop": + user.setEditingTutorial(false); + user.setTutorial(null); + user.setTutorialSlide(-1); + s.sendMessage(Lang.TUTORIALS.f("&7You are no longer editing a tutorial!")); + return true; + case "set": + if (args.length == 1) { + s.sendMessage(Utils.f("&c/tutorial set name <name>")); + s.sendMessage(Utils.f("&c/tutorial set invisible <boolean>")); + s.sendMessage(Utils.f("&c/tutorial set playersInvisible <boolean>")); + return true; + } + String s1 = args[1].toLowerCase(); + if ("name:".equals(s1)) { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/tutorial set name <name>")); + return true; + } + Tutorial tut = Core.getTutorialManager().getTutorial(user.getTutorial()); + if (tut == null || !user.isEditingTutorial()) { + s.sendMessage(Utils.f(Lang.TUTORIALS + "&7You are not editing any tutorial!")); + return true; + } + tut.setName(args[2]); + s.sendMessage(Lang.TUTORIALS.f("&7You set the name of your tutorial to &a" + tut.getName() + "&7!")); + return true; + } else if ("invisible".equals(s1)) { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/tutorial set invisible <boolean>")); + return true; + } + Tutorial tut = Core.getTutorialManager().getTutorial(user.getTutorial()); + if (tut == null || !user.isEditingTutorial()) { + s.sendMessage(Utils.f(Lang.TUTORIALS + "&7You are not editing any tutorial!")); + return true; + } + boolean invisible; + if ("true".equalsIgnoreCase(args[2])) + invisible = true; + else if ("false".equalsIgnoreCase(args[2])) + invisible = false; + else { + player.sendMessage(Lang.TUTORIALS.f("&7Please specify true/false.")); + return true; + } + tut.setInvisible(invisible); + s.sendMessage(Lang.TUTORIALS.f("&7You will now be &a" + (invisible ? "invisible" : "visible") + "&7 during tutorial &a" + tut.getName() + "&7!")); + return true; + } else if ("playersinvisible".equals(s1)) { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/tutorial set playersInvisible <boolean>")); + return true; + } + Tutorial tut = Core.getTutorialManager().getTutorial(user.getTutorial()); + if (tut == null || !user.isEditingTutorial()) { + s.sendMessage(Utils.f(Lang.TUTORIALS + "&7You are not editing any tutorial!")); + return true; + } + boolean invisible; + if ("true".equalsIgnoreCase(args[2])) + invisible = true; + else if ("false".equalsIgnoreCase(args[2])) + invisible = false; + else { + player.sendMessage(Lang.TUTORIALS.f("&7Please specify true/false.")); + return true; + } + tut.setPlayersInvisible(invisible); + s.sendMessage(Lang.TUTORIALS.f("&7You will&a" + (invisible ? " not" : "") + "&7be able to see players during tutorial &a" + tut.getName() + "&7!")); + return true; + } + case "slide": + if (args.length == 1) { + s.sendMessage(Utils.f("&2/tutorial&7 slide info &a<id>")); + s.sendMessage(Utils.f("&2/tutorial&7 slide play &a<id>")); + s.sendMessage(Utils.f("&2/tutorial&7 slide add &a[id]")); + s.sendMessage(Utils.f("&2/tutorial&7 slide remove &a<id>")); + s.sendMessage(Utils.f("&2/tutorial&7 slide edit &a<id>")); + s.sendMessage(Utils.f("&2/tutorial&7 slide canConfirm &a<boolean>")); + s.sendMessage(Utils.f("&2/tutorial&7 slide delay &a<ticks>")); + s.sendMessage(Utils.f("&2/tutorial&7 slide location")); + s.sendMessage(Utils.f("&2/tutorial&7 slide actionBarMessage &a<msg>")); + s.sendMessage(Utils.f("&2/tutorial&7 slide title &a<title>")); + s.sendMessage(Utils.f("&2/tutorial&7 slide subtitle &a<subTitle>")); + s.sendMessage(Utils.f("&2/tutorial&7 slide timings &a<fadeIn> <stay> <fadeOut> ")); + s.sendMessage(Utils.f("&2/tutorial&7 slide gamemode &a<gameM-mode> ")); + s.sendMessage(Utils.f("&2/tutorial&7 slide message add &a<message> &a[id]")); + s.sendMessage(Utils.f("&2/tutorial&7 slide message remove &a<id>")); + s.sendMessage(Utils.f("&2/tutorial&7 slide headerAndFooter &a<boolean>")); + s.sendMessage(Utils.f("&2/tutorial&7 slide sound add &a<sound> [volume] [pitch] [delay]")); + s.sendMessage(Utils.f("&2/tutorial&7 slide sound remove &a<id>")); + s.sendMessage(Utils.f("&2/tutorial&7 slide slot &a<slot>")); + s.sendMessage(Utils.f("&2/tutorial&7 slide menu &a<menu>")); + return true; + } + String s2 = args[1].toLowerCase(); + if ("info".equals(s2)) { + if (args.length != 4) { + s.sendMessage(Utils.f("&c/tutorial slide info <tutorial> <id>")); + return true; + } + Tutorial tutorial = Core.getTutorialManager().getTutorial(args[2]); + if (tutorial == null) { + s.sendMessage(Utils.f(Lang.TUTORIALS + "&7That tutorial does not exist!")); + return true; + } + int id; + try { + id = Integer.parseInt(args[3]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f(Lang.TUTORIALS.f("&7The ID must be a number!"))); + return true; + } + Slide slide = tutorial.getSlide(id); + if (slide == null) { + s.sendMessage(Lang.TUTORIALS.f("&7That slide does not exist!")); + return true; + } + s.sendMessage(Lang.TUTORIALS.f("&2&lTutorial &a" + tutorial.getName() + "&2&l Slide &a" + id)); + s.sendMessage(Utils.f("&2Can Confirm: &a" + slide.isCanConfirm())); + s.sendMessage(Utils.f("&2Delay: &a" + slide.getDelay())); + if (slide.getLocation() != null) + s.sendMessage(Utils.f("&2Location: &a" + Utils.teleportLocationToString(slide.getLocation()))); + if (slide.getGameMode() != null) + s.sendMessage(Utils.f("&2GameMode: &a" + slide.getGameMode())); + if (slide.getActionBarMessage() != null) + s.sendMessage(Utils.f("&2Action Bar Message: &a" + slide.getActionBarMessage())); + Title title = slide.getTitle(); + if (title != null) + s.sendMessage( + Utils.f("&2Title: &a" + title.getTitle() + ',' + title.getSubtitle() + ',' + title.getFadeIn() + ',' + title.getStay() + ',' + title.getFadeOut())); + if (slide.getSounds() != null) + for (SoundEffect sound : slide.getSounds()) { + s.sendMessage(Utils.f("&2Sound: &a" + sound.getSound() + " &2Volume: &a" + sound.getVolume() + " &2 Pitch: &a" + sound.getPitch() + " &2 Delay: &a" + + sound.getDelay())); + } + slide.sendMessages(player); + return true; + } else if ("play".equals(s2)) { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/tutorial slide play <id>")); + return true; + } + Tutorial tut = Core.getTutorialManager().getTutorial(user.getTutorial()); + if (tut == null || !user.isEditingTutorial()) { + s.sendMessage(Utils.f(Lang.TUTORIALS + "&7You are not editing any tutorial!")); + return true; + } + int id; + try { + id = Integer.parseInt(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f(Lang.TUTORIALS.f("&7The ID must be a number!"))); + return true; + } + Slide slide = tut.getSlide(id); + if (slide == null) { + s.sendMessage(Lang.TUTORIALS.f("&7That slide does not exist!")); + return true; + } + slide.play(player); + return true; + } else if ("add".equals(s2)) { + if (args.length > 3) { + s.sendMessage(Utils.f("&c/tutorial slide add")); + return true; + } + Tutorial tut = Core.getTutorialManager().getTutorial(user.getTutorial()); + if (tut == null || !user.isEditingTutorial()) { + s.sendMessage(Utils.f(Lang.TUTORIALS + "&7You are not editing any tutorial!")); + return true; + } + if (args.length == 3) { + int id; + try { + id = Integer.parseInt(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Lang.TUTORIALS.f("&7The ID must be a number!")); + return true; + } + id = tut.addSlide(id); + user.setTutorialSlide(id); + s.sendMessage(Lang.TUTORIALS.f("&7You have added a slide with id &a" + id + "&7! You are now editing this slide.")); + return true; + } + tut.addSlide(); + int id = tut.getSlides().size() - 1; + user.setTutorialSlide(id); + s.sendMessage(Lang.TUTORIALS.f("&7You have added a slide with id &a" + id + "&7! You are now editing this slide.")); + return true; + } else if ("remove".equals(s2)) { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/tutorial slide remove <id>")); + return true; + } + Tutorial tut = Core.getTutorialManager().getTutorial(user.getTutorial()); + if (tut == null || !user.isEditingTutorial()) { + s.sendMessage(Utils.f(Lang.TUTORIALS + "&7You are not editing any tutorial!")); + return true; + } + int id; + try { + id = Integer.parseInt(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f(Lang.TUTORIALS.f("&7The ID must be a number!"))); + return true; + } + Slide slide = tut.getSlide(id); + if (slide == null) { + s.sendMessage(Lang.TUTORIALS.f("&7That slide does not exist!")); + return true; + } + tut.removeSlide(slide); + s.sendMessage(Lang.TUTORIALS.f("&7You have removed a slide with id &a" + id + "&7!")); + return true; + } else if ("edit".equals(s2)) { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/tutorial slide remove <id>")); + return true; + } + Tutorial tut = Core.getTutorialManager().getTutorial(user.getTutorial()); + if (tut == null || !user.isEditingTutorial()) { + s.sendMessage(Utils.f(Lang.TUTORIALS + "&7You are not editing any tutorial!")); + return true; + } + int id; + try { + id = Integer.parseInt(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f(Lang.TUTORIALS.f("&7The ID must be a number!"))); + return true; + } + Slide slide = tut.getSlide(id); + if (slide == null) { + s.sendMessage(Lang.TUTORIALS.f("&7That slide does not exist!")); + return true; + } + user.setTutorialSlide(id); + s.sendMessage(Lang.TUTORIALS.f("&7You are now editing a slide with id &a" + id + "&7!")); + return true; + } else if ("canconfirm".equals(s2)) { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/tutorial slide canConfirm <boolean>")); + return true; + } + Tutorial tut = Core.getTutorialManager().getTutorial(user.getTutorial()); + if (tut == null || !user.isEditingTutorial()) { + s.sendMessage(Utils.f(Lang.TUTORIALS + "&7You are not editing any tutorial!")); + return true; + } + Slide slide = tut.getSlide(user.getTutorialSlide()); + if (slide == null) { + s.sendMessage(Lang.TUTORIALS.f("&7You are not editing any slide!")); + return true; + } + boolean b; + if ("true".equalsIgnoreCase(args[2])) + b = true; + else if ("false".equalsIgnoreCase(args[2])) + b = false; + else { + player.sendMessage(Lang.TUTORIALS.f("&7Please specify true/false.")); + return true; + } + slide.setCanConfirm(b); + s.sendMessage(Lang.TUTORIALS.f("&7Players can &a" + (b ? "now" : "no longer") + "&7 skip slide &a" + user.getTutorialSlide() + "&7!")); + return true; + } else if ("delay".equals(s2)) { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/tutorial slide delay <ticks>")); + return true; + } + Tutorial tut = Core.getTutorialManager().getTutorial(user.getTutorial()); + if (tut == null || !user.isEditingTutorial()) { + s.sendMessage(Utils.f(Lang.TUTORIALS + "&7You are not editing any tutorial!")); + return true; + } + Slide slide = tut.getSlide(user.getTutorialSlide()); + if (slide == null) { + s.sendMessage(Lang.TUTORIALS.f("&7You are not editing any slide!")); + return true; + } + int delay; + try { + delay = Integer.parseInt(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f(Lang.TUTORIALS.f("&7The delay must be a number!"))); + return true; + } + if (delay < 0) { + s.sendMessage(Lang.TUTORIALS.f("&7The delay must be at least 0!")); + return true; + } + slide.setDelay(delay); + s.sendMessage(Lang.TUTORIALS.f("&7You set the delay to &a" + delay + "&7 for slide &a" + user.getTutorialSlide() + "&7!")); + return true; + } else if ("location".equals(s2) || "loc".equals(s2)) { + if (args.length != 2) { + s.sendMessage(Utils.f("&c/tutorial slide loc")); + return true; + } + Tutorial tut = Core.getTutorialManager().getTutorial(user.getTutorial()); + if (tut == null || !user.isEditingTutorial()) { + s.sendMessage(Utils.f(Lang.TUTORIALS + "&7You are not editing any tutorial!")); + return true; + } + Slide slide = tut.getSlide(user.getTutorialSlide()); + if (slide == null) { + s.sendMessage(Lang.TUTORIALS.f("&7You are not editing any slide!")); + return true; + } + slide.setLocation(player.getLocation()); + s.sendMessage(Lang.TUTORIALS.f("&7You set the location for slide &a" + user.getTutorialSlide() + "&7!")); + return true; + } else if ("actionbarmessage".equals(s2)) { + if (args.length < 3) { + s.sendMessage(Utils.f("&c/tutorial slide actionbarmessage <msg/none>")); + return true; + } + Tutorial tut = Core.getTutorialManager().getTutorial(user.getTutorial()); + if (tut == null || !user.isEditingTutorial()) { + s.sendMessage(Utils.f(Lang.TUTORIALS + "&7You are not editing any tutorial!")); + return true; + } + Slide slide = tut.getSlide(user.getTutorialSlide()); + if (slide == null) { + s.sendMessage(Lang.TUTORIALS.f("&7You are not editing any slide!")); + return true; + } + if ("none".equalsIgnoreCase(args[2])) { + s.sendMessage(Lang.TUTORIALS.f("&7You unset the ActionBar message for slide &a" + user.getTutorialSlide() + "&7!")); + slide.setActionBarMessage(null); + return true; + } + String message = args[2]; + for (int i = 3; i < args.length; i++) + message = message + ' ' + args[i]; + slide.setActionBarMessage(message); + slide.sendActionBarMessage(player); + s.sendMessage(Lang.TUTORIALS.f("&7You set the ActionBar message for slide &a" + user.getTutorialSlide() + "&7!")); + return true; + } else if ("title".equals(s2)) { + if (args.length < 3) { + s.sendMessage(Utils.f("&c/tutorial slide set title <title/none>")); + return true; + } + Tutorial tut = Core.getTutorialManager().getTutorial(user.getTutorial()); + if (tut == null || !user.isEditingTutorial()) { + s.sendMessage(Utils.f(Lang.TUTORIALS + "&7You are not editing any tutorial!")); + return true; + } + Slide slide = tut.getSlide(user.getTutorialSlide()); + if (slide == null) { + s.sendMessage(Lang.TUTORIALS.f("&7You are not editing any slide!")); + return true; + } + if ("none".equalsIgnoreCase(args[2])) { + slide.setTitle(null); + s.sendMessage(Lang.TUTORIALS.f("&7You unset the Title for slide &a" + user.getTutorialSlide() + "&7!")); + return true; + } + String message = args[2]; + for (int i = 3; i < args.length; i++) + message = message + ' ' + args[i]; + Title title = new Title(message, null, 20, 20, 20); + slide.setTitle(title); + s.sendMessage(Lang.TUTORIALS.f("&7You set the title for slide &a" + user.getTutorialSlide() + "&7!")); + title.play(player); + return true; + } else if ("subtitle".equals(s2)) { + if (args.length < 3) { + s.sendMessage(Utils.f("&c/tutorial slide subtitle <subtitle/none>")); + return true; + } + Tutorial tut = Core.getTutorialManager().getTutorial(user.getTutorial()); + if (tut == null || !user.isEditingTutorial()) { + s.sendMessage(Utils.f(Lang.TUTORIALS + "&7You are not editing any tutorial!")); + return true; + } + Slide slide = tut.getSlide(user.getTutorialSlide()); + if (slide == null) { + s.sendMessage(Lang.TUTORIALS.f("&7You are not editing any slide!")); + return true; + } + Title title = slide.getTitle(); + if (title == null) { + s.sendMessage(Lang.TUTORIALS.f("&7Please set the Title first!")); + return true; + } + if ("none".equalsIgnoreCase(args[2])) { + title.setSubtitle(null); + s.sendMessage(Lang.TUTORIALS.f("&7You unset the subtitle for slide &a" + user.getTutorialSlide() + "&7!")); + return true; + } + String message = args[2]; + for (int i = 3; i < args.length; i++) + message += ' ' + args[i]; + title.setSubtitle(message); + s.sendMessage(Lang.TUTORIALS.f("&7You set the subtitle for slide &a" + user.getTutorialSlide() + "&7!")); + title.play(player); + return true; + } else if ("gamemode".equals(s2)) { + if (args.length != 4) { + s.sendMessage(Utils.f("&c/tutorial slide gameMode <gameMode/none>")); + return true; + } + Tutorial tut = Core.getTutorialManager().getTutorial(user.getTutorial()); + if (tut == null || !user.isEditingTutorial()) { + s.sendMessage(Utils.f(Lang.TUTORIALS + "&7You are not editing any tutorial!")); + return true; + } + Slide slide = tut.getSlide(user.getTutorialSlide()); + if (slide == null) { + s.sendMessage(Lang.TUTORIALS.f("&7You are not editing any slide!")); + return true; + } + GameMode gameMode = null; + String s3 = args[2].toLowerCase(); + switch (s3) { + case "0": + case "survival": + case "s": + gameMode = GameMode.SURVIVAL; + + break; + case "1": + case "creative": + case "c": + gameMode = GameMode.CREATIVE; + + break; + case "2": + case "adventure": + case "a": + gameMode = GameMode.ADVENTURE; + + break; + case "3": + case "spectator": + gameMode = GameMode.SPECTATOR; + + break; + default: + s.sendMessage(Lang.TUTORIALS.f("&7You unset the gamemode for slide &a" + user.getTutorialSlide() + "&7!")); + slide.setGameMode(gameMode); + return true; + } + slide.setGameMode(gameMode); + s.sendMessage(Lang.TUTORIALS.f("&7You set the gamemode to &a" + gameMode + "&7 for slide &a" + user.getTutorialSlide() + "&7!")); + return true; + } else if ("timings".equals(s2)) { + if (args.length != 5) { + s.sendMessage(Utils.f("&c/tutorial slide timings <fadeIn> <stay> <fadeOut>")); + return true; + } + Tutorial tut = Core.getTutorialManager().getTutorial(user.getTutorial()); + if (tut == null || !user.isEditingTutorial()) { + s.sendMessage(Utils.f(Lang.TUTORIALS + "&7You are not editing any tutorial!")); + return true; + } + Slide slide = tut.getSlide(user.getTutorialSlide()); + if (slide == null) { + s.sendMessage(Lang.TUTORIALS.f("&7You are not editing any slide!")); + return true; + } + Title title = slide.getTitle(); + if (title == null) { + s.sendMessage(Lang.TUTORIALS.f("&7Please set the Title first!")); + return true; + } + try { + title.setFadeIn(Integer.parseInt(args[2])); + title.setStay(Integer.parseInt(args[3])); + title.setFadeOut(Integer.parseInt(args[4])); + } catch (NumberFormatException e) { + s.sendMessage(Lang.TUTORIALS.f("&7The values must be numbers!")); + return true; + } + s.sendMessage(Lang.TUTORIALS.f("&7You set the title timings for slide &a" + user.getTutorialSlide() + "&7!")); + title.play(player); + return true; + } else if ("headerandfooter".equals(s2)) { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/tutorial slide headerandfooter <boolean>")); + return true; + } + Tutorial tut = Core.getTutorialManager().getTutorial(user.getTutorial()); + if (tut == null || !user.isEditingTutorial()) { + s.sendMessage(Utils.f(Lang.TUTORIALS + "&7You are not editing any tutorial!")); + return true; + } + Slide slide = tut.getSlide(user.getTutorialSlide()); + if (slide == null) { + s.sendMessage(Lang.TUTORIALS.f("&7You are not editing any slide!")); + return true; + } + boolean b; + if ("true".equalsIgnoreCase(args[2])) + b = true; + else if ("false".equalsIgnoreCase(args[2])) + b = false; + else { + player.sendMessage(Lang.TUTORIALS.f("&7Please specify true/false.")); + return true; + } + slide.setHeaderAndFooter(b); + s.sendMessage(Lang.TUTORIALS.f("You set header and footer to &a" + b + "&7 for slide &a" + user.getTutorialSlide() + "&7!")); + return true; + } else if ("message".equals(s2)) { + if (args.length == 2) { + s.sendMessage(Utils.f("&2/tutorial&7 slide message add &a<message>")); + s.sendMessage(Utils.f("&2/tutorial&7 slide message remove &a<id>")); + return true; + } + switch (args[2].toLowerCase()) { + case "add": { + if (args.length < 4) { + s.sendMessage(Utils.f("&c/tutorial slide message add <message>")); + return true; + } + Tutorial tut = Core.getTutorialManager().getTutorial(user.getTutorial()); + if (tut == null || !user.isEditingTutorial()) { + s.sendMessage(Utils.f(Lang.TUTORIALS + "&7You are not editing any tutorial!")); + return true; + } + Slide slide = tut.getSlide(user.getTutorialSlide()); + if (slide == null) { + s.sendMessage(Lang.TUTORIALS.f("&7You are not editing any slide!")); + return true; + } + String msg = args[3]; + for (int i = 4; i < args.length; i++) + msg = msg + ' ' + args[i]; + slide.addMessage(msg); + s.sendMessage(Lang.TUTORIALS.f("&7You added a message to slide &a" + user.getTutorialSlide() + "&7!")); + slide.sendMessages(player); + return true; + } + case "remove": + if (args.length != 4) { + s.sendMessage(Utils.f("&c/tutorial slide message remove <id>")); + return true; + } + Tutorial tut = Core.getTutorialManager().getTutorial(user.getTutorial()); + if (tut == null || !user.isEditingTutorial()) { + s.sendMessage(Utils.f(Lang.TUTORIALS + "&7You are not editing any tutorial!")); + return true; + } + Slide slide = tut.getSlide(user.getTutorialSlide()); + if (slide == null) { + s.sendMessage(Lang.TUTORIALS.f("&7You are not editing any slide!")); + return true; + } + int id; + try { + id = Integer.parseInt(args[3]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f(Lang.TUTORIALS.f("&7The ID must be a number!"))); + return true; + } + if (slide.getMessages().length <= id) { + s.sendMessage(Lang.TUTORIALS.f("&7There are only &a" + slide.getMessages().length + "&7 messages!")); + return true; + } + slide.removeMessage(id); + s.sendMessage(Lang.TUTORIALS.f("&7You removed a message from slide &a" + user.getTutorialSlide() + "&7!")); + slide.sendMessages(player); + return true; + } + + if (args.length == 2) { + s.sendMessage(Utils.f("&2/tutorial&7 slide sound add &a<sound> [volume] [pitch] [delay]")); + s.sendMessage(Utils.f("&2/tutorial&7 slide sound remove &a<id>")); + return true; + } + switch (args[2].toLowerCase()) { + case "add": { + if (args.length < 4 || args.length > 7) { + s.sendMessage(Utils.f("&c/tutorial slide sound add <sound> [volume] [pitch] [delay]")); + return true; + } + Tutorial tut = Core.getTutorialManager().getTutorial(user.getTutorial()); + if (tut == null || !user.isEditingTutorial()) { + s.sendMessage(Utils.f(Lang.TUTORIALS + "&7You are not editing any tutorial!")); + return true; + } + Slide slide = tut.getSlide(user.getTutorialSlide()); + if (slide == null) { + s.sendMessage(Lang.TUTORIALS.f("&7You are not editing any slide!")); + return true; + } + Sound sound = null; + for (Sound so : Sound.values()) + if (so.toString().equalsIgnoreCase(args[3])) { + sound = so; + break; + } + if (sound == null) { + s.sendMessage(Lang.TUTORIALS.f("&7That sound does not exist!")); + return true; + } + float volume = 1; + float pitch = 1; + int delay = 0; + if (args.length > 4) + try { + volume = Float.parseFloat(args[4]); + if (args.length > 5) + pitch = Float.parseFloat(args[5]); + if (args.length > 6) + delay = Integer.parseInt(args[6]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f(Lang.TUTORIALS.f("&7The volume, pitch and delay must be numbers!"))); + return true; + } + SoundEffect e = new SoundEffect(sound, volume, pitch, delay); + slide.addSound(e); + s.sendMessage(Lang.TUTORIALS.f("&7You added a sound to slide &a" + user.getTutorialSlide() + "&7!")); + e.play(player); + return true; + } + case "remove": + if (args.length != 4) { + s.sendMessage(Utils.f("&c/tutorial slide sound remove <id>")); + return true; + } + Tutorial tut = Core.getTutorialManager().getTutorial(user.getTutorial()); + if (tut == null || !user.isEditingTutorial()) { + s.sendMessage(Utils.f(Lang.TUTORIALS + "&7You are not editing any tutorial!")); + return true; + } + Slide slide = tut.getSlide(user.getTutorialSlide()); + if (slide == null) { + s.sendMessage(Lang.TUTORIALS.f("&7You are not editing any slide!")); + return true; + } + int id = -1; + try { + Integer.parseInt(args[3]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f(Lang.TUTORIALS.f("&7The ID must be a number!"))); + return true; + } + if (slide.getSounds().size() <= id) { + s.sendMessage(Lang.TUTORIALS.f("&7There are only &a" + slide.getSounds().size() + "&7 sounds!")); + return true; + } + slide.removeSound(id); + s.sendMessage(Lang.TUTORIALS.f("&7You removed a sound from slide &a" + user.getTutorialSlide() + "&7!")); + slide.sendSoundEffects(player); + return true; + } + } else if ("sound".equals(s2)) { + if (args.length == 2) { + s.sendMessage(Utils.f("&2/tutorial&7 slide sound add &a<sound> [volume] [pitch] [delay]")); + s.sendMessage(Utils.f("&2/tutorial&7 slide sound remove &a<id>")); + return true; + } + String s3 = args[2].toLowerCase(); + if ("add".equals(s3)) { + if (args.length < 4 || args.length > 7) { + s.sendMessage(Utils.f("&c/tutorial slide sound add <sound> [volume] [pitch] [delay]")); + return true; + } + Tutorial tut = Core.getTutorialManager().getTutorial(user.getTutorial()); + if (tut == null || !user.isEditingTutorial()) { + s.sendMessage(Utils.f(Lang.TUTORIALS + "&7You are not editing any tutorial!")); + return true; + } + Slide slide = tut.getSlide(user.getTutorialSlide()); + if (slide == null) { + s.sendMessage(Lang.TUTORIALS.f("&7You are not editing any slide!")); + return true; + } + Sound sound = null; + for (Sound so : Sound.values()) + if (so.toString().equalsIgnoreCase(args[3])) { + sound = so; + break; + } + if (sound == null) { + s.sendMessage(Lang.TUTORIALS.f("&7That sound does not exist!")); + return true; + } + float volume = 1; + float pitch = 1; + int delay = 0; + if (args.length > 4) + try { + volume = Float.parseFloat(args[4]); + if (args.length > 5) + pitch = Float.parseFloat(args[5]); + if (args.length > 6) + delay = Integer.parseInt(args[6]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f(Lang.TUTORIALS.f("&7The volume, pitch and delay must be numbers!"))); + return true; + } + SoundEffect e = new SoundEffect(sound, volume, pitch, delay); + slide.addSound(e); + s.sendMessage(Lang.TUTORIALS.f("&7You added a sound to slide &a" + user.getTutorialSlide() + "&7!")); + e.play(player); + return true; + } else if ("remove".equals(s3)) { + if (args.length != 4) { + s.sendMessage(Utils.f("&c/tutorial slide sound remove <id>")); + return true; + } + Tutorial tut = Core.getTutorialManager().getTutorial(user.getTutorial()); + if (tut == null || !user.isEditingTutorial()) { + s.sendMessage(Utils.f(Lang.TUTORIALS + "&7You are not editing any tutorial!")); + return true; + } + Slide slide = tut.getSlide(user.getTutorialSlide()); + if (slide == null) { + s.sendMessage(Lang.TUTORIALS.f("&7You are not editing any slide!")); + return true; + } + int id = -1; + try { + Integer.parseInt(args[3]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f(Lang.TUTORIALS.f("&7The ID must be a number!"))); + return true; + } + if (slide.getSounds().size() <= id) { + s.sendMessage(Lang.TUTORIALS.f("&7There are only &a" + slide.getSounds().size() + "&7 sounds!")); + return true; + } + slide.removeSound(id); + s.sendMessage(Lang.TUTORIALS.f("&7You removed a sound from slide &a" + user.getTutorialSlide() + "&7!")); + slide.sendSoundEffects(player); + return true; + } + } else if ("slot".equals(s2)) { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/tutorial slide slot <slot>")); + return true; + } + Tutorial tut = Core.getTutorialManager().getTutorial(user.getTutorial()); + if (tut == null || !user.isEditingTutorial()) { + s.sendMessage(Utils.f(Lang.TUTORIALS + "&7You are not editing any tutorial!")); + return true; + } + Slide slide = tut.getSlide(user.getTutorialSlide()); + if (slide == null) { + s.sendMessage(Lang.TUTORIALS.f("&7You are not editing any slide!")); + return true; + } + int slot; + try { + slot = Integer.parseInt(args[2 + ]); + } catch (NumberFormatException e) { + s.sendMessage(Lang.TUTORIALS.f("&7The slot must be a number!")); + return true; + } + if (slot < 0 || slot > 8) { + s.sendMessage(Lang.TUTORIALS.f( + "&7The slot must be between 0 and 8!")); + return true; + } + slide.setSlot(slot); + s.sendMessage(Lang.TUTORIALS.f("&7You set the slot for slide &a" + user.getTutorialSlide() + "&7 to slot &a" + slot + "&7!")); + return true; + } else if ("menu".equals(s2)) { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/tutorial slide menu <menu>")); + return true; + } + Tutorial tut = Core.getTutorialManager().getTutorial(user.getTutorial()); + if (tut == null || !user.isEditingTutorial()) { + s.sendMessage(Utils.f(Lang.TUTORIALS + "&7You are not editing any tutorial!")); + return true; + } + Slide slide = tut.getSlide(user.getTutorialSlide()); + if (slide == null) { + s.sendMessage(Lang.TUTORIALS.f("&7You are not editing any slide!")); + return true; + } + Menu menu = MenuManager.getMenu(args[2]); + if (menu == null) { + s.sendMessage(Lang.TUTORIALS.f("&7That menu does not exist!")); + return true; + } + slide.setMenu(menu.getName()); + s.sendMessage(Lang.TUTORIALS.f("&7You set the menu for slide &a" + user.getTutorialSlide() + "&7 to &a" + menu + "&7!")); + return true; + } + } + return true; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/tutorials/TutorialManager.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/tutorials/TutorialManager.java new file mode 100644 index 0000000..45c41c2 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/tutorials/TutorialManager.java @@ -0,0 +1,165 @@ +package net.grandtheftmc.core.tutorials; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.util.Component; +import net.grandtheftmc.core.util.SoundEffect; +import net.grandtheftmc.core.util.Title; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Sound; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class TutorialManager implements Component<TutorialManager, Core> { + + private List<Tutorial> tutorials = new ArrayList<>(); + private Map<String, Tutorial> mappedTuts = new HashMap<>(); + + public TutorialManager() { + this.load(); + } + + @Override + public TutorialManager onDisable(Core plugin) { + this.tutorials.forEach(t -> t.getSlides().clear()); + this.tutorials.clear(); + + mappedTuts.clear(); + return this; + } + + public List<Tutorial> getTutorials() { + return this.tutorials; + } + + public Tutorial getTutorial(String name) { + for (Tutorial tutorial : this.tutorials) + if (tutorial.getName().equalsIgnoreCase(name)) + return tutorial; + return null; + } + + public List<Tutorial> getTutorials(int start, int end) { + List<Tutorial> l = new ArrayList<>(); + for (int i = 0; i < this.tutorials.size(); i++) + if (i >= start && i <= end) + l.add(this.tutorials.get(i)); + return l; + } + + public void addTutorial(Tutorial tutorial) { + this.tutorials.add(tutorial); + } + + public void removeTutorial(Tutorial tutorial) { + this.tutorials.remove(tutorial); + } + + public void load() { + YamlConfiguration c = Core.getSettings().getTutorialsConfig(); + this.tutorials = new ArrayList<>(); + for (String name : c.getKeys(false)) { + try { + boolean invisible = c.get(name + ".invisible") != null && c.getBoolean(name + ".invisible"); + boolean playersInvisible = c.get(name + ".playersInvisible") != null && c.getBoolean(name + ".playersInvisible"); + List<Slide> slides = new ArrayList<>(); + if (c.get(name + ".slides") != null) + for (String s : c.getConfigurationSection(name + ".slides").getKeys(false)) { + boolean canConfirm = c.get(name + ".slides." + s + ".canConfirm") != null && c.getBoolean(name + ".slides." + s + ".canConfirm"); + int delay = c.get(name + ".slides." + s + ".delay") == null ? -1 : c.getInt(name + ".slides." + s + ".delay"); + Location location = Utils.teleportLocationFromString(c.getString(name + ".slides." + s + ".location")); + GameMode gameMode = c.get(name + ".slides." + s + ".gameMode") == null ? null : GameMode.valueOf(c.getString(name + ".slides." + s + ".gameMode")); + String actionBarMessage = c.getString(name + ".slides." + s + ".actionBarMessage"); + List<String> msges = c.getStringList(name + ".slides." + s + ".messages"); + String[] messages = c.get(name + ".slides." + s + ".messages") == null ? null : msges.toArray(new String[msges.size()]); + boolean headerAndFooter = c.getBoolean(name + ".slides." + s + ".headerAndFooter"); + Title title = null; + if (c.get(name + ".slides." + s + ".title") != null) { + String string = c.getString(name + ".slides." + s + ".title.title"); + String subtitle = c.getString(name + ".slides." + s + ".title.subtitle"); + int fadeIn = c.get(name + ".slides." + s + ".title.fadeIn") == null ? 0 : c.getInt(name + ".slides." + s + ".title.fadeIn"); + int stay = c.get(name + ".slides." + s + ".title.stay") == null ? 0 : c.getInt(name + ".slides." + s + ".title.stay"); + int fadeOut = c.get(name + ".slides." + s + ".title.fadeOut") == null ? 0 : c.getInt(name + ".slides." + s + ".title.fadeOut"); + title = new Title(string, subtitle, fadeIn, stay, fadeOut); + } + List<SoundEffect> sounds = new ArrayList<>(); + if (c.get(name + ".slides." + s + ".sounds") != null) { + for (String s2 : c.getConfigurationSection(name + ".slides." + s + ".sounds").getKeys(false)) { + Sound sound = c.get(name + ".slides." + s + ".sounds." + s2 + ".sound") == null ? null + : Sound.valueOf(c.getString(name + ".slides." + s + ".sounds." + s2 + ".sound")); + int volume = c.get(name + ".slides." + s + ".sounds." + s2 + ".volume") == null ? 1 : c.getInt(name + ".slides." + s + ".sounds." + s2 + ".volume"); + int pitch = c.get(name + ".slides." + s + ".sounds." + s2 + ".pitch") == null ? 1 : c.getInt(name + ".slides." + s + ".sounds." + s2 + ".pitch"); + int d = c.get(name + ".slides." + s + ".sounds." + s2 + ".delay") == null ? 1 : c.getInt(name + ".slides." + s + ".sounds." + s2 + ".delay"); + sounds.add(new SoundEffect(sound, volume, pitch, d)); + } + } + int slot = Integer.parseInt(c.getString(name + ".slides." + s + ".slot")); + String menu = c.getString(name + ".slides." + s + ".menu"); + slides.add(new Slide(canConfirm, delay, location, gameMode, messages, headerAndFooter, actionBarMessage, title, sounds, slot, menu)); + } + Tutorial t = new Tutorial(name, slides, invisible, playersInvisible); + this.tutorials.add(t); + this.mappedTuts.put(name.toLowerCase(), t); + } catch (Exception e) { + Core.log("Error while loading tutorial " + name + ");"); + e.printStackTrace(); + } + } + } + + public void save(boolean shutdown) { + YamlConfiguration c = Core.getSettings().getTutorialsConfig(); + for (String s : c.getKeys(false)) + c.set(s, null); + for (Tutorial tut : this.tutorials) { + try { + String name = tut.getName(); + c.set(name + ".invisible", tut.isInvisible()); + c.set(name + ".playersInvisible", tut.isPlayersInvisible()); + int i = 0; + for (Slide slide : tut.getSlides()) { + String path = name + ".slides." + i; + c.set(path + ".canConfirm", slide.isCanConfirm()); + c.set(path + ".delay", slide.getDelay()); + if (slide.getLocation() != null) + c.set(path + ".location", Utils.teleportLocationToString(slide.getLocation())); + c.set(path + ".gameMode", slide.getGameMode() == null ? null : slide.getGameMode().toString()); + c.set(path + ".actionBarMessage", slide.getActionBarMessage()); + List<String> messages = Utils.toList(slide.getMessages()); + c.set(path + ".messages", messages); + c.set(path + ".headerAndFooter", slide.getHeaderAndFooter()); + Title title = slide.getTitle(); + if (title != null) { + c.set(path + ".title.title", title.getTitle()); + c.set(path + ".title.subtitle", title.getSubtitle()); + c.set(path + ".title.fadeIn", title.getFadeIn()); + c.set(path + ".title.stay", title.getStay()); + c.set(path + ".title.fadeOut", title.getFadeOut()); + } + int i2 = 0; + if (slide.getSounds() != null) + for (SoundEffect s : slide.getSounds()) { + c.set(path + ".sounds." + i2 + ".sound", s.getSound().toString()); + c.set(path + ".sounds." + i2 + ".volume", s.getVolume()); + c.set(path + ".sounds." + i2 + ".pitch", s.getPitch()); + c.set(path + ".sounds." + i2 + ".delay", s.getDelay()); + i2++; + } + c.set(path + ".slot", slide.getSlot()); + c.set(path + ".menu", slide.getMenu()); + i++; + } + } catch (Exception e) { + Core.error("&7Eror while saving tutorial " + tut.getName()); + e.printStackTrace(); + } + } + Utils.saveConfig(c, "tutorials"); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/CooldownDAO.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/CooldownDAO.java new file mode 100644 index 0000000..0f5b61f --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/CooldownDAO.java @@ -0,0 +1,110 @@ +package net.grandtheftmc.core.users; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.database.BaseDatabase; + +import java.sql.*; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +/** + * Created by Timothy Lampen on 2/4/2018. + */ +public class CooldownDAO { + + public static Set<CooldownPayload> loadCooldowns(User user) { + Set<CooldownPayload> set = new HashSet<>(); + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + set.addAll(loadCooldown(connection, user.getUUID(), Core.name().toLowerCase())); + set.addAll(loadCooldown(connection, user.getUUID(), "global")); + + } catch (SQLException e) { + e.printStackTrace(); + } + return set; + } + + /** + * Load cooldown information for a user. + * + * @param conn - the database connection thread + * @param uuid - the uuid of the user + * @param serverKey - the server key identifier + * @return + */ + public static Set<CooldownPayload> loadCooldown(Connection conn, UUID uuid, String serverKey) { + + Set<CooldownPayload> set = new HashSet<>(); + + String query = "SELECT * FROM `user_cooldown` WHERE `uuid`=UNHEX(?) AND `server_key`=?"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setString(1, uuid.toString().replace("-", "")); + ps.setString(2, Core.name().toLowerCase()); + + try (ResultSet result = ps.executeQuery()) { + while (result.next()) { + String id = result.getString("id"); + + + Timestamp endTime = result.getTimestamp("endTime"); + if (endTime.getTime() <= System.currentTimeMillis()) { + continue; + } + + CooldownPayload payload = new CooldownPayload(id, endTime.getTime(), !serverKey.equals("global"), true); + set.add(payload); + } + } + } catch (Exception e) { + Core.log("[CooldownDAO] Error executing loadCooldown for uuid=" + uuid.toString() + ", serverKey=" + serverKey); + e.printStackTrace(); + } + + return set; + } + + public static void saveCooldowns(Connection connection, User user) { + try (PreparedStatement statement = connection.prepareStatement("DELETE FROM `user_cooldown` WHERE `uuid`=UNHEX(?) AND `server_key`=? OR `server_key`=?;")) { + statement.setString(1, user.getUUID().toString().replace("-", "")); + statement.setString(2, Core.name().toLowerCase()); + statement.setString(3, "global"); + statement.execute(); + + uploadCooldowns(connection, user); + + } catch (SQLException e) { + e.printStackTrace(); + } + } + + /** + * @apiNote for internal use only! + */ + private static void uploadCooldowns(Connection connection, User user) { + if (user.getCooldowns() == null) { + return; + } + + for (CooldownPayload payload : user.getCooldowns()) { + if (payload == null) { + continue; + } + + if (!payload.isSaveToMySQL()) { + continue; + } + + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO `user_cooldown` (uuid,server_key,id,endTime) VALUES (UNHEX(?),?,?,?)")) { + statement.setString(1, user.getUUID().toString().replace("-", "")); + statement.setString(2, payload.isServerSpecific() ? Core.name().toLowerCase() : "global"); + statement.setString(3, payload.getId()); + statement.setTimestamp(4, payload.getExpireTime()); + statement.execute(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/CooldownPayload.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/CooldownPayload.java new file mode 100644 index 0000000..3657fa4 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/CooldownPayload.java @@ -0,0 +1,35 @@ +package net.grandtheftmc.core.users; + +import java.sql.Timestamp; + +/** + * Created by Timothy Lampen on 2/4/2018. + */ +public class CooldownPayload { + private final String id; + private final Timestamp expireTime; + private final boolean saveToMySQL, serverSpecific; + + public CooldownPayload(String id, long expireTime, boolean serverSpecific, boolean saveToMySQL) { + this.id = id; + this.expireTime = new Timestamp(expireTime); + this.serverSpecific = serverSpecific; + this.saveToMySQL = saveToMySQL; + } + + public boolean isServerSpecific() { + return serverSpecific; + } + + public Timestamp getExpireTime() { + return expireTime; + } + + public String getId() { + return id; + } + + public boolean isSaveToMySQL() { + return saveToMySQL; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/Pref.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/Pref.java new file mode 100644 index 0000000..7673c76 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/Pref.java @@ -0,0 +1,97 @@ +package net.grandtheftmc.core.users; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.servers.ServerType; +import org.bukkit.Material; +import org.bukkit.entity.Player; + +public enum Pref { + + PLAYERS_SHOWN("playersShown", "Show Players", Material.EYE_OF_ENDER), + TP_REQUESTS("tpRequests", "Teleport Requests", Material.ENDER_PEARL), + ANNOUNCEMENTS("announcements", "Announcements", Material.EMPTY_MAP), + MESSAGES("messages", "Private Messages", Material.BOOK), + DEATH_MESSAGES("deathMessages", "Death Messages", Material.SKULL_ITEM), + USE_SCOREBOARD("useScoreboard", "Show Scoreboard", Material.DIAMOND), + SOCIALSPY("socialSpy", "SocialSpy", Material.NETHER_STAR), + TINT_HEALTH("tintHealth", "Tint Health", Material.INK_SACK, (byte) 1), + KEEP_COSMETICS("keepCosmetics", "Keep Cosmetics", Material.ENDER_CHEST), + SHOW_PARTICLES("showParticles", "Show Bullet Particles", Material.IRON_HOE), + AUTO_CLAIM_VOTE_REWARD("autoVoteClaim", "Auto Claim Vote Rewards", Material.FLINT_AND_STEEL, (byte) 45); + private final String dbName; + private final String displayName; + private final Material material; + private byte materialData = 0; + + Pref(String dbName, String displayName, Material material) { + this.dbName = dbName; + this.displayName = displayName; + this.material = material; + } + + Pref(String dbName, String displayName, Material material, Byte materialData) { + this.dbName = dbName; + this.displayName = displayName; + this.material = material; + this.materialData = materialData; + } + + public static Pref getPref(String dbName) { + for (Pref pref : Pref.values()) + if (pref.dbName.equalsIgnoreCase(dbName)) + return pref; + return null; + } + + public static Pref getPrefByDisplayName(String displayName) { + for (Pref pref : Pref.values()) + if (pref.displayName.equalsIgnoreCase(displayName)) + return pref; + return null; + } + + public String getDbName() { + return this.dbName; + } + + public String getDisplayName() { + return this.displayName; + } + + public Material getMaterial() { + return this.material; + } + + public Byte getMaterialData() { + return this.materialData; + } + + public boolean isEnabled(Player player, User u, ServerType type) { + switch (this) { + case PLAYERS_SHOWN: + return u.canTogglePlayers() && type == ServerType.HUB; + case TP_REQUESTS: + return type != ServerType.GLIDERS && type != ServerType.HUB; + case ANNOUNCEMENTS: + return !Core.getAnnouncer().getAnnouncements().isEmpty(); + case MESSAGES: + return true; + case DEATH_MESSAGES: + return type == ServerType.GLIDERS || type == ServerType.GTM; + case USE_SCOREBOARD: + return type != ServerType.CREATIVE; + case SOCIALSPY: + return player.hasPermission("socialspy") || u.isRank(UserRank.SRMOD); + case TINT_HEALTH: + return type == ServerType.GTM; + case KEEP_COSMETICS: + return type != ServerType.GLIDERS; + case SHOW_PARTICLES: + return type == ServerType.GTM; + case AUTO_CLAIM_VOTE_REWARD: + return type == ServerType.GTM; + default: + return false; + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/User.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/User.java new file mode 100644 index 0000000..b19a052 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/User.java @@ -0,0 +1,1454 @@ +package net.grandtheftmc.core.users; + +import java.sql.Connection; +import java.sql.Timestamp; +import java.text.DecimalFormat; +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.lang3.StringUtils; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.boss.BarColor; +import org.bukkit.boss.BarStyle; +import org.bukkit.boss.BossBar; +import org.bukkit.entity.Player; +import org.bukkit.permissions.PermissionAttachment; +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; +import org.bukkit.scoreboard.Scoreboard; +import org.bukkit.util.Vector; + +import com.earth2me.essentials.Essentials; +import com.j0ach1mmall3.ultimatecosmetics.api.storage.ParticleCosmeticStorage; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.achivements.Achievement; +import net.grandtheftmc.core.currency.Currency; +import net.grandtheftmc.core.currency.Purse; +import net.grandtheftmc.core.currency.component.CurrencySource; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.database.dao.CurrencyDAO; +import net.grandtheftmc.core.database.dao.OldVoteDAO; +import net.grandtheftmc.core.database.dao.VoteDAO; +import net.grandtheftmc.core.database.mutex.Mutexable; +import net.grandtheftmc.core.events.DisplayNameUpdateEvent; +import net.grandtheftmc.core.events.MoneyEvent; +import net.grandtheftmc.core.events.MoneyEvent.MoneyEventType; +import net.grandtheftmc.core.events.UpdateEvent; +import net.grandtheftmc.core.nametags.Nametag; +import net.grandtheftmc.core.nametags.NametagManager; +import net.grandtheftmc.core.servers.ServerType; +import net.grandtheftmc.core.users.eventtag.EventTag; +import net.grandtheftmc.core.users.eventtag.PreTagEquipEvent; +import net.grandtheftmc.core.users.targets.TrackedTarget; +import net.grandtheftmc.core.util.CoreLocation; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.util.time.TimeUtil; +import net.grandtheftmc.core.voting.ShopItem; +import net.grandtheftmc.core.voting.VoteRecord; +import net.grandtheftmc.core.voting.crates.Crate; +import net.grandtheftmc.core.voting.crates.CrateReward; + +public class User extends Mutexable { + + /** The uuid of the user */ + private final UUID uuid; + /** The name of the user */ + private final String name; + protected final EnumSet<Pref> prefs = EnumSet.noneOf(Pref.class); + // COSMETICS +// private final List<Cosmetic> cosmetics = new ArrayList<>(); +// private final EnumSet<CosmeticType> allCosmetics = EnumSet.noneOf(CosmeticType.class); +// private final Map<Cosmetic, EnumSet<PetData>> petDataPerms = new EnumMap<>(Cosmetic.class); +// private final Map<CosmeticType, String> lastCosmetics = new HashMap<>(); + private Set<CooldownPayload> cooldowns = null; + private final List<Nametag> nametags = new ArrayList<>(); + private Set<EventTag> unlockedTags = new HashSet<>(); + protected final Set<Achievement> unlockedAchievements = new HashSet<>(); + + /** The local rank of the user */ + protected UserRank ur; + /** The trial rank for the user */ + protected UserRank trialRank; + /** The global rank for the user */ + protected UserRank globalRank; + private EventTag equipedTag; + protected long trialRankExpiry; + + /** Holds currencies */ + private Purse purse; + /** Vote record for the user */ + private VoteRecord voteRecord; + + protected int bucks; //Currency + protected long dailyPlayTime; + private long loginTime = System.currentTimeMillis(); +// private Cosmetic activatingCosmetic; +// private Cosmetic buyingCosmetic; + private ShopItem buyingShopItem; + private int cosmeticVariant; + private ParticleCosmeticStorage.Shape particleShape; + //private EnumSet<PetData> petData = EnumSet.noneOf(PetData.class); + private Nametag petNametag; + private Nametag activatingNametag; + private Nametag buyingNametag; + // REWARDS + /** The daily reward streak */ + protected int dailyStreak; + protected long lastDailyReward; + private long lastSpanked = 0L; + protected String lastDonorReward; + private Crate selectedCrate; + private CrateReward confirmingCrateReward; + private long lastPlayersToggle; + private boolean editMode; + private String tutorial; + private int tutorialSlide; + private boolean editingTutorial; + private BossBar bossBar; + protected Achievement shownAchievement; + + private PermissionAttachment pa; + private final List<TrackedTarget> bossBarTargets = new ArrayList<>(); + private Scoreboard scoreboard; + private UUID lastMessage; + protected List<String> ignored = new ArrayList<>(); + private boolean hasMoved; + + private String language = "NONE"; + private CoreLocation location; + + private Long joinTime = 0L; + private Long leaveTime = 0L; + + /** The join address they used to connect to the server */ + private String serverJoinAddress; + + private BukkitTask updateTrackerTask; + + /** + * Construct a new user object. + * + * @param uuid - the uuid of the user + * @param name - the name of the user + */ + public User(UUID uuid, String name) { + this.uuid = uuid; + this.name = name; + this.purse = new Purse(); + + for (Currency curr : Currency.values()){ + purse.registerCurrency(curr); + } + } + + /** + * Called when we need to load data pertaining to the user. + * + * @param conn - the database connection thread + * + * @return {@code true} if the data was loaded, {@code false} otherwise. + */ + public boolean onLoad(Connection conn) { + + boolean result = false; + + result = UserDAO.fetchGeneralUser(this); + if(!result) return false; + + for (Currency curr : Currency.values()){ + switch(curr){ + case TOKEN: + case CROWBAR: + case COUPON_CREDIT: + case VOTE_TOKEN: + // grab currency based off serverKey + int amount = CurrencyDAO.getCurrency(conn, curr.getServerKey(), getUUID(), curr); + // set in the purse + getPurse().set(curr, amount); + + // TODO remove debug messages + Core.log("[User] uuid=" + uuid.toString() + ", curr=" + curr.getId() + ", amount=" + getPurse().getBalance(curr)); + break; + } + } + + result = UserDAO.fetchServerStats(this); + if(!result) return false; + + // load unlocked tags + this.unlockedTags = UserDAO.fetchAndEquipServerPlayerTags(this); + + // load cooldowns + this.cooldowns = CooldownDAO.loadCooldowns(this); + + // load their vote record + voteRecord = VoteDAO.getUserVoteRecord(conn, getUUID()); + + return result; + } + + /** + * Call when we need to save data pertaining to the user. + * + * @param conn - the database connection thread + * + * @return {@code true} if the data was saved, {@code false} otherwise. + */ + public boolean onSave(Connection conn) { + + // clear preferences + if (!this.prefs.isEmpty()) { + this.prefs.clear(); + } + + // clear nametags + if (!this.nametags.isEmpty()){ + this.nametags.clear(); + } + + // clear unlocked achievements + if (!this.unlockedAchievements.isEmpty()){ + this.unlockedAchievements.clear(); + } + + // clear ignore list + if (this.ignored != null && !this.ignored.isEmpty()){ + this.ignored.clear(); + } + + // save all the currencies + for (Currency curr : getPurse().getCurrencies().keySet()) { + + // only save + switch(curr){ + case TOKEN: + case CROWBAR: + case COUPON_CREDIT: + case VOTE_TOKEN: + int balance = getPurse().getBalance(curr); + + // TODO test remove + Core.log("[User][CurrencyTest] Saving user uuid=" + getUUID().toString() + ", currency=: " + curr.getId() + ", amt=" + balance); + CurrencyDAO.saveCurrency(conn, curr.getServerKey(), getUUID(), curr, balance); + break; + } + } + + // save cooldowns + CooldownDAO.saveCooldowns(conn, this); + + return true; + } + + public void dataCheck() { + + UserDAO.insertUser(getUUID(), getName()); + UserDAO.insertVoter(getUUID(), getName()); + + // if server is NOT Hub OR the default rank is global + // this means likely that all ranks are global, and therefore we should create + if (Core.getSettings().getType() != ServerType.HUB || UserRank.DEFAULT.getServerKey().equalsIgnoreCase("GLOBAL")){ + try (Connection conn = BaseDatabase.getInstance().getConnection()){ + + // create the users rank for this serverKey if they dont have one + UserDAO.createRank(conn, UserRank.DEFAULT.getServerKey(), uuid, UserRank.DEFAULT); + } + catch(Exception e){ + e.printStackTrace(); + } + } + + // insert currencies if not exists + for (Currency curr : Currency.values()){ + + // do not create currencies for HUB, if its a server currency + if (Core.getSettings().getType() == ServerType.HUB && (!curr.getServerKey().equalsIgnoreCase("GLOBAL"))){ + continue; + } + + // within because if one currency fails to create, we still wanna try others + try (Connection conn = BaseDatabase.getInstance().getConnection()){ + CurrencyDAO.createCurrency(conn, curr.getServerKey(), uuid, curr); + } + catch(Exception e){ + e.printStackTrace(); + } + } + } + + /** + * Get the uuid of the user. + * + * @return The uuid of the user. + */ + public UUID getUUID() { + return this.uuid; + } + + /** + * Get the name of the user. + * + * @return The name of the user. + */ + public String getName() { + return this.name; + } + + public Set<CooldownPayload> getCooldowns() { + return this.cooldowns; + } + + /** + * @param target The target that the bossbar will point to, can be made using a new TrackedEntity or Tracked Target + */ + public void addBossBarTarget(TrackedTarget target){ + this.bossBarTargets.add(target); + } + + /** + * @param target The target to remove from the bossbar + */ + public void removeBossBarTarget(TrackedTarget target){ + this.bossBarTargets.add(target); + } + + public void setEquipedTag(EventTag tag) { + PreTagEquipEvent tagEquipEvent = new PreTagEquipEvent(Bukkit.getPlayer(this.uuid), this.equipedTag, tag); + Bukkit.getPluginManager().callEvent(tagEquipEvent); + if (tagEquipEvent.isCancelled()) return; + + this.equipedTag = tag; + ServerUtil.runTaskAsync(() -> UserDAO.updatePlayerTags(getUUID(), tag)); + } + + public void giveEventTag(EventTag tag){ + if(!this.unlockedTags.contains(tag)) { + this.unlockedTags.add(tag); + ServerUtil.runTaskAsync(() -> UserDAO.addPlayerTag(getUUID(), tag)); + } + } + + public EventTag getEquipedTag() { + return this.equipedTag; + } + + /** + * @param loc the location of the target to remove from the bossbar + */ + public boolean removeBossBarTarget(Location loc){ + List<TrackedTarget> clone = new ArrayList<>(this.bossBarTargets); + Optional<TrackedTarget> optTarget = clone.stream().filter(target -> target.getLocation().equals(loc)).findFirst(); + if(optTarget.isPresent()) { + this.bossBarTargets.remove(optTarget.get()); + return true; + } + return false; + } + + public Set<EventTag> getUnlockedTags(){ + return this.unlockedTags; + } + + private int getBossBarSlotForTarget(Player player, Location target) { + Location clone = player.getEyeLocation().clone(); + clone.setPitch(0.0f); + clone.setY(target.getY()); + Vector dirToDestination = target.toVector().subtract(clone.toVector()); + Vector playerDirection = clone.getDirection(); + double angle = Math.toDegrees(dirToDestination.angle(playerDirection)); + if(angle >= 90) + return Integer.MAX_VALUE; + Location pointA = player.getLocation(); + Location pointB = player.getLocation().clone().add(player.getLocation().clone().getDirection().setY(0).normalize().multiply(100000)); + double signum = Math.signum((target.getBlockX()-pointA.getX()) * (pointB.getZ()-pointA.getZ()) - ((target.getBlockZ()-pointA.getZ()) * (pointB.getX() - pointA.getX()))); + + int posFromMiddle = (int)Math.round(angle/4.029); + + + return signum >= 0 ? 23 - posFromMiddle : 23 + posFromMiddle; + } + + public static final String EMPTY_BAR = " "; + public void refreshBossBar(){ + if(this.bossBar==null && this.bossBarTargets.size()==0) + return; + if(this.bossBar!=null && this.bossBarTargets.size()==0){ + this.bossBar.removeAll(); + return; + } + if(Bukkit.getPlayer(this.uuid)==null) { + this.updateTrackerTask.cancel(); + this.updateTrackerTask.cancel(); + return; + } + if(this.bossBar == null) { + this.bossBar = Bukkit.getServer().createBossBar("", BarColor.RED, BarStyle.SOLID); + refreshBossBar(); + return; + } + Player player = Bukkit.getPlayer(this.uuid); + if(!this.bossBar.getPlayers().contains(player)) + this.bossBar.addPlayer(player); + HashMap<Integer, String> placeholders = new HashMap<>(); + for (TrackedTarget target : this.bossBarTargets) { + if(!target.getLocation().getWorld().equals(player.getWorld())) + continue; + int slot = getBossBarSlotForTarget(player, target.getLocation()); + if(slot == Integer.MAX_VALUE) + continue; + placeholders.put(slot, getColorFromDistance(target.getLocation().distance(player.getLocation())) + "" + target.getPointer()); + } + if(placeholders.size()==0) { + this.bossBar.removeAll(); + return; + } + + StringBuilder sb = new StringBuilder(EMPTY_BAR); + for(Map.Entry<Integer, String> entry : placeholders.entrySet()) { + sb.replace(entry.getKey(), entry.getKey()+1, entry.getValue()); + } + + this.bossBar.setTitle(sb.toString()); + } + + private static ChatColor getColorFromDistance(double distance){ + if(distance<=10) + return ChatColor.GREEN; + else if(distance<=50) + return ChatColor.YELLOW; + else if(distance<=100) + return ChatColor.GOLD; + else + return ChatColor.RED; + } + + public long getLoginTime() { + return loginTime; + } + + // GETTING + + + public void setDailyPlayTime(long dailyPlayTime) { + this.dailyPlayTime = dailyPlayTime; + } + + public int getCouponCredits() { + return getPurse().getBalance(Currency.COUPON_CREDIT); + } + + public void setCouponCredits(int couponCredits) { + getPurse().set(Currency.COUPON_CREDIT, couponCredits); + } + + /** + * Get the highest rank of the user possible. + * <p> + * This will traverse all the ranks of the user, and returns the highest rank for this user. + * </p> + * + * @return The highest rank for this user. + */ + public UserRank getUserRank() { + + // if no user rank specified, set as default + if (this.ur == null){ + this.ur = UserRank.DEFAULT; + } + + // the highest found rank + UserRank highestRank = this.ur; + + // if they have a global rank, and it's HIGHER + if (this.globalRank != null && this.getGlobalRank().isHigherThan(highestRank)){ + highestRank = this.globalRank; + } + + // if they have a trial rank, and it's HIGHER + if (this.trialRank != null && this.hasTrialRank() && this.trialRank.isHigherThan(highestRank)){ + highestRank = this.trialRank; + } + + return highestRank; + } + + public void setLoginTime(long loginTime) { + this.loginTime = loginTime; + } + + /** + * Set the user's rank. + * + * @param ur - the new rank to set + */ + public void setUserRank(UserRank ur) { + Player player = Bukkit.getPlayer(this.uuid); + if (this.prefs.contains(Pref.SOCIALSPY) && UserRank.MOD.isHigherThan(ur)) + this.setPref(player, Pref.SOCIALSPY, false); + + // async save of rank, based on rank's serverKey + ServerUtil.runTaskAsync(() -> { + try (Connection conn = BaseDatabase.getInstance().getConnection()){ + UserDAO.saveRank(conn, ur.getServerKey(), uuid, ur); + } + catch(Exception e){ + e.printStackTrace(); + } + }); + + // if we're setting a global rank, set locally + if (ur.getServerKey().equalsIgnoreCase("GLOBAL")){ + this.globalRank = ur; + } + else{ + this.ur = ur; + } + + this.updateNameTag(player); + this.updateDisplayName(player); + this.setPerms(player); + } + + /** + * Set the user's rank. + * + * @param ur - the new rank to set + * @param serverKey - the rank on the server key + */ + public void setUserRank(UserRank ur, String serverKey) { + Player player = Bukkit.getPlayer(this.uuid); + if (this.prefs.contains(Pref.SOCIALSPY) && UserRank.MOD.isHigherThan(ur)) + this.setPref(player, Pref.SOCIALSPY, false); + + // async save of rank, based on rank's serverKey + ServerUtil.runTaskAsync(() -> { + try (Connection conn = BaseDatabase.getInstance().getConnection()){ + UserDAO.saveRank(conn, serverKey, uuid, ur); + } + catch(Exception e){ + e.printStackTrace(); + } + }); + + // if we're setting a global rank, set locally + if (serverKey.equalsIgnoreCase("GLOBAL")){ + this.globalRank = ur; + } + else{ + this.ur = ur; + } + + this.updateNameTag(player); + this.updateDisplayName(player); + this.setPerms(player); + } + + /** + * Get the rank of the user, without taking into consideration their trial rank. + * + * @return The rank of the user, without it being a trial. + */ + public UserRank getUserRankNonTrial() { + + // if no user rank specified, set as default + if (this.ur == null){ + this.ur = UserRank.DEFAULT; + } + + // the highest found rank + UserRank highestRank = this.ur; + + // if they have a global rank, and it's HIGHER + if (this.globalRank != null && this.getGlobalRank().isHigherThan(highestRank)){ + highestRank = this.globalRank; + } + + return highestRank; + } + + public boolean checkTrialRankExpiry() { + if (this.trialRank == null || this.trialRankExpiry > System.currentTimeMillis()) + return false; + Player player = Bukkit.getPlayer(this.uuid); + new BukkitRunnable() { + @Override + public void run() { + Player player = Bukkit.getPlayer(User.this.uuid); + if (player != null) + player.sendMessage(Lang.RANKS.f("&7Your &a&lfree " + User.this.trialRank.getColoredNameBold() + "&7 trial has expired! You can buy it permanently for &a$&l" + + User.this.trialRank.getPrice() + "&7 at &a&l" + Core.getSettings().getStoreLink() + "&7!")); + } + }.runTaskLater(Core.getInstance(), 20); + + ServerUtil.runTaskAsync(() -> UserDAO.updateUserTrialRank(this.uuid, null, 0)); + + this.trialRank = null; + this.trialRankExpiry = 0; + this.updateNameTag(player); + this.updateDisplayName(player); + this.setPerms(player); + return true; + } + + public boolean hasTrialRank() { + this.checkTrialRankExpiry(); + return this.trialRank != null; + } + + public UserRank getTrialRank() { + return this.hasTrialRank() ? this.trialRank : null; + } + + public void setTrialRank(UserRank trialRank, long trialRankExpiry) { + Player player = Bukkit.getPlayer(this.uuid); + if (this.prefs.contains(Pref.SOCIALSPY)) + this.setPref(player, Pref.SOCIALSPY, false); + + ServerUtil.runTaskAsync(() -> UserDAO.updateUserTrialRank(this.uuid, trialRank, trialRankExpiry)); + + this.trialRank = trialRank; + this.trialRankExpiry = trialRankExpiry; + this.updateNameTag(player); + this.updateDisplayName(player); + this.setPerms(player); + } + + public long getTrialRankExpiry() { + return this.trialRankExpiry; + } + + /** + * Get the global rank for this user. + * + * @return The global rank for this user, if one exists. + */ + public UserRank getGlobalRank(){ + return globalRank; + } + + /** + * Sets the global rank of the specified user. + * + * @param userRank - the rank to set their global rank to + */ + public void setGlobalRank(UserRank userRank){ + this.globalRank = userRank; + } + + public long getTimeUntilTrialRankExpires() { + return this.hasTrialRank() ? 0 : System.currentTimeMillis() - this.trialRankExpiry; + } + + public boolean isSpecial() { + return this.getUserRank() != UserRank.DEFAULT; + } + + public boolean isRank(UserRank rank) { + UserRank r = this.getUserRank(); + return r == rank || r.isHigherThan(rank); + } + + public boolean isPremium() { + return this.isRank(UserRank.PREMIUM); + } + + public boolean isStaff() { + return this.isRank(UserRank.HELPOP); + } + + public boolean isAdmin() { + return this.isRank(UserRank.ADMIN); + } + + /** + * Get the purse that holds the currency for this player. + * + * @return The purse that holds the currency for this player. + */ + public Purse getPurse() { + return purse; + } + + /** + * Get the vote record for this player. + * + * @return The vote record for this player. + */ + public VoteRecord getVoteRecord(){ + return voteRecord; + } + + /** + * Get the amonut of votes for this player. + * + * @return The amount of votes they have. + * @deprecated - This is used for compatibility purposes, please use {@link #getPurse()} instead. + */ + @Deprecated + public int getVotes() { + return getPurse().getBalance(Currency.VOTE_TOKEN); + } + + /** + * Remove a vote for this player. + * + * @deprecated - This is for compatibility purposes, please use {@link #getPurse()}. + */ + @Deprecated + public void removeVote() { + getPurse().withdraw(CurrencySource.CUSTOM, Currency.VOTE_TOKEN, 1); + } + + /** + * Get the chance this user has to get double rewards. + * + * @return The chance this user has to get double rewards. + */ + public int getDoubleVoteChance(){ + int chance = getVoteRecord().getStreak() * 5; + if (chance >= 100){ + return 100; + } + + return chance; + } + + /** + * Get whether or not the player's vote streak has expired. + * + * @return {@code true} if the vote streak has expired, {@code false} otherwise. + * + * @deprecated - Please do not rely on this method to exist in the future. + */ + @Deprecated + public boolean voteStreakExpired() { + + VoteRecord vr = getVoteRecord(); + + // if they never voted before + if (!vr.getLastVoted().isPresent()){ + return false; + } + + if (getVoteRecord().getStreak() > 0 && getVoteRecord().getLastVoted().get().getTime() + 172800000 < System.currentTimeMillis()) { + return true; + } + + return false; + } + + /** + * Get whether or not this user can increment their vote streak if they were to vote. + * + * @return {@code true} if they can extend their vote streak with another vote, {@code false} otherwise. + */ + public boolean canVoteStreak() { + + // get the last time they ever voted + Timestamp lastVoteEver = getVoteRecord().getLastVoted().orElse(null); + if (lastVoteEver != null){ + + Timestamp current = new Timestamp(System.currentTimeMillis()); + + // don't count same days as vote streak increment + boolean isDiff = TimeUtil.isDifferentDay(current, lastVoteEver); + if (isDiff) { + + // if voted within timeframe + int hoursDiff = TimeUtil.getDifferenceInHours(current, lastVoteEver); + if (hoursDiff <= 48) { + return true; + } + else { + return false; + } + } + + // if same day + return false; + } + + // never voted + return true; + } + + /** + * Get the timestamp for when the player can vote again to increment their vote streak. + * + * @return The timestamp for when the player can vote again, if present, otherwise empty and they can vote now. + */ + public Optional<Timestamp> getTimeUntilVoteStreak() { + + // get the last time they ever voted + Timestamp lastVoteEver = getVoteRecord().getLastVoted().orElse(null); + if (lastVoteEver != null){ + + Timestamp current = new Timestamp(System.currentTimeMillis()); + + // don't count same days as vote streak increment + boolean isDiff = TimeUtil.isDifferentDay(current, lastVoteEver); + if (isDiff) { + // can vote streak now + return Optional.empty(); + } + else{ + return Optional.of(new Timestamp(lastVoteEver.getNanos() + 86400000 - System.currentTimeMillis())); + } + } + + // can vote streak now + return Optional.empty(); + } + + public int getBucks() { + return this.bucks; + } + + public void setBucks(int amnt) { + ServerUtil.runTaskAsync(() -> UserDAO.updateUserBucks(this.uuid, amnt)); + this.bucks = amnt; + } + + public boolean hasBucks(int i) { + return this.bucks >= i; + } + + public void addBucks(int amnt) { + this.bucks += amnt; + ServerUtil.runTaskAsync(() -> UserDAO.updateUserBucks(this.uuid, this.bucks)); + } + + public void takeBucks(int amnt) { + this.bucks -= amnt; + ServerUtil.runTaskAsync(() -> UserDAO.updateUserBucks(this.uuid, this.bucks)); + } + + public long getLastSpanked() { + return lastSpanked; + } + + public void setLastSpanked(long lastSpanked) { + this.lastSpanked = lastSpanked; + } + + public int getTokens() { + return getPurse().getBalance(Currency.TOKEN); + //return this.tokens; + } + + public void setTokens(int amnt) { + getPurse().set(Currency.TOKEN, amnt); + } + + public boolean hasTokens(int i) { + return getPurse().getBalance(Currency.TOKEN) >= i; + } + + public void addTokens(int amnt) { + getPurse().set(Currency.TOKEN, getPurse().getBalance(Currency.TOKEN) + amnt); + } + + public void takeTokens(int amnt) { + getPurse().set(Currency.TOKEN, getPurse().getBalance(Currency.TOKEN) - amnt); + } + + public int getCrowbars() { + return getPurse().getBalance(Currency.CROWBAR); + } + + public void setCrowbars(int amnt) { + getPurse().set(Currency.CROWBAR, amnt); + } + + public boolean hasCrowbars(int i) { + return getPurse().getBalance(Currency.CROWBAR) >= i; + } + + public void addCrowbars(int amnt) { + getPurse().set(Currency.CROWBAR, getPurse().getBalance(Currency.CROWBAR) + amnt); + } + + public void takeCrowbars(int amnt) { + getPurse().set(Currency.CROWBAR, getPurse().getBalance(Currency.CROWBAR) - amnt); + } + + public double getMoney() { + MoneyEvent e = new MoneyEvent(this.uuid); + Bukkit.getPluginManager().callEvent(e); + return e.getBalance(); + } + + public boolean hasMoney(double i) { + return this.getMoney() >= i; + } + + public boolean addMoney(double amount) { + MoneyEvent e = new MoneyEvent(this.uuid, amount); + Bukkit.getPluginManager().callEvent(e); + return e.isSuccessfull(); + } + + public boolean takeMoney(double amount) { + MoneyEvent e = new MoneyEvent(this.uuid, MoneyEventType.TAKE, amount); + Bukkit.getPluginManager().callEvent(e); + return e.isSuccessfull(); + } + + public long getLastPlayersToggle() { + return this.lastPlayersToggle; + } + + public void setLastPlayersToggle(long lastPlayersToggle) { + this.lastPlayersToggle = lastPlayersToggle; + } + + public boolean canTogglePlayers() { + return this.lastPlayersToggle + 10000 < System.currentTimeMillis(); + } + + public boolean getPref(Pref pref) { + return this.prefs.contains(pref); + } + + public void togglePref(Player player, Pref pref) { + this.setPref(player, pref, !this.prefs.contains(pref)); + } + + public void setPref(Player player, Pref pref, boolean b) { + if (b && !this.prefs.contains(pref)) this.prefs.add(pref); + else if (!b) this.prefs.remove(pref); + + ServerUtil.runTaskAsync(() -> UserDAO.updateUserPref(this.uuid, pref, this.prefs.contains(pref))); + + Bukkit.getPluginManager().callEvent(new UpdateEvent(player, pref)); + } + + public ParticleCosmeticStorage.Shape getParticleShape() { + return this.particleShape; + } + + public void setParticleShape(ParticleCosmeticStorage.Shape shape) { + this.particleShape = shape; + } + + public int getCosmeticVariant() { + return this.cosmeticVariant; + } + + public void setCosmeticVariant(int i) { + this.cosmeticVariant = i; + } + + public boolean hasNametag(Nametag tag) { + return this.nametags.contains(tag); + } + + public void giveNametag(Nametag tag) { + if (!this.nametags.contains(tag)) this.nametags.add(tag); + ServerUtil.runTaskAsync(() -> UserDAO.updateUserNametag(this.uuid, tag.getName(), true)); + } + + public void takeNametag(Nametag tag) { + this.nametags.remove(tag); + ServerUtil.runTaskAsync(() -> UserDAO.updateUserNametag(this.uuid, tag.getName(), false)); + } + + public Nametag getActivatingNametag() { + return this.activatingNametag; + } + + public void setActivatingNametag(Nametag tag) { + this.activatingNametag = tag; + } + + public Nametag getBuyingNametag() { + return this.buyingNametag; + } + + public void setBuyingNametag(Nametag buyingNametag) { + this.buyingNametag = buyingNametag; + } + + public ShopItem getBuyingShopItem() { + return this.buyingShopItem; + } + + public void setBuyingShopItem(ShopItem buyingShopItem) { + this.buyingShopItem = buyingShopItem; + } + + public boolean dailyStreakExpired() { + if (this.dailyStreak > 0 && this.lastDailyReward + 172800000 < System.currentTimeMillis()) { + this.setDailyStreak(0); + this.setLastDailyReward(0); + return true; + } + return false; + } + + public int getDailyStreak() { + this.dailyStreakExpired(); + return this.dailyStreak; + } + + public long getDailyPlayTime() { + return dailyPlayTime; + } + + public void setDailyStreak(int dailyStreak) { + this.dailyStreak = dailyStreak; + ServerUtil.runTaskAsync(() -> OldVoteDAO.updateUserDailyStreak(this.uuid, this.dailyStreak)); + } + + public int getLuckyDailyChance() { + this.dailyStreakExpired(); + return this.dailyStreak >= 20 ? 100 : this.dailyStreak * 5; + } + + public void addDailyStreak(int i) { + this.lastDailyReward = System.currentTimeMillis(); + this.dailyStreak += i; + ServerUtil.runTaskAsync(() -> OldVoteDAO.updateUserDaily(this.uuid, this.dailyStreak, this.lastDailyReward)); + } + + public long getLastDailyReward() { + return this.lastDailyReward; + } + + public void setLastDailyReward(long l) { + this.lastDailyReward = l; + ServerUtil.runTaskAsync(() -> OldVoteDAO.updateUserLastDailyReward(this.uuid, this.lastDailyReward)); + } + + public void setLastDailyReward() { + this.setLastDailyReward(System.currentTimeMillis()); + } + + public boolean canClaimDailyReward() { + return this.lastDailyReward + 86400000 < System.currentTimeMillis(); + } + + public long getTimeUntilDailyReward() { + return this.lastDailyReward + 86400000 - System.currentTimeMillis(); + } + + public String getLastDonorReward() { + return this.lastDonorReward; + } + + public void setLastDonorReward() { + LocalDateTime now = LocalDateTime.now(); + this.lastDonorReward = now.getYear() + ":" + now.getMonthValue(); + ServerUtil.runTaskAsync(() -> UserDAO.updateUserLastDonorReward(this.uuid, this.lastDonorReward)); + } + + public boolean canClaimMonthlyReward() { + // if their highest rank is a default user + if (getUserRankNonTrial() == UserRank.DEFAULT) return false; + + if (this.lastDonorReward == null) return true; + String[] a + = this.lastDonorReward.split(":"); + if (a.length == 2) + try { + int year = Integer.parseInt(a[0]); + int month = Integer.parseInt(a[1]); + LocalDateTime time = LocalDateTime.now(); + return year < time.getYear() || month < time.getMonthValue(); + } catch (NumberFormatException ignored) { + } + return true; + } + + public long getTimeUntilMonthlyReward() { + if (this.canClaimMonthlyReward()) return 0; + LocalDateTime now = LocalDateTime.now(); + LocalDateTime next = now.getMonthValue() == 12 ? LocalDateTime.of(now.getYear() + 1, 1, 1, 0, 0) + : LocalDateTime.of(now.getYear(), now.getMonthValue() + 1, 1, 0, 0); + return ChronoUnit.MILLIS.between(now, next); + } + + public boolean hasEditMode() { + return this.editMode; + } + + public void setEditMode(boolean b) { + this.editMode = b; + if (!b && !this.isRank(UserRank.ADMIN)) { + Player player = Bukkit.getPlayer(this.uuid); + player.getInventory().iterator().forEachRemaining(itemStack -> player.getInventory().remove(itemStack)); + } + } + + public String getTutorial() { + return this.tutorial; + } + + public void setTutorial(String tutorial) { + this.tutorial = tutorial; + } + + public boolean isInTutorial() { + return this.tutorial != null; + } + + public int getTutorialSlide() { + return this.tutorialSlide; + } + + public void setTutorialSlide(int tutorialSlide) { + this.tutorialSlide = tutorialSlide; + } + + public boolean isEditingTutorial() { + return this.editingTutorial; + } + + public void setEditingTutorial(boolean editingTutorial) { + this.editingTutorial = editingTutorial; + } + + public Scoreboard getScoreboard() { + if (this.scoreboard == null) + this.scoreboard = Bukkit.getScoreboardManager().getNewScoreboard(); + return this.scoreboard; + } + + public void setScoreboard(Scoreboard scoreboard) { + this.scoreboard = scoreboard; + } + + // UTILS + + public void updateVisibility(Player p) { + if (p == null) + p = Bukkit.getPlayer(this.uuid); + if (this.isSpecial()) { + for (Player pl : Bukkit.getOnlinePlayers()) { + pl.showPlayer(p); + if (this.prefs.contains(Pref.PLAYERS_SHOWN)) p.showPlayer(pl); + else p.hidePlayer(pl); + } + return; + } + for (Player pl : Bukkit.getOnlinePlayers()) { + if (this.prefs.contains(Pref.PLAYERS_SHOWN)) p.showPlayer(pl); + else p.hidePlayer(pl); + User u = Core.getUserManager().getLoadedUser(pl.getUniqueId()); + if (u.getPref(Pref.PLAYERS_SHOWN)) pl.showPlayer(p); + else pl.hidePlayer(p); + } + } + + public void updateDisplayName(Player p) { + if (p == null) + return; + DisplayNameUpdateEvent event = new DisplayNameUpdateEvent(p); + UserRank rank = this.getUserRank(); + event.setPrefix(""); + event.setSuffix(""); + event.setRankPrefix(rank.getPrefix()); + event.setNameColor(rank.getColor()); + Bukkit.getPluginManager().callEvent(event); + if(this.equipedTag!=null) { + event.setPrefix(this.equipedTag.getBoldName()); + } + p.setDisplayName(Utils.f(event.getRankPrefix() + ' ' + event.getPrefix() + + (event.getPrefix().isEmpty() ? "" : " ") + event.getNameColor() + (this.isSpecial() ? "&l" : "") + + p.getName() + (event.getSuffix().isEmpty() ? "" : " ") + event.getSuffix())); + } + + public void updateFlyMode(Player p) { + if (p == null) + return; + if (!this.isSpecial()) + return; + p.setAllowFlight(true); + p.setFlying(true); + } + + public void setPerms(Player p) { + if (p == null) + p = Bukkit.getPlayer(this.uuid); + if (p == null) + return; + List<String> ls = Core.getPermsManager().getAllPerms(this.getUserRank(), this.uuid); + if (this.pa != null) + p.removeAttachment(this.pa); + this.pa = p.addAttachment(Core.getInstance()); + for (String s : ls) + if (s.startsWith("-")) this.pa.setPermission(s.substring(1), false); + else this.pa.setPermission(s, true); + + } + + public void removePerms(Player p) { + if (this.pa != null) + p.removeAttachment(this.pa); + this.pa = null; + } + + public void updateNameTag(Player p) { + NametagManager.updateNametag(p); + } + + public String getColoredName(Player player) { + return this.getUserRank().getColor() + (this.isSpecial() ? "&l" : "") + player.getName(); + } + + public UUID getLastMessage() { + return this.lastMessage; + } + + public void setLastMessage(UUID lastMessage) { + this.lastMessage = lastMessage; + } + + public boolean hasMoved() { + return this.hasMoved; + } + + public void setHasMoved() { + this.hasMoved = true; + } + + public void insertLog(Player player, String action, String type, String reward, double amount, double price) { + Utils.insertLogLater(player.getUniqueId(), player.getName(), action, type, reward, amount, price); + } + + public void updateIgnored() { + String s = ""; + for (String st : this.ignored) + s += st + ','; + if (s.endsWith(",")) + s = s.substring(0, s.length() - 1); + + String finalS = s; + ServerUtil.runTaskAsync(() -> UserDAO.updateUserIgnore(this.uuid, finalS)); + } + + public void addIgnored(String name) { + this.ignored.add(name); + this.updateIgnored(); + } + + public void removeIgnored(String name) { + this.ignored.remove(name); + this.updateIgnored(); + } + + public List<String> getIgnored() { + return this.ignored; + } + + public boolean isIgnored(String name) { + return this.ignored.contains(name); + } + + public boolean isVanished(Player player) { + Plugin plugin = Bukkit.getPluginManager().getPlugin("Essentials"); + return plugin != null && ((Essentials) plugin).getVanishedPlayers().contains(player.getName()); + } + + public Long getJoinTime() { + return this.joinTime; + } + + public void setJoinTime(Long joinTime) { + this.joinTime = joinTime; + } + + public Long getLeaveTime() { + return this.leaveTime; + } + + public void setLeaveTime(Long leaveTime) { + this.leaveTime = leaveTime; + } + + public void updateAchievements() { + if (this.unlockedAchievements.isEmpty()) return; + if (this.unlockedAchievements.size() > Achievement.values().length) return; + Set<String> temp = new HashSet<>(); + this.unlockedAchievements.forEach(achievement -> temp.add(achievement.getShortName())); + String s = StringUtils.join(temp, ","); + + ServerUtil.runTaskAsync(() -> UserDAO.updateUnlockedAchievements(this.uuid, s)); + + if (this.shownAchievement != null) { + ServerUtil.runTaskAsync(() -> UserDAO.updateShownAchievement(this.uuid, this.shownAchievement.getShortName())); + } + } + + public Set<Achievement> getUnlockedAchievements() { + return this.unlockedAchievements; + } + + public boolean hasAchievement(Achievement achievement) { + return this.unlockedAchievements.contains(achievement); + } + + public void addAchievement(Achievement achievement) { + boolean disabled = true; + if (disabled) return; // TODO + if (achievement == null) return; + if (hasAchievement(achievement)) return; + this.unlockedAchievements.add(achievement); + if (this.shownAchievement == null) this.setShownAchievement(achievement); + if (achievement.ordinal() > this.getShownAchievement().ordinal()) this.setShownAchievement(achievement); + this.updateAchievements(); + } + + public Achievement getShownAchievement() { + if (!this.unlockedAchievements.contains(this.shownAchievement)) this.addAchievement(this.shownAchievement); + return this.shownAchievement; + } + + public void setShownAchievement(Achievement achievement) { + if (achievement == null) return; + if (!this.unlockedAchievements.contains(achievement)) return; + this.shownAchievement = achievement; + ServerUtil.runTaskAsync(() -> UserDAO.updateShownAchievement(this.uuid, this.shownAchievement.getShortName())); + } + + public Crate getSelectedCrate() { + return this.selectedCrate; + } + + public void setSelectedCrate(Crate selectedCrate) { + this.selectedCrate = selectedCrate; + } + + public CrateReward getConfirmingCrateReward() { + return this.confirmingCrateReward; + } + + public void setConfirmingCrateReward(CrateReward c) { + this.confirmingCrateReward = c; + } + + /** + * @param length how long the cooldown is (in seconds) + * @param saveToMySQL if the cooldown should be saved to mySQL (if for more than 6 hours, it probably should) + * @param id the id of the cooldown + * @param serverSpecific if the cooldown should only effect the one server. + */ + public void addCooldown(String id, long length, boolean saveToMySQL, boolean serverSpecific){ + this.cooldowns.add(new CooldownPayload(id, (length*1000) + System.currentTimeMillis(), serverSpecific, saveToMySQL)); + } + + + /** + * @param type the type of thing the cooldown falls under + * @return true if the player still has a cooldown. + */ + public boolean isOnCooldown(String type){ + if(this.cooldowns==null) + return false; + Set<CooldownPayload> clone = this.cooldowns; + for(CooldownPayload obj : clone) { + if(obj.getId().equals(type)) { + if(System.currentTimeMillis()>=obj.getExpireTime().getTime()) { + this.cooldowns.remove(obj); + return false; + } + return true; + } + } + return false; + } + + public void removeCooldown(String type) { + Set<CooldownPayload> clone = this.cooldowns; + for(CooldownPayload o : clone) { + if(o.getId().equalsIgnoreCase(type)) { + this.cooldowns.remove(o); + } + } + } + + /** + * @param type the string identifier of the cooldown + * @return a String formated #.# displaying the seconds remaining until expire + */ + public String getFormattedCooldown(String type){ + DecimalFormat df = new DecimalFormat("#.#"); + Optional<CooldownPayload> optCD = this.cooldowns.stream().filter(obj -> obj.getId().equals(type)).findFirst(); + if(!optCD.isPresent()) { + Core.error("Tried to get formatted cooldown of " + type + " but the player " + this.getName() + " does not have a cooldown of that type!"); + return ChatColor.RED + "ERROR: Could not find your cooldown! Report this to an admin id: " + type; + } + long time = optCD.map(c -> c.getExpireTime().getTime()).orElse(0L); + time -= System.currentTimeMillis(); + time /= 1000; + String returnStr; + if(TimeUnit.SECONDS.toDays(time)>1) + returnStr = TimeUnit.SECONDS.toDays(time) + " day"; + else if(TimeUnit.SECONDS.toHours(time)>1) + returnStr = TimeUnit.SECONDS.toHours(time) + " hour"; + else if(TimeUnit.SECONDS.toMinutes(time)>1) + returnStr = TimeUnit.SECONDS.toMinutes(time) + " minute"; + else + returnStr = df.format(time) + " second"; + + return returnStr + (returnStr.equals("1") || returnStr.equals("1.0") ? "" : "s"); + } + + public long getCooldownTimeLeft(String type) { + Optional<CooldownPayload> optCD = this.cooldowns.stream().filter(obj -> obj.getId().equals(type)).findFirst(); + if(!optCD.isPresent()) { + Core.error("Tried to get formatted cooldown of " + type+ " but the player " + this.getName() + " does not have a cooldown of that type!"); + throw new NullPointerException(); + } + long time = optCD.map(c -> c.getExpireTime().getTime()).orElse(0L); + time -= System.currentTimeMillis(); + time /= 1000; + return time; + } + + public CoreLocation getLocation() { + return location; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + /** + * Get the address that the user used to join the server. + * + * @return The IP address that the user used to join the server. + */ + public String getServerJoinAddress() { + return serverJoinAddress; + } + + /** + * Set the address that the user used to join the server. + * + * @param joinAddress - the join IP address + */ + public void setServerJoinAddress(String joinAddress){ + this.serverJoinAddress = joinAddress; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/UserDAO.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/UserDAO.java new file mode 100644 index 0000000..3ed4a92 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/UserDAO.java @@ -0,0 +1,1891 @@ +package net.grandtheftmc.core.users; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +import javax.annotation.Nullable; + +import org.apache.commons.lang3.tuple.Pair; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.achivements.Achievement; +import net.grandtheftmc.core.currency.Currency; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.database.dao.CurrencyDAO; +import net.grandtheftmc.core.servers.ServerType; +import net.grandtheftmc.core.stat.StatDAO; +import net.grandtheftmc.core.users.eventtag.EventTag; +import net.grandtheftmc.core.users.eventtag.EventTagDAO; +import net.grandtheftmc.core.users.eventtag.TagVisibility; +import net.grandtheftmc.core.util.CoreLocation; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.UUIDUtil; + +public class UserDAO { + + /** + * This method will fetch all of the general user stats, + * - User Rank + * - Trial Rank + * - Trial Rank Expiry + * - Bucks + * - Tokens + * - Crowbars + * - Prefs + * - Votes + * - Vote Streak + * - Last Vote Streak + * - Daily Streak + * - Last Daily Reward + * - Last Donor Reward + * - Shown Achievements + * - Unlocked Achievements + * - Ignored + * + * @param user - user profile + * @return Whether the stats were fetched + */ + public static boolean fetchGeneralUser(User user) { + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM `users` WHERE `uuid`=?;")) { + statement.setString(1, user.getUUID().toString()); + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + //user.ur = UserRank.getUserRank(result.getString("userrank")); + //user.trialRank = UserRank.getUserRankOrNull(result.getString("trialRank")); + //user.trialRankExpiry = result.getLong("trialRankExpiry"); + // TODO perhaps remove bucks, as its in users table but might be unused + user.bucks = result.getInt("bucks"); + // removed due to CurrencyDAO + //user.tokens = result.getInt("tokens"); + //user.crowbars = result.getInt("crowbars"); + user.prefs.clear(); + for (Pref pref : Pref.values()) + if (result.getBoolean(pref.getDbName())) + user.prefs.add(pref); + //user.couponCredits = result.getInt("couponCredits"); + user.dailyStreak = result.getInt("dailyStreak"); + user.lastDailyReward = result.getLong("lastDailyReward"); + user.lastDonorReward = result.getString("lastDonorReward"); + user.shownAchievement = Achievement.getAchivementExact(result.getString("shownAchievement")).orElse(Achievement.Hobo); + if (result.getString("unlockedAchievements") == null || result.getString("unlockedAchievements").equalsIgnoreCase("NULL")) { + user.addAchievement(Achievement.Hobo); + user.setShownAchievement(Achievement.Hobo); + } + String a = result.getString("unlockedAchievements"); + if (a != null) { + for (String string : a.split(",")) { + Achievement.getAchivementExact(string).ifPresent(user.unlockedAchievements::add); + } + } + String ignored = result.getString("ignored"); + user.ignored = new ArrayList<>(); + if (ignored != null) { + Collections.addAll(user.ignored, ignored.split(",")); + } + } + } + } + + // get global rank if there is one + UserRank globalRank = getRank(connection, "GLOBAL", user.getUUID()); + if (globalRank != null) { + user.globalRank = globalRank; + } + + // get server rank if there is one + UserRank serverRank = getRank(connection, Core.name().toUpperCase(), user.getUUID()); + if (serverRank != null) { + user.ur = serverRank; + } + + // get trial rank if there is one + // Note: We use the default's rank serverKey, as most settings will have per server + // or global ranks based off this rank. + Pair<UserRank, Timestamp> trialInfo = getTrialRank(connection, UserRank.DEFAULT.getServerKey(), user.getUUID()); + if (trialInfo != null) { + user.trialRank = trialInfo.getLeft(); + user.trialRankExpiry = trialInfo.getRight().getTime(); + } + + user.setServerJoinAddress(StatDAO.getUserJoinAddress(connection, user.getUUID()).orElse("mc.gtm.net")); + + // per request of prez, perhaps change down the road + if (Core.getInstance().getSettings().getType() == ServerType.VICE){ + user.setServerJoinAddress("play.vicemc.net"); + } + + } catch (SQLException e) { + Core.error("[UserDAO:fetchGeneralUser(user)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + /** + * This will insert the user to the 'users' database. + * + * @param uuid - Unique Identifier of the user + * @param name - Name of the user + * + * @return Whether the data was inserted + */ + public static boolean insertUser(UUID uuid, String name) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO `users`(`uuid`,`lastname`) VALUES(?,?) ON DUPLICATE KEY UPDATE `lastname`=?;")) { + statement.setString(1, uuid.toString()); + statement.setString(2, name); + statement.setString(3, name); + statement.execute(); + } + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO `user`(`uuid`,`name`) VALUES(UNHEX(?),?) ON DUPLICATE KEY UPDATE `name`=?;")) { + statement.setString(1, uuid.toString().replaceAll("-", "")); + statement.setString(2, name); + statement.setString(3, name); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:insertUser(uuid,name)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + /** + * This will insert the user to the 'voters' database. + * + * @param uuid - Unique Identifier of the user + * @param name - Name of the user + * @return Whether the data was inserted + */ + public static boolean insertVoter(UUID uuid, String name) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO `votes`(`uuid`,`name`) VALUES (?,?) ON DUPLICATE KEY UPDATE `name`=?;")) { + statement.setString(1, uuid.toString()); + statement.setString(2, name); + statement.setString(3, name); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:insertVoter(uuid,name)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + /** + * Adds the player tag to the specified user. + * + * @param uuid - the uuid of the user to add the tag to + * @param tag - the tag that you are adding to the player + * + * @return true if the update was successful + */ + public static boolean addPlayerTag(UUID uuid, EventTag tag) { + + try (Connection connect = BaseDatabase.getInstance().getConnection()) { + + String query = "INSERT IGNORE INTO user_tag (uuid, server_key, tag, enabled) VALUES (UNHEX(?), ?, ?, ?);"; + + try (PreparedStatement statement = connect.prepareStatement(query)){ + statement.setString(1, uuid.toString().replaceAll("-", "")); + statement.setString(2, tag.isGlobal() ? "GLOBAL" : Core.name().toUpperCase()); + statement.setString(3, tag.toString()); + statement.setBoolean(4, false); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:addPlayerTag(uuid, tag)] SQLException occurred"); + e.printStackTrace(); + return false; + } + return true; + } + + /** + * Adds the player tag to the specified user for the specified server key. + * + * @param uuid - the uuid of the user to add the tag to + * @param serverKey - the server key to add the tag for + * @param tag - the tag that you are adding to the player + * + * @return {@code true} if the update was successful, {@code false} otherwise. + */ + public static boolean addPlayerTag(UUID uuid, String serverKey, EventTag tag) { + + try (Connection connect = BaseDatabase.getInstance().getConnection()) { + + String query = "INSERT IGNORE INTO user_tag (uuid, server_key, tag, enabled) VALUES (UNHEX(?), ?, ?, ?);"; + + try (PreparedStatement statement = connect.prepareStatement(query)){ + statement.setString(1, uuid.toString().replaceAll("-", "")); + statement.setString(2, serverKey); + statement.setString(3, tag.toString()); + statement.setBoolean(4, false); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:addPlayerTag(uuid, serverKey, tag)] SQLException occurred"); + e.printStackTrace(); + return false; + } + return true; + } + + /** + * Updates the player tags for the given user. + * + * @param uuid - the uuid of the user + * @param newEquipped the newly equipped tag + * + * @return true if the update was successful + */ + public static boolean updatePlayerTags(UUID uuid, EventTag newEquipped){ + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + + String disableQuery = "UPDATE user_tag SET enabled=0 WHERE uuid=UNHEX(?) AND (server_key=? OR server_key=?);"; + + try (PreparedStatement statement = connection.prepareStatement(disableQuery)) { + statement.setString(1, uuid.toString().replaceAll("-", "")); + statement.setString(2, "GLOBAL"); + statement.setString(3, Core.name().toUpperCase()); + statement.executeUpdate(); + } + + if(newEquipped!=null) { + + String equipQuery = "UPDATE user_tag SET enabled=1 WHERE uuid=UNHEX(?) AND tag=?;"; + + try (PreparedStatement statement = connection.prepareStatement(equipQuery)) { + statement.setString(1, uuid.toString().replaceAll("-", "")); + statement.setString(2, newEquipped.toString()); + statement.executeUpdate(); + } + } + + } catch (SQLException e) { + Core.error("[UserDAO:updatePlayerTags(user, equippedTag)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + /** + * @param uuid - the uuid of the player to remove from + * @param tag - the tag that must be removed. + * + * @return true if the method was successful. + */ + public static boolean removePlayerTag(UUID uuid, EventTag tag) { + try (Connection connection = BaseDatabase.getInstance().getConnection()){ + String removeQuery = "DELETE FROM user_tag WHERE uuid=UNHEX(?) AND tag=?"; + + try (PreparedStatement statement = connection.prepareStatement(removeQuery)) { + statement.setString(1, uuid.toString().replaceAll("-", "")); + statement.setString(2, tag.toString()); + statement.execute(); + } + + } catch (SQLException e) { + Core.error("[UserDAO:removePlayerTag(user, tag)] SQLException occurred"); + e.printStackTrace(); + return false; + } + return true; + } + + /** + * @param uuid - the uuid of the player + * @return a readable copy of the player's event tags. + */ + public static Set<String> fetchReadablePlayerTags(UUID uuid) { + Set<String> tags = new HashSet<>(); + try (Connection connect = BaseDatabase.getInstance().getConnection()) { + + String query = "SELECT * FROM user_tag WHERE uuid=UNHEX(?);"; + + try (PreparedStatement statement = connect.prepareStatement(query)){ + statement.setString(1, uuid.toString().replaceAll("-", "")); + try(ResultSet result = statement.executeQuery()) { + while (result.next()) { + EventTag tag = EventTag.valueOf(result.getString("tag")); + String serverKey = result.getString("server_key"); + tags.add("&b" + tag.toString() + " &7From Server: &6&l" + serverKey.toUpperCase()); + } + } + } + } catch (SQLException e) { + Core.error("[UserDAO:fetchPlayerTags(uuid)] SQLException occurred"); + e.printStackTrace(); + return null; + } + return tags; + } + + /** + * Get all the player tags for the given user. + * + * @param user - the user to get the tags of + * + * @return a set of all the unlocked tags a player has for their current server and globally. Also places the enabled tag into the enabled tag slot for the user + */ + public static Set<EventTag> fetchAndEquipServerPlayerTags(User user){ + Set<EventTag> tags = new HashSet<>(); + try (Connection connect = BaseDatabase.getInstance().getConnection()) { + + String query = "SELECT * FROM user_tag WHERE uuid=UNHEX(?) AND (server_key=? OR server_key=?);"; + + try (PreparedStatement statement = connect.prepareStatement(query)){ + statement.setString(1, user.getUUID().toString().replaceAll("-", "")); + statement.setString(2, "GLOBAL"); + statement.setString(3, Core.name().toUpperCase()); + try(ResultSet result = statement.executeQuery()) { + while (result.next()) { + EventTag tag = EventTag.valueOf(result.getString("tag")); + tags.add(tag); + if(result.getBoolean("enabled") && EventTagDAO.getTagVisibility(tag)!= TagVisibility.NO_ONE) + ServerUtil.runTask(() -> user.setEquipedTag(tag)); + } + } + } + } catch (SQLException e) { + Core.error("[UserDAO:fetchPlayerTags(uuid)] SQLException occurred"); + e.printStackTrace(); + return null; + } + return tags; + } + + /** + * @param uuid the uuid of the player + * @param credits the amount of credits to insert + */ + public static boolean updateCouponCredits(UUID uuid, int credits) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + CurrencyDAO.saveCurrency(connection, Currency.COUPON_CREDIT.getServerKey(), uuid, Currency.COUPON_CREDIT, credits); +// try (PreparedStatement statement = connection.prepareStatement("UPDATE `users` SET `couponCredits`=? WHERE `uuid`=?;")) { +// statement.setInt(1, credits); +// statement.setString(2, uuid.toString()); +// statement.execute(); +// } + } catch (SQLException e) { + Core.error("[UserDAO:updateCouponCredits(uuid,rank)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + + /** + * This method will fetch the server_stats related data.<br> + * (DailyPlayTime, PlayedServers, Etc..) + * + * @param user - user profile + * @return Whether the data were fetched + */ + public static boolean fetchServerStats(User user) { + long time = System.currentTimeMillis(); + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM `server_stats` WHERE `uuid`=?;")) { + statement.setString(1, user.getUUID().toString()); + try (ResultSet result = statement.executeQuery()) { + if (result.next()) { + user.dailyPlayTime = result.getLong("dailyPlayTime"); + + try (PreparedStatement statement2 = connection.prepareStatement("UPDATE `server_stats` SET `dailyLoginTime`=?,`playedServers`=?,`weeklyLoginTime`=? WHERE `uuid`=?;")) { + statement2.setLong(1, time); + + String playedServers = result.getString("playedServers"); + if (playedServers == null) + playedServers = Core.name(); + if (!playedServers.toLowerCase().contains(Core.name().toLowerCase())) + playedServers += Core.name(); + statement2.setString(2, playedServers); + + long weeklyLoginTime = result.getLong("weeklyLoginTime"); + weeklyLoginTime = weeklyLoginTime == 0 ? time : weeklyLoginTime; + statement2.setLong(3, weeklyLoginTime); + + statement2.setString(4, user.getUUID().toString()); + statement2.execute(); + } + } else { + try (PreparedStatement statement2 = connection.prepareStatement("INSERT INTO `server_stats`(`uuid`,`firstLogin`,`dailyLoginTime`,`dailyPlayTime`,`playedServers`,`weeklyLoginTime`) VALUES(?,?,?,?,?,?);")) { + statement2.setString(1, user.getUUID().toString()); + statement2.setLong(2, 0); + statement2.setLong(3, time); + statement2.setLong(4, 0); + statement2.setString(5, Core.name()); + statement2.setLong(6, time); + + user.dailyPlayTime = 0; + statement2.execute(); + } + } + } + } + } catch (SQLException e) { + Core.error("[UserDAO:fetchServerStats(user)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + /** + * This will update the users rank in the database only. + * + * @param uuid - Unique Identifier of the user + * @param rank - Rank to update to + * @return Whether the data updated + * + * @deprecated - Please see {@link #saveRank(Connection, String, UUID, UserRank)} for how to update a user rank properly. This exists for compatibility purposes only. + */ + @Deprecated + public static boolean updateUserRank(UUID uuid, UserRank rank) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + return saveRank(connection, rank.getServerKey(), uuid, rank); + } catch (SQLException e) { + Core.error("[UserDAO:updateUserRank(uuid,rank)] SQLException occurred"); + e.printStackTrace(); + return false; + } + } + + /** + * This will update the trial rank data in 'user_trial_rank' table only. + * <p> + * Note: If a player has a trial rank, this will delete their old one and add the new one. + * </p> + * + * @param uuid - Unique Identifier of the user + * @param rank - Rank of the trial (can be null) + * @param expiry - Time in milliseconds of the expiry + * @return Whether the data updated + * + * @deprecated - Please see {@link #createTrialRank(Connection, String, UUID, UserRank, Timestamp)} for how to update a trial rank properly. This exists for compatibility purposes only. + */ + @Deprecated + public static boolean updateUserTrialRank(UUID uuid, @Nullable UserRank rank, long expiry) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + + // grab the trial data + Pair<UserRank, Timestamp> trialData = getTrialRank(connection, rank.getServerKey(), uuid); + if (trialData != null){ + // remove old data + removeTrialRank(connection, rank.getServerKey(), uuid); + } + + return createTrialRank(connection, rank.getServerKey(), uuid, rank, new Timestamp(expiry)); + } catch (SQLException e) { + Core.error("[UserDAO:updateUserTrialRank(uuid,rank,expiry)] SQLException occurred"); + e.printStackTrace(); + return false; + } + } + + /** + * This fetch the amount of bucks from 'users' only. + * + * @param uuid - Unique Identifier of the user + * @return Whether the data updated + * + * @deprecated - possibly unused as money is per server and this isn't a global currency. + */ + @Deprecated + public static int fetchUserBucks(UUID uuid) { + int bucks = 0; + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT `bucks` FROM `users` WHERE `uuid`=?;")) { + statement.setString(1, uuid.toString()); + try (ResultSet result = statement.executeQuery()) { + if(result.next()) { + bucks = result.getInt("bucks"); + } + } + } + } catch (SQLException e) { + Core.error("[UserDAO:fetchUserBucks(uuid,bucks)] SQLException occurred"); + e.printStackTrace(); + return -1; + } + + return bucks; + } + + /** + * This fetch the amount of bucks from 'users' only. + * + * @param name - Name of the user + * @return Whether the data updated + * + * + * @deprecated - possibly unused as money is per server and this isn't a global currency. + */ + @Deprecated + public static int fetchUserBucksByName(String name) { + int bucks = 0; + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT `bucks` FROM `users` WHERE `lastname`=?;")) { + statement.setString(1, name); + try (ResultSet result = statement.executeQuery()) { + if(result.next()) { + bucks = result.getInt("bucks"); + } + } + } + } catch (SQLException e) { + Core.error("[UserDAO:fetchUserBucksByName(name,bucks)] SQLException occurred"); + e.printStackTrace(); + return -1; + } + + return bucks; + } + + /** + * This will update the amount of bucks in 'users' only. + * + * @param uuid - Unique Identifier of the user + * @param bucks - Amount of bucks + * @return Whether the data updated + * + * @deprecated - possibly unused as money is per server and this isn't a global currency. + */ + @Deprecated + public static boolean updateUserBucks(UUID uuid, int bucks) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `users` SET `bucks`=? WHERE `uuid`=?;")) { + statement.setInt(1, bucks); + statement.setString(2, uuid.toString()); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:updateUserBucks(uuid,bucks)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + /** + * This will update the amount of bucks in 'users' only. + * + * @param name - Name of the user + * @param bucks - Amount of bucks + * @return Whether the data updated + * + * @deprecated - possibly unused as money is per server and this isn't a global currency. + */ + @Deprecated + public static boolean updateUserBucksByName(String name, int bucks) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `users` SET `bucks`=? WHERE `lastname`=?;")) { + statement.setInt(1, bucks); + statement.setString(2, name); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:updateUserBucksByName(name,bucks)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + /** + * This will update the amount of bucks in 'users' only. + * + * @param name - Name of the user + * @param bucks - Amount of bucks + * @return Whether the data updated + * + * @deprecated - possibly unused as money is per server and this isn't a global currency. + */ + @Deprecated + public static boolean addUserBucksByName(String name, int bucks) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `users` SET `bucks`=bucks+? WHERE `lastname`=?;")) { + statement.setInt(1, bucks); + statement.setString(2, name); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:addUserBucksByName(name,bucks)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + /** + * This will update the amount of bucks in 'users' only. + * + * @param uuid - Unique Identifier of the user + * @param bucks - Amount of bucks + * @return Whether the data updated + * + * @deprecated - possibly unused as money is per server and this isn't a global currency. + */ + @Deprecated + public static boolean addUserBucks(UUID uuid, int bucks) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `users` SET `bucks`=bucks+? WHERE `uuid`=?;")) { + statement.setInt(1, bucks); + statement.setString(2, uuid.toString()); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:addUserBucks(uuid,bucks)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + /** + * This will update the amount of bucks in 'users' only. + * + * @param name - Name of the user + * @param bucks - Amount of bucks + * @return Whether the data updated + * + * @deprecated - possibly unused as money is per server and this isn't a global currency. + */ + @Deprecated + public static boolean subtractUserBucksByName(String name, int bucks) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `users` SET `bucks`=bucks-? WHERE `lastname`=?;")) { + statement.setInt(1, bucks); + statement.setString(2, name); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:subtractUserBucksByName(name,bucks)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + /** + * This will update the amount of bucks in 'users' only. + * + * @param uuid - Unique Identifier of the user + * @param bucks - Amount of bucks + * @return Whether the data updated + * + * @deprecated - possibly unused as money is per server and this isn't a global currency. + */ + @Deprecated + public static boolean subtractUserBucks(UUID uuid, int bucks) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `users` SET `bucks`=bucks-? WHERE `uuid`=?;")) { + statement.setInt(1, bucks); + statement.setString(2, uuid.toString()); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:subtractUserBucks(uuid,bucks)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + /** + * This will update the amount of tokens in 'user_currency' table. + * + * @param uuid - Unique Identifier of the user + * @param tokens - Amount of tokens + * @return Whether the data updated + * + * @deprecated - Please see CurrencyDAO for how to use this global currency. + */ + @Deprecated + public static boolean updateUserTokens(UUID uuid, int tokens) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + CurrencyDAO.saveCurrency(connection, Currency.TOKEN.getServerKey(), uuid, Currency.TOKEN, tokens); + } catch (SQLException e) { + Core.error("[UserDAO:updateUserTokens(uuid,tokens)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + /** + * This will update the amount of tokens in 'user_currency' table. + * + * @param name - Name of the user + * @param tokens - Amount of tokens + * @return Whether the data updated + * + * @deprecated - Please see CurrencyDAO for how to use this global currency. + */ + @Deprecated + public static boolean updateUserTokensByName(String name, int tokens) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + UUID uuid = UserDAO.getUuidByName(name); + if (uuid != null){ + CurrencyDAO.saveCurrency(connection, Currency.TOKEN.getServerKey(), uuid, Currency.TOKEN, tokens); + } + } catch (SQLException e) { + Core.error("[UserDAO:updateUserTokensByName(name,tokens)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + /** + * This will add to the amount of tokens in 'user_currency' table. + * + * @param uuid - Unique Identifier of the user + * @param tokens - Amount of tokens + * @return Whether the data updated + * + * @deprecated - Please see CurrencyDAO for how to use this global currency. + */ + @Deprecated + public static boolean addUserTokens(UUID uuid, int tokens) { + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + return CurrencyDAO.addCurrency(connection, Currency.TOKEN.getServerKey(), uuid, Currency.TOKEN, tokens); + } catch (SQLException e) { + Core.error("[UserDAO:addUserTokens(uuid,tokens)] SQLException occurred"); + e.printStackTrace(); + return false; + } + } + + /** + * This will add to the amount of tokens in 'user_currency' table. + * + * @param name - Name of the user + * @param tokens - Amount of tokens + * @return Whether the data updated + * + * @deprecated - Please see CurrencyDAO for how to use this global currency. + */ + @Deprecated + public static boolean addUserTokensByName(String name, int tokens) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + UUID uuid = UserDAO.getUuidByName(name); + if (uuid != null){ + return CurrencyDAO.addCurrency(connection, Currency.TOKEN.getServerKey(), uuid, Currency.TOKEN, tokens); + } + } catch (SQLException e) { + Core.error("[UserDAO:addUserTokens(name,tokens)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + /** + * This will subtract to the amount of tokens in 'user_currency' table. + * + * @param uuid - Unique Identifier of the user + * @param tokens - Amount of tokens + * @return Whether the data updated + * + * @deprecated - Please see CurrencyDAO for how to use this global currency. + */ + @Deprecated + public static boolean subtractUserTokens(UUID uuid, int tokens) { + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + return CurrencyDAO.addCurrency(connection, Currency.TOKEN.getServerKey(), uuid, Currency.TOKEN, -1 * tokens); + } catch (SQLException e) { + Core.error("[UserDAO:subtractUserTokens(uuid,tokens)] SQLException occurred"); + e.printStackTrace(); + return false; + } + } + + /** + * This will subtract to the amount of tokens in 'user_currency' table. + * + * @param name - Name of the user + * @param tokens - Amount of tokens + * @return Whether the data updated + * + * @deprecated - Please see CurrencyDAO for how to use this global currency. + */ + @Deprecated + public static boolean subtractUserTokensByName(String name, int tokens) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + UUID uuid = UserDAO.getUuidByName(name); + if (uuid != null){ + return CurrencyDAO.addCurrency(connection, Currency.TOKEN.getServerKey(), uuid, Currency.TOKEN, -1 * tokens); + } + } catch (SQLException e) { + Core.error("[UserDAO:subtractUserTokensByName(name,tokens)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + /** + * This will subtract to the amount of tokens in 'user_currency' table. + * + * @param uuid - Unique Identifier of the user + * @return Whether the data updated + * + * @deprecated - Please see CurrencyDAO for how to use this global currency. + */ + @Deprecated + public static int getUserTokens(UUID uuid) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + return CurrencyDAO.getCurrency(connection, Currency.TOKEN.getServerKey(), uuid, Currency.TOKEN); + } catch (SQLException e) { + Core.error("[UserDAO:getUserTokens(uuid)] SQLException occurred"); + e.printStackTrace(); + return -1; + } + } + + /** + * This will subtract to the amount of tokens in 'user_currency' table. + * + * @param name - Name of the user + * @return Whether the data updated + * + * @deprecated - Please see CurrencyDAO for how to use this global currency. + */ + @Deprecated + public static int getUserTokensByName(String name) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + UUID uuid = UserDAO.getUuidByName(name); + if (uuid != null){ + return CurrencyDAO.getCurrency(connection, Currency.TOKEN.getServerKey(), uuid, Currency.TOKEN); + } + } catch (SQLException e) { + Core.error("[UserDAO:getUserTokensByName(name)] SQLException occurred"); + e.printStackTrace(); + } + + return -1; + } + + /** + * This will update the amount of crowbars in 'user_currency' table. + * + * @param uuid - Unique Identifier of the user + * @param crowbars - Amount of crowbars + * @return Whether the data updated + * + * @deprecated - Please see CurrencyDAO for how to use this global currency. + */ + @Deprecated + public static boolean updateUserCrowbars(UUID uuid, int crowbars) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + return CurrencyDAO.saveCurrency(connection, Currency.CROWBAR.getServerKey(), uuid, Currency.CROWBAR, crowbars); + } catch (SQLException e) { + Core.error("[UserDAO:updateUserCrowbars(uuid,crowbars)] SQLException occurred"); + e.printStackTrace(); + return false; + } + } + + /** + * This will update the amount of crowbars in 'user_currency' table. + * + * @param name - Name of the user + * @param crowbars - Amount of crowbars + * @return Whether the data updated + * + * @deprecated - Please see CurrencyDAO for how to use this global currency. + */ + @Deprecated + public static boolean updateUserCrowbarsByName(String name, int crowbars) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + + UUID uuid = UserDAO.getUuidByName(name); + if (uuid != null){ + return CurrencyDAO.saveCurrency(connection, Currency.CROWBAR.getServerKey(), uuid, Currency.CROWBAR, crowbars); + } + } catch (SQLException e) { + Core.error("[UserDAO:updateUserCrowbarsByName(name,crowbars)] SQLException occurred"); + e.printStackTrace(); + } + + return false; + } + + /** + * This will add to the amount of crowbars in 'user_currency' table. + * + * @param uuid - Unique Identifier of the user + * @param crowbars - Amount of crowbars + * @return Whether the data updated + * + * @deprecated - Please see CurrencyDAO for how to use this global currency. + */ + @Deprecated + public static boolean addUserCrowbars(UUID uuid, int crowbars) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + return CurrencyDAO.addCurrency(connection, Currency.CROWBAR.getServerKey(), uuid, Currency.CROWBAR, crowbars); + } catch (SQLException e) { + Core.error("[UserDAO:addUserCrowbars(uuid,crowbars)] SQLException occurred"); + e.printStackTrace(); + } + + return false; + } + + /** + * This will add to the amount of crowbars in 'user_currency' table. + * + * @param name - Name of the user + * @param crowbars - Amount of crowbars + * @return Whether the data updated + * + * @deprecated - Please see CurrencyDAO for how to use this global currency. + */ + @Deprecated + public static boolean addUserCrowbarsByName(String name, int crowbars) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + UUID uuid = UserDAO.getUuidByName(name); + if (uuid != null){ + return CurrencyDAO.addCurrency(connection, Currency.CROWBAR.getServerKey(), uuid, Currency.CROWBAR, crowbars); + } + } catch (SQLException e) { + Core.error("[UserDAO:addUserCrowbarsByName(name,crowbars)] SQLException occurred"); + e.printStackTrace(); + } + + return false; + } + + /** + * This will subtract to the amount of crowbars in 'user_currency' table. + * + * @param uuid - Unique Identifier of the user + * @param crowbars - Amount of crowbars + * @return Whether the data updated + * + * @deprecated - Please see CurrencyDAO for how to use this global currency. + */ + @Deprecated + public static boolean subtractUserCrowbars(UUID uuid, int crowbars) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + return CurrencyDAO.addCurrency(connection, Currency.CROWBAR.getServerKey(), uuid, Currency.CROWBAR, -1 * crowbars); + } catch (SQLException e) { + Core.error("[UserDAO:subtractUserCrowbars(uuid,crowbars)] SQLException occurred"); + e.printStackTrace(); + } + + return false; + } + + /** + * This will subtract to the amount of crowbars in 'user_currency' table. + * + * @param name - Name of the user + * @param crowbars - Amount of crowbars + * @return Whether the data updated + * + * @deprecated - Please see CurrencyDAO for how to use this global currency. + */ + @Deprecated + public static boolean subtractUserCrowbarsByName(String name, int crowbars) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + UUID uuid = UserDAO.getUuidByName(name); + if (uuid != null){ + return CurrencyDAO.addCurrency(connection, Currency.CROWBAR.getServerKey(), uuid, Currency.CROWBAR, -1 * crowbars); + } + } catch (SQLException e) { + Core.error("[UserDAO:subtractUserCrowbarsByName(name,crowbars)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + /** + * This will get the amount of crowbars in 'user_currency' table. + * + * @param uuid - Unique Identifier of the user + * @return Whether the data updated + * + * @deprecated - Please see CurrencyDAO for how to use this global currency. + */ + @Deprecated + public static int getUserCrowbars(UUID uuid) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + return CurrencyDAO.getCurrency(connection, Currency.CROWBAR.getServerKey(), uuid, Currency.CROWBAR); + } catch (SQLException e) { + Core.error("[UserDAO:getUserCrowbars(uuid,crowbars)] SQLException occurred"); + e.printStackTrace(); + return -1; + } + } + + /** + * This will get the amount of crowbars in 'user_currency' table. + * + * @param name - Name of the user + * @return Whether the data updated + * + * @deprecated - Please see CurrencyDAO for how to use this global currency. + */ + @Deprecated + public static int getUserCrowbarsByName(String name) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + UUID uuid = UserDAO.getUuidByName(name); + if (uuid != null){ + return CurrencyDAO.getCurrency(connection, Currency.CROWBAR.getServerKey(), uuid, Currency.CROWBAR); + } + } catch (SQLException e) { + Core.error("[UserDAO:getUserCrowbarsByName(name,crowbars)] SQLException occurred"); + e.printStackTrace(); + } + + return -1; + } + + public static boolean updateUserPref(UUID uuid, Pref pref, boolean status) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `users` SET `" + pref.getDbName() + "`=? WHERE `uuid`=?;")) { + statement.setBoolean(1, status); + statement.setString(2, uuid.toString()); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:updateUserPref(uuid,pref,status)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean updateUserNametag(UUID uuid, String nametag, boolean add) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `nametags` SET `" + nametag + "`=? WHERE `uuid`=?;")) { + statement.setInt(1, add ? 1 : 0); + statement.setString(2, uuid.toString()); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:updateUserNametag(uuid,nametag,add)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean updateUserLastDonorReward(UUID uuid, String lastDonorReward) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `users` SET `lastDonorReward`=? WHERE `uuid`=?;")) { + statement.setString(1, lastDonorReward); + statement.setString(2, uuid.toString()); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:updateUserLastDonorReward(uuid,lastDonorReward)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean updateUserLastDonorRewardByName(String name, long lastDonorReward) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `users` SET `lastDonorReward`=? WHERE `lastname`=?;")) { + statement.setLong(1, lastDonorReward); + statement.setString(2, name); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:updateUserLastDonorReward(uuid,lastDonorReward)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean updateUserIgnore(UUID uuid, String ignore) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `users` SET `ignored`=? WHERE `uuid`=?;")) { + statement.setString(1, ignore); + statement.setString(2, uuid.toString()); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:updateUserIgnore(uuid,ignore)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean updateUnlockedAchievements(UUID uuid, String unlockedAchievements) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `users` SET `unlockedAchievements`=? WHERE `uuid`=?;")) { + statement.setString(1, unlockedAchievements); + statement.setString(2, uuid.toString()); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:updateUnlockedAchievements(uuid,unlockedAchievements)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean updateShownAchievement(UUID uuid, String achievement) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `users` SET `shownAchievement`=? WHERE `uuid`=?;")) { + statement.setString(1, achievement); + statement.setString(2, uuid.toString()); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:updateShownAchievement(uuid,achievement)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + /** + * Note: This defaults to lookup the serverKey based on the serverKey of the "DEFAULT" rank. + * + * @deprecated - Please see {@link #getRank(Connection, String, UUID)} for how to get a user rank properly. This exists for compatibility purposes only. + */ + @Deprecated + public static UserRank fetchUserRank(UUID uuid) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + return getRank(connection, UserRank.DEFAULT.getServerKey(), uuid); + } catch (SQLException e) { + Core.error("[UserDAO:fetchUserRank(uuid)] SQLException occurred"); + e.printStackTrace(); + return UserRank.DEFAULT; + } + } + + public static int countUsers() { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT COUNT(1) AS rowcount FROM `users`;")) { + try (ResultSet result = statement.executeQuery()) { + if (result.next()) + return result.getInt("rowcount"); + } + } + } catch (SQLException e) { + Core.error("[UserDAO:countUsers()] SQLException occurred"); + e.printStackTrace(); + return 0; + } + + return 0; + } + + public static boolean isLastMonthsVoteWinner(String name) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM `last_months_voters` WHERE `name`=?;")) { + statement.setString(1, name); + try (ResultSet result = statement.executeQuery()) { + return result.next(); + } + } + } catch (SQLException e) { + Core.error("[UserDAO:isLastMonthsVoteWinner(name)] SQLException occurred"); + e.printStackTrace(); + return false; + } + } + + /** + * @deprecated - Please see {@link #saveRank(Connection, String, UUID, UserRank)} for how to save a user rank properly. This exists for compatibility purposes only. + */ + @Deprecated + public static boolean updateRankByName(String name, UserRank rank) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + + UUID uuid = getUuidByName(name); + if (uuid != null){ + return saveRank(connection, rank.getServerKey(), uuid, rank); + } + } catch (SQLException e) { + Core.error("[UserDAO:updateRankByName(name,rank)] SQLException occurred"); + e.printStackTrace(); + } + + return false; + } + + /** + * @deprecated - Please see {@link #saveRank(Connection, String, UUID, UserRank)} for how to save a user rank properly. This exists for compatibility purposes only. + */ + @Deprecated + public static boolean updateRankByNameAndRank(String name, UserRank from, UserRank to) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + + UUID uuid = getUuidByName(name); + if (uuid != null){ + // Note: This might not be the correct way of implementation for new system + return saveRank(connection, to.getServerKey(), uuid, to); + } + } catch (SQLException e) { + Core.error("[UserDAO:updateRankByNameAndRank(name,from,to)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean isUserBanned(String uuid) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM `BAT_ban` WHERE `UUID`=?;")) { + statement.setString(1, uuid); + try (ResultSet result = statement.executeQuery()) { + return result.next() && result.getBoolean("ban_state"); + } + } + } catch (SQLException e) { + Core.error("[UserDAO:isUserBanned(uuid)] SQLException occurred"); + e.printStackTrace(); + return false; + } + } + + /** + * @deprecated due to database table changes, and therefore this method may not work. This method may not even be used. + */ + @Deprecated + public static boolean reset(String name) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `users` SET `tokens`=0,`bucks`=0,`votes`=0,`voteStreak`=0,`lastVoteStreak`=0,`dailyStreak`=0,`lastDailyReward`=0,`lastDonorReward`=0 WHERE `lastname`=?;")) { + statement.setString(1, name); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:reset(name)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + /** + * Get the UUID of a user based off their name. + * + * @param conn - the database connection thread + * @param name - the name of the user + * + * @return The UUID that was found for the given name, + * if more than one record exists, we return the first instance, + * and log an error message. If none are found, we return null. + */ + public static UUID getUUID(Connection conn, String name) { + + String query = "SELECT HEX(uuid) AS uuid FROM user WHERE name=?"; + UUID uuid = null; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setString(1, name); + + try (ResultSet result = ps.executeQuery()) { + if (result.next()) { + + // change from HEX into UUID object + uuid = UUIDUtil.createUUID(result.getString("uuid")).orElse(null); + + // safe check to see if there's more than one result + if (result.next()) { + Core.error("[UserDAO:getUuidByName(name)] There exists more than one user with the name: " + name); + } + } + } + } + catch (SQLException e) { + Core.error("[UserDAO:getUuidByName(name)] SQLException occurred"); + e.printStackTrace(); + } + + return uuid; + } + + /** + * Get the UUID of a user based off their name. + * + * @param name - the name of the user + * + * @return The UUID that was found for the given name, + * if more than one record exists, we return the first instance, + * and log an error message. If none are found, we return null. + * @deprecated - Please use {@link #getUUID(Connection, String)} instead. + */ + @Deprecated + public static UUID getUuidByName(String name) { + + try (Connection conn = BaseDatabase.getInstance().getConnection()) { + return getUUID(conn, name); + } + catch (SQLException e) { + Core.error("[UserDAO:getUuidByName(name)] SQLException occurred"); + e.printStackTrace(); + } + + return null; + } + + /** + * Get the name of the user with the specified uuid. + * + * @param conn - the database connection thread + * @param uuid - the uuid of the user to get the name of + * + * @return The string representation of the name for the user with the given uuid. + */ + public static String getName(Connection conn, UUID uuid) { + + String query = "SELECT name FROM user WHERE uuid=UNHEX('" + uuid.toString().replaceAll("-", "") + "')"; + + try (ResultSet result = conn.createStatement().executeQuery(query)) { + if (result.next()) { + String username = result.getString(1); + return username; + } + } + catch (SQLException e) { + Core.error("[UserDAO:getNameByUuid(uuid)] SQLException occurred"); + e.printStackTrace(); + } + + return null; + } + + /** + * Get the name of the user with the specified uuid. + * + * @param uuid - the uuid of the user to get the name of + * + * @return The string representation of the name for the user with the given uuid. + * @deprecated - Please use {@link #getName(Connection, UUID)} instead. + */ + @Deprecated + public static String getNameByUuid(UUID uuid) { + + String query = "SELECT name FROM user WHERE uuid=UNHEX('" + uuid.toString().replaceAll("-", "") + "')"; + + try (Connection conn = BaseDatabase.getInstance().getConnection()) { + return getName(conn, uuid); + } + catch (SQLException e) { + Core.error("[UserDAO:getNameByUuid(uuid)] SQLException occurred"); + e.printStackTrace(); + } + + return null; + } + + public static boolean deleteFromByName(String name, String table) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("DELETE FROM `" + table + "` WHERE `name`=?;")) { + statement.setString(1, name); + statement.execute(); + } + } catch (SQLException e) { + Core.error("[UserDAO:deleteFromByName(name,table)] SQLException occurred"); + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean updateCountry(UUID uuid, String country) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE users SET `country`=? WHERE `uuid`=?;")) { + statement.setString(1, country); + statement.setString(2, uuid.toString()); + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean updateUserLocation(UUID uuid, CoreLocation location) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO user_location " + + "(uuid, country, city, country_code, isp, latitude, longitude, region, region_name, timezone, zip) " + + "VALUES " + + "(UNHEX(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) " + + "ON DUPLICATE KEY UPDATE " + + "country = ?, " + + "city = ?, " + + "country_code = ?, " + + "isp = ?, " + + "latitude = ?, " + + "longitude = ?, " + + "region = ?, " + + "region_name = ?, " + + "timezone = ?, " + + "zip = ?" + + ";") + ) { + statement.setString(1, uuid.toString().replaceAll("-", "")); + statement.setString(2, trimToSize(location.getCountry(), 16)); + statement.setString(3, trimToSize(location.getCity(), 16)); + statement.setString(4, trimToSize(location.getCountryCode(), 6)); + statement.setString(5, trimToSize(location.getIsp(), 16)); + statement.setString(6, trimToSize(location.getLat(), 10)); + statement.setString(7, trimToSize(location.getLon(), 10)); + statement.setString(8, trimToSize(location.getRegion(), 8)); + statement.setString(9, trimToSize(location.getRegionName(), 16)); + statement.setString(10, trimToSize(location.getTimezone(), 16)); + statement.setString(11, trimToSize(location.getZip(), 10)); + statement.setString(12, trimToSize(location.getCountry(), 16)); + statement.setString(13, trimToSize(location.getCity(), 16)); + statement.setString(14, trimToSize(location.getCountryCode(), 5)); + statement.setString(15, trimToSize(location.getIsp(), 16)); + statement.setString(16, trimToSize(location.getLat(), 10)); + statement.setString(17, trimToSize(location.getLon(), 10)); + statement.setString(18, trimToSize(location.getRegion(), 8)); + statement.setString(19, trimToSize(location.getRegionName(), 16)); + statement.setString(20, trimToSize(location.getTimezone(), 16)); + statement.setString(21, trimToSize(location.getZip(), 10)); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static CoreLocation getUserLocation(UUID uuid) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM user_location WHERE uuid=UNHEX(?);")) { + statement.setString(1, uuid.toString().replaceAll("-", "")); + + try (ResultSet result = statement.executeQuery()) { + if (result.next()) { + CoreLocation location = new CoreLocation(); + location.setCountry(result.getString("country")); + location.setCountry(result.getString("city")); + location.setCountry(result.getString("country_code")); + location.setCountry(result.getString("isp")); + location.setCountry(result.getString("latitude")); + location.setCountry(result.getString("longitude")); + location.setCountry(result.getString("region")); + location.setCountry(result.getString("region_name")); + location.setCountry(result.getString("timezone")); + location.setCountry(result.getString("zip")); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + + return null; + } + + private static String trimToSize(String input, int size) { + if (input.length() <= size) return input; + return input.substring(0, size); + } + + public static boolean updateLanguage(UUID uuid, String language) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE users SET `language`=? WHERE `uuid`=?;")) { + statement.setString(1, language); + statement.setString(2, uuid.toString()); + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static String[] getCountryAndLanguage(UUID uuid) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT `country`,`language` FROM users WHERE `uuid`=?;")) { + statement.setString(1, uuid.toString()); + try (ResultSet result = statement.executeQuery()) { + if(result.next()) { + return new String[]{result.getString("country"), result.getString("language")}; + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + + return null; + } + + /** + * Get the rank of the specified user on the given server_key. + * + * @param conn - the database connection thread + * @param serverKey - the server key + * @param uuid - the uuid of the user to get the rank for + * + * @return The rank of the user, if they have a rank, otherwise {@code null}. + */ + public static UserRank getRank(Connection conn, String serverKey, UUID uuid){ + + String query = "SELECT rank FROM user_profile WHERE uuid=UNHEX(?) AND server_key=?;"; + + try (PreparedStatement ps = conn.prepareStatement(query)){ + ps.setString(1, uuid.toString().replaceAll("-", "")); + ps.setString(2, serverKey); + + try (ResultSet result = ps.executeQuery()){ + if (result.next()){ + return UserRank.getUserRankOrNull(result.getString("rank")); + } + } + } + catch (SQLException exc) { + Core.log("[UserDAO] Error attempting to getRank() for serverKey=" + serverKey + ", uuid=" + uuid.toString()); + exc.printStackTrace(); + } + + return null; + } + + /** + * Get the highest rank we know about for this user on the global or server specific scale. + * <p> + * Note: This exists purely as a helper method and only should + * be suitable for if you read the method implementation. This + * makes two calls to getRank() with "GLOBAL" and the SERVERKEY + * of this plugin to determine which is higher. + * </p> + * + * @param conn - the database connection thread + * @param uuid - the uuid of the user + * + * @return The highest rank, if any were found, for the specified user uuid. + */ + public static UserRank getHighestRank(Connection conn, UUID uuid){ + + UserRank globalRank = getRank(conn, "GLOBAL", uuid); + UserRank localRank = getRank(conn, Core.name().toUpperCase(), uuid); + + UserRank highest = null; + + // init highest if we can + if (globalRank != null){ + highest = globalRank; + } + + // if local rank found + if (localRank != null){ + // if no highest yet, this is default highest + if (highest == null || localRank.isHigherThan(highest)){ + highest = localRank; + } + } + + return highest; + } + + /** + * Updates the rank of the user uuid in the database for the specified serverKey. + * <p> + * Note: The user rank must already exist for this to happen. + * </p> + * + * @param conn - the database connection thread + * @param serverKey - the server key + * @param uuid - the uuid of the user to save the rank for + * @param rank - the rank to save + * + * @return {@code true} if the query ran, {@code false} otherwise. + */ + public static boolean saveRank(Connection conn, String serverKey, UUID uuid, UserRank rank){ + + //String query = "UPDATE user_profile SET rank=? WHERE uuid=UNHEX(?) AND server_key=?;"; + String query = "INSERT IGNORE INTO user_profile (uuid, server_key, rank) VALUES (UNHEX(?), ?, ?) ON DUPLICATE KEY UPDATE rank=VALUES(rank);"; + + try (PreparedStatement ps = conn.prepareStatement(query)){ + ps.setString(1, uuid.toString().replaceAll("-", "")); + ps.setString(2, serverKey); + ps.setString(3, rank.getName()); + + ps.executeUpdate(); + return true; + } + catch (SQLException exc) { + Core.log("[UserDAO] Error attempting to saveRank() for serverKey=" + serverKey + ", uuid=" + uuid.toString() + ", rank=" + rank.getName()); + exc.printStackTrace(); + return false; + } + } + + /** + * Creates a new entry in the user_profile table for a user with the specified rank on the specified server key. + * + * @param conn - the database connection thread + * @param serverKey - the key of the server + * @param uuid - the uuid of the user + * @param rank - the rank for that user + * + * @return {@code true} if the create query ran, {@code false} otherwise. + */ + public static boolean createRank(Connection conn, String serverKey, UUID uuid, UserRank rank){ + + // if ANY rank exists already + boolean rankExists = false; + + String existQuery = "SELECT rank FROM user_profile WHERE uuid=UNHEX(?) AND server_key=?"; + try (PreparedStatement ps = conn.prepareStatement(existQuery)){ + ps.setString(1, uuid.toString().replaceAll("-", "")); + ps.setString(2, serverKey); + + try (ResultSet result = ps.executeQuery()){ + if (result.next()){ + UserRank ur = UserRank.getUserRankOrNull(result.getString("rank")); + if (ur != null){ + rankExists = true; + } + } + } + } + catch (SQLException exc) { + Core.log("[UserDAO] Error attempting to createRank(EXISTS) for serverKey=" + serverKey + ", uuid=" + uuid.toString() + ", rank=" + rank.getName()); + exc.printStackTrace(); + return false; + } + + // if it doesn't exist in db yet + if (!rankExists){ + + String query = "INSERT INTO user_profile (uuid, server_key, rank) VALUES (UNHEX(?), ?, ?);"; + + try (PreparedStatement ps = conn.prepareStatement(query)){ + ps.setString(1, uuid.toString().replaceAll("-", "")); + ps.setString(2, serverKey); + ps.setString(3, rank.getName()); + + ps.executeUpdate(); + return true; + } + catch (SQLException exc) { + Core.log("[UserDAO] Error attempting to createRank(CREATE) for serverKey=" + serverKey + ", uuid=" + uuid.toString() + ", rank=" + rank.getName()); + exc.printStackTrace(); + return false; + } + } + + return false; + } + + /** + * Deletes a rank entry for the specified user, on the specified server key, with the specified rank. + * <p> + * If they do not have the given rank on the specific server key, nothing will happen. + * </p> + * + * @param conn - the database connection thread + * @param serverKey - the key of the server + * @param uuid - the uuid of the user + * @param rank - the rank for that user + * + * @return {@code true} if the create query ran, {@code false} otherwise. + */ + public static boolean deleteRank(Connection conn, String serverKey, UUID uuid, UserRank rank){ + + String query = "DELETE FROM user_profile WHERE uuid=UNHEX(?) AND server_key=? AND rank=?;"; + + try (PreparedStatement ps = conn.prepareStatement(query)){ + ps.setString(1, uuid.toString().replaceAll("-", "")); + ps.setString(2, serverKey); + ps.setString(3, rank.getName()); + + ps.executeUpdate(); + return true; + } + catch (SQLException exc) { + Core.log("[UserDAO] Error attempting to deleteRank() for serverKey=" + serverKey + ", uuid=" + uuid.toString() + ", rank=" + rank.getName()); + exc.printStackTrace(); + return false; + } + } + + /** + * Get the trial rank for the specified user. + * + * @param conn - the database connection thread + * @param serverKey - the server key lookup + * @param uuid - the uuid of the user to lookup + * + * @return The pair that represents their trial rank, and when it expires, if one exists. + */ + public static Pair<UserRank, Timestamp> getTrialRank(Connection conn, String serverKey, UUID uuid){ + + String query = "SELECT rank, expire_at FROM user_trial_rank WHERE uuid=UNHEX(?) AND server_key=?;"; + + try (PreparedStatement ps = conn.prepareStatement(query)){ + ps.setString(1, uuid.toString().replaceAll("-", "")); + ps.setString(2, serverKey); + + try (ResultSet result = ps.executeQuery()){ + if (result.next()){ + UserRank trialRank = UserRank.getUserRankOrNull(result.getString("rank")); + if (trialRank != null){ + Timestamp expireAt = result.getTimestamp("expire_at"); + return Pair.of(trialRank, expireAt); + } + } + } + } + catch (SQLException exc) { + Core.log("[UserDAO] Error attempting to getTrialRank() for serverKey=" + serverKey + ", uuid=" + uuid.toString()); + exc.printStackTrace(); + } + + return null; + } + + public static void saveTrialRank(Connection conn, String serverKey, UUID uuid, UserRank trialRank, Timestamp expireAt){ + + // TODO is this even needed? + } + + /** + * Creates a trial rank record in the database for the specified user/serverKey combo. + * <p> + * Note: This query will fail if the user already has a trial rank in the database for that serverKey. + * </p> + * + * @param conn - the database connection thread + * @param serverKey - the server key to update + * @param uuid - the uuid of the user + * @param trialRank - the trial rank they have + * @param expireAt - when the rank expires + * + * @return {@code true} if the trial rank query ran, {@code false} otherwise. + */ + public static boolean createTrialRank(Connection conn, String serverKey, UUID uuid, UserRank trialRank, Timestamp expireAt){ + + String query = "INSERT INTO user_trial_rank (uuid, server_key, rank, expire_at) VALUES (UNHEX(?), ?, ?, ?);"; + + try (PreparedStatement ps = conn.prepareStatement(query)){ + ps.setString(1, uuid.toString().replaceAll("-", "")); + ps.setString(2, serverKey); + ps.setString(3, trialRank.getName()); + ps.setTimestamp(4, expireAt); + + ps.executeUpdate(); + return true; + } + catch (SQLException exc) { + Core.log("[UserDAO] Error attempting to createTrialRank() for serverKey=" + serverKey + ", uuid=" + uuid.toString() + ", trialRank=" + trialRank.getName() + ", expireAt=" + expireAt); + exc.printStackTrace(); + return false; + } + } + + /** + * Removes the trial rank for the specified uuid on the server key. + * + * @param conn - the database connection thread + * @param serverKey - the server key to delete it for + * @param uuid - the uuid of the user to remove + * + * @return {@code true} if the query ran, {@code false} otherwise. + */ + public static boolean removeTrialRank(Connection conn, String serverKey, UUID uuid){ + + String query = "DELETE FROM user_trial_rank WHERE uuid=UNHEX(?) AND server_key=?;"; + + try (PreparedStatement ps = conn.prepareStatement(query)){ + ps.setString(1, uuid.toString().replaceAll("-", "")); + ps.setString(2, serverKey); + + ps.executeUpdate(); + return true; + } + catch (SQLException exc) { + Core.log("[UserDAO] Error attempting to removeTrialRank() for serverKey=" + serverKey + ", uuid=" + uuid.toString()); + exc.printStackTrace(); + return false; + } + } + + /** + * Remove all expired trial ranks from the "user_trial_rank" table. + * <p> + * Note: This is a costly query if there are a lot of trial ranks, so we should run this periodically. + * </p> + * + * @param conn - the database connection thread + * + * @return {@code true} if the query ran, {@code false} otherwise. + */ + public static boolean removeAllExpiredTrialRanks(Connection conn){ + + String query = "DELETE FROM user_trial_rank WHERE expire_at < NOW();"; + + try (PreparedStatement ps = conn.prepareStatement(query)){ + ps.executeUpdate(); + return true; + } + catch (SQLException exc) { + Core.log("[UserDAO] Error attempting to removeAllExpiredTrialRanks()"); + exc.printStackTrace(); + return false; + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/UserManager.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/UserManager.java new file mode 100644 index 0000000..c15e24e --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/UserManager.java @@ -0,0 +1,194 @@ +package net.grandtheftmc.core.users; + +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +import net.grandtheftmc.core.Core; + +public class UserManager { + + /** Singleton of this class */ + private static UserManager instance; + /** Mapping of uuid to user objects */ + private final Map<UUID, User> users = new ConcurrentHashMap<>(); + + /** + * Private constructor since singletons cannot be initialized + */ + private UserManager() { + } + + /** + * Gets the instance of the singleton. + * + * @return The singleton of this class. + */ + public static UserManager getInstance() { + if (instance == null) { + instance = new UserManager(); + } + + return instance; + } + + /** + * Add a new user to the container. + * + * @param user - the user to add + * + * @return {@code true} if the user was successfully added, {@code false} if + * the user already exists. + */ + public boolean addUser(User user) { + if (!users.containsKey(user.getUUID())) { + // TODO debug remove + Core.log("[UserManager] Adding new user to UserManager, uuid=" + user.getUUID() + ", name=" + user.getName()); + users.put(user.getUUID(), user); + return true; + } + + return false; + } + + /** + * Get whether or not the container has a user with the specified uuid. + * + * @param uuid - the uuid to lookup + * + * @return {@code true} if the user exists already in the container, + * {@code false} otherwise. + */ + public boolean hasUser(UUID uuid) { + if (users.containsKey(uuid)) { + return true; + } + + return false; + } + + /** + * Get whether or not the container has a user with the specified name. + * + * @param name - the name to lookup + * + * @return {@code true} if the user exists already in the container, + * {@code false} otherwise. + */ + public boolean hasUser(String name) { + + for (User user : users.values()) { + if (user.getName().equalsIgnoreCase(name)) { + return true; + } + } + + return false; + } + + /** + * Get the user with the specified uuid from the container. + * + * @param uuid - the uuid to lookup + * + * @return The user with the specified uuid, if one exists, otherwise empty. + */ + public Optional<User> getUser(UUID uuid) { + if (users.containsKey(uuid)) { + return Optional.of(users.get(uuid)); + } + + return Optional.empty(); + } + + /** + * Get the user with the specified name from the container. + * + * @param name - the name to lookup + * + * @return The user with the specified name, if one exists, otherwise empty. + */ + public Optional<User> getUser(String name) { + for (User user : users.values()) { + if (user.getName().equalsIgnoreCase(name)) { + return Optional.of(user); + } + } + + return Optional.empty(); + } + + /** + * Removes the user with the specified uuid. + * + * @param uuid - the uuid of the user to remove + * + * @return The user that was removed, if one was found, otherwise empty. + */ + public Optional<User> removeUser(UUID uuid) { + if (users.containsKey(uuid)) { + // TODO debug remove + Core.log("[UserManager] Removing user from UserManager, uuid=" + uuid.toString()); + return Optional.of(users.remove(uuid)); + } + + return Optional.empty(); + } + + /** + * Removes the user with the specified name. + * + * @param name - the name of the user to remove + * + * @return The user that was removed, if one was found, otherwise empty. + */ + public Optional<User> removeUser(String name) { + + // lookup user + User user = getUser(name).orElse(null); + + if (user != null) { + if (users.containsKey(user.getUUID())) { + return Optional.of(users.remove(user.getUUID())); + } + } + + return Optional.empty(); + } + + /** + * Get all users in this container. + * + * @return {@link Collection} of {@link User}s inside this container. + */ + public Collection<User> getUsers() { + return Collections.unmodifiableCollection(users.values()); + } + + /** + * A wrapper around {@link Map#size()}. + * + * @return The size of the collection that contains the users. + */ + public int size() { + return users.size(); + } + + /** + * Get the user from this manager. + * + * @param uuid - the uuid of the user to lookup + * + * @return The user from this manager, if one is found. + * + * @deprecated - Please use {@link #getUser(UUID)}} instead as the result + * can be {@code null} + */ + @Deprecated + public User getLoadedUser(UUID uuid) { + return getUser(uuid).orElse(null); + } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/UserRank.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/UserRank.java new file mode 100644 index 0000000..7432b42 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/UserRank.java @@ -0,0 +1,315 @@ +package net.grandtheftmc.core.users; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.Utils; +import org.bukkit.Material; + +import java.util.Objects; + +public enum UserRank { + + DEFAULT("&8", "DEFAULT"), VIP("&6", "VIP"), PREMIUM("&a", "PREMIUM"), ELITE("&b", "ELITE"), SPONSOR("&5", "SPONSOR"), SUPREME("&c", "SUPREME"), YOUTUBER("&r", "YOUTUBER"), + BUILDTEAM("&3","BUILDTEAM"), HELPOP("&d", "HELPER"), MOD("&9", "MOD"), SRMOD("&9", "SRMOD"), BUILDER("&f", "BUILDER"), ADMIN("&c", "ADMIN"), DEV("&9", "DEV"), MANAGER("&4", "MANAGER"), OWNER("&4", "OWNER"); + + private final String color; + private final String displayName; + /** The server_key that this rank is for */ + private String serverKey; + + UserRank(String color, String displayName) { + this.color = color; + this.displayName = displayName; + } + + public static UserRank[] getUserRanks() { + return UserRank.class.getEnumConstants(); + } + + public static UserRank getUserRank(String name) { + if (name == null) + return UserRank.DEFAULT; + for (UserRank ur : getUserRanks()) + if (ur.getName().equalsIgnoreCase(name)) + return ur; + return UserRank.DEFAULT; + } + + public static UserRank getUserRankOrNull(String name) { + if (name == null) + return null; + for (UserRank ur : getUserRanks()) + if (ur.getName().equalsIgnoreCase(name)) + return ur; + return null; + } + + public static UserRank getUserRankExact(String name) { + if (name == null) + return null; + for (UserRank ur : getUserRanks()) + if (ur.getName().equalsIgnoreCase(name)) + return ur; + return null; + } + + public static UserRank getUserRank(Material type) { + if (type == null) + return null; + for (UserRank ur : getUserRanks()) + if (ur.getMaterial() == type) + return ur; + return null; + } + + public static UserRank[] getDonorRanks() { + return new UserRank[]{VIP, PREMIUM, ELITE, SPONSOR, SUPREME}; + } + + public String getName() { + return this.toString(); + } + + public String getColor() { + return this.color; + } + + public String getDisplayName(){ + return this.displayName; + } + + public String getColoredName() { + return Utils.f(this == UserRank.YOUTUBER ? "&rYOU&4TUBER" : this.color + this.getDisplayName()); + } + + public String getColoredNameBold() { + return Utils.f(this == UserRank.YOUTUBER ? "&r&lYOU&4&lTUBER" : this.color + "&l" + this.getDisplayName()); + } + + public String getTabPrefix() { + return Utils.f(this == UserRank.YOUTUBER ? "&r&lY&4&lT" : (this == UserRank.BUILDTEAM ? "&3&lBT" : this.color + "&l" + this.getDisplayName())); + } + + public String getPrefix() { + if (!Objects.equals(this.getName(), "DEFAULT")) + return Utils.f(' ' + this.getColoredNameBold() + "&8&l>"); + return ""; + } + + public UserRank getNext() { + boolean picknext = false; + for (UserRank u : getUserRanks()) { + if (picknext) + return u; + if (Objects.equals(u.getName(), this.getName())) + picknext = true; + } + return UserRank.DEFAULT; + } + + public boolean isHigherThan(UserRank rank) { + for (UserRank r : getUserRanks()) + if (r == this) + return false; + else if (r == rank) + return true; + return false; + + } + + public boolean hasRank(UserRank rank) { + return this.ordinal() >= rank.ordinal(); + } + + public double getBucksModifier() { + switch (this) { + case DEFAULT: + return 1; + case VIP: + return 1.5; + case PREMIUM: + return 2; + case ELITE: + return 2.5; + case SPONSOR: + return 3; + case SUPREME: + return 4; + default: + return 4; + } + } + + public int getNumberOfHomes(){ + switch (this) { + case DEFAULT: + return 1; + case VIP: + return 2; + case PREMIUM: + return 4; + case ELITE: + return 7; + case SPONSOR: + return 12; + case SUPREME: + return 20; + default: + return 20; + } + } + + public int getHomeTPCooldown(){ + switch (this) { + case DEFAULT: + return 10; + case VIP: + return 9; + case PREMIUM: + return 8; + case ELITE: + return 7; + case SPONSOR: + return 6; + case SUPREME: + return 5; + default: + return 5; + } + } + + public int getPrice() { + switch (this) { + case VIP: + return 10; + case PREMIUM: + return 25; + case ELITE: + return 50; + case SPONSOR: + return 100; + case SUPREME: + return 200; + default: + return -1; + } + } + + public Material getMaterial() { + switch (this) { + case DEFAULT: + return Material.IRON_INGOT; + case VIP: + return Material.GOLD_INGOT; + case PREMIUM: + return Material.EMERALD; + case ELITE: + return Material.DIAMOND; + case SPONSOR: + return Material.NETHER_BRICK_ITEM; + default: + return Material.CLAY_BRICK; + } + } + + public int getBackpackRows() { + switch (this) { + case DEFAULT: + return 2; + case VIP: + return 3; + case PREMIUM: + return 5; + case ELITE: + return 7; + case SPONSOR: + return 9; + default: + return 11; + } + } + + public int getCompassRadius() { + switch (this) { + case DEFAULT: + case VIP: + return 30; + case PREMIUM: + return 25; + case ELITE: + return 20; + case SPONSOR: + return 15; + default: + return 10; + } + } + + public int getMonthlyTokens() { + switch (this) { + case DEFAULT: + return 0; + case VIP: + return 100; + case PREMIUM: + return 250; + case ELITE: + return 500; + case SPONSOR: + return 1000; + default: + return 2000; + + } + } + + public int getPetRespawnDelay() { + switch (this) { + case DEFAULT: + return 900; + case VIP: + return 720; + case PREMIUM: + return 600; + case ELITE: + return 480; + case SPONSOR: + return 360; + default: + return 300; + } + } + + /** + * Get the server key that this rank is for. + * <p> + * Note: This must be set by the plugin or project for each rank. + * </p> + * + * @return If a rank is a global one, "GLOBAL" is returned, or if it's a + * per server rank, the server will be returned, i.e. "GTM1". + */ + public String getServerKey() { + + // if not set, assume per server + if (serverKey == null || serverKey.isEmpty()){ + return Core.name().toUpperCase(); + } + + return serverKey; + } + + /** + * Set the server key that this rank is for. + * <p> + * Note: This must be set by the plugin or project for each rank. + * </p> + * If a rank is a global rank, set this as "GLOBAL". If a rank is per server, set this as the name of the server, "GTM1". + * + * @param serverKey - the server key for this rank + */ + public void setServerKey(String serverKey) { + this.serverKey = serverKey; + } + + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/eventtag/EventTag.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/eventtag/EventTag.java new file mode 100644 index 0000000..6420ea5 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/eventtag/EventTag.java @@ -0,0 +1,47 @@ +package net.grandtheftmc.core.users.eventtag; + +import org.bukkit.ChatColor; + +/** + * Created by Timothy Lampen on 2017-12-16. + */ +public enum EventTag {//the names must have same characters in the same arrangement of the enum type. + FESTIVE("&b&lFestive", false), + XMAS("&2&lXMAS", false), + SNOWMAN("&r&lSnowman", false), + SANTA("&c&lSanta", false), + HOHOHO("&c&lH&2&lo&c&lH&2&lo&c&lH&2&lo", false), + NICE("&a&lNice", false), + NAUGHTY("&c&lNaughty", false), + HEART("&d&l❤❤❤", false), + SEXY("&d&lSexy", false), + STEAMY("&d&lSteamy", false), + HOT("&d&lHot", false), + DADDY("&5&lDaddy", false), + EGG("&c&lE&6&lG&e&lG", false); + + private final String disp; + private final boolean global; + EventTag(String disp, boolean global) { + this.global = global; + this.disp = ChatColor.translateAlternateColorCodes('&', disp); + } + + public String getBoldName() { + return this.disp; + } + + public boolean isGlobal() { + return global; + } + + public static EventTag getEventTagFromName(String name){ + name = ChatColor.stripColor(name); + + if(name.contains("❤❤❤"))//hard coded because it uses UTF-8 characters. + return EventTag.HEART; + + name = name.toUpperCase(); + return EventTag.valueOf(name); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/eventtag/EventTagDAO.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/eventtag/EventTagDAO.java new file mode 100644 index 0000000..6006740 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/eventtag/EventTagDAO.java @@ -0,0 +1,128 @@ +package net.grandtheftmc.core.users.eventtag; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashMap; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.nametags.NametagManager; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserManager; +import net.grandtheftmc.core.util.ServerUtil; + +/** + * Created by Timothy Lampen on 1/7/2018. + */ +public class EventTagDAO { + + private static final HashMap<EventTag, TagVisibility> VISIBILITY = new HashMap<>(); + + /* + * Everything is static to maintain the pattern of DAO classes. + * Caches the results from the mysql for 15min, then updates. + */ + static { + new BukkitRunnable() { + @Override + public void run() { + refreshTagVisiblity(); + } + }.runTaskTimerAsynchronously(Core.getInstance(), 0, 20 * 60 * 15); + } + + /** + * @param tag - the tag that is being checked for visiblity + * @return the visibility of the tag according to the cached results. + */ + public static TagVisibility getTagVisibility(EventTag tag) { + if (VISIBILITY.containsKey(tag)) + return VISIBILITY.get(tag); + + //the tag was added to the plugin, but not to the actual database, so update the database with an entry. + ServerUtil.runTaskAsync(() -> { + addTagToDatabase(tag);//finally add it. + }); + return TagVisibility.EVERYONE; + } + + public static void setVisibility(EventTag tag, TagVisibility visibility) { + String query = "UPDATE tag_visibility set visibility = ? WHERE tag = ?"; + try (Connection c = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = c.prepareStatement(query)) { + statement.setInt(1, visibility.getID()); + statement.setString(2, tag.toString()); + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + } + } + + /** + * @param tag - the tag that is not currently in the database but must be added. + */ + private static void addTagToDatabase(EventTag tag) { + String query = "INSERT IGNORE INTO tag_visibility(tag,visibility) VALUES (?,?);"; + try (Connection c = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = c.prepareStatement(query)) { + statement.setString(1, tag.toString()); + statement.setInt(2, TagVisibility.NO_ONE.getID()); + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + } + } + + /** + * @apiNote refreshes the cache of tag visibility. + */ + public static void refreshTagVisiblity() { + String query = "SELECT * FROM tag_visibility;"; + try (Connection c = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = c.prepareStatement(query)) { + try (ResultSet set = statement.executeQuery()) { + HashMap<EventTag, TagVisibility> copy = new HashMap<>(); + while (set.next()) { + EventTag tag = EventTag.valueOf(set.getString("tag")); + TagVisibility v = TagVisibility.fromID(set.getInt("visibility")); + copy.put(tag, v); + } + + // get back on sync + ServerUtil.runTask(() -> { + VISIBILITY.clear(); + VISIBILITY.putAll(copy); + + // for all players + for (Player player : Bukkit.getOnlinePlayers()) { + + User user = UserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + if (user != null){ + if (user.getEquipedTag() == null) + continue; + if (getTagVisibility(user.getEquipedTag()) == TagVisibility.NO_ONE) { + user.setEquipedTag(null); + user.updateDisplayName(player); + NametagManager.updateNametagsTo(player, user); + NametagManager.updateNametag(player); + player.sendMessage(Lang.REWARDS.f("&cYour current event tag was dequiped because it was disabled.")); + } + } + } + }); + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/eventtag/PreTagEquipEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/eventtag/PreTagEquipEvent.java new file mode 100644 index 0000000..4208b4e --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/eventtag/PreTagEquipEvent.java @@ -0,0 +1,45 @@ +package net.grandtheftmc.core.users.eventtag; + +import net.grandtheftmc.core.events.CoreEvent; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; + +public final class PreTagEquipEvent extends CoreEvent implements Cancellable { + + private final Player player; + private final EventTag from, to; + + private boolean cancel; + + /** + * Construct a new Event + */ + public PreTagEquipEvent(Player player, EventTag from, EventTag to) { + super(false); + this.player = player; + this.from = from; + this.to = to; + } + + public Player getPlayer() { + return player; + } + + public EventTag getFrom() { + return from; + } + + public EventTag getTo() { + return to; + } + + @Override + public boolean isCancelled() { + return cancel; + } + + @Override + public void setCancelled(boolean b) { + this.cancel = b; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/eventtag/TagVisibility.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/eventtag/TagVisibility.java new file mode 100644 index 0000000..b9c1e57 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/eventtag/TagVisibility.java @@ -0,0 +1,26 @@ +package net.grandtheftmc.core.users.eventtag; + +/** + * Created by Timothy Lampen on 1/7/2018. + */ +public enum TagVisibility { + EVERYONE(0), + THOSE_WHO_HAVE_IT_UNLOCKED(1), + NO_ONE(2); + + private int id; + TagVisibility(int id) { + this.id = id; + } + + public int getID() { + return this.id; + } + + public static TagVisibility fromID(int id) { + for(TagVisibility v : TagVisibility.values()) + if(v.getID()==id) + return v; + return null; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/targets/TrackedEntity.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/targets/TrackedEntity.java new file mode 100644 index 0000000..1a53a7a --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/targets/TrackedEntity.java @@ -0,0 +1,26 @@ +package net.grandtheftmc.core.users.targets; + +import org.bukkit.Location; +import org.bukkit.entity.Entity; + +/** + * Created by Timothy Lampen on 12/11/2017. + */ +public class TrackedEntity extends TrackedTarget{ + + public final Entity entity; + + public TrackedEntity(Entity entity) { + this.entity = entity; + } + + public TrackedEntity(Entity entity, char pointer) { + super(pointer); + this.entity = entity; + } + + @Override + public Location getLocation() { + return this.entity.getLocation().clone().add(0,1,0); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/targets/TrackedLocation.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/targets/TrackedLocation.java new file mode 100644 index 0000000..af97713 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/targets/TrackedLocation.java @@ -0,0 +1,24 @@ +package net.grandtheftmc.core.users.targets; + +import org.bukkit.Location; + +/** + * Created by Timothy Lampen on 12/11/2017. + */ +public class TrackedLocation extends TrackedTarget { + + private final Location loc; + public TrackedLocation (Location loc, char pointer){ + super(pointer); + this.loc = loc; + } + + public TrackedLocation (Location loc){ + this.loc = loc; + } + + @Override + public Location getLocation() { + return this.loc; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/targets/TrackedTarget.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/targets/TrackedTarget.java new file mode 100644 index 0000000..bde8a68 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/users/targets/TrackedTarget.java @@ -0,0 +1,23 @@ +package net.grandtheftmc.core.users.targets; + +import org.bukkit.Location; + +/** + * Created by Timothy Lampen on 12/11/2017. + */ +public abstract class TrackedTarget { + private char pointer; + public abstract Location getLocation(); + + public TrackedTarget(char pointer) { + this.pointer = pointer; + } + + public TrackedTarget() { + this.pointer = '▲'; + } + + public char getPointer(){ + return this.pointer; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/AngleUtil.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/AngleUtil.java new file mode 100644 index 0000000..1fe45e5 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/AngleUtil.java @@ -0,0 +1,12 @@ +package net.grandtheftmc.core.util; + +public class AngleUtil { + + public static double getRadianFromDegree(double degree) { + return Math.toRadians(degree); + } + + public static double getDegreesFromRadians(double radian) { + return Math.toDegrees(radian); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/Attribute.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/Attribute.java new file mode 100644 index 0000000..f595b87 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/Attribute.java @@ -0,0 +1,27 @@ +package net.grandtheftmc.core.util; + +/** + * Created by Liam on 27/10/2016. + */ +public enum Attribute { + MAX_HEALTH("generic.maxHealth"), + FOLLOW_RANGE("generic.followRange"), + KNOCKBACK_RESISTANCE("generic.knockbackResistance"), + MOVEMENT_SPEED("generic.movementSpeed"), + ATTACK_DAMAGE("generic.attackDamage"), ARMOR("generic.armor"), + ARMOR_THOUGHNESS("generic.armorToughness"), + ATTACK_SPEED("generic.attackSpeed"), + LUCK("generic.luck"), + JUMP_STRENGTH("horse.jumpStrength"), + SPAWN_REINFORCEMENTS("zombie.spawnReinforcements"); + + private final String name; + + Attribute(String name) { + this.name = name; + } + + public String getName() { + return this.name; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/AttributeModifier.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/AttributeModifier.java new file mode 100644 index 0000000..471bd13 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/AttributeModifier.java @@ -0,0 +1,80 @@ +package net.grandtheftmc.core.util; + +import org.bukkit.Bukkit; + +import java.lang.reflect.InvocationTargetException; +import java.util.UUID; + +public class AttributeModifier +{ + private String attribute; + private String name; + private String slot; + private int operation; + private double amount; + private UUID uuid; + + public AttributeModifier(Attribute attribute, String name, Slot slot, int operation, double amount, UUID uuid) + { + this.attribute = attribute.getName(); + this.name = name; + this.slot = slot.getName(); + this.operation = operation; + this.amount = amount; + this.uuid = uuid; + } + + @Deprecated + public AttributeModifier(String attribute, String name, String slot, int operation, double amount, UUID uuid) + { + this.attribute = attribute; + this.name = name; + this.slot = slot; + this.operation = operation; + this.amount = amount; + this.uuid = uuid; + } + + public AttributeModifier(Object modifier) + { + try + { + this.attribute = (String)modifier.getClass().getMethod("getString", new Class[] { String.class }).invoke(modifier, "AttributeName"); + this.name = (String)modifier.getClass().getMethod("getString", new Class[] { String.class }).invoke(modifier, "Name"); + this.slot = (String)modifier.getClass().getMethod("getString", new Class[] { String.class }).invoke(modifier, "Slot"); + this.operation = (Integer) modifier.getClass().getMethod("getInt", new Class[]{String.class}).invoke(modifier, "Operation"); + this.amount = (Double) modifier.getClass().getMethod("getDouble", new Class[]{String.class}).invoke(modifier, "Amount"); + this.uuid = new UUID((Long) modifier.getClass().getMethod("getLong", new Class[]{String.class}).invoke(modifier, "UUIDMost"), (Long) modifier.getClass().getMethod("getLong", new Class[]{String.class}).invoke(modifier, "UUIDLeast")); + } + catch (IllegalAccessException|IllegalArgumentException|InvocationTargetException|NoSuchMethodException|SecurityException e) + { + Bukkit.getLogger().info("[ItemAttributeAPI] Incompatible server version! Some methods can't be applied."); + } + } + + public Object getNBT() + { + try + { + Object data = ReflectionUtils.getNMSClass("NBTTagCompound").newInstance(); + if (data != null) + { + data.getClass().getMethod("setString", new Class[] { String.class, String.class }).invoke(data, "AttributeName", this.attribute); + data.getClass().getMethod("setString", new Class[] { String.class, String.class }).invoke(data, "Name", this.name); + data.getClass().getMethod("setString", new Class[] { String.class, String.class }).invoke(data, "Slot", this.slot); + data.getClass().getMethod("setInt", new Class[] { String.class, Integer.TYPE }).invoke(data, "Operation", this.operation); + data.getClass().getMethod("setDouble", new Class[] { String.class, Double.TYPE }).invoke(data, "Amount", this.amount); + data.getClass().getMethod("setLong", new Class[] { String.class, Long.TYPE }).invoke(data, "UUIDMost", this.uuid.getMostSignificantBits()); + data.getClass().getMethod("setLong", new Class[] { String.class, Long.TYPE }).invoke(data, "UUIDLeast", this.uuid.getLeastSignificantBits()); + return data; + } + Bukkit.getLogger().info("[ItemAttributeAPI] Incompatible Server version! Missing classes."); + return null; + } + catch (InstantiationException|IllegalAccessException|NoSuchMethodException|SecurityException|IllegalArgumentException|InvocationTargetException e) + { + Bukkit.getLogger().info("[ItemAttributeAPI] Incompatible server version! Some methods can't be applied."); + } + return null; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/C.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/C.java new file mode 100644 index 0000000..a2cf9a2 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/C.java @@ -0,0 +1,42 @@ +package net.grandtheftmc.core.util; + +import java.util.regex.Pattern; + +/** + * Created by Luke Bingham on 25/07/2017. + */ +public class C { + public static final char COLOR_CHAR = '\u00A7'; + + public static final String BOLD = COLOR_CHAR + "l"; + public static final String STRIKE = COLOR_CHAR + "m"; + public static final String UNDERLINE = COLOR_CHAR + "n"; + public static final String MAGIC = COLOR_CHAR + "k"; + public static final String ITALIC = COLOR_CHAR + "o"; + public static final String RESET = COLOR_CHAR + "r"; + + public static final String BLACK = COLOR_CHAR + "0"; + public static final String DARK_BLUE = COLOR_CHAR + "1"; + public static final String DARK_GREEN = COLOR_CHAR + "2"; + public static final String DARK_AQUA = COLOR_CHAR + "3"; + public static final String DARK_RED = COLOR_CHAR + "4"; + public static final String DARK_PURPLE = COLOR_CHAR + "5"; + public static final String GOLD = COLOR_CHAR + "6"; + public static final String GRAY = COLOR_CHAR + "7"; + public static final String DARK_GRAY = COLOR_CHAR + "8"; + public static final String BLUE = COLOR_CHAR + "9"; + public static final String GREEN = COLOR_CHAR + "a"; + public static final String AQUA = COLOR_CHAR + "b"; + public static final String RED = COLOR_CHAR + "c"; + public static final String LIGHT_PURPLE = COLOR_CHAR + "d"; + public static final String YELLOW = COLOR_CHAR + "e"; + public static final String WHITE = COLOR_CHAR + "f"; + + //Key colors + public static final String ERROR = RED, WARNING = YELLOW, INFO = GREEN, SUCCESS = GREEN; + + public static boolean isNumeral(String color) { + Pattern pattern = Pattern.compile("^(" + COLOR_CHAR + ")\\d$"); + return pattern.matcher(color).find(); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/Callback.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/Callback.java new file mode 100644 index 0000000..15f1019 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/Callback.java @@ -0,0 +1,8 @@ +package net.grandtheftmc.core.util; + +/** + * Created by Luke Bingham on 10/07/2017. + */ +public interface Callback<T> { + void call(T obj); +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/Component.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/Component.java new file mode 100644 index 0000000..00adfde --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/Component.java @@ -0,0 +1,41 @@ +package net.grandtheftmc.core.util; + +import org.bukkit.Bukkit; +import org.bukkit.event.Listener; +import org.bukkit.plugin.java.JavaPlugin; + +/** + * Created by Luke Bingham on 04/07/2017. + */ +public interface Component<T, E extends JavaPlugin> extends Listener { + + /** + * This will run when the plugin (E) is enabled. + * + * @param plugin The JavaPlugin + */ + default T onEnable(E plugin) { + return null; + } + + /** + * This will run when the plugin (E) is disabling. + * + * @param plugin The JavaPlugin + */ + default T onDisable(E plugin) { + return null; + } + + default void log(boolean enabled) { + StringBuilder log = new StringBuilder((enabled ? C.GREEN + "Component loaded" : C.RED + "Component disabled") + C.WHITE + ": " + C.YELLOW + getClass().getSimpleName() + C.GRAY); + int classLength = getClass().getSimpleName().length(), max = 30, difference = max - classLength; + for(int i = 0; i < difference; i++) log.append("."); + log.append(disableAble() ? C.GREEN : C.RED).append(String.valueOf(disableAble()).toUpperCase()); + Bukkit.getConsoleSender().sendMessage(log.toString()); + } + + default boolean disableAble() { + return true; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/CoreLocation.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/CoreLocation.java new file mode 100644 index 0000000..8f744b4 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/CoreLocation.java @@ -0,0 +1,155 @@ +package net.grandtheftmc.core.util; + +import com.google.gson.Gson; +import net.buycraft.plugin.internal.okhttp3.OkHttpClient; +import net.buycraft.plugin.internal.okhttp3.Request; +import net.buycraft.plugin.internal.okhttp3.Response; + +import java.io.IOException; +import java.util.Optional; + +public class CoreLocation { + private String region; + private String zip; + private String lon; + private String status; + private String query; + private String isp; + private String countryCode; + private String regionName; + private String as; + private String org; + private String city; + private String country; + private String timezone; + private String lat; + + public String getRegion() { + return region; + } + + public void setRegion(String region) { + this.region = region; + } + + public String getZip() { + return zip; + } + + public void setZip(String zip) { + this.zip = zip; + } + + public String getLon() { + return lon; + } + + public void setLon(String lon) { + this.lon = lon; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getQuery() { + return query; + } + + public void setQuery(String query) { + this.query = query; + } + + public String getIsp() { + return isp; + } + + public void setIsp(String isp) { + this.isp = isp; + } + + public String getCountryCode() { + return countryCode; + } + + public void setCountryCode(String countryCode) { + this.countryCode = countryCode; + } + + public String getRegionName() { + return regionName; + } + + public void setRegionName(String regionName) { + this.regionName = regionName; + } + + public String getAs() { + return as; + } + + public void setAs(String as) { + this.as = as; + } + + public String getOrg() { + return org; + } + + public void setOrg(String org) { + this.org = org; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } + + public String getTimezone() { + return timezone; + } + + public void setTimezone(String timezone) { + this.timezone = timezone; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + @Override + public String toString() { + return "ClassPojo [region = " + region + ", zip = " + zip + ", lon = " + lon + ", status = " + status + ", query = " + query + ", isp = " + isp + ", countryCode = " + countryCode + ", regionName = " + regionName + ", as = " + as + ", org = " + org + ", city = " + city + ", country = " + country + ", timezone = " + timezone + ", lat = " + lat + "]"; + } + + public static Optional<CoreLocation> getCountry(String ip) { + //http://ip-api.com/json/151.224.74.1 + OkHttpClient client = new OkHttpClient(); + Request request = new Request.Builder().url("http://ip-api.com/json/" + ip).build(); + try (Response response = client.newCall(request).execute()) { + return Optional.of(new Gson().fromJson(response.body().string(), CoreLocation.class)); + } catch (IOException e) { + e.printStackTrace(); + } + return Optional.empty(); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/DefaultFontInfo.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/DefaultFontInfo.java new file mode 100644 index 0000000..53984ea --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/DefaultFontInfo.java @@ -0,0 +1,129 @@ +package net.grandtheftmc.core.util; + +import java.util.Arrays; +import java.util.Optional; + +public enum DefaultFontInfo { + A_UPPER('A', 5), + A_LOWER('a', 5), + B_UPPER('B', 5), + B_LOWER('b', 5), + C_UPPER('C', 5), + C_LOWER('c', 5), + D_UPPER('D', 5), + D_LOWER('d', 5), + E_UPPER('E', 5), + E_LOWER('e', 5), + F_UPPER('F', 5), + F_LOWER('f', 4), + G_UPPER('G', 5), + G_LOWER('g', 5), + H_UPPER('H', 5), + H_LOWER('h', 5), + I_UPPER('I', 3), + I_LOWER('i', 1), + J_UPPER('J', 5), + J_LOWER('j', 5), + K_UPPER('K', 5), + K_LOWER('k', 4), + L_UPPER('L', 5), + L_LOWER('l', 1), + M_UPPER('M', 5), + M_LOWER('m', 5), + N_UPPER('N', 5), + N_LOWER('n', 5), + O_UPPER('O', 5), + O_LOWER('o', 5), + P_UPPER('P', 5), + P_LOWER('p', 5), + Q_UPPER('Q', 5), + Q_LOWER('q', 5), + R_UPPER('R', 5), + R_LOWER('r', 5), + S_UPPER('S', 5), + S_LOWER('s', 5), + T_UPPER('T', 5), + T_LOWER('t', 4), + U_UPPER('U', 5), + U_LOWER('u', 5), + V_UPPER('V', 5), + V_LOWER('v', 5), + W_UPPER('W', 5), + W_LOWER('w', 5), + X_UPPER('X', 5), + X_LOWER('x', 5), + Y_UPPER('Y', 5), + Y_LOWER('y', 5), + Z_UPPER('Z', 5), + Z_LOWER('z', 5), + NUM_1('1', 5), + NUM_2('2', 5), + NUM_3('3', 5), + NUM_4('4', 5), + NUM_5('5', 5), + NUM_6('6', 5), + NUM_7('7', 5), + NUM_8('8', 5), + NUM_9('9', 5), + NUM_0('0', 5), + EXCLAMATION_POINT('!', 1), + AT_SYMBOL('@', 6), + NUM_SIGN('#', 5), + DOLLAR_SIGN('$', 5), + PERCENT('%', 5), + UP_ARROW('^', 5), + AMPERSAND('&', 5), + ASTERISK('*', 5), + LEFT_PARENTHESIS('(', 4), + RIGHT_PERENTHESIS(')', 4), + MINUS('-', 5), + UNDERSCORE('_', 5), + PLUS_SIGN('+', 5), + EQUALS_SIGN('=', 5), + LEFT_CURL_BRACE('{', 4), + RIGHT_CURL_BRACE('}', 4), + LEFT_BRACKET('[', 3), + RIGHT_BRACKET(']', 3), + COLON(':', 1), + SEMI_COLON(';', 1), + DOUBLE_QUOTE('"', 3), + SINGLE_QUOTE('\'', 1), + LEFT_ARROW('<', 4), + RIGHT_ARROW('>', 4), + QUESTION_MARK('?', 5), + SLASH('/', 5), + BACK_SLASH('\\', 5), + LINE('|', 1), + TILDE('~', 5), + TICK('`', 2), + PERIOD('.', 1), + COMMA(',', 1), + SPACE(' ', 3), + DEFAULT('a', 4); + + private final char character; + private final int length; + + DefaultFontInfo(char character, int length) { + this.character = character; + this.length = length; + } + + public char getCharacter() { + return this.character; + } + + public int getLength() { + return this.length; + } + + public int getBoldLength() { + if (this == SPACE) return this.length; + return this.length + 1; + } + + public static DefaultFontInfo getDefaultFontInfo(char c) { + Optional<DefaultFontInfo> defaultFontInfo = Arrays.stream(values()).filter(d -> d.character == c).findFirst(); + return defaultFontInfo.orElse(DEFAULT); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/EntityUtil.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/EntityUtil.java new file mode 100644 index 0000000..ec0270f --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/EntityUtil.java @@ -0,0 +1,35 @@ +package net.grandtheftmc.core.util; + +import java.util.Arrays; +import java.util.List; + +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; + +public class EntityUtil { + + private final static List<EntityType> passiveEntitys = Arrays.asList(EntityType.BOAT, EntityType.MINECART, + EntityType.ITEM_FRAME, EntityType.ARMOR_STAND, EntityType.MINECART_CHEST, EntityType.MINECART_COMMAND, + EntityType.MINECART_FURNACE, EntityType.MINECART_HOPPER, EntityType.MINECART_MOB_SPAWNER, + EntityType.MINECART_TNT, EntityType.SHULKER, EntityType.SHULKER_BULLET, EntityType.AREA_EFFECT_CLOUD, + EntityType.DRAGON_FIREBALL, EntityType.FIREBALL, EntityType.FISHING_HOOK, EntityType.LIGHTNING, + EntityType.PRIMED_TNT, EntityType.WEATHER, EntityType.DROPPED_ITEM, EntityType.ARROW, + EntityType.LINGERING_POTION, EntityType.LEASH_HITCH, EntityType.ENDER_PEARL); + + public static Entity getEntityByEntityID(int entityID, World world) { + Entity result = null; + for (Entity en : world.getEntities()) + if (en.getEntityId() == entityID) + result = en; + return result; + } + + public static boolean isPassive(EntityType type) { + return passiveEntitys.contains(type); + } + + public static boolean isPassive(Entity entity) { + return isPassive(entity.getType()); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/HTTPUtil.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/HTTPUtil.java new file mode 100644 index 0000000..1a86fe8 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/HTTPUtil.java @@ -0,0 +1,18 @@ +package net.grandtheftmc.core.util; + +import com.google.gson.Gson; + +/** + * Created by Luke Bingham on 28/08/2017. + */ +public class HTTPUtil { + + private static final Gson GSON = new Gson(); + + /** + * Transform Json text to a class object. + */ + public static <T> T transform(String json, Class<T> clazz) { + return GSON.fromJson(json, clazz); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/IconConverter.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/IconConverter.java new file mode 100644 index 0000000..30e54b7 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/IconConverter.java @@ -0,0 +1,719 @@ +package net.grandtheftmc.core.util; + +import java.util.HashMap; +import java.util.Map; + +public class IconConverter { + + private static final String[] CHARACTER_NAME_LIST; + private static final Map<String, Character> CHARACTER_NAME_MAP; + private static final int UNICODE_OFFSET = 36864; + private static boolean escape; + + static { + CHARACTER_NAME_LIST = new String[]{ + "woodensword", "woodenpickaxe", "woodenshovel", "woodenaxe", "woodenhoe", + "stonesword", "stone pickaxe", "stoneshovel", "stoneaxe", "stonehoe", + "goldensword", "goldenpickaxe", "goldenshovel", "goldenaxe", "goldenhoe", "unused", + + "ironsword", "ironpickaxe", "ironshovel", "ironaxe", "ironhoe", + "diamondsword", "diamondpickaxe", "diamondshovel", "diamondaxe", "diamond hoe", + "bow", "bow1", "bow2", "bow3", "arrow", "quiver", + + "head", "body", "legs", "boots", + "whiteleathercap", "whiteleathertunic", "whiteleatherpants", "whiteleatherboots", + "blankleathercap", "blankleathertunic", "blankleatherpants", "blankleatherboots", + "leathercap", "leathertunic", "leatherpants", "leather boots", + + "chainhelmet", "chainchestplate", "chainleggings", "chainboots", + "goldenhelmet", "goldenchestplate", "goldenleggings", "goldenboots", + "ironhelmet", "ironchestplate", "ironleggings", "ironboots", + "diamondhelmet", "diamondchestplate", "diamondleggings", "diamondboots", + + "compasssouth", "compasssouthwest", "compasswest", "compassnorthwest", + "compassnorth", "compassnortheast", "compasseast", "compasssoutheast", + "clocknoon", "clockevening", "clockdusk", "clocknight", + "clockmidnight", "clockweehours", "clockdawn", "clockmorning", + + "fishingrod", "fishingrodcast", "carrotonastick", "flintandsteel", "shears", "lead", "name tag", + "iron horsearmor", "goldhorsearmor", "diamondhorsearmor", "saddle", + "minecart", "minecartwithchest", "minecartwithfurnace", "minecartwithhopper", "minecartwithtnt", + + "boat", "book", "bookandquill", "writtenbook", "enchantedbook", "map", "emptymap", + "bucket", "waterbucket", "lavabucket", "milk", + "snowball", "egg", "enderpearl", "eyeofender", "firecharge", + + "disc13", "disccat", "disc blocks", "disc chirp", "disc far", "disc mall", + "discmellohi", "disc stal", "disc strad", "disc ward", "disc 11", "disc wait", + "bottle o' enchanting", "firework", "firework star blank", "firework star spots", + + "firework star white", "firework star orange", "firework star magenta", "firework star light blue", + "firework star yellow", "firework star lime", "firework star pink", "firework star gray", + "firework star light gray", "firework star cyan", "firework star purple", "firework star blue", + "firework star brown", "firework star green", "firework star red", "firework star black", + + "bonemeal", "orange dye", "magenta dye", "light blue dye", "dandelion yellow", "lime dye", "pink dye", "gray dye", + "light gray dye", "cyan dye", "purple dye", "lapis lazuli", "cocoa beans", "cactus green", "rose red", "ink sac", + + "sign", "painting", "item frame", "flower pot", "wooden door", "iron door", "hopper", "brewing stand", + "cauldron", "bed", "repeater", "comparator", "redstone dust", "glowstone dust", "gunpowder", "sugar", + + "iron ingot", "gold ingot", "brick", "nether brick", "coal", "charcoal", "diamond", "ruby", "emerald", + "nether quartz", "flint", "gold nugget", "ghast tear", "nether star", "clay ball", "slimeball", + + "skeletonskull", "witherskeletonskull", "zombiehead", "head", "creeperhead", + "stick", "bone", "blazerod", "blazepowder", "magma cream", "leather", + "feather", "paper", "string", "fermentedspidereye", "spidereye", + + "seeds", "melon seeds", "pumpkin seeds", "netherwart", "sugarcane", "wheat", "carrot", "golden carrot", + "potato", "baked potato", "poisonous potato", "melon", "glistering melon", "apple", "golden apple", "rotten flesh", + + "rawporkchop", "porkchop", "rawbeef", "steak", "rawfish", "cookedfish", "rawchicken", "cookedchicken", + "bowl", "mushroomstew", "bread", "cookie", "cake", "pumpkinpie", "glassbottle", "waterbottle", + + "potionofregeneration", "splash potion of regeneration", "potion of swiftness", "splash potion of swiftness", + "potionoffire resistance", "splash potion of fire resistance", "potion of poison", "splash potion of poison", + "potionof healing", "splash potion of healing", "potion of night vision", "splash potion of night vision", + "potionof weakness", "splash potion of weakness", "potion of strength", "splash potion of strength", + + "potion of slowness", "splash potion of slowness", "potion of harming", "splash potion of harming", + "potion of invisibility", "splash potion of invisibility", "splash potion bottle", "potion liquid", + "potion of milk", "splash potion of milk", "white potion", "white splash potion", + "swiftness potion", "splash swiftness potion", "slowness potion", "splash slowness potion", + + "haste potion potion", "splash haste potion", "dullness potion", "splash dullness potion", + "strength potion", "splash strength potion", "health potion", "splash health potion", + "harm potion", "splash harm potion", "jump boost potion", "splash jump boost potion", + "nausea potion", "splash nausea potion", "regeneration potion", "splash regeneration potion", + + "resistance potion", "splash resistance potion", "fire resistance potion", "splash fire resistance potion", + "water breathing potion", "splash water breathing potion", "invisibility potion", "splash invisibility potion", + "blindness potion", "splash blindness potion", "night vision potion", "splash night vision potion", + "hungerpotion", "splash hunger potion", "weakness potion", "splash weakness potion", + "poisonpotion", "splash poison potion", "wither potion", "splash wither potion", + "healthboostpotion", "splash health boost potion", "absorption potion", "splash absorption potion", + "saturationpotion", "splash saturation potion", "splash mundane potion", + "spawnegg", "spawn egg spots", "white spawn egg", "spawn creeper", "spawn skeleton", + + "spawn spider", "spawn zombie", "spawn slime", "spawn ghast", "spawn zombie pigman", "spawn enderman", + "spawn cave spider", "spawn silverfish", "spawn blaze", "spawn magma cube", "spawn bat", "spawn witch", + "spawn pig", "spawn sheep", "spawn cow", "spawn chicken", + + "spawn squid", "spawn wolf", "spawn mooshroom", "spawn ocelot", "spawn horse", "spawn villager", + "spawn snow golem", "spawn iron golem", "spawn wither skeleton", "spawn wither", + "spawn human", "spawn tnt", "spawn spawner", "unused", "unused", "unused", + + "tfda wooden sword", "tfda wooden pickaxe", "tfda wooden shovel", "tfda wooden axe", "tfda wooden hoe", + "tfda stone sword", "tfda stone pickaxe", "tfda stone shovel", "tfda stone axe", "tfda stone hoe", + "tfda golden sword", "tfda golden pickaxe", "tfda golden shovel", "tfda golden axe", "tfda golden hoe", "unused", + + "tfda iron sword", "tfda iron pickaxe", "tfda iron shovel", "tfda iron axe", "tfda iron hoe", + "tfda diamond sword", "tfda diamond pickaxe", "tfda diamond shovel", "tfda diamond axe", "tfda diamond hoe", + "tfda fishing rod", "tfda fishing rod cast", "tfda carrot on a stick", "unused", "tfda wooden door", "tfda iron door", + + "tfda white leather cap", "tfda white leather tunic", "tfda white leather pants", "tfda white leather boots", + "tfda blank leather cap", "tfda blank leather tunic", "tfda blank leather pants", "tfda blank leather boots", + "tfda leather cap", "tfda leather tunic", "tfda leather pants", "tfda leather boots", + "tfda chain helmet", "tfda chain chestplate", "tfda chain leggings", "tfda chain boots", + + "tfda golden helmet", "tfda golden chestplate", "tfda golden leggings", "tfda golden boots", + "tfda iron helmet", "tfda iron chestplate", "tfda iron leggings", "tfda iron boots", + "tfda diamond helmet", "tfda diamond chestplate", "tfda diamond leggings", "tfda diamond boots", + "unused", "tfda gold nugget", "tfda gold ingot", "tfda golden apple", + + "tfda nether brick", "tfda nether quartz", "tfda zombie head", "tfda purple dye", + "unused", "unused", "unused", "unused", "old cocoa beans", "unused", "starfish", "seashell", + "custom disc dream", "custom disc ezusht", "custom disc friend", "custom disc ran", + + "oaksapling", "sprucesapling", "birchsapling", "junglesapling", "deadbush", "shrub", + "whitefern", "fern", "whitegrass", "grass", "whitestemattached", "stemattached", + "whitestem", "stem", "whitevines", "vines", + + "whitelilypad", "lilypad", "sugarcaneblock", "netherwart3", "netherwart2", "netherwart1", + "redmushroom", "brownmushroom", "rose", "cyanflower", "dandelion", + "unused", "unused", "iron bars", "glasspane", "cobweb", + + "wheat8", "wheat7", "wheat6", "wheat5", "wheat4", "wheat3", "wheat2", "wheat1", + "potatoes4", "potatoes3", "potatoes2", "potatoes1", "carrots4", "carrots3", "carrots2", "carrots1", + + "rail", "rail north-east", "powered rail", "powered powered rail", "detector rail", "powered detector rail", + "activator rail", "powered activator rail", "rail horizontal", "rail east-south", + "powered rail horizontal", "powered powered rail horizontal", + "detector rail horizontal", "powered detector rail horizontal", + "activator rail horizontal", "powered activator rail horizontal", + + "rail south-east", "raileast-north", "ladder", "ladderhorizontal", + "redstone", "redstone horizontal", "redstonevertical", + "tripwire", "tripwirehorizontal", "tripwirevertical", "tripwirecross", "tripwirehook", + "lever", "torch", "redstonetorch", "redstone torchoff", + + "fire0", "fire1", "fire2", "fire3", "fire4", "fire5", + "fireinside0", "fireinside1", "fireinside2", "fireinside3", "fireinside4", + "stationarywater", "flowingwater", "stationarylava", "flowinglava", "netherportal", + + "stationary water solid", "flowing water solid", "nether portal solid", + "break 0", "break 1", "break 2", "break 3", "break 4", "break 5", "break 6", "break 7", "break 8", "break 9", + "unused", "unused", "unused", + + "coal ore tile", "iron ore tile", "gold ore tile", "redstone ore tile", "diamond ore tile", + "lapis lazuli ore tile", "emerald ore tile", "cobblestone tile", "mossy cobblestone tile", + "stone tile", "stone bricks tile", "mossy stone bricks tile", "cracked stone bricks tile", + "chiseled stone bricks tile", "stone slab top tile", "stone slab side tile", + + "coal block tile", "iron block tile", "gold block tile", "redstone block tile", "diamond block tile", + "lapis lazuli block tile", "emerald block tile", "bedrock tile", "furnace tile", "burning furnace tile", + "furnace back tile", "furnace top tile", "dispenser tile", "dispenser top tile", "dropper tile", "dropper top tile", + + "piston tile", "piston head tile", "piston top tile", "repeater tile", "powered repeater tile", + "comparator tile", "powered comparator tile", "redstone lamp tile", "powered redstone lamp tile", + "daylight detector bottom tile", "daylight detector tile", "crafting table top tile", + "crafting table side tile", "crafting table tile", "jukebox tile", "note block tile", + + "dirt tile", "grass block tile", "snowy grass block tile", "mycelium tile", "farmland tile", "wet farmland tile", + "snow tile", "soul sand tile", "gravel tile", "sand tile", "sandstone tile", "smooth sandstone tile", + "chiseled sandstone tile", "sandstone top tile", "sandstone bottom tile", "end stone tile", + + "obsidian tile", "glowstone tile", "nether brick block tile", "netherrack tile", "nether quartz ore tile", + "quartz block tile", "quartz block bottom tile", "pillar quartz tile", "pillar quartz top tile", + "chiseled quartz tile", "chiseled quartz top tile", "oak log tile", "oak log top tile", "oak planks tile", + "bookshelf tile", "trapdoor tile", + + "pumpkin tile", "jack o' lantern tile", "pumkin side tile", "pumpkin top tile", "melon block tile", + "melon block top tile", "cactus tile", "mushroom stem tile", "mushroom brown tile", "mushroom red tile", + "mushroom pores tile", "hay bale tile", "sponge tile", "ice tile", "tnt tile", "spawner tile", + + "enchantment table top tile", "enchantment table side tile", "end portal frame tile", "end portal frame side tile", + "cake top tile", "cake side tile", "cake side eaten tile", "command block tile", "unused", "unused", + "unused", "unused", "beacon crystal tile", "item frame back tile", "painting back tile", "static tile", + + "tfda bedrock tile", "summoning brick tile", "corrupt brick side tile", "corrupt brick top tile", + "tfda redstone ore tile", "corrupt runes tile", "tfda netherbrick tile", "tfda netherrack", + "tfda obsidian tile", "air glyph tile", "water glyph tile", "earth glyph tile", "fire glyph tile", + "tfda glowstone tile", "tfda cobblestone tile", "cracked icy bricks tile", + + "light blue cloth tile", "green cloth tile", "yellow cloth tile", "purple cloth tile", + "glowing red cloth tile", "red cloth tile", "tfda coal block tile", "tfda redstone block tile", + "tfda lapis lazuli block tile", "tfda hardened clay tile", "tfda snow tile", "tfda snowy grass block tile", + "tfda mycelium tile", "tfda ice tile", "tfda tnt tile", "tfda sponge tile", + + "tfda chiseled sandstone tile", "tfda bricks tile", "tfda daylight detector bottom tile", + "tfda daylight detector tile", "tfda bookshelf tile", "tfda cactus tile", + "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", + + "creeper", "chargedcreeper", "skeleton", "wither skeleton", "spider", "zombie", "zombie villager", "slime", + "ghast", "firingghast", "zombiepigman", "enderman", "cavespider", "silverfish", "blaze", "magma cube", + + "bat", "witch", "unused", "pig", "sheep", "cow", "chicken", "squid", "wolf", "dog", "angry wolf", + "mooshroom", "ocelot", "black cat", "ginger cat", "siamese cat", + + "horse", "donkey", "mule", "skeletonhorse", "zombiehorse", "villager", "human", "snow golem", + "irongolem", "unused", "enderdragon", "wither", "witherprotected", "unused", "witherskull", "bluewitherskull", + + "rideable minecart", "chest minecart", "furnace minecart", "hopper minecart", "tnt minecart", + "spawner minecart", "boat entity", "sign front", "sign back", "chest tile", "trapped chest tile", + "ender chest tile", "christmas chest tile", "doublechest", "trapped doublechest", "christmas doublechest", + + "ender crystal shell", "ender crystal gem 1", "ender crystal gem 2", "ender crystal gem 3", + "ender crystal gem 4", "ender crystal gem 5", "ender crystal gem 6", "ender crystal 1", + "ender crystal 2", "ender crystal 3", "ender crystal 4", "ender crystal 5", "ender crystal 6", + "beacon beam", "arrow entity", "item frame entity", + + "painting kebab", "painting aztec", "painting alban", "painting aztec2", "painting bomb", "painting plant", + "painting wasteland", "painting pool", "painting courbet", "painting sea", "painting sunset", + "painting creebet", "painting wanderer", "painting graham", "painting skeleton", "painting donkeykong", + + "painting match", "painting bust", "painting stage", "painting void", "painting skullandroses", + "painting wither", "painting fighters", "painting pointer", "painting pigscene", "painting flaming skull", + "unused", "unused", "unused", "unused", "unused", "unused", + + "xp orb 1", "xp orb 2", "xp orb 3", "xp orb 4", "xp orb 5", "xp orb 6", "xp orb 7", "xp orb 8", + "xp orb 9", "xp orb 10", "xp orb 11", "unused", "unused", "unused", "unused", "unused", + + "inventory slot", "button", "button disabled", "button highlighted", "delete slot", + "gui arrow", "gui blocked arrow", "gui complete arrow", "gui burning", "gui burning full", + "gui plus", "gui integral", "gui delete", "gui potion", "gui green check", "gui red x", + + "hammer", "hammer and anvil", "abacus", "broken shovel", "right button", "right button highlighted", + "right button disabled", "left button", "left button highlighted", "left button disabled", + "up button", "down button", "gui language", "realms off", "realms on", "realms none", + + "white gui arrow", "white gui burning", "white gui plus", "white gui integral", "white gui delete", + "white gui potion", "white gui check", "white gui x", "gui circle", "gui cursor", + "connection5", "connection4", "connection3", "connection2", "connection1", "connection0", + + "connecting1", "connecting2", "connecting3", "connecting4", "connecting5", + "hotbar slot", "hotbar cursor", "selected hotbar slot", "gui 1", "gui 2", "gui 3", "gui 4", "gui 5", + "gui !!!", "unused", "unused", + + "messages highlighted", "messages", "1 message highlighted", "2 messages highlighted", + "3 messages highlighted", "4 messages highlighted", "5 messages highlighted", "!!! messages highlighted", + "1 message", "2 messages", "3 messages", "4 messages", "5 messages", "!!! messages", "heart container", "healing heart container", + + "heart", "halfheart", "poisonheart", "halfpoisonheart", "witherheart", "halfwitherheart", + "mob heart", "half mob heart", "hardcore heart", "hardcore half heart", + "hardcore poison heart", "hardcore half poison heart", "hardcore wither heart", "hardcore half wither heart", + "absorption heart", "half absorption heart", + + "light heart", "light half heart", "light poison heart", "light half poison heart", + "light wither heart", "light half wither heart", "light mob heart", "light half mob heart", + "light hardcore heart", "light hardcore half heart", "light hardcore poison heart", + "light hardcore half poison heart", "light hardcore wither heart", "light hardcore half wither heart", + "hardcore absorption heart", "hardcore half absorption heart", + + "healing heart", "healing half heart", "healing poison heart", "healing half poison heart", + "healing wither heart", "healing half wither heart", "healing mob heart", "healing half mob heart", + "healing hardcore heart", "healing hardcore half heart", "healing hardcore poison heart", + "healing hardcore half poison heart", "healing hardcore wither heart", "healing hardcore half wither heart", + "red heart container", "red wither heart", + + "armor point", "half armor point", "empty armor point", "air bubble", "half air bubble", + "reversed hunger point", "hunger container", "healing hunger container", "red hunger container", + "green hunger container", "brown hunger container", "unused", "unused", "unused", "unused", "unused", + + "hunger point", "half hunger point", "light hunger point", "light half hunger point", + "poison hunger point", "half poison hunger point", "light poison hunger point", + "light half poison hunger point", "healing hunger point", "healing half hunger point", + "healing poison hunger point", "healing half poison hunger point", "hunger hunger point", + "half hunger hunger point", "healing hunger hunger point", "healing half hunger hunger point", + + "swiftness", "slowness", "haste", "mining fatigue", "strength", "weakness", "poison", "regeneration", + "invisibility", "hunger", "jump boost", "nausea", "night vision", "blindness", "resistance", "fire resistance", + + "water breathing", "wither status", "absorption", "unused", "unused", "unused", "unused", "unused", + "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", + + "tfda zombie", "tfda woman", "unused", "unused", "unused", "unused", "unused", "unused", "unused", + "unused", "unused", "unused", "unused", "unused", "tfda trapped chest tile", "tfda trapped doublechest", + + "tfda swiftness", "tfda slowness", "tfda regeneration", "tfda jump boost", "tfda nausea", + "tfda blindness", "tfda wither status", "unused", "unused", "unused", "unused", "unused", + "unused", "unused", "unused", "unused", + + "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", + "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", + + "map landmark", "map nether portal", "map end portal", "map portal", "map floating island", + "map basin", "map lake", "map lava lake", "map river", "map waterfall", "map cave", "map ravine", + "map dungeon", "map mineshaft", "map stronghold", "map village", + + "map desert well", "map desert temple", "map jungle temple", "map witch hut", "map nether fortress", + "map obsidian pillar", "map ender crystal", "map end exit portal", "map teleport altar", + "map estate agency", "map port", "map bank", "map bed", "map inn", "map chest", "map ender chest", + + "map crafting table", "map furnace", "map brewing stand", "map brewing stand and cauldron", + "map cauldron", "map enchantment table", "map anvil", "map anvil damaged", "map cake", "map cake eaten", + "map jukebox", "map map", "map beacon", "map fishing", "map wishing well", "map library", + + "map mine", "map stable", "map fountain", "map shop", "map trading", "map challenge", "map plot", + "map monument", "map gravestone", "map house", "map large house", "map shack", "map tower", + "map castle", "map treehouse", "map ruins", + + "map totem", "map danger", "map prohibited", "map farm", "map wheat", "map sugarcane", + "map cocoa beans", "map netherwart", "map tree", "map melon", "map pumpkin", "map cactus", + "map carrot", "map potato", "map animal farm", "map pig farm", + + "map sheep farm", "map cow farm", "map chicken farm", "map horse farm", "map mooshroom farm", + "map squid farm", "map snow golem farm", "map forest", "map desert", "map plains", "map swamp", + "map jungle", "map taiga", "map tundra", "map mountains", "map mushroom island", + + "mapspawner", "mapzombiespawner", "mapskeletonspawner", "mapspiderspawner", "mapcavespiderspawner", + "mapblaze spawner", "mapsilverfishspawner", "mapendermanspawner", "mappigspawner", + "pigmob", "sheepmob", "cowmob", "chickenmob", "horsemob", "donkeymob", "mulemob", + + "map grinder", "map zombie grinder", "map skeleton grinder", "map spider grinder", "map cave spider grinder", + "map blaze grinder", "map silverfish grinder", "map enderman grinder", "map pig grinder", + "skeleton horse mob", "zombie horse mob", "mooshroom mob", "squid mob", "wolf mob", "dog mob", "angry wolf mob", + + "map xp grinder", "map zombie xp grinder", "map skeleton xp grinder", "map spider xp grinder", + "map cave spider xp grinder", "map blaze xp grinder", "map silverfish xp grinder", "map enderman xp grinder", + "map pig xp grinder", "ocelotmob", "blackcatmob", "gingercatmob", "siamesecatmob", "batmob", + "farmermob", "butchermob", + + "blacksmithmob", "librarianmob", "priestmob", "villagermob", "humanmob", "snowgolemmob", + "iron golemmob", "enderdragonmob", "withermob", "witherprotectedmob", "creepermob", + "chargedcreepermob", "skeletonmob", "witherskeletonmob", "spidermob", "zombiemob", + + "zombievillagermob", "slimemob", "ghastmob", "firingghastmob", "zombiepigmanmob", "endermanmob", + "cavespidermob", "silverfishmob", "blazemob", "magmacubemob", "witchmob", + "unused", "unused", "unused", "unused", "unused", + + "amenity hidden chest", "amenity multi chest", "amenity hidden trapped chest", "amenity return portal", + "amenity floor plan map", "amenity map", "amenity secrets map", "amenity wastebasket", + "amenity fountain of life", "amenity key portal", "amenity xp bank", "amenity alchemic circle", + "amenity meeting chamber", "amenity item spawn", "amenity heaven's door", "amenity hell's door", + + "amenity buying trader", "amenity gear trader", "amenity food/material trader", "amenity food/mat/pot trader", + "amenity omni trader", "map tfda zombie spawner", "map tfda zombie grinder", "map tfda zombie xp grinder", + "unused", "unused", "unused", "unused", "unused", "unused", "map christmas chest", "map trapped chest", + + "tfda zombie mob", "tfda woman mob", "unused", "unused", "unused", "unused", "unused", "unused", + "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", + + "white sword", "white pickaxe", "white shovel", "white axe", "white hoe", "white bow", "white arrow", + "white helmet", "white chestplate", "white leggings", "white boots", + "white fishing rod", "white lead", "white name tag", "white horse armor", "white saddle", + + "white minecart", "white minecart with chest", "white boat", "white book", "white empty map", "white map", + "white bucket", "white egg", "white ender pearl", "white eye of ender", "white fire charge", "white disc", + "white bottle o' enchanting", "white firework", "white firework star blank", "white firework star", + + "white orange dye", "white magenta dye", "white light blue dye", "white dandelion yellow", + "white light gray dye", "white cyan dye", "white lapis lazuli", "white cocoa beans", "white cactus green", + "white rose red", "white ink sac", "white sign", "white painting", "white item frame", "white door", "white hopper", + + "white bed", "white redstone dust", "white iron ingot", "white coal", "white charcoal", "white diamond", + "white ruby", "white emerald", "white nether quartz", "white flint", "white gold nugget", + "white ghast tear", "white nether star", "white clay ball", "white slimeball", "unused", + + "white skeleton skull", "white wither skeleton skull", "white zombie head", "white head", "white creeper head", + "white stick", "white blaze rod", "white blaze powder", "white magma cream", "white leather", + "white paper", "white fermented spider eye", "white spider eye", "unused", "unused", "unused", + + "white seeds", "white melon seeds", "white pumpkin seeds", "white netherwart", "white sugarcane", + "white wheat", "white carrot", "white golden carrot", "white potato", "white baked potato", "white poisonous potato", + "white melon", "white glistering melon", "white apple", "white golden apple", "white rotten flesh", + + "white raw porkchop", "white porkchop", "white raw beef", "white steak", "white raw fish", + "white cooked fish", "white raw chicken", "white cooked chicken", "white bowl", "white mushroom stew", + "white bread", "white cookie", "white cake", "white pumpkin pie", "unused", "unused", + + "tfda white helmet", "tfda white chestplate", "tfda white leggings", "tfda white boots", + "tfda white nether quartz", "tfda white zombie head", "tfda white purple dye", "old white cocoa beans", + "unused", "unused", "unused", "unused", "unused", "unused", "white starfish", "white seashell", + + "white oak sapling", "white spruce sapling", "white birch sapling", "white jungle sapling", + "white sugarcane block", "white netherwart 3", "white netherwart 2", "white netherwart 1", + "white red mushroom", "white brown mushroom", "white rose", "white dandelion", + "white iron bars", "white wheat block", "white potatoes", "white carrots", + + "white rail", "white rail horizontal", "white ladder", "white ladder horizontal", + "white lever", "white torch", "white shrub", + "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", + + "white fire", "white stationary water", "white flowing water", "white stationary lava", + "white flowing lava", "white nether portal", "white stationary water solid", + "white flowing water solid", "white nether portal solid", "white ore tile", "white stone tile", + "white stone bricks tile", "white cracked stone bricks tile", "white chiseled stone bricks tile", + "white stone slab top tile", "white stone slab side tile", + + "white furnace top tile", "white coal block tile", "white iron block tile", "white gold block tile", + "white redstone block tile", "white lapis lazuli block tile", "white emerald block tile", + "white bedrock tile", "white redstone lamp tile", "white powered redstone lamp tile", + "white daylight detector bottom tile", "white daylight detector tile", + "white jukebox tile", "white note block tile", "white dirt tile", "white grass block tile", + + "white mycelium tile", "white farmland tile", "white snow tile", "white soul sand tile", "white gravel tile", + "white sand tile", "white sandstone tile", "white smooth sandstone tile", "white chiseled sandstone tile", + "white sandstone top tile", "white sandstone bottom tile", "white end stone tile", + "white obsidian tile", "white glowstone tile", "white nether brick block tile", "white netherrack tile", + + "white oak log tile", "white oak log top tile", "white oak planks tile", "white pumpkin tile", + "white jack o' lantern tile", "white pumkin side tile", "white pumpkin top tile", "white melon block tile", + "white melon block top tile", "white tnt tile", "white spawner tile", "white command block tile", + "white beacon crystal tile", "white item frame back tile", "white painting back tile", "white static tile", + + "tfda white coal block tile", "tfda white redstone block tile", "tfda white lapis lazuli block tile", + "tfda white hardened clay tile", "unused", "unused", "unused", "tfda white snowy grass block tile", + "tfda white snow tile", "unused", "unused", "unused", "unused", "unused", + "tfda white chiseled sandstone tile", "tfda white bricks tile", + + "white boat entity", "white sign front", "white sign back", "white chest tile", "white trapped chest tile", + "white ender chest tile", "white christmas chest tile", "white doublechest", "white trapped doublechest", + "white christmas doublechest", "unused", "unused", "unused", "unused", + "tfda white trapped chest tile", "tfda white trapped doublechest", + + "white ender crystal shell", "white ender crystal gem 1", "white ender crystal gem 2", + "white ender crystal gem 3", "white ender crystal gem 4", "white ender crystal gem 5", + "white ender crystal gem 6", "white ender crystal 1", "white ender crystal 2", "white ender crystal 3", + "white ender crystal 4", "white ender crystal 5", "white ender crystal 6", "white arrow entity", + "white wither skull", "white blue wither skull", + + "white zombie", "white zombie villager", "white witch", "white villager", "white human", "unused", + "white enderman", "white blaze", "unused", "white wither", "unused", "unused", "unused", "unused", + "tfda white zombie", "tfda white woman", + + "white gui blocked arrow", "white gui burning full", "white gui green check", "white gui red x", + "unused", "unused", "unused", "unused", + "white hammer", "white hammer and anvil", "white abacus", "white broken shovel", + "unused", "white realms off", "white realms on", "white realms none", + + "white connection 5", "white connection 4", "white connection 3", "white connection 2", "white connection 1", + "white connection 0", "white gui 1", "white gui 2", "white gui 3", "white gui 4", "white gui 5", + "white gui !!!", "unused", "unused", "unused", "unused", + + "white heart container", "white heart", "white half heart", "white poison heart", "white half poison heart", + "white mob heart", "white half mob heart", "white hardcore heart", "white hardcore half heart", + "white hardcore poison heart", "white hardcore half poison heart", "white absorption heart", + "white half absorption heart", "white light heart", "white light half heart", "unused", + + "white armor point", "white half armor point", "white empty armor point", "white air bubble", + "white half air bubble", "white reversed hunger point", "white hunger container", + "white hunger point", "white half hunger point", "white light hunger point", "white light half hunger point", + "white poison hunger point", "white half poison hunger point", "unused", "unused", "unused", + + "white swiftness", "white slowness", "white haste", "white mining fatigue", + "white strength", "white weakness", "white poison", "white regeneration", + "white invisibility", "white hunger", "white jump boost", "white nausea", + "white night vision", "white blindness", "white resistance", "white fire resistance", + + "white water breathing", "white wither status", "white absorption", "unused", "unused", "unused", + "unused", "unused", "unused", "tfda white swiftness", "tfda white slowness", "tfda white regeneration", + "tfda white jump boost", "tfda white nausea", "tfda white blindness", "tfda white wither status", + + "northarrow", "northeastarrow", "eastarrow", "southeastarrow", + "southarrow", "southwestarrow", "westarrow", "northwestarrow", + "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", + + "symbol cycloid emblem aa", "symbol snub diamond twist aa", "symbol diamond twist aa", + "symbol astroid fractal aa", "symbol tight astroid twist aa", "symbol astroid twist aa", "unused", "unused", + "symbol cycloid emblem", "symbol snub diamond twist", "symbol diamond twist", "symbol astroid fractal", + "symbol tight astroid twist", "symbol astroid twist", "unused", "unused", + + "symbol astroid lace aa", "symbol astroid lace thin aa", "symbol astroid lace split aa", + "symbol astroid lace small split aa", "symbol ashndar aa", "symbol quest aa", "unused", "unused", + "symbol astroid lace", "symbol astroid lace thin", "symbol astroid lace split", + "symbol astroid lace small split", "symbol ashndar", "symbol quest", "unused", "unused", + + "symbol x tight aa", "symbol x tight even-odd aa", "symbol adventure aa", "symbol x even-odd aa", + "unused", "unused", "unused", "unused", + "symbol x tight", "symbol x tight even-odd", "symbol adventure", "symbol x even-odd", + "unused", "unused", "unused", "unused", + + "symbol corner pair aa", "symbol corner diamond aa", "symbol inverted corner diamond aa", + "symbol overlay rune aa", "symbol minigame aa", "unused", "unused", "unused", + "symbol corner pair", "symbol corner diamond", "symbol inverted corner diamond", + "symbol overlay rune", "symbol minigame", "unused", "unused", "unused", + + "quest icon", "ashndar icon", "adventure icon", "minigame icon", "unused", "unused", "unused", "unused", + "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", + + "white quest icon", "white ashndar icon", "white adventure icon", "white minigame icon", "unused", "unused", + "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", + + "air", "stone", "bedrock", "obsidian", "netherrack", "glowstone", "endstone", "ice", + "dirt", "grassblock", "mycelium", "sand", "gravel", "soulsand", "clay", "snowblock", + + "coalore", "ironore", "goldore", "redstoneore", "diamondore", "lapislazuliore", "emeraldore", + "netherquartzore", "unused", "coalblock", "ironblock", "goldblock", "redstoneblock", "diamondblock", + "lapislazuliblock", "emeraldblock", + + "cobblestone", "mossy cobblestone", "stone bricks", "mossy stone bricks", "cracked stone bricks", + "chiseled stone bricks", "bricks", "nether brick block", "sandstone", "smooth sandstone", + "chiseled sandstone", "quartz block", "pillar quartz", "chiseled quartz", "hardened clay", "glass", + + "whitestainedclay", "orangestainedclay", "magentastainedclay", "lightbluestainedclay", + "yellowstainedclay", "limestainedclay", "pinkstainedclay", "graystainedclay", + "lightgray stainedclay", "cyanstainedclay", "purplestainedclay", "bluestainedclay", + "brownstainedclay", "greenstainedclay", "redstainedclay", "blackstainedclay", + + "whitewool", "orangewool", "magentawool", "lightbluewool", + "yellowwool", "limewool", "pinkwool", "graywool", + "lightgraywool", "cyanwool", "purplewool", "bluewool", + "brownwool", "greenwool", "redwool", "blackwool", + + "whitecarpet", "orangecarpet", "magentacarpet", "lightbluecarpet", + "yellowcarpet", "limecarpet", "pinkcarpet", "graycarpet", + "lightgray carpet", "cyancarpet", "purplecarpet", "bluecarpet", + "browncarpet", "greencarpet", "redcarpet", "blackcarpet", + + "oaklog", "sprucelog", "birchlog", "junglelog", + "oakplanks", "spruceplanks", "birchplanks", "jungleplanks", + "oakleaves", "spruceleaves", "birchleaves", "jungleleaves", + "oakleaveshd", "spruceleaves hd", "birchleaveshd", "jungleleaveshd", + + "oakwoodstairs", "sprucewoodstairs", "birchwoodstairs", "junglewoodstairs", + "cobblestonestairs", "stonebrickstairs", "sandstonestairs", "brickstairs", "netherbrickstairs", + "quartzstairs", "unused", "pumpkin", "jackolantern", "melonblock", "cactus", "sponge", + + "oakwoodslab", "sprucewoodslab", "birchwoodslab", "junglewoodslab", + "cobblestoneslab", "stonebrickslab", "sandstoneslab", "brickslab", "netherbrickslab", "quartzslab", + "stoneslab", "cobblestonewall", "mossycobblestonewall", "fence", "netherbrickfence", "fencegate", + + "bookshelf", "crafting table", "furnace", "dispenser", "dropper", "piston", "sticky piston", + "note block", "jukebox", "redstone lamp", "tnt", "hay bale", "stone pressure plate", + "wooden pressure plate", "weighted pressure plate (light)", "weighted pressure plate (heavy)", + + "chest", "trapped chest", "ender chest", "enchantment table", "end portal frame", + "anvil", "slightly damaged anvil", "very damaged anvil", "trapdoor", "snow", "daylight detector", + "stone button", "wooden button", "enderdragonegg", "command block", "spawner", + + "doubleslab", "smooth stone doubleslab", "smooth sandstone doubleslab", "farmland", "wet farmland", + "furnace back", "lit redstone lamp", "error block", "cake block", "eaten cake block", + "nether portal block", "flipped nether portal block", "unused", + "flipped pumpkin", "flipped jack o' lantern", "uncarved pumpkin", + + "left oak log", "left spruce log", "left birch log", "left jungle log", + "right oak log", "right spruce log", "right birch log", "right jungle log", + "full bark oak log", "full bark spruce log", "full bark birch log", "full bark jungle log", + "left pillar quartz", "right pillar quartz", "left hay bale", "right hay bale", + + "mushroom pore", "mushroom stem", "mushroom full stem", + "brown mushroom left", "brown mushroom center", "brown mushroom right", "brown mushroom full block", + "red mushroom left", "red mushroom center", "red mushroom right", "red mushroom full block", + "unused", "locked chest", "glowingobsidian", "nether reactor", "stonecutter", + + "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", + "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", + + "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", + "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", + + "tfda bedrock", "tfda redstone ore", "corrupt bricks", "summoning brick", + "tfda obsidian", "tfda glowstone", "air glyph", "water glyph", "earth glyph", "fire glyph", + "unused", "tfda netherrack", "tfda ice", "tfda mycelium", "tfda snow block", "tfda snow", + + "tfda coal block", "tfda redstone block", "tfda lapis lazuli block", "cracked icy bricks", + "tfda chiseled sandstone", "tfda hardened clay", "tfda bookshelf", "tfda tnt", "tfda locked chest", + "tfda birch log", "tfda cactus", "tfda sponge", "icy brick fence", "tfda nether brick fence", "unused", "unused", + + "tfda white stained clay", "tfda light blue stained clay", "tfda lime stained clay", + "tfda pink stained clay", "tfda gray stained clay", "tfda light gray stained clay", "tfda cyan stained clay", + "tfda purple stained clay", "tfda blue stained clay", "tfda green stained clay", "tfda black stained clay", + "unused", "tfda cobblestone", "tfda bricks", "tfda nether brick block", "tfda spruce planks", + + "icy brick stairs", "tfda brick stairs", "tfda nether brick stairs", "tfda spruce wood stairs", + "icy brick slab", "tfda brick slab", "tfda nether brick slab", "tfda spruce wood slab", + "unused", "tfda orange wool", "glowing red cloth", "light blue cloth", "yellow cloth", + "purple cloth", "green cloth", "red cloth", + + "tfda orange carpet", "glowing red carpet", "tfda light blue carpet", "tfda yellow carptet", + "tfda purple carpet", "tfda green carpet", "tfda red carpet", "unused", + "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", + + "white stone", "white bedrock", "white obsidian", "white netherrack", "white glowstone", + "white end stone", "white ice", "white dirt", "white sand", "white gravel", "white soul sand", + "white clay", "white snow block", "white ore", "unused", "unused", + + "white coal block", "white iron block", "white gold block", "white redstone block", + "white lapis lazuli block", "white emerald block", "white oak log", "white birch log", + "white jungle log", "white planks", "white oak leaves", "white spruce leaves", "white jungle leaves", + "white oak leaves hd", "white spruce leaves hd", "white jungle leaves hd", + + "white cobblestone", "white stone bricks", "white chiseled stone bricks", "white bricks", + "white nether brick block", "white sandstone", "white smooth sandstone", "white chiseled sandstone", + "white quartz block", "white pillar quartz", "white chiseled quartz", "white hardened clay", + "white glass", "white chest", "white ender chest", "white end portal frame", + + "white wood stairs", "white cobblestone stairs", "white stone brick stairs", "white sandstone stairs", + "white brick stairs", "white nether brick stairs", "white quartz stairs", "unused", + "white pumpkin", "white jack o' lantern", "white melon", "white cactus", "white sponge", + "white anvil", "white slightly damaged anvil", "white very damaged anvil", + + "white wood slab", "white cobblestone slab", "white stone brick slab", "white sandstone slab", + "white brick slab", "white nether brick slab", "white quartz slab", "white stone slab", + "white cobblestone wall", "white fence", "white netherbrick fence", "white fence gate", + "white snow", "white daylight detector", "white stone button", "white wooden button", + + "white bookshelf", "white crafting table", "white furnace", "white dispenser", "white dropper", + "white piston", "white note block", "white jukebox", "white redstone lamp", "white tnt", "white hay bale", + "white stone pressure plate", "white wooden pressure plate", "white weighted pressure plate (light)", + "white weighted pressure plate (heavy)", "white trapdoor", + + "white enderdragon egg", "white command block", "white spawner", "white doubleslab", + "white smooth stone doubleslab", "white smooth sandstone doubleslab", "white farmland", "white wet farmland", + "white furnace back", "white lit redstone lamp", "white error block", "white cake block", + "white eaten cake block", "white nether portal block", "white flipped nether portal block", "unused", + + "white left oak log", "white left birch log", "white left jungle log", + "white right oak log", "white right birch log", "white right jungle log", + "white full bark oak log", "white full bark birch log", "white full bark jungle log", + "white flipped pumpkin", "white flipped jack o' lantern", "white uncarved pumpkin", + "white left pillar quartz", "white right pillar quartz", "white left hay bale", "white right hay bale", + + "white mushroom pore", "white mushroom stem", "white mushroom full stem", "white brown mushroom left", + "white brown mushroom center", "white brown mushroom right", "white brown mushroom full block", + "white red mushroom left", "white red mushroom center", "white red mushroom right", + "white red mushroom full block", "unused", "white locked chest", + "white glowing obsidian", "white nether reactor", "white stonecutter", + + "tfda white bedrock", "tfda white redstone ore", "tfda white obsidian", "tfda white glowstone", + "white air glyph", "white water glyph", "white earth glyph", "white fire glyph", + "unused", "tfda white ice", "tfda white mycelium", "white cracked icy bricks", + "tfda white chiseled sandstone", "tfda white hardened clay", "tfda white cobblestone", "tfda white bricks", + + "white glowing red cloth", "white light blue cloth", "white yellow cloth", + "white purple cloth", "white green cloth", "white red cloth", + "white glowing red carpet", "tfda white light blue carpet", "tfda white yellow carptet", + "tfda white purple carpet", "tfda white green carpet", "tfda white red carpet", + "white icy brick fence", "tfda white trapped chest", "unused", "unused", + + "glowing nether star", "glowing bottle o' enchanting", "glowing golden apple", "glowing enchanted book", + "glowing written book", "unused", "unused", "unused", "celestial magic powder", "arcane magic powder", + "aetheric magic powder", "sagittan magic powder", "tenacious magic powder", "lithe magic powder", + "unearthly magic powder", "divine magic powder", + + "tfda clock noon", "tfda clock sunset", "tfda clock sunrise", "tfda clock midnight", + "unused", "unused", "unused", "unused", + "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", + + "large north arrow", "large northeast arrow", "large east arrow", "large southeast arrow", + "large south arrow", "large southwest arrow", "large west arrow", "large northwest arrow", + "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", + + "large symbol cycloid emblem aa", "large symbol snub diamond twist aa", "large symbol diamond twist aa", + "large symbol astroid fractal aa", "large symbol tight astroid twist aa", "large symbol astroid twist aa", + "unused", "unused", "large symbol cycloid emblem", "large symbol snub diamond twist", + "large symbol diamond twist", "large symbol astroid fractal", "large symbol tight astroid twist", + "large symbol astroid twist", "unused", "unused", + + "large symbol astroid lace aa", "large symbol astroid lace thin aa", "large symbol astroid lace split aa", + "large symbol astroid lace small split aa", "large symbol ashndar aa", "large symbol quest aa", "unused", + "unused", "large symbol astroid lace", "large symbol astroid lace thin", "large symbol astroid lace split", + "large symbol astroid lace small split", "large symbol ashndar", "large symbol quest", "unused", "unused", + + "large symbol x tight aa", "large symbol x tight even-odd aa", "large symbol adventure aa", "large symbol x even-odd aa", + "unused", "unused", "unused", "unused", + "large symbol x tight", "large symbol x tight even-odd", "large symbol adventure", "large symbol x even-odd", + "unused", "unused", "unused", "unused", + + "large symbol corner pair aa", "large symbol corner diamond aa", "large symbol inverted corner diamond aa", + "large symbol overlay rune aa", "large symbol minigame aa", "unused", "unused", "unused", + "large symbol corner pair", "large symbol corner diamond", "large symbol inverted corner diamond", + "large symbol overlay rune", "large symbol minigame", "unused", "unused", "unused", + + "large quest icon", "large ashndar icon", "large adventure icon", "large minigame icon", + "unused", "unused", "unused", "unused", + "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", + + "large white quest icon", "large white ashndar icon", "large white adventure icon", + "large white minigame icon", "unused", "unused", + "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused"}; + + CHARACTER_NAME_MAP = new HashMap(); + for (int i = 0; i < CHARACTER_NAME_LIST.length; i++) { + CHARACTER_NAME_MAP.put(CHARACTER_NAME_LIST[i], (char) (i + UNICODE_OFFSET)); + } + } + + public static String convertInput(String inputText) { + StringBuilder newString = new StringBuilder(inputText.length()); + String[] tokens = inputText.split("[\\:\\}]"); + for (int i = 0; i < tokens.length; i++) { + if (i % 2 > 0) { + Character translatedChar = CHARACTER_NAME_MAP.get(tokens[i].toLowerCase()); + if (translatedChar == null) { + if (translatedChar == null) { + newString.append(':').append(tokens[i]).append(':'); + } else { + appendCharacter(newString, translatedChar); + } + } else { + appendCharacter(newString, translatedChar); + } + } else { + newString.append(tokens[i]); + } + } + return newString.toString(); + } + + private static void appendCharacter(StringBuilder string, Character character) { + if (escape) { + string.append("��f"); + } + string.append(character); + if (escape) { + string.append("��0"); + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/Identifiable.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/Identifiable.java new file mode 100644 index 0000000..5d5f34b --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/Identifiable.java @@ -0,0 +1,15 @@ +package net.grandtheftmc.core.util; + +/** + * This interface is especially useful for storing serialized objects in a map, + * and acts as a reminder to engineers to mark an object with an id. + */ +public interface Identifiable<T> { + + /** + * Get the identification for this object. + * + * @return The identification for this object. + */ + T getId(); +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/ImageRenderer.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/ImageRenderer.java new file mode 100644 index 0000000..67f2d7a --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/ImageRenderer.java @@ -0,0 +1,73 @@ +package net.grandtheftmc.core.util; + +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.lang.ref.SoftReference; +import java.net.URL; +import java.util.HashMap; +import java.util.UUID; + +import javax.imageio.ImageIO; + +import com.google.common.collect.Maps; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.map.MapCanvas; +import org.bukkit.map.MapRenderer; +import org.bukkit.map.MapView; + +/** + * Created by Luke Bingham on 12/09/2017. + */ +public class ImageRenderer extends MapRenderer { + + public static final HashMap<UUID, ImageRenderer> RENDERED_USERS = Maps.newHashMap(); + + // So fancy. + private BufferedImage cacheImage; + + public ImageRenderer(String url) throws IOException { + this.cacheImage = this.getImage(url); + } + + @Override + public void render(MapView view, MapCanvas canvas, Player player) { +// if(RENDERED_USERS.containsKey(player.getUniqueId())) return; + RENDERED_USERS.put(player.getUniqueId(), this); + + if (this.cacheImage != null) { + canvas.drawImage(0, 0, this.cacheImage); + } else { + player.sendMessage(ChatColor.RED + "Attempted to render the image, but the cached image was null!"); + } + } + + private BufferedImage getImage(String url) throws IOException { + boolean useCache = ImageIO.getUseCache(); + + // Temporarily disable cache, if it isn't already, + // so we can get the latest image. + ImageIO.setUseCache(false); + + BufferedImage image = resize(new URL(url), new Dimension(128, 128)); + // TODO find import for RenderUtils + //RenderUtils.resizeImage(image); + + // Renable it with the old value. + ImageIO.setUseCache(useCache); + + return image; + } + + private BufferedImage resize(final URL url, final Dimension size) throws IOException { + final BufferedImage image = ImageIO.read(url); + final BufferedImage resized = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_ARGB); + final Graphics2D g = resized.createGraphics(); + g.drawImage(image, 0, 0, size.width, size.height, null); + g.dispose(); + return resized; + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/ItemAttributes.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/ItemAttributes.java new file mode 100644 index 0000000..e5d219c --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/ItemAttributes.java @@ -0,0 +1,112 @@ +package net.grandtheftmc.core.util; + + +import org.bukkit.Bukkit; +import org.bukkit.inventory.ItemStack; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; + +public class ItemAttributes { + private Object modifiers; + + public ItemAttributes() { + try { + this.modifiers = ReflectionUtils.getNMSClass("NBTTagList").newInstance(); + if (this.modifiers == null) { + Bukkit.getLogger().info("[ItemAttributeAPI] Incompatible Server version! Missing classes."); + } + } catch (InstantiationException | IllegalAccessException e) { + Bukkit.getLogger().info("[ItemAttributeAPI] Incompatible server version! Some methods can't be applied."); + } + } + + public void addModifier(AttributeModifier modifier) { + if (this.modifiers != null) { + try { + this.modifiers.getClass().getMethod("add", new Class[]{ReflectionUtils.getNMSClass("NBTBase")}).invoke(this.modifiers, modifier.getNBT()); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) { + Bukkit.getLogger().info("[ItemAttributeAPI] Incompatible server version! Some methods can't be applied."); + } + } + } + + public void removeModifier(int i) { + if (this.modifiers != null) { + try { + try { + this.modifiers.getClass().getMethod("a", new Class[]{Integer.TYPE}).invoke(this.modifiers, i); + } catch (NoSuchMethodException e) { + this.modifiers.getClass().getMethod("remove", new Class[]{Integer.TYPE}).invoke(this.modifiers, i); + } + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) { + Bukkit.getLogger().info("[ItemAttributeAPI] Incompatible server version! Some methods can't be applied."); + } + } + } + + public void removeModifier(AttributeModifier modifier) { + if (this.modifiers != null) { + try { + int size = (Integer) this.modifiers.getClass().getMethod("size", new Class[0]).invoke(this.modifiers); + for (int i = 0; i < size; i++) { + if (this.modifiers.getClass().getMethod("get", new Class[]{Integer.TYPE}).invoke(this.modifiers, new Object[]{Integer.valueOf(i)}).equals(modifier.getNBT())) { + try { + this.modifiers.getClass().getMethod("a", new Class[]{Integer.TYPE}).invoke(this.modifiers, i); + } catch (NoSuchMethodException e) { + this.modifiers.getClass().getMethod("remove", new Class[]{Integer.TYPE}).invoke(this.modifiers, i); + } + } + } + } catch (IllegalAccessException | InvocationTargetException | SecurityException | NoSuchMethodException e) { + Bukkit.getLogger().info("[ItemAttributeAPI] Incompatible server version! Some methods can't be applied."); + } + } + } + + public List<AttributeModifier> getModifiers() { + if (this.modifiers != null) { + try { + List<AttributeModifier> modifiers = new ArrayList(); + int size = (Integer) this.modifiers.getClass().getMethod("size", new Class[0]).invoke(this.modifiers); + for (int i = 0; i < size; i++) { + modifiers.add(new AttributeModifier(this.modifiers.getClass().getMethod("get", new Class[]{Integer.TYPE}).invoke(this.modifiers, i))); + } + return modifiers; + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) { + Bukkit.getLogger().info("[ItemAttributeAPI] Incompatible server version! Some methods can't be applied."); + return null; + } + } + return null; + } + + public ItemStack apply(ItemStack item) { + try { + Object itemNMS = ReflectionUtils.getCBClass("inventory.CraftItemStack").getMethod("asNMSCopy", new Class[]{ItemStack.class}).invoke(null, item); + itemNMS.getClass().getMethod("a", new Class[]{String.class, ReflectionUtils.getNMSClass("NBTBase")}).invoke(itemNMS, "AttributeModifiers", this.modifiers); + return (ItemStack) ReflectionUtils.getCBClass("inventory.CraftItemStack").getMethod("asBukkitCopy", new Class[]{ReflectionUtils.getNMSClass("ItemStack")}).invoke(null, itemNMS); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) { + Bukkit.getLogger().info("[ItemAttributeAPI] Incompatible server version! Some methods can't be applied."); + } + return null; + } + + public void getFromStack(ItemStack item) { + try { + Object itemNMS = ReflectionUtils.getCBClass("inventory.CraftItemStack").getMethod("asNMSCopy", new Class[]{ItemStack.class}).invoke(null, item); + Object itemNMSTag = itemNMS.getClass().getMethod("getTag", new Class[0]).invoke(itemNMS); + this.modifiers = itemNMSTag.getClass().getMethod("getList", new Class[]{String.class, Integer.TYPE}).invoke(itemNMSTag, "AttributeModifiers", 10); + if (this.modifiers == null) { + this.modifiers = ReflectionUtils.getNMSClass("NBTTagList").newInstance(); + } + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException | InstantiationException e) { + Bukkit.getLogger().info("[ItemAttributeAPI] Incompatible server version! Some methods can't be applied."); + } + } + + public String getVersion() { + return "1.1,Release"; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/ItemStackManager.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/ItemStackManager.java new file mode 100644 index 0000000..260e6fd --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/ItemStackManager.java @@ -0,0 +1,105 @@ +package net.grandtheftmc.core.util; + +import java.util.HashMap; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.ItemStack; + +import com.google.common.collect.Maps; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.events.ItemStackEvent; + +/** + * Created by Luke Bingham on 06/08/2017. + */ +public class ItemStackManager implements Listener { + + public static final HashMap<Material, Integer> STACKABLES; + + static { + STACKABLES = Maps.newHashMap(); + new ItemStackManager(); + } + + public ItemStackManager() { + Bukkit.getPluginManager().registerEvents(this, Core.getInstance()); + } + + @EventHandler //TODO + protected final void onInventoryClick(InventoryClickEvent event) { + + if(event.isCancelled()) return; + if(event.getSlotType() == null) return; + boolean cursorStack = false; + if(event.getSlotType() == InventoryType.SlotType.RESULT) { + if(event.getRawSlot() == 0) { + return; + } + } + + ItemStack cursor = event.getCursor(), clicked = event.getCurrentItem(); + if(event.getClick() == ClickType.SHIFT_RIGHT || event.getClick() == ClickType.SHIFT_LEFT) { + ItemStackEvent stackEvent = new ItemStackEvent(clicked); + Bukkit.getPluginManager().callEvent(stackEvent); + + if(stackEvent.isClickOnly()) { + event.setCancelled(true); + ((Player) event.getWhoClicked()).updateInventory(); + return; + } + } + + // if one of the cursors or clicked is null, allow + if(cursor == null || clicked == null) return; + + // if they are not the same type, allow + if(cursor.getType() != clicked.getType()) return; + //if(!STACKABLES.containsKey(cursor.getType())) return; + if(cursor.getDurability() != clicked.getDurability()) return; + + ((Player) event.getWhoClicked()).updateInventory(); + if((clicked.getAmount() >= 64 || cursor.getAmount() >= 64) || (clicked.getAmount() + cursor.getAmount() > 64)) { + event.setCancelled(true); + return; + } + + if(!cursor.hasItemMeta() && !clicked.hasItemMeta()) { + ItemStackEvent stackEvent = new ItemStackEvent(clicked); + Bukkit.getPluginManager().callEvent(stackEvent); + + if(!stackEvent.isCancelled()) { + event.setCancelled(true); + if(!cursorStack) { + clicked.setAmount(clicked.getAmount() + cursor.getAmount()); + event.setCursor(new ItemStack(Material.AIR)); + } + ((Player) event.getWhoClicked()).updateInventory(); + } else event.setCancelled(true); + return; + } + + if(cursor.getItemMeta() == null || cursor.getItemMeta().getDisplayName() == null) return; + if(!cursor.getItemMeta().getDisplayName().equals(clicked.getItemMeta().getDisplayName())) + return; + + ItemStackEvent stackEvent = new ItemStackEvent(clicked); + Bukkit.getPluginManager().callEvent(stackEvent); + + if(!stackEvent.isCancelled()) { + event.setCancelled(true); + if(!cursorStack) { + clicked.setAmount(clicked.getAmount() + cursor.getAmount()); + event.setCursor(new ItemStack(Material.AIR)); + } + ((Player) event.getWhoClicked()).updateInventory(); + } else event.setCancelled(true); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/MathUtil.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/MathUtil.java new file mode 100644 index 0000000..202b234 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/MathUtil.java @@ -0,0 +1,28 @@ +package net.grandtheftmc.core.util; + +public class MathUtil { + + /** + * Get the percentage based on the distance between 'goal' and 'value' + * + * @param goal - Highest point + * @param value - Your input value (lower than 'goal') + * @return percentage + */ + public static double getPercentBetweenValues(double goal, double value) { + if(value >= goal) return 100.0; + return 100 - Math.abs(((goal - value) / goal) * 100); + } + + /** + * Get the percentage based on the distance between 'goal' and 'value' + * + * @param goal - Lowest point + * @param value - Your input value (higher than 'goal') + * @return percentage + */ + public static double getPercentBetweenValuesReverse(double goal, double value) { + if(goal >= value) return 100.0; + return 100 - Math.abs(((value - goal) / value) * 100); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/NMSUtil.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/NMSUtil.java new file mode 100644 index 0000000..3abf25c --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/NMSUtil.java @@ -0,0 +1,53 @@ +package net.grandtheftmc.core.util; + +import com.comphenix.protocol.wrappers.EnumWrappers; +import com.comphenix.protocol.wrappers.WrappedChatComponent; +import net.grandtheftmc.core.wrapper.packet.out.WrapperPlayServerPlayerListHeaderFooter; +import net.grandtheftmc.core.wrapper.packet.out.WrapperPlayServerWorldBorder; +import org.bukkit.entity.Player; + +public class NMSUtil { + + public static void sendTabTitle(Player player, String header, String footer) { +// org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer craftplayer = (org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer) player; +// net.minecraft.server.v1_12_R1.PlayerConnection connection = craftplayer.getHandle().playerConnection; +// net.minecraft.server.v1_12_R1.IChatBaseComponent JSONheader = net.minecraft.server.v1_12_R1.IChatBaseComponent.ChatSerializer.a("{\"text\": \"" + header + "\"}"); +// net.minecraft.server.v1_12_R1.IChatBaseComponent JSONfooter = net.minecraft.server.v1_12_R1.IChatBaseComponent.ChatSerializer.a("{\"text\": \"" + footer + "\"}"); +// net.minecraft.server.v1_12_R1.PacketPlayOutPlayerListHeaderFooter packet = new net.minecraft.server.v1_12_R1.PacketPlayOutPlayerListHeaderFooter(); +// try { +// Field headerField = packet.getClass().getDeclaredField("a"); +// headerField.setAccessible(true); +// headerField.set(packet, JSONheader); +// headerField.setAccessible(!headerField.isAccessible()); +// +// Field footerField = packet.getClass().getDeclaredField("b"); +// footerField.setAccessible(true); +// footerField.set(packet, JSONfooter); +// footerField.setAccessible(!footerField.isAccessible()); +// } catch (Exception ex) { +// ex.printStackTrace(); +// } +// connection.sendPacket(packet); + + WrapperPlayServerPlayerListHeaderFooter wrappedPacket = new WrapperPlayServerPlayerListHeaderFooter(); + wrappedPacket.setHeader(WrappedChatComponent.fromJson("{\"text\": \"" + header + "\"}")); + wrappedPacket.setFooter(WrappedChatComponent.fromJson("{\"text\": \"" + footer + "\"}")); + wrappedPacket.sendPacket(player); + } + + public static void setWorldBoarderTint(Player player, int percentage) { +// if (percentage < 0) percentage = 0; +// if (percentage > 100) percentage = 100; +// +// WrapperPlayServerWorldBorder wrappedPacket = new WrapperPlayServerWorldBorder(); +// wrappedPacket.setCenterX(player.getLocation().getX()); +// wrappedPacket.setCenterZ(player.getLocation().getZ()); +// wrappedPacket.setWarningDistance(5000000 + percentage * 2000000); +// wrappedPacket.setWarningTime(0); +// wrappedPacket.setAction(EnumWrappers.WorldBorderAction.INITIALIZE); +// wrappedPacket.setRadius(6.0E7D); +// wrappedPacket.setOldRadius(6.0E7D); +// wrappedPacket.setSpeed(0L); +// wrappedPacket.sendPacket(player); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/NMSVersion.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/NMSVersion.java new file mode 100644 index 0000000..80d99ae --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/NMSVersion.java @@ -0,0 +1,59 @@ +package net.grandtheftmc.core.util; + +import org.bukkit.entity.Player; + +import net.grandtheftmc.core.Core; +import us.myles.ViaVersion.api.Via; + +/** + * Created by Luke Bingham on 02/08/2017. + */ +public enum NMSVersion { + MC_1_8(47), + + MC_1_9(107), + MC_1_9_1(108), + MC_1_9_2(109), + MC_1_9_4(110), + + MC_1_10(210), + + MC_1_11(315), + MC_1_11_2(316), + + MC_1_12(335), + MC_1_12_1(338), + MC_1_12_2(340), + + MC_1_13(393), + MC_1_13_1(401), + + UNKNOWN(0); + ; + + private int protocol; + + private NMSVersion(int protocol) { + this.protocol = protocol; + } + + public int getProtocol() { + return protocol; + } + + public static NMSVersion getVersion(int id) { + for(NMSVersion version : values()) + if(version.protocol == id) return version; + return UNKNOWN; + } + + public static NMSVersion getVersion(Player player) { + int id = Via.getAPI().getPlayerVersion(player.getUniqueId()); + + Core.log("[NMSVersion][Resolve] Player " + player.getName() + " has version id=" + id); + + for(NMSVersion version : values()) + if(version.protocol == id) return version; + return UNKNOWN; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/NumeralUtil.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/NumeralUtil.java new file mode 100644 index 0000000..50461db --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/NumeralUtil.java @@ -0,0 +1,29 @@ +package net.grandtheftmc.core.util; + +import java.text.NumberFormat; +import java.util.Locale; + +/** + * Created by Luke Bingham on 01/08/2017. + */ +public class NumeralUtil { + /** + * If the given Number is, 29956 + * The returned state will be, 29,956.00 + */ + public static <T extends Number> String toCurrency(T number) { + return String.format("%,.2f", number); + } + + /** + * If the given Number is, 29956 + * If the symbol depends on the Locale. + * en_US = $ + * en_GB = £ + * + * The returned state will be, $29,956.00 + */ + public static <T extends Number> String toCurrency(T number, Locale locale) { + return NumberFormat.getCurrencyInstance(locale).format(number); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/PlayerAndIP.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/PlayerAndIP.java new file mode 100644 index 0000000..40080d2 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/PlayerAndIP.java @@ -0,0 +1,28 @@ +package net.grandtheftmc.core.util; + +import org.bukkit.entity.Player; + +public final class PlayerAndIP { + private final Player player; + private final String ip; + + private final CoreLocation coreLocation; + + public PlayerAndIP(Player player, String ip, CoreLocation coreLocation) { + this.player = player; + this.ip = ip; + this.coreLocation = coreLocation; + } + + public Player getPlayer() { + return player; + } + + public String getIp() { + return ip; + } + + public CoreLocation getCoreLocation() { + return coreLocation; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/Playtime.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/Playtime.java new file mode 100644 index 0000000..306a53d --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/Playtime.java @@ -0,0 +1,8 @@ +package net.grandtheftmc.core.util; + +import java.util.HashMap; +import java.util.Map; + +public class Playtime { + public static Map<String, Long> playtime = new HashMap<>(); +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/PluginAssociated.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/PluginAssociated.java new file mode 100644 index 0000000..18cf169 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/PluginAssociated.java @@ -0,0 +1,19 @@ +package net.grandtheftmc.core.util; + +import org.bukkit.plugin.Plugin; + +/** + * Allows super classes to remind that an interface or object might need a + * plugin associated with it. + * + * @author sbahr + */ +public interface PluginAssociated<P extends Plugin> { + + /** + * Get the plugin that is associated with this object. + * + * @return The plugin associated with this object. + */ + P getPlugin(); +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/ReflectionUtils.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/ReflectionUtils.java new file mode 100644 index 0000000..fc1ab37 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/ReflectionUtils.java @@ -0,0 +1,63 @@ +package net.grandtheftmc.core.util; + +import org.bukkit.Bukkit; + +import java.lang.reflect.Field; + +public final class ReflectionUtils +{ + private ReflectionUtils() { + } + + public static Class<?> getNMSClass(String name) + { + try + { + return Class.forName("net.minecraft.server." + Bukkit.getServer().getClass().getName().split("\\.")[3] + '.' + name); + } + catch (ClassNotFoundException e) + { + Bukkit.getLogger().info("[Reflection] Can't find NMS Class! (net.minecraft.server." + Bukkit.getServer().getClass().getName().split("\\.")[3] + '.' + name + ')'); + } + return null; + } + + public static Class<?> getCBClass(String name) + { + try + { + return Class.forName("org.bukkit.craftbukkit." + Bukkit.getServer().getClass().getName().split("\\.")[3] + '.' + name); + } + catch (ClassNotFoundException e) + { + Bukkit.getLogger().info("[Reflection] Can't find CB Class! (org.bukkit.craftbukkit." + Bukkit.getServer().getClass().getName().split("\\.")[3] + '.' + name + ')'); + } + return null; + } + + public static <K, V> K setField(K obj, String field, V value) { + try { + Field f = obj.getClass().getDeclaredField(field); + if(!f.isAccessible()) f.setAccessible(true); + f.set(obj, value); + } catch (NoSuchFieldException | IllegalAccessException e) { + e.printStackTrace(); + } + return obj; + } + + public static <T, E> E getField(T obj, String field, Class<E> clazz) { + try { + Field f = obj.getClass().getDeclaredField(field); + if(!f.isAccessible()) f.setAccessible(true); + E e = (E) f.get(obj); + if(clazz.isInstance(e)) + return e; + } catch (NoSuchFieldException | IllegalAccessException e) { + e.printStackTrace(); + } + + return null; + } +} + diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/ServerUtil.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/ServerUtil.java new file mode 100644 index 0000000..cc2fba0 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/ServerUtil.java @@ -0,0 +1,33 @@ +package net.grandtheftmc.core.util; + +import net.grandtheftmc.core.Core; +import org.bukkit.Bukkit; + +/** + * Created by Luke Bingham on 29/08/2017. + */ +public class ServerUtil { + + private static final boolean DEBUG; + static { DEBUG = Core.getSettings().getNumber() <= 0; } + + public static void runTask(Runnable runnable) { + Bukkit.getScheduler().runTask(Core.getInstance(), runnable); + } + + public static void runTaskLater(Runnable runnable, long time) { + Bukkit.getScheduler().runTaskLater(Core.getInstance(), runnable, time); + } + + public static void runTaskAsync(Runnable runnable) { + Bukkit.getScheduler().runTaskAsynchronously(Core.getInstance(), runnable); + } + + public static void runTaskLaterAsync(Runnable runnable, long time) { + Bukkit.getScheduler().runTaskLaterAsynchronously(Core.getInstance(), runnable, time); + } + + public static void debug(String str) { + if(DEBUG) Bukkit.getConsoleSender().sendMessage(str); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/Similarity.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/Similarity.java new file mode 100644 index 0000000..99b89f3 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/Similarity.java @@ -0,0 +1,8 @@ +package net.grandtheftmc.core.util; + +/** + * Created by Luke Bingham on 21/07/2017. + */ +public interface Similarity<T> { + boolean isSimilar(T obj); +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/Slot.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/Slot.java new file mode 100644 index 0000000..d3d1639 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/Slot.java @@ -0,0 +1,25 @@ +package net.grandtheftmc.core.util; + +public enum Slot { + + MAIN_HAND("mainhand"), + OFF_HAND("offhand"), + FEET("feet"), + LEGS("legs"), + CHEST("chest"), + HEAD("head"); + private final String name; + + Slot(String name) { + this.name = name; + } + + /** + * Get the predefined, global and unique name of this slot. + * + * @return The name + */ + public String getName() { + return this.name; + } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/SoundEffect.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/SoundEffect.java new file mode 100644 index 0000000..a439097 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/SoundEffect.java @@ -0,0 +1,131 @@ +package net.grandtheftmc.core.util; + +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import net.grandtheftmc.core.Core; + +public class SoundEffect { + + private Sound sound; + private float volume; + private float pitch; + private int delay; + + public SoundEffect(Sound sound, float volume, float pitch) { + this.sound = sound; + this.volume = volume; + this.pitch = pitch; + } + + public SoundEffect(Sound sound, float volume, float pitch, int delay) { + this.sound = sound; + this.volume = volume; + this.pitch = pitch; + this.delay = delay; + } + + public void play() { + if (this.hasDelay()) { + new BukkitRunnable() { + @Override + public void run() { + for (Player player : Bukkit.getOnlinePlayers()) + player.playSound(player.getLocation(), SoundEffect.this.sound, SoundEffect.this.volume, SoundEffect.this.pitch); + } + }.runTaskLater(Core.getInstance(), this.delay); + return; + } + for (Player player : Bukkit.getOnlinePlayers()) + player.playSound(player.getLocation(), this.sound, this.volume, this.pitch); + } + + public void play(Location location) { + if (this.hasDelay()) { + new BukkitRunnable() { + @Override + public void run() { + for (Player player : Bukkit.getOnlinePlayers()) + player.playSound(location, SoundEffect.this.sound, SoundEffect.this.volume, SoundEffect.this.pitch); + } + }.runTaskLater(Core.getInstance(), this.delay); + return; + } + for (Player player : Bukkit.getOnlinePlayers()) + player.playSound(location, this.sound, this.volume, this.pitch); + } + + public void play(Player player) { + UUID uuid = player.getUniqueId(); + if (this.hasDelay()) { + new BukkitRunnable() { + @Override + public void run() { + Player player = Bukkit.getPlayer(uuid); + if (player != null) + player.playSound(player.getLocation(), SoundEffect.this.sound, SoundEffect.this.volume, SoundEffect.this.pitch); + } + }.runTaskLater(Core.getInstance(), this.delay); + return; + } + player.playSound(player.getLocation(), this.sound, this.volume, this.pitch); + } + + public void play(Player player, Location location) { + UUID uuid = player.getUniqueId(); + if (this.hasDelay()) { + new BukkitRunnable() { + @Override + public void run() { + Player player = Bukkit.getPlayer(uuid); + if (player != null) + player.playSound(location, SoundEffect.this.sound, SoundEffect.this.volume, SoundEffect.this.pitch); + } + }.runTaskLater(Core.getInstance(), this.delay); + return; + } + player.playSound(location, this.sound, this.volume, this.pitch); + } + + public Sound getSound() { + return this.sound; + } + + public void setSound(Sound sound) { + this.sound = sound; + } + + public float getVolume() { + return this.volume; + } + + public void setVolume(float volume) { + this.volume = volume; + } + + public float getPitch() { + return this.pitch; + } + + public void setPitch(float pitch) { + this.pitch = pitch; + } + + public int getDelay() { + return this.delay; + } + + public void setDelay(int delay) { + this.delay = delay; + } + + public boolean hasDelay() { + return this.delay > 0; + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/State.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/State.java new file mode 100644 index 0000000..4d55e5c --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/State.java @@ -0,0 +1,23 @@ +package net.grandtheftmc.core.util; + +/** + * Created by Timothy Lampen on 8/21/2017. + */ +public enum State { + ON(1), + OFF(0), + LOCKED(-1); + + private final int num; + State(int num){ + this.num = num; + } + + public int toInt(){ + return num; + } + + public int getInt() { + return num; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/StringUtil.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/StringUtil.java new file mode 100644 index 0000000..a514c91 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/StringUtil.java @@ -0,0 +1,88 @@ +package net.grandtheftmc.core.util; + +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +public class StringUtil { + + private final static int CENTER_PX = 154; + private final static int CENTER_MENU_PX = 80; + + public static void sendCenteredMessage(Player player, String message) { + if (message == null || message.equals("")) player.sendMessage(""); + message = ChatColor.translateAlternateColorCodes('&', message); + + int messagePxSize = 0; + boolean previousCode = false; + boolean isBold = false; + + for (char c : message.toCharArray()) { + if (c == '§') { + previousCode = true; continue; + } + + else if (previousCode) { + previousCode = false; + if (c == 'l' || c == 'L') { + isBold = true; continue; + } else isBold = false; + } + + else { + DefaultFontInfo dFI = DefaultFontInfo.getDefaultFontInfo(c); + messagePxSize += isBold ? dFI.getBoldLength() : dFI.getLength(); + messagePxSize++; + } + } + + int halvedMessageSize = messagePxSize / 2; + int toCompensate = CENTER_PX - halvedMessageSize; + int spaceLength = DefaultFontInfo.SPACE.getLength() + 1; + int compensated = 0; + StringBuilder sb = new StringBuilder(); + while (compensated < toCompensate) { + sb.append(" "); + compensated += spaceLength; + } + player.sendMessage(sb.toString() + message); + } + + public static String getCenteredMenuText(String message) { + message = ChatColor.translateAlternateColorCodes('&', message); + + int messagePxSize = 0; + boolean previousCode = false; + boolean isBold = false; + + for (char c : message.toCharArray()) { + if (c == '§') { + previousCode = true; continue; + } + + else if (previousCode) { + previousCode = false; + if (c == 'l' || c == 'L') { + isBold = true; continue; + } else isBold = false; + } + + else { + DefaultFontInfo dFI = DefaultFontInfo.getDefaultFontInfo(c); + messagePxSize += isBold ? dFI.getBoldLength() : dFI.getLength(); + messagePxSize++; + } + } + + int halvedMessageSize = messagePxSize / 2; + int toCompensate = CENTER_MENU_PX - halvedMessageSize; + int spaceLength = DefaultFontInfo.SPACE.getLength() + 1; + int compensated = 0; + StringBuilder sb = new StringBuilder(); + while (compensated < toCompensate) { + sb.append(" "); + compensated += spaceLength; + } + + return sb.toString() + message; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/TimeFormatter.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/TimeFormatter.java new file mode 100644 index 0000000..24260a8 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/TimeFormatter.java @@ -0,0 +1,45 @@ +package net.grandtheftmc.core.util; + +import java.util.concurrent.TimeUnit; + +public class TimeFormatter { + private final TimeUnit timeUnit; + private Long time; + + public TimeFormatter(TimeUnit timeUnit, Long time) { + this.timeUnit = timeUnit; + this.time = time; + } + + public Long getTime() { + return new Long(this.time); + } + + public void setTime(Long time) { + this.time = time; + } + + public TimeUnit getTimeUnit() { + return this.timeUnit; + } + + public Long getSeconds() { + return timeUnit.toSeconds(time) - (timeUnit.toMinutes(time) * 60); + } + + public Long getMinutes() { + return timeUnit.toMinutes(time) - (timeUnit.toHours(time) * 60); + } + + public Long getHours() { + return timeUnit.toHours(time) - (timeUnit.toDays(time) * 24); + } + + public Long getDays() { + return timeUnit.toDays(time); + } + + public Long getMillis() { + return timeUnit.toMillis(time); + } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/Title.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/Title.java new file mode 100644 index 0000000..1dcc943 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/Title.java @@ -0,0 +1,69 @@ +package net.grandtheftmc.core.util; + +import org.bukkit.entity.Player; + +public class Title { + + private String title; + private String subtitle; + private int fadeIn; + private int stay; + private int fadeOut; + + public Title(String title, String subtitle, int fadeIn, int stay, int fadeOut) { + this.title = title; + this.subtitle = subtitle; + this.fadeIn = fadeIn; + this.stay = stay; + this.fadeOut = fadeOut; + } + + public String getTitle() { + return this.title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getSubtitle() { + return this.subtitle; + } + + public void setSubtitle(String subtitle) { + this.subtitle = subtitle; + } + + public int getFadeIn() { + return this.fadeIn; + } + + public void setFadeIn(int fadeIn) { + this.fadeIn = fadeIn; + } + + public int getStay() { + return this.stay; + } + + public void setStay(int stay) { + this.stay = stay; + } + + public int getFadeOut() { + return this.fadeOut; + } + + public void setFadeOut(int fadeOut) { + this.fadeOut = fadeOut; + } + + public void play() { + Utils.sendTitle(this); + } + + public void play(Player player) { + Utils.sendTitle(player, this); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/TopValue.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/TopValue.java new file mode 100644 index 0000000..d315eab --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/TopValue.java @@ -0,0 +1,55 @@ +package net.grandtheftmc.core.util; + +public class TopValue implements Identifiable<String>, Comparable<TopValue>{ + + /** The identifier of this top value*/ + private String id; + /** The amount for this value */ + private int amount; + + /** + * Construct a new TopValue, useful for sorting top scores. + * <p> + * The id can be any string, like a username or a uuid string. + * </p> + * + * @param id - the id for the top value + * @param amount - the amount of the value + */ + public TopValue(String id, int amount){ + this.id = id; + this.amount = amount; + } + + /** + * {@inheritDoc} + */ + @Override + public String getId() { + return id; + } + + /** + * Get the amount of this top value. + * + * @return The amount for this top value. + */ + public int getAmount(){ + return amount; + } + + /** + * {@inheritDoc} + */ + @Override + public int compareTo(TopValue o) { + if (this.amount > o.getAmount()){ + return 1; + } + else if (this.amount < o.getAmount()){ + return -1; + } + + return 0; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/TrigUtil.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/TrigUtil.java new file mode 100644 index 0000000..21d2f42 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/TrigUtil.java @@ -0,0 +1,17 @@ +package net.grandtheftmc.core.util; + +import org.bukkit.Location; + +public class TrigUtil { + + public static float wrapAngleTo180_float(float value) { + value %= 360.0F; + if (value >= 180.0F) value -= 360.0F; + if (value < -180.0F) value += 360.0F; + return value; + } + + public static double getDirection(Location from, Location to) { + return wrapAngleTo180_float((float) (Math.atan2(to.getZ() - from.getZ(), to.getX() - from.getX()) * 180.0D / Math.PI) - 90.0F); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/UUIDUtil.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/UUIDUtil.java new file mode 100644 index 0000000..1be0292 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/UUIDUtil.java @@ -0,0 +1,72 @@ +package net.grandtheftmc.core.util; + +import java.util.Optional; +import java.util.UUID; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Created by Stephen + */ +public class UUIDUtil { + + /** + * A {@link Pattern} used to identify and/or split full UUIDs + */ + private static final Pattern PATTERN_UUID = Pattern.compile("^[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}$", Pattern.CASE_INSENSITIVE); + /** + * A {@link Pattern} used to identify and/or split trimmed UUIDs + */ + private static final Pattern PATTERN_TRIMMED_UUID = Pattern.compile("^([a-z0-9]{8})([a-z0-9]{4})([a-z0-9]{4})([a-z0-9]{4})([a-z0-9]{12})$", Pattern.CASE_INSENSITIVE); + + + /** + * Create a UUID safely from a {@link String}. + * + * @param string The {@link String} to deserialize into an {@link UUID} object. + * @return {@link Optional#empty()} if the provided {@link String} is illegal, otherwise an {@link Optional} + * containing the deserialized {@link UUID} object. + */ + public static Optional<UUID> createUUID(String string) { + + if (string == null) { + return Optional.empty(); + } + + UUID result = null; + + try { + // Is it a valid UUID? + if (!PATTERN_UUID.matcher(string).matches()) { + + // Un-trim UUID if it is trimmed + Matcher matcher = PATTERN_TRIMMED_UUID.matcher(string); + if (matcher.matches()) { + + StringBuilder sb = new StringBuilder(); + + for (int i = 1; i <= matcher.groupCount(); i++) { + if (i != 1) { + sb.append("-"); + } + + sb.append(matcher.group(i)); + } + + string = sb.toString(); + } else { + // Invalid UUID + string = null; + } + } + + if (string != null) { + result = UUID.fromString(string); + } + } catch (IllegalArgumentException ignored) { + // Useless data passed + } + + return Optional.ofNullable(result); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/Utils.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/Utils.java new file mode 100644 index 0000000..4c81759 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/Utils.java @@ -0,0 +1,1139 @@ +package net.grandtheftmc.core.util; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; +import java.text.NumberFormat; +import java.time.LocalDate; +import java.time.Month; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Random; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Color; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.WorldCreator; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.BlockState; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Creature; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.LeatherArmorMeta; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.plugin.Plugin; +import org.bukkit.potion.PotionEffect; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolManager; +import com.comphenix.protocol.events.ListenerPriority; +import com.comphenix.protocol.events.PacketAdapter; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; +import com.j0ach1mmall3.jlib.inventory.CustomEnchantment; +import com.j0ach1mmall3.jlib.methods.ReflectionAPI; +import com.j0ach1mmall3.jlib.player.JLibPlayer; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.boards.Board; +import net.grandtheftmc.core.boards.BoardType; +import net.grandtheftmc.core.database.dao.LogDAO; +import net.grandtheftmc.core.database.dao.ServerInfoDAO; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserDAO; +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.TextComponent; + +public final class Utils { + private static final Random RANDOM = new Random(); + private static final List<String> DEBUGGERS = Arrays.asList("Presidentx", "j0ach1mmall3", "Duci13", "KwonShiYun"); + private static final Class BLOCK_POSITION_CLASS = ReflectionAPI.getNmsClass("BlockPosition"); + private static final Class TILE_ENTITY_CHEST_CLASS = ReflectionAPI.getNmsClass("TileEntityChest"); + private static final Class PACKET_PLAY_OUT_BLOCK_ACTION_CLASS = ReflectionAPI.getNmsClass("PacketPlayOutBlockAction"); + private static final Class BLOCK_CLASS = ReflectionAPI.getNmsClass("Block"); + private static final Enchantment GLOW; + + static { + CustomEnchantment customEnchantment = new CustomEnchantment("GTMCore_Glow", new ArrayList<>(), null, 0, 1); + customEnchantment.register(); + GLOW = customEnchantment.getEnchantment(); + } + + private Utils() { + } + + public static boolean isInteger(String s) { + try { + Integer.parseInt(s); + } catch (NumberFormatException e) { + return false; + } + return true; + } + + public static boolean returnTrue() { + return true; + } + + public static Random getRandom() { + return RANDOM; + } + + public static void broadcast(String string) { + Bukkit.broadcastMessage(f(string)); + } + + public static void broadcastExcept(Player player, String string) { + Bukkit.getOnlinePlayers().stream().filter(p -> !p.equals(player)).forEach(p -> p.sendMessage(Utils.f(string))); + } + + public static ItemStack setLore(ItemStack is, String... lore){ + if(is==null) + return null; + List<String> l = new ArrayList<>(); + for(String s : lore){ + l.add(ChatColor.translateAlternateColorCodes('&', s)); + } + + ItemMeta im = is.getItemMeta(); + im.setLore(l); + is.setItemMeta(im); + return is; + } + + public static void m(int i) { + b(String.valueOf(i)); + } + + public static void b(String string) { + DEBUGGERS.stream().map(Bukkit::getPlayer).filter(p -> p != null).forEach(p -> p.sendMessage(string)); + Core.log(string); + } + + /** + * @param player The player whose line of sight we will use + * @param targetLocation The target location that is converted to a vector to form an angle with line of sight + * @return angle between entity's line of sight and the target vector + */ + public static double getAngleBetweenVectors(Player player, Location targetLocation) { + Vector lineOfSight = player.getEyeLocation().toVector(); + Vector target = targetLocation.toVector(); + target.setY(0); + lineOfSight.setY(0); + return lineOfSight.angle(target); + } + + public static List<Block> blocksFromTwoPoints(Location loc1, Location loc2) { + if (loc1 == null || loc2 == null) return null; + List<Block> blocks = new ArrayList<>(); + + int topBlockX = loc1.getBlockX() < loc2.getBlockX() ? loc2.getBlockX() : loc1.getBlockX(); + int bottomBlockX = loc1.getBlockX() > loc2.getBlockX() ? loc2.getBlockX() : loc1.getBlockX(); + + int topBlockY = loc1.getBlockY() < loc2.getBlockY() ? loc2.getBlockY() : loc1.getBlockY(); + int bottomBlockY = loc1.getBlockY() > loc2.getBlockY() ? loc2.getBlockY() : loc1.getBlockY(); + + int topBlockZ = loc1.getBlockZ() < loc2.getBlockZ() ? loc2.getBlockZ() : loc1.getBlockZ(); + int bottomBlockZ = loc1.getBlockZ() > loc2.getBlockZ() ? loc2.getBlockZ() : loc1.getBlockZ(); + + for (int x = bottomBlockX; x <= topBlockX; x++) { + for (int z = bottomBlockZ; z <= topBlockZ; z++) { + for (int y = bottomBlockY; y <= topBlockY; y++) { + blocks.add(loc1.getWorld().getBlockAt(x, y, z)); + } + } + } + + return blocks; + } + + public static Location getCenterOfBlock(Location loc) { + return loc.add(0.5, 0, 0.5); + } + + public static Location getCenterOfTwoBlocks(Location loc1, Location loc2) { + loc1 = getCenterOfBlock(loc1); + loc2 = getCenterOfBlock(loc2); + return new Location(loc1.getWorld(), (loc1.getX() + loc2.getX()) / 2, loc1.getY(), (loc1.getZ() + loc2.getZ()) / 2); + } + + public static Block getSecondHalfChest(Block block) { + Optional<Block> possibleChest = Stream.of(BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST).map(block::getRelative).filter(b -> b.getType() == Material.CHEST || b.getType() == Material.TRAPPED_CHEST).findFirst(); + return possibleChest.isPresent() ? possibleChest.get() : null; + } + + public static void playDoorAnimation(Location location, boolean open) { + playDoorAnimation(location.getBlock().getState(), open); + } + + public static void playDoorAnimation(Player player, Location location, boolean open) { + playDoorAnimation(player, location.getBlock().getState(), open); + } + + public static void playDoorAnimation(BlockState state, boolean open) { + Bukkit.getOnlinePlayers().forEach(p -> playDoorAnimation(p, state, open)); + } + + @SuppressWarnings("deprecation") + public static void playDoorAnimation(Player player, BlockState state, boolean open) { + byte data = state.getRawData(); + byte b = data < 4 ? open ? (byte) (data + 4) : data : open ? data : (byte) (data - 4); + player.sendBlockChange(state.getLocation(), Material.IRON_DOOR_BLOCK, b); + } + + private static final TimeUnit[] TIME_UNITS = new TimeUnit[] {TimeUnit.DAYS, TimeUnit.HOURS, TimeUnit.MINUTES, TimeUnit.SECONDS}; + public static String formatMillisToTime(long time){ + int counter = 0; + StringBuilder sb = new StringBuilder(); + for(TimeUnit unit : TIME_UNITS) { + if(counter>=2) + break; + long amt = TimeUnit.MILLISECONDS.convert(time, unit); + if(amt>0) { + String strUnit = unit.toString().toLowerCase(); + strUnit = amt==1 ? strUnit.substring(0, strUnit.length()-1) : strUnit; + sb.append(amt + " " + strUnit + " "); + counter++; + } + } + return sb.toString().substring(0, sb.length()-1); + } + + public static void playIronDoorAnimation(Player player, Location loc, boolean open) { + // TODO + } + + public static boolean putItemInInventoryRandomly(Inventory inv, ItemStack item) { + List<Integer> list = new ArrayList<>(); + for (int i = 0; i < inv.getSize(); i++) { + if (inv.getItem(i) == null) list.add(i); + } + + if (list.isEmpty()) return false; + int i = list.get(RANDOM.nextInt(list.size())); + inv.setItem(i, item); + return true; + } + + public static String f(String string) { + return ChatColor.translateAlternateColorCodes('&', string); + } + + public static String fColor(String string) { + for (Character c : new Character[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}) { + if (string.contains("&" + c)) string = string.replace("&" + c, ChatColor.getByChar(c).toString()); + } + + return string; + } + + public static net.md_5.bungee.api.ChatColor getLastColor(String string) { + net.md_5.bungee.api.ChatColor chatColor = null; + for (Character c : new Character[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}) { + if (string.contains("&" + c)) { + chatColor = net.md_5.bungee.api.ChatColor.getByChar(c); + } + } + return chatColor; + } + + public static String deFormat(String string) { + return string.replace(ChatColor.COLOR_CHAR, '&'); + } + + public static String[] f(String[] array) { + if (array == null) return null; + for (int i = 0; i < array.length; i++) { + array[i] = Utils.f(array[i]); + } + + return array; + } + + public static String[] deFormat(String[] array) { + if (array == null) return null; + for (int i = 0; i < array.length; i++) { + array[i] = Utils.deFormat(array[i]); + } + + return array; + } + + public static Location blockLocationFromString(String string) { + if (string == null) return null; + String[] coords = string.split(","); + if (coords.length != 4) return null; + World world = Bukkit.getWorld(coords[0]); + if (world == null) return null; + int x; + int y; + int z; + try { + x = Integer.parseInt(coords[1]); + y = Integer.parseInt(coords[2]); + z = Integer.parseInt(coords[3]); + } catch (NumberFormatException e) { + return null; + } + + return new Location(world, x, y, z); + + } + + public static double round(double value) { + return new BigDecimal(value).setScale(2, RoundingMode.HALF_UP).doubleValue(); + } + + public static float round(float value) { + return new BigDecimal(value).setScale(2, RoundingMode.HALF_UP).floatValue(); + } + + public static String blockLocationToString(Location loc) { + if (loc == null) return null; + return loc.getWorld().getName() + ',' + loc.getBlockX() + ',' + loc.getBlockY() + ',' + loc.getBlockZ(); + } + + public static Location teleportLocationFromString(String string) { + if (string == null) return null; + String[] coords = string.split(","); + if (coords.length != 6) return null; + World world = Bukkit.getWorld(coords[0]); + double x; + double y; + double z; + float pitch; + float yaw; + try { + x = round(Double.parseDouble(coords[1])); + y = round(Double.parseDouble(coords[2])); + z = round(Double.parseDouble(coords[3])); + pitch = round(Float.parseFloat(coords[4])); + yaw = round(Float.parseFloat(coords[5])); + } catch (NumberFormatException e) { + return null; + } + + Location location = new Location(world, x, y, z); + location.setPitch(pitch); + location.setYaw(yaw); + return location; + } + + public static String teleportLocationToString(Location loc) { + if (loc == null) return null; + return loc.getWorld().getName() + ',' + round(loc.getX()) + ',' + round(loc.getY()) + ',' + round(loc.getZ()) + ',' + round(loc.getPitch()) + ',' + round(loc.getYaw()); + } + + public static void giveLobbyItems(Player player) { + if (player == null) return; + player.setHealth(20); + player.setMaxHealth(20); + player.setFoodLevel(20); + player.setGameMode(GameMode.SURVIVAL); + PlayerInventory inv = player.getInventory(); + inv.clear(); + player.getInventory().setHeldItemSlot(4); + + inv.setItem(0, createItem(Material.COMPASS, "&e&lServer Warper &7&lRight Click")); + inv.setItem(4, createItem(Material.ENDER_CHEST, "&6&lCosmetics &7&lRight Click")); + // inv.setItem(6, createItem(Material.NETHER_STAR, "&d&lStats &7&lRight Click")); + inv.setItem(7, createItem(Material.EXP_BOTTLE, "&a&lRewards &7&lRight Click")); + inv.setItem(8, createItem(Material.REDSTONE_COMPARATOR, "&5&lPreferences &7&lRight Click")); + + player.getActivePotionEffects().clear(); + inv.setArmorContents(null); + player.updateInventory(); + + } + + public static void sendLobbyJoinMessage(Player p, User user) { + p.sendMessage(new String[]{"", "", "", "", "", "", "", "", ""}); + String[] header = Core.getAnnouncer().getHeader(); + if (header != null && header.length > 0) ; + p.sendMessage(f(Core.getAnnouncer().getHeader())); + p.sendMessage(new String[]{"", + Utils.fc("Welcome, " + user.getColoredName(p) + "&r to the &7&l" + Core.getSettings().getNetworkShortName() + " &6&lHub&r!"), + Utils.fc("&e&l&oGTA in Minecraft!"), "", Utils.fc("&e&lSTORE &r&n" + Core.getSettings().getStoreLink()), + Utils.fc("&a&lSITE &r&n" + Core.getSettings().getWebsiteLink()), "", Utils.fc("&7Use the &eserver warper&7 to play!")}); + String[] footer = Core.getAnnouncer().getFooter(); + if (footer != null && footer.length > 0) ; + p.sendMessage(f(Core.getAnnouncer().getFooter())); + } + + public static void setInvisible(Player player, boolean b) { + Bukkit.getOnlinePlayers().stream().filter(p -> !Objects.equals(player, p)).forEach(p -> { + if (b) + p.hidePlayer(player); + else + p.showPlayer(player); + }); + } + + public static List<String> f(List<String> lore) { + return lore.stream().map(Utils::f).collect(Collectors.toList()); + } + + public static ItemStack createItem(Material material, String name, int amnt, String... lore) { + return createItem(material, name, toList(lore), amnt); + } + + public static ItemStack createItem(Material material, String name, List<String> lore, int amnt) { + ItemStack item = new ItemStack(material); + if (amnt > 0) + item.setAmount(amnt); + if (name != null || lore != null) { + ItemMeta meta = item.getItemMeta(); + if (name != null) + meta.setDisplayName(Utils.f(name)); + if (lore != null) + meta.setLore(f(lore)); + item.setItemMeta(meta); + } + return item; + } + + public static ItemStack createItem(Material material, int durability, String name, String... lore) { + return createItem(material, durability, name, toList(lore)); + } + + public static ItemStack createItem(Material material, int durability, String name, List<String> lore) { + ItemStack item = new ItemStack(material); + if (durability > 0) + item.setDurability((short) durability); + if (name != null || lore != null) { + ItemMeta meta = item.getItemMeta(); + if (name != null) + meta.setDisplayName(Utils.f(name)); + if (lore != null) + meta.setLore(f(lore)); + item.setItemMeta(meta); + } + return item; + } + + public static ItemStack createItem(Material material, int durability, String name, int amnt, String... lore) { + return createItem(material, durability, name, toList(lore), amnt); + } + + public static ItemStack createItem(Material material, int durability, String name, List<String> lore, int amnt) { + ItemStack item = new ItemStack(material); + if (amnt > 0) + item.setAmount(amnt); + if (durability > 0) + item.setDurability((short) durability); + if (name != null || lore != null) { + ItemMeta meta = item.getItemMeta(); + if (name != null) + meta.setDisplayName(Utils.f(name)); + if (lore != null) + meta.setLore(f(lore)); + item.setItemMeta(meta); + } + return item; + } + + public static ItemStack createItem(Material material, String name, String... lore) { + return createItem(material, name, toList(lore)); + } + + public static ItemStack createItem(Material material, String name, List<String> lore) { + ItemStack item = new ItemStack(material); + + if (name != null || lore != null) { + ItemMeta meta = item.getItemMeta(); + if (name != null) + meta.setDisplayName(Utils.f(name)); + if (lore != null) + meta.setLore(f(lore)); + item.setItemMeta(meta); + } + return item; + } + + public static ItemStack createItem(Material material, String name) { + ItemStack item = new ItemStack(material); + if (name != null) { + ItemMeta meta = item.getItemMeta(); + if (name != null) + meta.setDisplayName(Utils.f(name)); + item.setItemMeta(meta); + } + return item; + } + + public static ItemStack createItem(Material material, int durability, String name) { + ItemStack item = new ItemStack(material); + if (durability > 0) + item.setDurability((short) durability); + if (name != null) { + ItemMeta meta = item.getItemMeta(); + if (name != null) + meta.setDisplayName(Utils.f(name)); + item.setItemMeta(meta); + } + return item; + } + + public static ItemStack setArmorColor(ItemStack item, int red, int green, int blue) { + return setArmorColor(item, Color.fromRGB(red, green, blue)); + } + + public static ItemStack setArmorColor(ItemStack item, Color color) { + if (!(item.getItemMeta() instanceof LeatherArmorMeta)) + return item; + LeatherArmorMeta meta = (LeatherArmorMeta) item.getItemMeta(); + meta.setColor(color); + item.setItemMeta(meta); + return item; + } + + public static ItemStack setSkullOwner(ItemStack item, String owner) { + item.setDurability((short) 3); + SkullMeta meta = (SkullMeta) item.getItemMeta(); + meta.setOwner(owner); + item.setItemMeta(meta); + return item; + } + + public static void hidePlayersTo(Player player) { + Bukkit.getOnlinePlayers().stream().filter(p -> !Objects.equals(p, player)).forEach(player::hidePlayer); + } + + public static void showPlayersTo(Player player) { + Bukkit.getOnlinePlayers().stream().filter(p -> !Objects.equals(p, player)).forEach(player::showPlayer); + } + + public static void sendTitle(Player player, Title title) { + sendTitle(player, title.getTitle(), title.getSubtitle(), title.getFadeIn(), title.getStay(), + title.getFadeOut()); + } + + public static void sendTitle(Title title) { + sendTitle(title.getTitle(), title.getSubtitle(), title.getFadeIn(), title.getStay(), title.getFadeOut()); + } + + public static void sendTitle(String title, String subTitle, int fadeIn, int stay, int fadeOut) { + for (Player p : Bukkit.getOnlinePlayers()) + sendTitle(p, title, subTitle, fadeIn, stay, fadeOut); + } + + public static void sendTitle(Player player, String title, String subtitle, int fadeIn, int stay, int fadeOut) { + new JLibPlayer(player).sendTitle(fadeIn, fadeOut, stay, Utils.f(title)); + if (subtitle != null) + new JLibPlayer(player).sendSubTitle(fadeIn, fadeOut, stay, Utils.f(subtitle)); + } + + public static void sendActionBar(Player player, String message) { + //new JLibPlayer(pl).sendActionBar(msg); + + if (player == null || message == null) return; + String nmsVersion = Bukkit.getServer().getClass().getPackage().getName(); + nmsVersion = nmsVersion.substring(nmsVersion.lastIndexOf(".") + 1); + + //1.10 and up + if (!nmsVersion.startsWith("v1_9_R") && !nmsVersion.startsWith("v1_8_R")) { + player.spigot().sendMessage(ChatMessageType.ACTION_BAR, new TextComponent(message)); + return; + } + + //1.8.x and 1.9.x + try { + Class<?> craftPlayerClass = Class.forName("org.bukkit.craftbukkit." + nmsVersion + ".entity.CraftPlayer"); + Object craftPlayer = craftPlayerClass.cast(player); + + Class<?> ppoc = Class.forName("net.minecraft.server." + nmsVersion + ".PacketPlayOutChat"); + Class<?> packet = Class.forName("net.minecraft.server." + nmsVersion + ".Packet"); + Object packetPlayOutChat; + Class<?> chat = Class.forName("net.minecraft.server." + nmsVersion + (nmsVersion.equalsIgnoreCase("v1_8_R1") ? ".ChatSerializer" : ".ChatComponentText")); + Class<?> chatBaseComponent = Class.forName("net.minecraft.server." + nmsVersion + ".IChatBaseComponent"); + + Method method = null; + if (nmsVersion.equalsIgnoreCase("v1_8_R1")) method = chat.getDeclaredMethod("a", String.class); + + Object object = nmsVersion.equalsIgnoreCase("v1_8_R1") ? chatBaseComponent.cast(method.invoke(chat, "{'text': '" + message + "'}")) : chat.getConstructor(new Class[]{String.class}).newInstance(message); + packetPlayOutChat = ppoc.getConstructor(new Class[]{chatBaseComponent, Byte.TYPE}).newInstance(object, (byte) 2); + + Method handle = craftPlayerClass.getDeclaredMethod("getHandle"); + Object iCraftPlayer = handle.invoke(craftPlayer); + Field playerConnectionField = iCraftPlayer.getClass().getDeclaredField("playerConnection"); + Object playerConnection = playerConnectionField.get(iCraftPlayer); + Method sendPacket = playerConnection.getClass().getDeclaredMethod("sendPacket", packet); + sendPacket.invoke(playerConnection, packetPlayOutChat); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + public static void sendActionBar(String msg) { + for (Player p : Bukkit.getOnlinePlayers()) + sendActionBar(p, msg); + } + + public static void updateHubScoreboard(Player player, User user) { + String rank = "No Rank"; + if (user.isSpecial()) + rank = user.getUserRank().getColoredNameBold(); + Board board = new Board("lobby", Core.getSettings().getType().getScoreboardHeader(), BoardType.KEY_VALUE); + board.addValue("a", "Bucks", String.valueOf(user.getBucks())); + board.addValue("e", "Tokens", String.valueOf(user.getTokens())); + board.addValue("6", "Rank", rank); + board.addValue("6", "Server IP", user.getServerJoinAddress() != null ? user.getServerJoinAddress() : Core.getSettings().getNetworkIP()); + board.updateFor(player, user); + } + + public static List<String> toList(String[] array) { + List<String> ls = new ArrayList<>(); + if (array == null) + return ls; + Collections.addAll(ls, array); + return ls; + } + + public static ItemStack[] toArray(List<ItemStack> list) { + ItemStack[] items = new ItemStack[list.size()]; + for (int i = 0; i < list.size(); i++) + items[i] = list.get(i); + return items; + } + + public static String[] stringsToArray(List<String> list) { + if (list == null) + return null; + String[] l = new String[list.size()]; + l = list.toArray(l); + return l; + } + + public static boolean calculateChance(double i) { + return ThreadLocalRandom.current().nextDouble(101) <= i; + } + + public static void sendToServer(Player player, String server) { + Core.getServerManager().sendToServer(player, server); + } + + public static void stopEntityTracking(Player player) { + player.getLocation().getWorld().getLivingEntities().stream().filter(e -> e instanceof Creature).forEach(e -> { + Creature c = (Creature) e; + if (c.getTarget() instanceof Player && c.getTarget().equals(player)) + c.setTarget(null); + }); + } + + public static void setFlyMode(Player player, boolean b) { + player.setAllowFlight(b); + player.setFlying(b); + } + + public static Location randomLocation(Location location, double d) { + double x = location.getX() + (RANDOM.nextDouble() * d) - (d / 2); + double z = location.getZ() + (RANDOM.nextDouble() * d) - (d / 2); + return new Location(location.getWorld(), x, location.getY(), z, location.getYaw(), location.getPitch()); + } + + public static int randomNumber(int start, int end) { + return RANDOM.nextInt(end - start + 1) + start; + } + + public static int randomNumber(int end) { + return RANDOM.nextInt(end + 1); + } + + public static void copyWorld(String name) { + try { + Core.log("Copying world " + "/home/mcservers/development/master/maps/" + name + " to " + Bukkit.getWorldContainer().getCanonicalPath() + '/' + name); + File source = new File("/home/mcservers/development/master/maps/" + name); + File dest = new File(name); + Files.delete(dest.toPath()); + Files.copy(source.toPath(), dest.toPath(), StandardCopyOption.REPLACE_EXISTING); + Core.log("Finished copying world " + name); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static World loadWorld(String name) { + copyWorld(name); + World world = Bukkit.getWorld(name); + if (world == null) { + WorldCreator creator = new WorldCreator(name); + creator.environment(World.Environment.NORMAL); + world = creator.createWorld(); + } + return world; + } + + public static YamlConfiguration loadConfigFile(File file) { + YamlConfiguration c = new YamlConfiguration(); + try { + if (!file.exists()) + file.createNewFile(); + c.load(file); + } catch (IOException | InvalidConfigurationException e1) { + e1.printStackTrace(); + } + return c; + } + + public static YamlConfiguration loadConfig(String src) { + return loadConfigFile(new File(src + ".yml")); + } + + public static YamlConfiguration loadConfigFromMaps(String src) { + return loadConfigFile(new File("/home/mcservers/development/master/maps/" + src + ".yml")); + } + + public static YamlConfiguration loadConfigFromMaster(String src) { + return loadConfigFile(new File("/home/mcservers/development/master/" + src + ".yml")); + } + + public static YamlConfiguration loadConfigFromPlugin(String src, String plugin) { + try { + return loadConfigFile(new File(Bukkit.getWorldContainer().getCanonicalPath() + '/' + plugin, src + ".yml")); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + public static void saveConfigFile(YamlConfiguration c, File file) { + try { + if (!file.exists()) + file.createNewFile(); + c.save(file); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static void saveConfig(YamlConfiguration c, String src) { + saveConfigFile(c, new File(src + ".yml")); + } + + public static void deletePlayerDatFiles(String world) { + File file = new File(Bukkit.getWorldContainer() + "/" + world + "/playerdata"); + if (file.isDirectory()) + for (File f : file.listFiles()) + f.delete(); + } + + public static void kaching(Player player) { + player.playSound(player.getLocation(), Sound.BLOCK_WOODEN_DOOR_CLOSE, 2, 1); + UUID uuid = player.getUniqueId(); + new BukkitRunnable() { + @Override + public void run() { + Player player = Bukkit.getPlayer(uuid); + if (player != null) + player.playSound(player.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 0.3F, 1); + + } + }.runTaskLater(Core.getInstance(), 5); + + } + + public static String timeInMillisToText(long millis, String numberColor, String textColor, String splitterColor) { + return timeInSecondsToText(millis / 1000, numberColor, textColor, splitterColor); + } + + public static String timeInMillisToText(Long millis) { + return timeInSecondsToText(millis / 1000); + } + + + public static String formatMoney(double money) { + return NumberFormat.getCurrencyInstance(Locale.US).format(money > 1000000 ? (money / 1000000) : money) + (money > 1000000 ? " mil" : ""); + } + + public static String numberFormat(int num) { + return NumberFormat.getCurrencyInstance(Locale.US).format(num); + } + + public static String numberFormat(double num) { + return NumberFormat.getCurrencyInstance(Locale.US).format(num); + } + + public static int getAmountInInv(Player player, ItemStack stack) { + int amnt = 0; + Inventory inventory = player.getInventory(); + for (ItemStack item : inventory.getContents()) { + if (item != null && item.isSimilar(stack)) + amnt += item.getAmount(); + } + return amnt; + } + + public static boolean giveItems(Player player, ItemStack... items) { + Map<Integer, ItemStack> hm = player.getInventory().addItem(items); + if (hm.isEmpty()) + return false; + World w = player.getWorld(); + Location loc = player.getLocation(); + for (ItemStack item : hm.values()) + w.dropItemNaturally(loc, item); + return true; + } + + public static void takeItems(Player player, int amount, ItemStack stack) { + int toRemove = amount; + Inventory inventory = player.getInventory(); + for (int i = 0; i < inventory.getSize(); i++) { + ItemStack item = inventory.getItem(i); + if (item != null && item.isSimilar(stack)) { + if (toRemove >= item.getAmount()) { + toRemove -= item.getAmount(); + inventory.setItem(i, null); + } else { + item.setAmount(item.getAmount() - toRemove); + return; + } + + } + } + } + + public static String fc(String s) { + s = Utils.f(s); + int messagePxSize = 0; + boolean previousCode = false; + boolean isBold = false; + + for (char c : s.toCharArray()) { + if (c == '§') { + previousCode = true; + } else if (previousCode) { + previousCode = false; + isBold = c == 'l' || c == 'L'; + } else { + DefaultFontInfo dFI = DefaultFontInfo.getDefaultFontInfo(c); + messagePxSize += isBold ? dFI.getBoldLength() : dFI.getLength(); + messagePxSize++; + } + } + + int halvedMessageSize = messagePxSize / 2; + int toCompensate = 154 - halvedMessageSize; + int spaceLength = DefaultFontInfo.SPACE.getLength() + 1; + int compensated = 0; + StringBuilder sb = new StringBuilder(); + while (compensated < toCompensate) { + sb.append(' '); + compensated += spaceLength; + } + return sb + s; + } + + public static String[] fc(String[] array) { + if (array == null) + return null; + String[] a = new String[array.length]; + for (int i = 0; i < array.length; i++) + a[i] = Utils.fc(array[i]); + return a; + } + + public static Map<Player, Double> sort(Map<Player, Double> unsortMap) { + List<Map.Entry<Player, Double>> list = new LinkedList<>(unsortMap.entrySet()); + Collections.sort(list, (o1, o2) -> o1.getValue().compareTo(o2.getValue())); + Map<Player, Double> sortedMap = new LinkedHashMap<>(); + for (Map.Entry<Player, Double> entry : list) + sortedMap.put(entry.getKey(), entry.getValue()); + return sortedMap; + } + + public static void clearPotionEffects(Player player) { + for (PotionEffect e : player.getActivePotionEffects()) + player.removePotionEffect(e.getType()); + } + + public static String getCardinalDirection(Location location) { + double rotation = location.getYaw() % 360; + if (rotation < 0) + rotation += 360.0; + if (rotation >= 0 && rotation < 22.5) + return "S"; + else if (rotation >= 22.5 && rotation < 67.5) + return "SW"; + else if (rotation >= 67.5 && rotation < 112.5) + return "W"; + else if (rotation >= 112.5 && rotation < 157.5) + return "NW"; + else if (rotation >= 157.5 && rotation < 202.5) + return "N"; + else if (rotation >= 202.5 && rotation < 247.5) + return "NE"; + else if (rotation >= 247.5 && rotation < 292.5) + return "E"; + else if (rotation >= 292.5 && rotation < 337.5) + return "SE"; + else if (rotation >= 337.5 && rotation < 360.0) + return "S"; + return null; + + } + + public static Location getInFrontOf(Location location) { + String s = getCardinalDirection(location); + switch (s) { + case "N": + return location.add(0, 0, -2); + case "NE": + return location.add(2, 0, -2); + case "E": + return location.add(2, 0, 0); + case "SE": + return location.add(2, 0, 2); + case "S": + return location.add(0, 0, 2); + case "SW": + return location.add(-2, 0, 2); + case "W": + return location.add(-2, 0, 0); + case "NW": + return location.add(-2, 0, -2); + default: + return location; + } + } + + public static void playChestAnimation(Location loc, boolean open) { + Bukkit.getOnlinePlayers().forEach(p -> playChestAnimation(p, loc, open)); + } + + public static void playChestAnimation(Player player, Location loc, boolean open) { + try { + Object world = ReflectionAPI.getHandle((Object) loc.getWorld()); + Object position = BLOCK_POSITION_CLASS.getConstructor(double.class, double.class, double.class).newInstance(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + Object tileChest = world.getClass().getMethod("getTileEntity", BLOCK_POSITION_CLASS).invoke(world, position); + Object packet = PACKET_PLAY_OUT_BLOCK_ACTION_CLASS.getConstructor(BLOCK_POSITION_CLASS, BLOCK_CLASS, int.class, int.class).newInstance(position, tileChest.getClass().getMethod("getBlock").invoke(tileChest), 1, open ? 1 : 0); + ReflectionAPI.sendPacket(player, packet); + } catch (Exception e) { + Core.error("An error occured while playing a chest animation"); + e.printStackTrace(); + } + } + + public static ItemStack addGlow(ItemStack item) { + item.addUnsafeEnchantment(GLOW, 1); + return item; + } + + public static void insertLogLater(UUID uuid, String name, String action, String type, String reward, double amount, double price) { + ServerUtil.runTaskAsync(() -> insertLog(uuid, name, action, type, reward, amount, price)); +// new BukkitRunnable() { +// @Override +// public void run() { +// Utils.insertLog(uuid, name, action, type, reward, amount, price); +// } +// }.runTaskAsynchronously(Core.getInstance()); + } + + public static void insertLog(UUID uuid, String name, String action, String type, String reward, double amount, double price) { + boolean result = LogDAO.insertLog(uuid, name, action, type, reward, amount, price); + if(!result) Core.error("Error while logging uuid " + uuid + " name " + name + " action " + action + " reward " + reward + " amount " + amount + " price " + price); + +// try (PreparedStatement st = Core.sql.prepareStatement("insert into logs(uuid, name, action, type, reward, amount, price, server) values (?,?,?,?,?,?,?,?);")) { +// st.setString(1, uuid.toString()); +// st.setString(2, name); +// st.setString(3, action); +// st.setString(4, type); +// st.setString(5, reward); +// st.setDouble(6, amount); +// st.setDouble(7, price); +// st.setString(8, Core.name()); +// st.execute(); +// st.close(); +// } catch (SQLException e) { +// Core.error("Error while logging uuid " + uuid + " name " + name + " action " + action + " reward " + reward + " amount " + amount + " price " + price); +// } + } + + public static Collection<String> getOfflineStaff() { +// Collection<String> staff = new ArrayList<>(); +// try (ResultSet resultSet = Core.getSQL().query("SELECT lastname FROM users WHERE userrank IN ( 'HELPOP', 'MOD', 'ADMIN', 'DEV' );")) { +// while (resultSet.next()) { +// staff.add(resultSet.getString("lastname")); +// } +// resultSet.close(); +// } catch (Exception exception) { +// +// } + return ServerInfoDAO.getOnlineStaff(); + } + + public static TimeFormatter timeFormatter(TimeUnit timeUnit, Long time) { + return new TimeFormatter(timeUnit, time); + } + + public static boolean isBanned(String uuid) { +// try (ResultSet rs = Core.sql.query("select * from BAT_ban where UUID='" + uuid + "';")) { +// if (rs.next()) { +// if (rs.getBoolean("ban_state")) { +// rs.close(); +// return true; +// } +// } +// rs.close(); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// return false; + return UserDAO.isUserBanned(uuid); + } + + /** + * Apply these item flags to ItemStack + * + * @param itemStack - the ItemStack to apply these flags to + * @param flags - the flags to apply + **/ + public static void applyItemFlags(ItemStack itemStack, ItemFlag... flags) { + ItemMeta itemMeta = itemStack.getItemMeta(); + + itemMeta.setUnbreakable(true); + itemMeta.addItemFlags(flags); + + itemMeta.addItemFlags(flags); + itemStack.setItemMeta(itemMeta); + } + + /** + * Clone ItemStack, apply flags and return new copy. + * + * @param itemStack the ItemStack to apply these flags to + * @param flags the flags to apply + * @return cloned ItemStack with itemflags + **/ + public static ItemStack addItemFlags(ItemStack itemStack, ItemFlag... flags) { + ItemStack stack = itemStack.clone(); + ItemMeta itemMeta = stack.getItemMeta(); + + itemMeta.setUnbreakable(true); + itemMeta.addItemFlags(flags); + + itemMeta.addItemFlags(flags); + stack.setItemMeta(itemMeta); + return stack; + } + + public static Month getMonth() { + Date date = new Date(); + LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); + return localDate.getMonth(); + } + + public static int getDay() { + Date date = new Date(); + LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); + return localDate.getDayOfMonth(); + } + + public static void setMaxPlayers(int maxPlayers) { + String bukkitversion = Bukkit.getServer().getClass().getPackage() + .getName().substring(23); + Object playerlist = null; + try { + playerlist = Class.forName("org.bukkit.craftbukkit." + bukkitversion + ".CraftServer") + .getDeclaredMethod("getHandle", null).invoke(Bukkit.getServer(), null); + Field maxplayers = playerlist.getClass().getSuperclass() + .getDeclaredField("maxPlayers"); + maxplayers.setAccessible(true); + maxplayers.set(playerlist, maxPlayers); + } catch (IllegalAccessException | InvocationTargetException | + NoSuchMethodException | + ClassNotFoundException | + NoSuchFieldException exception) { + exception.printStackTrace(); + } + Core.getSettings().setMaxPlayers(maxPlayers); + Core.getSettings().getCoreConfig().set("maxplayers", maxPlayers); + Utils.saveConfig(Core.getSettings().getCoreConfig(), "core"); + } + + public static void startEnchantmentShineRemover(ProtocolManager lib, Plugin owner){ + lib.addPacketListener(new PacketAdapter(owner, ListenerPriority.NORMAL, PacketType.Play.Server.ENTITY_EQUIPMENT, PacketType.Play.Server.WINDOW_ITEMS){ + @Override + public void onPacketSending(PacketEvent event){ + PacketContainer packet = event.getPacket(); + if(packet.getType()==PacketType.Play.Server.ENTITY_EQUIPMENT){ + removeEnchantments(packet.getItemModifier().read(0)); + } + else if(packet.getType()==PacketType.Play.Server.WINDOW_ITEMS){ + for(ItemStack is : packet.getItemArrayModifier().read(0)){ + if(is!=null) + removeEnchantments(is); + } + } + } + }); + } + + private static void removeEnchantments(ItemStack stack) { + if(stack==null) + return; + Object[] copy = stack.getEnchantments().keySet().toArray(); + + for (Object enchantment : copy) { + stack.removeEnchantment((Enchantment) enchantment); + } + } + + public static String timeInSecondsToText(long timer) { + return timeInSecondsToText(timer, C.WHITE, C.WHITE, C.WHITE); + } + + public static String timeInSecondsToText(long timer, String numberColor, String textColor, String splitterColor) { + StringBuilder sb = new StringBuilder(); + List<TimeUnit> units = Arrays.asList(TimeUnit.values()); + Collections.reverse(units); + int counter = 0; + for(TimeUnit u : units) { + if (counter >= 2) + break; + long time = u.convert(timer, TimeUnit.SECONDS); + if (time >= 1) { + sb.append(numberColor + time + C.RESET + " " + textColor + (time == 1 ? u.toString().toLowerCase().substring(0, u.toString().length()-1) : u.toString().toLowerCase()) + C.RESET + splitterColor + (counter == 1 ? "" : ", ")); + counter++; + timer -= TimeUnit.SECONDS.convert(time, u); + } + } + return counter==1 ? sb.toString().substring(0, sb.length()-2) : sb.toString(); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/WeightedRandomCollection.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/WeightedRandomCollection.java new file mode 100644 index 0000000..b496e65 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/WeightedRandomCollection.java @@ -0,0 +1,91 @@ +package net.grandtheftmc.core.util; +/* + * Copyright (C) 2013-Current Carter Gale (Ktar5) <buildfresh@gmail.com> + * + * This file is part of gtm. + * + * gtm can not be copied and/or distributed without the express + * permission of the aforementioned owner. + */ + +import com.google.common.collect.Lists; + +import java.util.*; +import java.util.concurrent.ThreadLocalRandom; + +/** + * A utility collection created in order to simplify the selection of a random + * element based on its corresponding relative weight + * <p> + * "Relative weight" means that, for example, each "weight" is a lottery ticket thrown + * into the "total weight". We pick a random ticket, and then return that element. Thus, + * the higher the weight, the higher the chance it will be picked. + * + * @param <E> the type of element to be placed into this collection + */ +public class WeightedRandomCollection<E> { + private final NavigableMap<Double, E> map = new TreeMap<>(); + private E last; + private double total; + + /** + * Add an item to the random collection with the + * specified weight + * + * @param weight the weight (relative to the others) + * @param result the item that corresponds to this weight + */ + public WeightedRandomCollection<E> add(double weight, E result) { + if (weight <= 0) return this; + this.total += weight; + this.map.put(this.total, result); + this.last = result; + return this; + } + + public E last() { + return this.last; + } + + /** + * Return a set of all the values + * + * @return a set of all the values + */ + public Set<E> values() { + return new HashSet<>(this.map.values()); + } + + /** + * Returns #amount of unique elements chosen randomly for a lottery-type system + * + * @param amount the max amount of unique elements you want returned + * @return a list containing maximum #amount unique elements, unless there are + * less than that many elements in the collection + */ + public List<E> getUniqueElements(int amount) { + if (this.map.size() <= amount) { + return Lists.newArrayList(this.map.values()); + } + List<E> uniqueElements = new ArrayList<>(amount); + while (uniqueElements.size() < amount && uniqueElements.size() < this.map.size()) { + if (!uniqueElements.contains(this.next())) { + uniqueElements.add(this.last()); + } + } + return uniqueElements; + } + + /** + * Select a random item from the list based on the chance + * Uses a ThreadLocalRandom because Random sucks shit + * ThreadLocalRandom is faster + * + * @return a random element from the collection, selected based on its relative weight + */ + public E next() { + double value = ThreadLocalRandom.current().nextDouble() * this.total; + this.last = this.map.ceilingEntry(value).getValue(); + return this.last; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/debug/Log.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/debug/Log.java new file mode 100644 index 0000000..a6fa0d1 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/debug/Log.java @@ -0,0 +1,59 @@ +package net.grandtheftmc.core.util.debug; + +import java.util.logging.Level; + +import org.bukkit.Bukkit; + +public class Log { + + /** + * Log an error message. This will show up in the console as + * [SEVERE][prefix] [message] + * + * @param args - Arguments to log in an error message. + * @param prefix - Prefix of the plugin. ex: "Hyphenical" + */ + public static void error(String prefix, String... args) { + log(Level.SEVERE, prefix, args); + } + + /** + * Log an info message. This will show up in the console as [INFO][prefix] + * [message] + * + * @param args - Arguments to log with the prefix of "[INFO]". + * @param prefix - Prefix of the plugin. ex: "Hyphenical" + */ + public static void info(String prefix, String... args) { + log(Level.INFO, prefix, args); + } + + /** + * Log a warning message. This will show up in the console as + * [WARNING][prefix] [message] + * + * @param args - Arguments to log with the prefix of "[WARNING]" + * @param prefix - Prefix of the plugin. ex: "Hyphenical" + */ + public static void warning(String prefix, String... args) { + log(Level.WARNING, prefix, args); + } + + /** + * Logs the error message to Bukkit's logger. This will show up in the + * console as [LEVEL][PLUGIN] [message] + * + * @param level - level in which to log the arguments. + * @param prefix - prefix of the plugin name. + * @param args - arguments to log. + */ + private static void log(Level level, String prefix, String... args) { + StringBuffer buffer = new StringBuffer(); + + for (int i = 0; i < args.length; i++) { + buffer.append(args[i]); + } + + Bukkit.getLogger().log(level, String.format("[" + prefix + "] %s", buffer.toString())); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/factory/CloneableFactory.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/factory/CloneableFactory.java new file mode 100644 index 0000000..2391d29 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/factory/CloneableFactory.java @@ -0,0 +1,8 @@ +package net.grandtheftmc.core.util.factory; + +/** + * Created by Luke Bingham on 21/07/2017. + */ +public interface CloneableFactory<T> { + T clone(); +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/factory/Factory.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/factory/Factory.java new file mode 100644 index 0000000..9769e26 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/factory/Factory.java @@ -0,0 +1,9 @@ +package net.grandtheftmc.core.util.factory; + +/** + * Created by Luke Bingham on 21/07/2017. + */ +public abstract class Factory<T> { + protected T object; + public abstract T build(); +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/factory/FireworkFactory.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/factory/FireworkFactory.java new file mode 100644 index 0000000..5e3eddc --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/factory/FireworkFactory.java @@ -0,0 +1,66 @@ +package net.grandtheftmc.core.util.factory; + +import org.bukkit.Color; +import org.bukkit.FireworkEffect; +import org.bukkit.Location; +import org.bukkit.entity.Firework; +import org.bukkit.inventory.meta.FireworkMeta; + +public class FireworkFactory extends Factory<Firework> { + + private FireworkMeta meta; + + private boolean flicker = false, trail = false; + private Color color = Color.BLACK, fade = Color.WHITE; + private FireworkEffect.Type type = FireworkEffect.Type.BALL; + + public FireworkFactory(Location location) { + super.object = location.getWorld().spawn(location, Firework.class); + this.meta = super.object.getFireworkMeta(); + } + + public FireworkFactory setPower(int power) { + this.meta.setPower(power); + return this; + } + + public FireworkFactory setFlicker(boolean flicker) { + this.flicker = flicker; + return this; + } + + public FireworkFactory setTrail(boolean trail) { + this.trail = trail; + return this; + } + + public FireworkFactory setColor(Color color) { + this.color = color; + return this; + } + + public FireworkFactory setFadeColor(Color fade) { + this.fade = fade; + return this; + } + + public FireworkFactory setType(FireworkEffect.Type type) { + this.type = type; + return this; + } + + @Override + public Firework build() { + FireworkEffect effect = FireworkEffect.builder() + .flicker(this.flicker) + .withColor(this.color).withFade(this.fade) + .with(this.type) + .trail(this.trail) + .build(); + + this.meta.addEffect(effect); + super.object.setFireworkMeta(this.meta); + + return super.object; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/factory/ItemFactory.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/factory/ItemFactory.java new file mode 100644 index 0000000..4c39ab2 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/factory/ItemFactory.java @@ -0,0 +1,125 @@ +package net.grandtheftmc.core.util.factory; + +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * Created by Luke Bingham on 21/07/2017. + */ +public class ItemFactory extends Factory<ItemStack> implements CloneableFactory<ItemFactory> { + + private ItemMeta itemMeta; + + public ItemFactory(Material material, byte data) { + this.object = new ItemStack(material, 1, data); + this.itemMeta = object.getItemMeta(); + } + + public ItemFactory(Material material, short data) { + this.object = new ItemStack(material, 1); + this.object.setDurability(data); + this.itemMeta = object.getItemMeta(); + } + + public ItemFactory(Material material) { + this(material, (byte) 0); + } + + public ItemFactory(ItemStack itemStack) { + this.object = itemStack; + this.itemMeta = itemStack.getItemMeta(); + } + + public final ItemFactory setAmount(int amount) { + if (amount > 64) amount = 64; + object.setAmount(amount); + return this; + } + + public final ItemFactory setName(String name) { + itemMeta.setDisplayName(name); + return this; + } + + public final ItemFactory setLore(List<String> lore) { + itemMeta.setLore(lore); + return this; + } + + public final ItemFactory setLore(Queue<String> lore) { + itemMeta.setLore((LinkedList<String>) lore); + return this; + } + + public final ItemFactory setLore(String... lore) { + itemMeta.setLore(Arrays.asList(lore)); + return this; + } + + public final ItemFactory setOwner(String name) { + if (object.getType().equals(Material.SKULL_ITEM)) { + SkullMeta meta = (SkullMeta) itemMeta; + meta.setOwner(name); + } + return this; + } + + public final ItemFactory setDurability(short durability) { + object.setDurability(durability); + return this; + } + + public final ItemStack build() { + object.setItemMeta(itemMeta); + return object; + } + + public final ItemFactory setData(byte data) { + object.setDurability(data); + return this; + } + + public final ItemFactory setUnsafeEnchantment(Enchantment enchantment, int level) { + object.addUnsafeEnchantment(enchantment, level); + return this; + } + + public final ItemFactory setEnchantment(Enchantment enchantment, int level) { + itemMeta.addEnchant(enchantment, level, true); + return this; + } + + public final ItemFactory addFlags(ItemFlag... flags) { + itemMeta.addItemFlags(flags); + return this; + } + +// public <T> ItemFactory setNBT(String key, T value) { +// net.minecraft.server.v1_8_R3.ItemStack nmsCopy = CraftItemStack.asNMSCopy(object); +// NBTTagCompound compoundTag = new NBTTagCompound(); +// nmsCopy.c(compoundTag); +// compoundTag.set(key, ); +// nmsCopy.f(compoundTag); +// } + + public ItemFactory setUnbreakable(boolean unbreakable) { + this.itemMeta.setUnbreakable(unbreakable); + return this; + } + + @Override + public final ItemFactory clone() { + ItemFactory clone = new ItemFactory(object.getType(), object.getData().getData()); + clone.itemMeta = this.itemMeta; + return clone; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/json/JSONBuilder.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/json/JSONBuilder.java new file mode 100644 index 0000000..d1846d1 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/json/JSONBuilder.java @@ -0,0 +1,50 @@ +package net.grandtheftmc.core.util.json; + +import org.json.simple.JSONObject; + +public class JSONBuilder { + + /** The json object being built */ + private final JSONObject jsonObject; + + /** + * Construct a new JSONBuilder, used to concatenate key/values into a valid + * JSON format. + */ + public JSONBuilder() { + this.jsonObject = new JSONObject(); + } + + /** + * Construct a new JSONBuilder, using an existing object. + * + * @param existing - the existing json object + */ + public JSONBuilder(JSONObject existing) { + this.jsonObject = existing; + } + + /** + * Set the key in the JSON to the specified value. + * + * @param key - the key to set + * @param value - the value to set + * + * @return This builder, in order to keep chaining. + */ + public JSONBuilder set(String key, Object value) { + jsonObject.put(key, value); + + return this; + } + + /** + * Creates the JSONObject from this builder. + * + * @return The JSONObject that was created from this builder. + */ + public JSONObject create() { + return jsonObject; + } +} + diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/json/JSONParser.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/json/JSONParser.java new file mode 100644 index 0000000..f31fccf --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/json/JSONParser.java @@ -0,0 +1,313 @@ +package net.grandtheftmc.core.util.json; + +import java.util.UUID; + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; + +public class JSONParser { + + /** The json object to parse */ + private final JSONObject jsonObject; + + /** + * Construct a new JSONParser, which is a utility tool to edit/grab keys. + * + * @param jsonObject - the json object to parse. + */ + public JSONParser(JSONObject jsonObject) { + this.jsonObject = jsonObject; + } + + /** + * Returns a new JSONParser, given the key specified can be converted to a + * JSONObject. + * + * @param key - the key attempting to parse + * + * @return A new JSONParser with the specified key as the new JSONObject in + * the parser. + */ + public JSONParser parseObject(String key) { + Object obj = jsonObject.get(key); + return new JSONParser(obj instanceof JSONObject ? (JSONObject) obj : new JSONObject()); + } + + /** + * Get whether or not this parser has the specified key. + * + * @param key - the key specified + * + * @return {@code true} if the parser has the specified key, {@code false} + * otherwise. + */ + public boolean hasKey(String key) { + return jsonObject.containsKey(key); + } + + /** + * Grab the key and convert it to a JSONObject. + * + * @param key - the key to grab + * + * @return The JSONObject that was retrieved. + */ + public JSONObject getObject(String key) { + return (JSONObject) jsonObject.get(key); + } + + /** + * Grab the key and convert it to a JSONArray. + * + * @param key - the key to grab + * + * @return The JSONArray that was retrieved. + */ + public JSONArray getJSONArray(String key) { + return (JSONArray) jsonObject.get(key); + } + + /** + * Grab the key and convert it to a String. + * + * @param key - the key to grab + * + * @return The String that was retrieved. + */ + public String getString(String key) { + return (String) jsonObject.get(key); + } + + /** + * Grab the key and convert it to an Int. + * <p> + * Note: If the value in the JSON is of a different type, values can be lost + * when casting. + * + * @param key - the key to grab + * + * @return The Int that was retrieved. + */ + public int getInt(String key) { + Object obj = jsonObject.get(key); + + if (obj instanceof Long) { + return ((Long) obj).intValue(); + } + else if (obj instanceof Double) { + return ((Double) obj).intValue(); + } + else if (obj instanceof Float) { + return ((Float) obj).intValue(); + } + else if (obj instanceof Short) { + return ((Short) obj).intValue(); + } + else if (obj instanceof Byte) { + return ((Byte) obj).intValue(); + } + + return (Integer) obj; + } + + /** + * Grab the key and convert it to a Long. + * <p> + * Note: If the value in the JSON is of a different type, values can be lost + * when casting. + * + * @param key - the key to grab + * + * @return The Long that was retrieved. + */ + public long getLong(String key) { + Object obj = jsonObject.get(key); + + if (obj instanceof Integer) { + return ((Integer) obj).longValue(); + } + else if (obj instanceof Double) { + return ((Double) obj).longValue(); + } + else if (obj instanceof Float) { + return ((Float) obj).longValue(); + } + else if (obj instanceof Short) { + return ((Short) obj).longValue(); + } + else if (obj instanceof Byte) { + return ((Byte) obj).longValue(); + } + + return (Long) obj; + } + + /** + * Grab the key and convert it to a Double. + * <p> + * Note: If the value in the JSON is of a different type, values can be lost + * when casting. + * + * @param key - the key to grab + * + * @return The Double that was retrieved. + */ + public double getDouble(String key) { + Object obj = jsonObject.get(key); + + if (obj instanceof Long) { + return ((Long) obj).doubleValue(); + } + else if (obj instanceof Integer) { + return ((Integer) obj).doubleValue(); + } + else if (obj instanceof Float) { + return ((Float) obj).doubleValue(); + } + else if (obj instanceof Short) { + return ((Short) obj).doubleValue(); + } + else if (obj instanceof Byte) { + return ((Byte) obj).doubleValue(); + } + + return (Double) obj; + } + + /** + * Grab the key and convert it to a Float. + * <p> + * Note: If the value in the JSON is of a different type, values can be lost + * when casting. + * + * @param key - the key to grab + * + * @return The Float that was retrieved. + */ + public float getFloat(String key) { + Object obj = jsonObject.get(key); + + if (obj instanceof Long) { + return ((Long) obj).floatValue(); + } + else if (obj instanceof Double) { + return ((Double) obj).floatValue(); + } + else if (obj instanceof Integer) { + return ((Integer) obj).floatValue(); + } + else if (obj instanceof Short) { + return ((Short) obj).floatValue(); + } + else if (obj instanceof Byte) { + return ((Byte) obj).floatValue(); + } + + return (Float) obj; + } + + /** + * Grab the key and convert it to a Short. + * <p> + * Note: If the value in the JSON is of a different type, values can be lost + * when casting. + * + * @param key - the key to grab + * + * @return The Short that was retrieved. + */ + public short getShort(String key) { + Object obj = jsonObject.get(key); + + if (obj instanceof Long) { + return ((Long) obj).shortValue(); + } + else if (obj instanceof Double) { + return ((Double) obj).shortValue(); + } + else if (obj instanceof Float) { + return ((Float) obj).shortValue(); + } + else if (obj instanceof Integer) { + return ((Integer) obj).shortValue(); + } + else if (obj instanceof Byte) { + return ((Byte) obj).shortValue(); + } + + return (Short) obj; + } + + /** + * Grab the key and convert it to a Byte. + * <p> + * Note: If the value in the JSON is of a different type, values can be lost + * when casting. + * + * @param key - the key to grab + * + * @return The Byte that was retrieved. + */ + public byte getByte(String key) { + Object obj = jsonObject.get(key); + + if (obj instanceof Long) { + return ((Long) obj).byteValue(); + } + else if (obj instanceof Double) { + return ((Double) obj).byteValue(); + } + else if (obj instanceof Float) { + return ((Float) obj).byteValue(); + } + else if (obj instanceof Integer) { + return ((Integer) obj).byteValue(); + } + else if (obj instanceof Byte) { + return ((Byte) obj).byteValue(); + } + + return (Byte) obj; + } + + /** + * Grab the key and convert it to a boolean. + * + * @param key - the key to grab + * + * @return The boolean that was retrieved. + */ + public boolean getBoolean(String key) { + return (Boolean) jsonObject.get(key); + } + + /** + * Grab the key and convert it to a UUID. + * + * @param key - the key to grab + * + * @return The UUID that was retrieved, if one exists. {@code null} if the + * value cannot be formatted to a UUID. + */ + public UUID getUUID(String key) { + try { + return UUID.fromString((String) jsonObject.get(key)); + } + catch (IllegalArgumentException ignored) { + } + + return null; + } + + /** + * Grab the key and convert it to an Object. + * + * @param key - the key to grab + * + * @return The Object that was retrieved. + */ + public Object get(String key) { + return jsonObject.get(key); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/json/JSONUtil.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/json/JSONUtil.java new file mode 100644 index 0000000..7274eef --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/json/JSONUtil.java @@ -0,0 +1,45 @@ +package net.grandtheftmc.core.util.json; + +import org.json.simple.JSONObject; + +public class JSONUtil { + + /** + * Merges 2 JSONObjects together recursively, resulting in the target + * containing both + * <p> + * The source will take priority over the target and will overwrite data if + * conflict arises + * + * @param source The source (the object to merge in to target) + * @param target The target (this ends up as the resultant object) + */ + public static void deepMerge(JSONObject source, JSONObject target) { + for (Object key : source.keySet()) { + + Object value = source.get(key); + + if (!target.containsKey(key)) { + // Add source to target + target.put(key, value); + } + else if (value instanceof JSONObject) { + // Value is JSONObject, let's have a look at target value + Object targetValue = target.get(key); + if (targetValue instanceof JSONObject) { + // Target has a JSONObject, combine recursively + deepMerge((JSONObject) value, (JSONObject) targetValue); + } + else { + // Target and source incompatible, source takes priority + target.put(key, value); + } + } + else { + // Source replaces target + target.put(key, value); + } + } + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/nbt/CoreNbt.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/nbt/CoreNbt.java new file mode 100644 index 0000000..073eb41 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/nbt/CoreNbt.java @@ -0,0 +1,11 @@ +package net.grandtheftmc.core.util.nbt; + +/** + * Created by ThatAbstractWolf on 2017-08-04. + */ +public interface CoreNbt { + + Object getNBTTag(String key); + + boolean hasNBTTag(String key); +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/nbt/NBTUtil1_12_2.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/nbt/NBTUtil1_12_2.java new file mode 100644 index 0000000..7bfa503 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/nbt/NBTUtil1_12_2.java @@ -0,0 +1,64 @@ +package net.grandtheftmc.core.util.nbt; + +import net.minecraft.server.v1_12_R1.NBTBase; +import net.minecraft.server.v1_12_R1.NBTTagCompound; +import org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack; +import org.bukkit.inventory.ItemStack; + +/** + * Created by ThatAbstractWolf on 2017-08-04. + */ +public class NBTUtil1_12_2 implements CoreNbt { + + private ItemStack item; + + public NBTUtil1_12_2(ItemStack item) { + this.item = item; + } + + public ItemStack setNBTTag(String key, NBTBase base) { + + net.minecraft.server.v1_12_R1.ItemStack item = CraftItemStack.asNMSCopy(this.item); + + NBTTagCompound compound; + + if (item.getTag() == null) { + compound = new NBTTagCompound(); + } else { + compound = item.getTag(); + } + + compound.set(key, base); + item.setTag(compound); + + return CraftItemStack.asBukkitCopy(item); + } + + @Override + public Object getNBTTag(String key) { + + net.minecraft.server.v1_12_R1.ItemStack item = CraftItemStack.asNMSCopy(this.item); + + NBTTagCompound compound = item.getTag(); + + if (compound == null) { + return false; + } + + return compound.get(key); + } + + @Override + public boolean hasNBTTag(String key) { + + net.minecraft.server.v1_12_R1.ItemStack item = CraftItemStack.asNMSCopy(this.item); + + NBTTagCompound compound = item.getTag(); + + if (compound == null) { + return false; + } + + return compound.get(key) != null; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/particles/ParticleEffects.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/particles/ParticleEffects.java new file mode 100644 index 0000000..e7b73c9 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/particles/ParticleEffects.java @@ -0,0 +1,30 @@ +package net.grandtheftmc.core.util.particles; + +import com.comphenix.protocol.wrappers.EnumWrappers; +import net.grandtheftmc.core.wrapper.packet.out.WrapperPlayServerWorldParticles; +import org.bukkit.Location; +import org.bukkit.entity.Player; + +public class ParticleEffects { + + private WrapperPlayServerWorldParticles wrappedPacket; + + public ParticleEffects(EnumWrappers.Particle particle, Location loc, float xOffset, float yOffset, float zOffset, float speed, int count) { + float x = (float) loc.getX(); + float y = (float) loc.getY(); + float z = (float) loc.getZ(); + + this.wrappedPacket = new WrapperPlayServerWorldParticles() + .setParticleType(particle) + .setLongDistance(false) + .setX(x).setY(y).setZ(z) + .setOffsetX(xOffset).setOffsetY(yOffset).setOffsetZ(zOffset) + .setParticleData(speed) + .setNumberOfParticles(count) + .setData(new int[] {}); + } + + public void show(Player p) { + wrappedPacket.sendPacket(p); + } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/time/TimeUtil.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/time/TimeUtil.java new file mode 100644 index 0000000..89d6934 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/time/TimeUtil.java @@ -0,0 +1,242 @@ +package net.grandtheftmc.core.util.time; + +import java.sql.Timestamp; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; + +import org.apache.commons.lang.Validate; + +public class TimeUtil { + + /** + * The timezone to use for {@link LocalDateTime} instances created in this + * Util + */ + private static ZoneId CURRENT_TIMEZONE = ZoneId.systemDefault(); + + /** A standard formatting of DateTime */ + public static final DateTimeFormatter DATE_TIME_FORMAT = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss"); + + /** + * Set the timezone to use for {@link LocalDateTime} instances created in + * this Util + * + * @param zoneId The timezone + */ + public static void setCurrentTimezone(ZoneId zoneId) { + Validate.notNull(zoneId); + + CURRENT_TIMEZONE = zoneId; + } + + /** + * Converts a time in milliseconds to a LocalDateTime based on + * {@link #CURRENT_TIMEZONE} + * + * @param millis The time in milliseconds + * + * @return A {@link LocalDateTime} based on {@link #CURRENT_TIMEZONE} + */ + public static LocalDateTime getLocalDateTime(long millis) { + return getLocalDateTime(millis, CURRENT_TIMEZONE); + } + + /** + * Converts a time in milliseconds to a LocalDateTime based on the specified + * timezone + * + * @param millis The time in milliseconds + * @param zoneId The timezone to use + * + * @return A {@link LocalDateTime} based on the specified timezone + */ + public static LocalDateTime getLocalDateTime(long millis, ZoneId zoneId) { + return LocalDateTime.ofInstant(Instant.ofEpochMilli(millis), zoneId); + } + + /** + * Formats a time in milliseconds following the outline of + * {@link #DATE_TIME_FORMAT} and {@link #CURRENT_TIMEZONE} + * + * @param millis The time in milliseconds + * + * @return The time in a readable format + * + * @see #DATE_TIME_FORMAT + */ + public static String format(long millis) { + return DATE_TIME_FORMAT.format(getLocalDateTime(millis)); + } + + /** + * Converts time into a String representation of minutes:seconds based off + * the integer provided. + * + * @param time - Time to be converted. + * @return String in the format of minutes:seconds. + */ + public static String formatSeconds(int time) { + int minutes = time / 60; + int seconds = time - (minutes * 60); + + StringBuilder stringBuilder = new StringBuilder(); + + if (minutes < 10) { + stringBuilder.append("0"); + } + + stringBuilder.append(String.valueOf(minutes) + ":"); + + if (seconds < 10) { + stringBuilder.append("0"); + } + + stringBuilder.append(String.valueOf(seconds)); + return stringBuilder.toString(); + } + + /** + * Formats milliseconds to seconds to the given degree. + * + * @param millis - the milliseconds to format + * @param degrees - the number of decimal places to format to + * + * @return The formatted string that represents the seconds, from the + * specified milliseconds. + */ + public static String formatMillisToSecs(long millis, int degrees) { + double amount = millis / 1000.0; + return String.format("%." + degrees + "f", amount); + } + + /** + * Formats milliseconds to seconds to the tens decimal. + * <p> + * Wrapper around {@link #formatMillisToSecs(long, int)}. + * </p> + * + * @param millis - the milliseconds to format + * + * @return The formatted string that represents the seconds, from the + * specified milliseconds. + */ + public static String formatMillisToSecs(long millis) { + return formatMillisToSecs(millis, 1); + } + + /** + * Converts the amount of seconds to a time readable format. + * + * Wrapper around {@link #timeToString(long)}. + * + * 330 seconds is represented as "5m 30s". + * + * @param secs - the amount of seconds + * + * @return A string format of the representation of the time. + */ + public static String timeToString(int secs) { + return timeToString(secs * 1000L); + } + + /** + * Converts the amount of seconds to a time readable format. + * + * 86400000 is represented as "24h". + * + * @param msec - the amount of milliseconds + * + * @return A string format of the representation of the time. + */ + public static String timeToString(long msec) { + if (msec < 1000) { + return "0s"; + } + + StringBuilder text = new StringBuilder(); + + if (msec >= 86400000) { + text.append(msec / 86400000).append("d "); + msec %= 86400000; + } + + if (msec >= 3600000) { + text.append(msec / 3600000).append("h "); + msec %= 3600000; + } + + if (msec >= 60000) { + text.append(msec / 60000).append("m "); + msec %= 60000; + } + + if (msec >= 1000) { + text.append(msec / 1000).append("s "); + msec %= 1000; + } + + return text.toString().trim(); + } + + /** + * Get the string representation of the time between time1 and time2. + * + * Wrapper around {@link #timeToString(long)}. + * + * 86400000 is represented as "24h". + * + * @param t1 - the time in milliseconds + * @param t2 - the time in milliseconds + * + * @return The string representation of the time between t1 and t2. + */ + public static String getTimeBetween(long t1, long t2) { + return timeToString(Math.abs(t1 - t2)); + } + + /** + * Get whether or not the these are different day timestamp. + * + * @param ts - the first timestamp + * @param ts2 - the second timestamp + * + * @return {@code true} if the timestamps are different days. + */ + public static boolean isDifferentDay(Timestamp ts, Timestamp ts2) { + + // if same year, month, and day + if (ts.getYear() == ts2.getYear()) { + if (ts.getMonth() == ts2.getMonth()) { + if (ts.getDay() == ts2.getDay()) { + return false; + } + } + } + + return true; + } + + /** + * Get the difference in hours between the two timestamps. + * <p> + * Note: This returns the whole number of hours. + * + * @param current - the current timestamp + * @param last - the last timestamp + * + * @return The difference in hours between the current timestamp and the + * last timestamp. + */ + public static int getDifferenceInHours(Timestamp current, Timestamp last) { + + long diff = current.getTime() - last.getTime(); + long diffSeconds = diff / 1000; + long diffMinutes = diff / (60 * 1000); + long diffHours = diff / (60 * 60 * 1000); + + return (int) diffHours; + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/title/NMSTitle.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/title/NMSTitle.java new file mode 100644 index 0000000..b4079bf --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/util/title/NMSTitle.java @@ -0,0 +1,14 @@ +package net.grandtheftmc.core.util.title; + +import org.bukkit.entity.Player; + +/** + * Created by Luke Bingham on 07/08/2017. + */ +public class NMSTitle { + + @Deprecated //NMS code removed. + public static void sendTitle (Player player, String title, String subtitle, int fadein, int duration, int fadeout) { + player.sendTitle(title, subtitle, fadein, duration, fadeout); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/Reward.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/Reward.java new file mode 100644 index 0000000..d3c8f70 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/Reward.java @@ -0,0 +1,422 @@ +package net.grandtheftmc.core.voting; + +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.achivements.Achievement; +import net.grandtheftmc.core.events.RewardEvent; +import net.grandtheftmc.core.events.UpdateEvent; +import net.grandtheftmc.core.nametags.Nametag; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.voting.events.RewardCheckEvent; +import net.grandtheftmc.core.voting.events.RewardGiveEvent; +import net.grandtheftmc.core.voting.events.RewardInfoEvent; + +public class Reward { + private final RewardType type; + private final String name; + + private ItemStack[] items; + private double amount = 1; + private String customType; + private String customName; + private List<String> customList; + private int minTokens; + private int maxTokens; + private UserRank rank; + private int days; + private Nametag nametag; + private Achievement achievement; + /** The skin id for the weapon */ + private short weaponSkinId; + /** The weapon star rating to give */ + private int stars; + + public Reward(String name, ItemStack[] items) { + this.name = name; + this.items = items; + this.type = RewardType.ITEMS; + } + + public Reward(String name, RewardType type, String customName){ + this.name = name; + this.type = type; + this.customName = customName; + } + + public Reward(String name, double amount, RewardType type) { + this.name = name; + this.amount = amount; + this.type = type; + } + + public Reward(String name, String customType, String customName, double amount) { + this.name = name; + this.type = RewardType.CUSTOM; + this.customType = customType; + this.customName = customName; + this.amount = amount; + } + + public Reward(String name, String customType, List<String> customList) { + this.name = name; + this.type = RewardType.CUSTOM; + this.customType = customType; + this.customList = customList; + } + + public Reward(String name, UserRank trialRank, int days) { + this.type = RewardType.TRIAL_RANK; + this.name = name; + this.rank = trialRank; + this.days = days; + } + + public Reward(String name, UserRank permanentRank) { + this.type = RewardType.RANK; + this.name = name; + this.rank = permanentRank; + } + + public Reward(String name, Nametag nametag) { + this.type = RewardType.NAMETAG; + this.name = name; + this.nametag = nametag; + } + + public Reward(String name, String customName, RewardType rewardType) { // FOR COMMANDS AND PERMISSIONS, {uuid} and {name} placeholders + this.type = rewardType; + this.name = name; + this.customName = customName; + } + + public Reward(String name, Achievement achievement) { + this.type = RewardType.ACHIEVEMENT; + this.name = name; + this.achievement = achievement; + } + + public Reward(String name, String customName, int stars, short weaponSkinID, RewardType rewardType) { // FOR COMMANDS AND PERMISSIONS, {uuid} and {name} placeholders + this.type = rewardType; + this.name = name; + this.customName = customName; + this.stars = stars; + this.weaponSkinId = weaponSkinID; + } + + public RewardType getType() { + return this.type; + } + + public String getName() { + return this.name; + } + + public String getDisplayName() { + switch (this.type) { + case ITEMS: + break; + case BUCKS: + return "&a&l" + (int) this.amount + " Bucks"; + case MONEY: + return "&a$&l" + (int) this.amount; + case TOKENS: + return "&a&l" + (int) this.amount + "&e&l Token" + (this.amount > 1 ? "s" : ""); + case NAMETAG: + return "&e&l" + this.nametag.getDisplayName(); + case RANK: + return this.rank.getColor() + "&lPermanent " + this.rank.getColoredNameBold(); + case TRIAL_RANK: + return "&a&l" + this.days + " day" + (this.days > 1 ? "s " : " ") + this.rank.getColoredNameBold() + "&a&l Trial"; + case CUSTOM: + break; +// case COSMETIC: +// return this.cosmetic == null ? this.cosmeticType == null ? "&e&lRandom Cosmetic " + +// "&7(&e" + (this.maxTokens > 0 ? this.minTokens + '-' + this.maxTokens : "min " + this.minTokens) + " tokens&7)" : +// '&' + this.cosmeticType.getColor() + "&lRandom " + this.cosmeticType.getColoredDisplayNameSingle() +// + " &7(&e" + (this.maxTokens > 0 ? this.minTokens + '-' + this.maxTokens : "min " + this.minTokens) + " tokens&7)" : +// this.cosmetic.getColoredDisplayName(); + case PERMISSION: + return this.name == null ? "&a&l" + this.customName : this.name; + case CROWBARS: + return "&9&l" + (int) this.amount + " Crowbar" + (this.amount > 1 ? "s" : ""); + case COMMAND: + break; + case ACHIEVEMENT: + return this.achievement.getTitle(); + case WEAPON: + case SKIN: + return "&9&l" + this.name; + + } + return this.name; + } + + public ItemStack[] getItems() { + return this.items; + } + + public double getAmount() { + return this.amount; + } + + public String getCustomType() { + return this.customType; + } + + public String getCustomName() { + return this.customName; + } + + public List<String> getCustomList() { + return this.customList; + } + + public int getMinTokens() { + return this.minTokens; + } + + public int getMaxTokens() { + return this.maxTokens; + } + + public UserRank getTrialRank() { + return this.rank; + } + + public UserRank getRank() { + return this.rank; + } + + public int getDays() { + return this.days; + } + + public Nametag getNametag() { + return this.nametag; + } + + public String getPermission() { + return this.customName; + } + + public short getWeaponSkinId() { + return weaponSkinId; + } + + public int getStars() { + return stars; + } + + public ItemStack getDisplayItem() { + switch (this.type) { + case ITEMS: + return this.items[0]; + case BUCKS: + case MONEY: + return new ItemStack(Material.PAPER, this.amount > 64 ? 64 : (int) this.amount); + case TOKENS: + return new ItemStack(Material.DOUBLE_PLANT, this.amount > 64 ? 64 : (int) this.amount); + case CROWBARS: + return Utils.addItemFlags(new ItemStack(Material.FLINT_AND_STEEL, this.amount > 64 ? 64 : (int) this.amount, (short) 45), ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ATTRIBUTES); +// case COSMETIC: +// return this.cosmeticType == null ? new ItemStack(Material.ENDER_CHEST) : this.cosmetic == null ? this.cosmeticType.getMenuItem() : this.cosmetic.getItem(); + case TRIAL_RANK: + return new ItemStack(this.rank.getMaterial(), this.days > 64 ? 64 : this.days); + case NAMETAG: + return new ItemStack(Material.NAME_TAG); + case RANK: + return new ItemStack(this.rank.getMaterial()); + default: + RewardInfoEvent rewardInfoEvent = new RewardInfoEvent(this, this.type, this.customName); + Bukkit.getPluginManager().callEvent(rewardInfoEvent); + return rewardInfoEvent.getDisplayItem(); + } + } + + public boolean hasReward(Player player, User user) { + switch (this.type) { +// case COSMETIC: +// return this.cosmetic == null ? this.cosmeticType == null ? Arrays.stream(CosmeticType.values()).allMatch(type -> type.getCosmetics().stream() +// .filter(c -> c.getTokens() > this.minTokens && (this.maxTokens <= 0 || c.getTokens() < this.maxTokens)).allMatch(user::hasCosmetic)) +// : this.cosmeticType.getCosmetics().stream().filter(c -> c.getTokens() > this.minTokens && (this.maxTokens <= 0 || c.getTokens() < this.maxTokens)).allMatch(user::hasCosmetic) +// : user.hasCosmetic(this.cosmetic); + case RANK: + return user.getUserRankNonTrial() == this.rank || user.getUserRankNonTrial().isHigherThan(this.rank); + case TRIAL_RANK: + return user.getUserRankNonTrial() == this.rank || user.getUserRank().isHigherThan(this.rank); + case NAMETAG: + return user.hasNametag(this.nametag); + case PERMISSION: + if (Core.getPermsManager().hasPerm(player.getUniqueId(), this.customName)) return true; + case ACHIEVEMENT: + return user.hasAchievement(this.achievement); + default: + RewardCheckEvent rewardCheckEvent = new RewardCheckEvent(player, this, this.type, this.customName); + Bukkit.getPluginManager().callEvent(rewardCheckEvent); + return rewardCheckEvent.getResult(); + } + } + + public void give(Player player, User user, boolean sendMessage) { + + switch (this.type) { + case ITEMS: + if (sendMessage) + player.sendMessage(Lang.REWARDS.f("&a" + this.getDisplayName())); + if (Utils.giveItems(player, this.items)) + player.sendMessage(Utils. + f(Lang.TOKEN_SHOP + "&7Your inventory was full so some items were dropped on the ground!")); + break; + case BUCKS: { + if (sendMessage) { + player.sendMessage(Lang.BUCKS_ADD.f(String.valueOf((int) this.amount))); + } + int amnt = (int) this.amount; + user.addBucks(amnt); + Bukkit.getPluginManager().callEvent(new UpdateEvent(player, UpdateEvent.UpdateReason.BUCKS)); + break; + } + case TOKENS: { + if (sendMessage) { + player.sendMessage(Lang.TOKENS_ADD.f(String.valueOf((int) this.amount))); + } + int amnt = (int) this.amount; + user.addTokens(amnt); + Bukkit.getPluginManager().callEvent(new UpdateEvent(player, UpdateEvent.UpdateReason.TOKENS)); + break; + } + case CROWBARS: + if (sendMessage) { + player.sendMessage(Lang.CROWBARS_ADD.f(String.valueOf((int) this.amount))); + } + int amnt = (int) this.amount; + user.addCrowbars(amnt); + Bukkit.getPluginManager().callEvent(new UpdateEvent(player, UpdateEvent.UpdateReason.CROWBARS)); + break; + case MONEY: + if (sendMessage) { + player.sendMessage(Lang.MONEY_ADD.f(String.valueOf(this.amount))); + } + if (!user.addMoney(this.amount)) { + Core.log(Lang.TOKEN_SHOP.f( + "&cOops " + player.getName() + "! Something went wrong with getting the reward:" + getCustomName() + "! Contact an admin with a screenshot of this message to get it. Time: " + new Date().toGMTString())); + } + Bukkit.getPluginManager().callEvent(new UpdateEvent(player, UpdateEvent.UpdateReason.MONEY)); + break; + case CUSTOM: + if (sendMessage) + player.sendMessage(Lang.REWARDS.f("&a" + this.getDisplayName())); + RewardEvent event = new RewardEvent(player, this); + Bukkit.getPluginManager().callEvent(event); + if (!event.isSuccessful()) + Core.log(Lang.TOKEN_SHOP.f( + "&cOops " + player.getName() + "! Something went wrong with getting the reward:" + getCustomName() + "! Contact an admin with a screenshot of this message to get it. Time: " + new Date().toGMTString())); + break; +// case COSMETIC: +// Cosmetic c = this.cosmetic; +// if (c == null) { +// if (this.cosmeticType == null) { +// List<Cosmetic> cosmetics = new ArrayList<>(); +// Arrays.stream(CosmeticType.values()).forEach(t -> cosmetics.addAll(t.getCosmetics().stream().filter(co -> !user.hasCosmetic(co) && co.getTokens() > 0 && co.getTokens() > this.minTokens && (this.maxTokens < 0 || co.getTokens() <= this.maxTokens)).collect(Collectors.toList()))); +// if (cosmetics.isEmpty()) { +// player.sendMessage(Lang.COSMETICS.f("Wow! You already own ALL cosmetics!")); +// break; +// } +// c = cosmetics.get(ThreadLocalRandom.current().nextInt(cosmetics.size())); +// } else { +// List<Cosmetic> cosmetics = this.cosmeticType.getCosmetics().stream().filter(co -> !user.hasCosmetic(co)).collect(Collectors.toList()); +// c = cosmetics.get(ThreadLocalRandom.current().nextInt(cosmetics.size())); +// if (c == null) { +// player.sendMessage(Lang.COSMETICS.f("Wow! You already own ALL " + this.cosmeticType.getDisplayName() + "s!")); +// break; +// } +// } +// } +// if (sendMessage) +// player.sendMessage(Lang.COSMETICS.f("&a" + this.getDisplayName() + this.cosmetic == null ? "&7: " + c.getColoredDisplayName() : "")); +// user.giveCosmetic(player, this.cosmetic); +// break; + case TRIAL_RANK: + if (user.hasTrialRank() && user.getTrialRank().isHigherThan(this.rank)) { + if (sendMessage) + player.sendMessage(Lang.RANKS.f("&7You already have a trial rank higher than the one you won (" + this.rank.getColoredNameBold() + "&7, &a" + this.days + "&7 days)!")); + return; + } + if (user.hasTrialRank() && user.getTrialRank() == this.rank) { + if (sendMessage) + player.sendMessage(Lang.RANKS.f("&a" + this.getDisplayName() + " &7(extended)")); + user.setTrialRank(this.rank, user.getTrialRankExpiry() + 86400000L * this.days); + Bukkit.getPluginManager().callEvent(new UpdateEvent(player, UpdateEvent.UpdateReason.RANK)); + } + if (sendMessage) + player.sendMessage(Lang.RANKS.f("&a" + this.getDisplayName())); + user.setTrialRank(this.rank, System.currentTimeMillis() + 86400000L * this.days); + Bukkit.getPluginManager().callEvent(new UpdateEvent(player, UpdateEvent.UpdateReason.RANK)); + break; + case NAMETAG: + if (sendMessage) + player.sendMessage(Lang.NAMETAGS.f("&a" + this.getDisplayName())); + user.giveNametag(this.nametag); + break; + case PERMISSION: + if (sendMessage) + player.sendMessage(Lang.REWARDS.f("&a" + this.getDisplayName())); + Core.getPermsManager().addPerm(player.getUniqueId(), this.customName); + break; + case RANK: + if (sendMessage) + player.sendMessage(Lang.RANKS.f("&a" + this.getDisplayName())); + user.setUserRank(this.rank); + Bukkit.getPluginManager().callEvent(new UpdateEvent(player, UpdateEvent.UpdateReason.RANK)); + break; + case COMMAND: + if (sendMessage) + player.sendMessage(Lang.REWARDS.f("&a" + this.getDisplayName())); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), this.customName.replace("{name}", player.getName()).replace("{uuid}", player.getUniqueId().toString())); + break; + case ACHIEVEMENT: + if (sendMessage) { + player.sendMessage(Lang.REWARDS.f("&aACHIEVEMENT " + this.achievement.getTitle())); + } + user.addAchievement(this.achievement); + break; + case WEAPON: + case SKIN: + if (sendMessage) + player.sendMessage(Lang.REWARDS.f("&a" + this.getDisplayName())); + event = new RewardEvent(player, this); + Bukkit.getPluginManager().callEvent(event); + if (!event.isSuccessful()) + Core.log(Lang.REWARDS.f( + "&cOops " + player.getName() + "! Something went wrong with getting the reward:" + getCustomName() + "! Contact an admin with a screenshot of this message to get it. Time: " + new Date().toGMTString())); + break; + default: + RewardGiveEvent rewardGiveEvent = new RewardGiveEvent(player, this.type, this.customName); + Bukkit.getPluginManager().callEvent(rewardGiveEvent); + break; + } + } + + public enum RewardType { + ITEMS, BUCKS, TOKENS, MONEY, CUSTOM, COSMETIC, TRIAL_RANK, NAMETAG, PERMISSION, CROWBARS, RANK, COMMAND, ACHIEVEMENT, + VEHICLE, CHEATCODE, WEAPON, SKIN; + + public static RewardType fromString(String string) { + return Arrays.stream(RewardType.class.getEnumConstants()).filter(type -> type.toString().equalsIgnoreCase(string)).findFirst().orElse(null); + } + + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/RewardPack.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/RewardPack.java new file mode 100644 index 0000000..5de5421 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/RewardPack.java @@ -0,0 +1,67 @@ +package net.grandtheftmc.core.voting; + +import net.grandtheftmc.core.users.User; +import org.bukkit.entity.Player; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Created by Liam on 23/04/2017. + */ +public class RewardPack { + + private final String name; + private final List<Reward> rewards; + private final String description; + + public RewardPack(Reward reward, String description) { + this.name = reward.getName(); + this.rewards = Collections.singletonList(reward); + this.description = description; + } + + public RewardPack(String name, List<Reward> rewards, String description) { + this.name = name; + this.rewards = rewards; + this.description = description; + } + + public List<Reward> get() { + return this.rewards; + } + + public String getName() { + return this.name; + } + + public String getDisplayName() { + return this.rewards.size() == 1 ? this.rewards.get(0).getDisplayName() : this.name; + } + + public String getDescription() { + // todo i want this shown in the crate rewards menu/tokenshop menu if not null + return this.description; + } + + public boolean hasAllRewards(Player player, User user) { + return this.rewards.stream().allMatch(r -> r.hasReward(player, user)); + } + + public boolean hasAnyReward(Player player, User user) { + return this.rewards.stream().anyMatch(r -> r.hasReward(player, user)); + } + + public int hasAnyRewardSize(Player player, User user) { + return this.rewards.stream().filter(r -> r.hasReward(player, user)).collect(Collectors.toList()).size(); + } + + public void give(Player player, User user, String action, double price, boolean sendMessage) { + for (Reward reward : this.rewards) + reward.give(player, user, sendMessage); + if (action != null) { + user.insertLog(player, action, this.rewards.size() > 1 ? "PACK" : this.rewards.size() == 1 ? this.rewards.get(0).getType().toString() : "ERROR", this.name, this.rewards.size() > 1 ? 1 : this.rewards.size() == 1 ? this.rewards.get(0).getAmount() : 1, price); + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/ShopItem.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/ShopItem.java new file mode 100644 index 0000000..297156d --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/ShopItem.java @@ -0,0 +1,53 @@ +package net.grandtheftmc.core.voting; + +import com.j0ach1mmall3.jlib.methods.Parsing; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.events.UpdateEvent; +import net.grandtheftmc.core.users.User; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public class ShopItem { + + private final int price; + private final ItemStack item; + private final RewardPack pack; + + public ShopItem(String name, int price, String item, RewardPack pack) { + this.price = price; + this.item = Parsing.parseItemStack(item); + this.pack = pack; + } + + + public String getName() { + return this.pack.getName(); + } + + public int getPrice() { + return this.price; + } + + public ItemStack getItem() { + return this.item; + } + + public RewardPack getRewardPack() { + return this.pack; + } + + public void buy(Player player, User user) { + if (this.price > 0 && !user.hasTokens(this.price)) { + player.sendMessage( + Lang.TOKEN_SHOP.f("&7You do not have the &e&l" + this.price + " Tokens&7 to pay for this item!")); + return; + } + player.sendMessage( + Lang.TOKEN_SHOP.f("&7You bought &a" + this.pack.getName() + "&7 for &e&l" + this.price + " Token" + (this.price == 1 ? "" : "s") + "&7!")); + user.takeTokens(this.price); + this.pack.give(player, user, "buyShopItem", this.price, true); + UpdateEvent e = new UpdateEvent(player, UpdateEvent.UpdateReason.TOKENS); + Bukkit.getPluginManager().callEvent(e); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/VoteCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/VoteCommand.java new file mode 100644 index 0000000..a4fe09d --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/VoteCommand.java @@ -0,0 +1,125 @@ +package net.grandtheftmc.core.voting; + +import java.sql.Timestamp; + +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.plugin.PluginManager; + +import com.vexsoftware.votifier.model.Vote; +import com.vexsoftware.votifier.model.VotifierEvent; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.util.Utils; + +public class VoteCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Utils.f("&cYou are not a player!")); + return true; + } + Player player = (Player) s; + if (args.length == 0 || !s.isOp()) { + MenuManager.openMenu((Player) s, "vote"); + return true; + } + + switch (args[0].toLowerCase()) { + case "test": { + + // vote test [TWO] + + PluginManager pm = Bukkit.getPluginManager(); + if (pm.getPlugin("NuVotifier") == null && + pm.getPlugin("Votifier") == null) { + s.sendMessage(Lang.VOTE.f("&7This command is disabled!")); + return true; + } + + VoteSite site = VoteSite.TWO; + if (args.length == 2){ + site = VoteSite.valueOf(args[1]); + } + + Vote vote = new Vote(); + vote.setUsername(player.getName()); + vote.setServiceName(site.getName()); + vote.setAddress(site.getURL()); + vote.setTimeStamp(new Timestamp(System.currentTimeMillis()).toString()); + VotifierEvent event = new + VotifierEvent(vote); + Bukkit.getPluginManager().callEvent(event); + return true; + }// + case "reward": { + if (args.length != 2) { + s.sendMessage(Utils.f("&c/vote reward <reward>")); + return true; + } + VoteReward reward = Core.getVoteManager().getVoteReward(args[1]); + if (reward == null) { + s.sendMessage(Lang.VOTE.f("&7That vote reward does not exist!")); + return true; + } + s.sendMessage(Lang.VOTE.f("&7Executing vote reward "+reward.getDisplayName()+"&7:")); + reward.give(player,Core.getUserManager().getLoadedUser(player.getUniqueId())); + return true; + } + case "resetmonth": + case "resetmonthly": + player.sendMessage(Utils.f("&7This command does not currently work.")); +// player.sendMessage(Utils.f("&7This month's top voters:")); +// ServerUtil.runTaskAsync(() -> { +// VoteDAO.deleteLastMonthsVoters(); +// +// Optional<VoteDAO.VoteUser[]> optional = VoteDAO.getTopTenVoters(); +// if(!optional.isPresent()) { +// player.sendMessage(Utils.f("&cAn error occurred when fetching top voters :(")); +// return; +// } +// +// for(VoteDAO.VoteUser voteUser : optional.get()) { +// player.sendMessage(Utils.f("&7#&6" + voteUser.getPossition() + " &7" + voteUser.getName() + " with &6" + voteUser.getVotes() + " &7votes.")); +// } +// +// //Core.getVoteManager().resetMonthlyVotes(); +// Core.getVoteManager().setLastMonthlyReset(System.currentTimeMillis()); +// s.sendMessage(Lang.VOTE.f("&7Monthly vote count has been reset!")); +// }); + +// new BukkitRunnable() { +// @Override +// public void run() { +// try { +// int counter = 1; +// Core.sql.prepareStatement("TRUNCATE table last_months_voters;").execute(); +// ResultSet rs = Core.sql.prepareStatement("SELECT * FROM votes ORDER BY `votes`.`monthlyVotes` DESC LIMIT 10;").executeQuery(); +// while (rs.next()) { +// String name = rs.getString("name"); +// int votes = rs.getInt("monthlyVotes"); +// Core.sql.prepareStatement("INSERT INTO last_months_voters (slot, name) VALUES ('" + counter + "', '" + name + "');").execute(); +// player.sendMessage(Utils.f("&7#&6" + counter + " &7" + name + " with &6" + votes + " &7votes.")); +// counter++; +// } +// Core.getVoteManager().resetMonthlyVotes(); +// Core.getVoteManager().setLastMonthlyReset(System.currentTimeMillis()); +// s.sendMessage(Lang.VOTE.f("&7Monthly vote count has been reset!")); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// } +// }.runTaskAsynchronously(Core.getInstance()); + return true; + default: + return true; + } + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/VoteManager.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/VoteManager.java new file mode 100644 index 0000000..71ed2c5 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/VoteManager.java @@ -0,0 +1,946 @@ +package net.grandtheftmc.core.voting; + +import java.sql.Connection; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.UUID; +import java.util.stream.Collectors; + +import org.bukkit.Bukkit; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitRunnable; +import org.json.simple.JSONObject; + +import com.j0ach1mmall3.jlib.methods.Parsing; +import com.vexsoftware.votifier.model.Vote; +import com.vexsoftware.votifier.model.VotifierEvent; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.achivements.Achievement; +import net.grandtheftmc.core.currency.Currency; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.database.dao.VoteDAO; +import net.grandtheftmc.core.events.UpdateEvent; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.nametags.Nametag; +import net.grandtheftmc.core.servers.ServerType; +import net.grandtheftmc.core.transaction.state.user.UserStateTransactionDAO; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserDAO; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.Component; +import net.grandtheftmc.core.util.PluginAssociated; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.util.debug.Log; +import net.grandtheftmc.core.util.json.JSONBuilder; +import net.grandtheftmc.core.util.time.TimeUtil; +import net.grandtheftmc.jedis.JedisChannel; +import net.grandtheftmc.jedis.message.UserStateTransactionCheck; +import net.grandtheftmc.jedis.message.VoteNotificationMessage; +import net.md_5.bungee.api.ChatColor; + +/** +<<<<<<< HEAD + * + * @deprecated `voters` field is traversed everytime someone votes, and + * therefore if we have 10,000 voters in one day, just inserting a + * vote looks through 10,000 records. This should be stored as a + * HashMap. Also this data is never cleaned up. Why do we have it + * here? Player data should be read/write to the database and not + * handled. +======= + * @deprecated `voters` field is traversed everytime someone votes, and therefore if we have 10,000 voters in one day, just inserting a vote looks through 10,000 records. This should be stored as a HashMap. Also this data is never cleaned up. Why do we have it here? Player data should be read/write to the database and not handled. +>>>>>>> refs/heads/develop + */ +@Deprecated +public class VoteManager implements Component<VoteManager, Core>, PluginAssociated { + + /** The owning plugin */ + private final Plugin plugin; + /** List of voters that have been registered as "voted" */ + private final List<Voter> voters = new ArrayList<>(); + /** Possible vote rewards */ + private final List<VoteReward> voteRewards = new ArrayList<>(); + /** Possible daily rewards */ + private final List<RewardPack> dailyRewards = new ArrayList<>(); + /** Possible lucky daily rewards */ + private final List<RewardPack> luckyDailyRewards = new ArrayList<>(); + /** Rewards per user rank */ + private final Map<UserRank, List<RewardPack>> monthlyRewards = new HashMap<>(); + private final List<ShopItem> shopItems = new ArrayList<>(); + private String voteLink = "vote.grandtheftmc.net"; + private long lastMonthlyReset; + private int taskId = -1; + + /** The top voters, populated by a repeating task */ + private VoteDAO.VoteUser[] topVoters; + /** The last month top voters, populated by a repeating task */ + private VoteDAO.VoteUser[] lastTopVoters; + + /** + * Construct a new VoteManager. + * <p> + * This handles the receiving of votes and credits the user with rewards as user state transactions. + * + * Note: When a vote is received it also forwards a vote message via redis to all servers. + * Therefore only hub1 should really be getting any VotifierEvents. + * </p> + * + * @param plugin - the owning plugin + */ + public VoteManager(Plugin plugin) { + this.plugin = plugin; + this.loadLinksAndRewards(); + this.loadTokenShop(); + this.startSchedule(); + + // every 10 minutes + Bukkit.getScheduler().runTaskTimerAsynchronously(getPlugin(), () -> { + + // local cache result + VoteDAO.VoteUser[] topVotersLocal = null; + // local cache result + VoteDAO.VoteUser[] lastVotersLocal = null; + + try (Connection conn = BaseDatabase.getInstance().getConnection()){ + topVotersLocal = VoteDAO.getTopVoters(conn, 10).orElse(null); + lastVotersLocal = VoteDAO.getLastTopVoters(conn, 10).orElse(null); + } + catch(Exception e){ + e.printStackTrace(); + } + + final VoteDAO.VoteUser[] finalTopVoters = topVotersLocal; + final VoteDAO.VoteUser[] finalLastVoters = lastVotersLocal; + Bukkit.getScheduler().runTask(getPlugin(), () -> { + topVoters = finalTopVoters; + lastTopVoters = finalLastVoters; + }); + + } , 0L, 20 * 600L); + } + + /** + * {@inheritDoc} + */ + @Override + public VoteManager onDisable(Core plugin) { + if (!this.voters.isEmpty()) + this.voters.clear(); + if (!this.voteRewards.isEmpty()) + this.voteRewards.clear(); + if (!this.dailyRewards.isEmpty()) + this.dailyRewards.clear(); + if (!this.luckyDailyRewards.isEmpty()) + this.luckyDailyRewards.clear(); + if (!this.monthlyRewards.isEmpty()) + this.monthlyRewards.clear(); + if (!this.shopItems.isEmpty()) + this.shopItems.clear(); + return this; + } + + /** + * Start the schedule task of broadcasting votes every 5 minutes. + */ + public void startSchedule() { + if (this.taskId > 0) + Bukkit.getScheduler().cancelTask(this.taskId); + this.taskId = new BukkitRunnable() { + @Override + public void run() { + VoteManager.this.broadcastVoteMessage(); + } + }.runTaskTimer(Core.getInstance(), 300, 300).getTaskId(); + } + + /** + * Iterate through all the voters that this manager knows about and send notifications across the server. + */ + public void broadcastVoteMessage() { + + // if no voters to display + if (this.voters.isEmpty()) + return; + + // build the broadcast string + StringBuilder s = new StringBuilder(Lang.VOTE.s()); + + int size = this.voters.size(); + for (int i = 0; i < this.voters.size(); i++) { + Voter voter = this.voters.get(i); + s.append("&a").append(voter.getName()).append(voter.getVotes() > 1 ? " &7(&e" + voter.getVotes() + "&7)" : "&7"); + if (size - i == 1){ + s.append(" voted for the server and received awesome rewards! Do &a\"/vote\"&7 to find out more! Vote on all &e5 &7sites for maximum rewards!"); + } + else if (size - i == 2){ + s.append(" and "); + } + else{ + s.append(", "); + } + } + + // broadcast to the server + Utils.broadcast(s.toString()); + + // clear voters list + this.voters.clear(); + } + + /** + * Listens in on the Votifier events. + * <p> + * This event is on low so we can run it first. + * + * @param event - the event + */ + @EventHandler(priority = EventPriority.LOW) + public void onVotifierEvent(VotifierEvent event) { + + // grab event variables + Vote vote = event.getVote(); + String userName = vote.getUsername(); + + Log.info("VoteManager", "Received vote from " + vote.getServiceName() + " for user=" + userName); + + // get the site that they voted on + VoteSite voteSite = VoteSite.find(vote.getServiceName()).orElse(null); + + // if not a valid site, log message + if (voteSite == null){ + Log.info("VoteManager", "Voting site '" + vote.getServiceName() + "' not found in our database!"); + return; + } + + // async fetch + Bukkit.getScheduler().runTaskAsynchronously(getPlugin(), () -> { + + try (Connection conn = BaseDatabase.getInstance().getConnection()) { + + UUID uuid = UserDAO.getUUID(conn, userName); + if (uuid != null) { + + // grab the user vote record + VoteRecord vr = VoteDAO.getUserVoteRecord(conn, uuid); + + // check if this vote site has already been voted on + if (isVoteSiteCooldown(vr, voteSite, userName)){ + return; + } + + // handle the vote streak increment + handleVoteStreakIncrement(conn, vr); + + // add a total vote + VoteDAO.incrementTotalVotes(conn, uuid); + + // update the timestamp for this vote site + VoteDAO.updateVoteSiteTimestamp(conn, uuid, voteSite); + + int numVoteTokens = 1; + + // determine chance of getting higher streak + int rollChance = vr.getStreak() * 5; + if (rollChance >= 100){ + rollChance = 100; + } + + // what additional message to send along in the payload + String message = "&7Remember to vote daily to increase your vote streak for more rewards! &e&lCurrent Vote Streak&7: " + (vr.getStreak() + 1); + + // if double reward + if (Utils.calculateChance(rollChance)) { + numVoteTokens = 2; + message = "&7You got lucky and earned a &e&lDouble Vote&7! Chance: &a&l" + rollChance + "%"; + } + // if first three days of month + else if (new Timestamp(System.currentTimeMillis()).getDate() <= 3) { + numVoteTokens = 2; + message = "&7Vote rewards are doubled in the first three days of every month! Make sure to keep voting all month to build up your &e&lVote Streak&7!"; + } + + // log the vote to the database + VoteDAO.logUserVote(conn, vr.getOwner(), numVoteTokens, voteSite != null ? voteSite.getId() : -1); + + // create in the format of + // {"type": "currency", "uuid": "0xDD", "currency": "VotingTokens", "amount": 1} + JSONObject payload = new JSONBuilder().set("type", "currency").set("uuid", uuid.toString()).set("currency", Currency.VOTE_TOKEN.getId()).set("amount", numVoteTokens).create(); + UserStateTransactionDAO.addUserStateTransaction(conn, uuid, payload); + + // get the global messaging channel and send a vote message payload through + Core.getJedisManager().getModule(JedisChannel.GLOBAL).sendMessage(new VoteNotificationMessage(uuid, message)); + // get the global messaging channel and send a check user state payload through + Core.getJedisManager().getModule(JedisChannel.GLOBAL).sendMessage(new UserStateTransactionCheck(uuid)); + } + } + catch (Exception e) { + e.printStackTrace(); + } + }); + } + + /** + * Claim the daily reward for the given player. + * + * @param player - the player claiming the reward + * @param user - the user object representation for this player + */ + public void claimDaily(Player player, User user) { + if (Core.getSettings().getType() == ServerType.HUB) { + player.sendMessage(Lang.REWARDS.f("&7Please claim this reward on " + Core.getSettings().getServer_GTM_shortName() + " to receive extra money!")); + return; + } + if (!user.canClaimDailyReward()) { + player.sendMessage(Lang.REWARDS.f("&7You need to wait &c&l" + Utils.timeInMillisToText(user.getTimeUntilDailyReward()) + "&7 until you can claim your daily reward again!")); + return; + } + user.setLastDailyReward(); + if (Utils.calculateChance(user.getLuckyDailyChance())) { + player.sendMessage(Lang.REWARDS.f("&7You got lucky and earned a &e&lLucky Reward&7 of &e&l5 Tokens&7! Chance: &a%&l" + user.getLuckyDailyChance())); + user.addTokens(5); + for (RewardPack pack : this.luckyDailyRewards) { + pack.give(player, user, null, 0, true); + } + } + else { + player.sendMessage(Lang.REWARDS.f("&7You received &e&l2 Tokens&7 as a daily reward!")); + user.addTokens(2); + for (RewardPack pack : this.dailyRewards) { + pack.give(player, user, null, 0, true); + } + } + user.addDailyStreak(1); + MenuManager.updateMenu(player, "rewards"); + Bukkit.getPluginManager().callEvent(new UpdateEvent(player, UpdateEvent.UpdateReason.TOKENS)); + } + + /** + * Claim the monthly reward for the given player. + * + * @param player - the player claiming the reward + * @param user - the user object representation for this player + */ + public void claimMonthly(Player player, User user) { + + // If user rank specifically is DEFAULT (exclude trial) + if (user.getUserRankNonTrial() == UserRank.DEFAULT) { + player.sendMessage(Lang.REWARDS.f("&7Only donators can claim Donor Rewards! Buy a rank at &a&l" + Core.getSettings().getStoreLink() + "&7!")); + return; + } + + // If server type is HUB + if (Core.getSettings().getType() == ServerType.HUB) { + player.sendMessage(Lang.REWARDS.f("&7Please claim this reward on " + Core.getSettings().getServer_GTM_shortName() + " to receive extra money and exclusive items!")); + return; + } + + // If user cannot claim rewards + if (!user.canClaimMonthlyReward()) { + player.sendMessage(Lang.REWARDS.f("&7You need to wait &c&l" + Utils.timeInMillisToText(user.getTimeUntilMonthlyReward()) + "&7 until you can claim your donor reward again!")); + return; + } + + user.setLastDonorReward(); + UserRank rank = user.getUserRankNonTrial().isHigherThan(UserRank.SUPREME) ? UserRank.SUPREME : user.getUserRankNonTrial(); + int tokens = rank.getMonthlyTokens(); + user.addTokens(tokens); + user.insertLog(player, "claimDonorReward", rank.toString(), "tokens", tokens, 0); + if (this.monthlyRewards.containsKey(rank)) + for (RewardPack pack : this.monthlyRewards.get(rank)) { + player.sendMessage(Lang.REWARDS.f(pack.getDisplayName())); + pack.give(player, user, "claimDonorReward", 0, true); + } + player.sendMessage(Lang.REWARDS.f("&7You claimed &e&l" + tokens + " Tokens&7 from your " + rank.getColoredNameBold() + "&7 rank!")); + Utils.broadcastExcept(player, Lang.REWARDS.f(user.getColoredName(player) + "&7 claimed &e&l" + tokens + " Tokens&7 and a bunch of other cool items from their " + rank.getColoredNameBold() + "&7 rank!")); + MenuManager.updateMenu(player, "rewards"); + Bukkit.getPluginManager().callEvent(new UpdateEvent(player, UpdateEvent.UpdateReason.TOKENS)); + } + + /** + * Spend amount of votes for the given player + * + * @param player - the player claiming the reward + * @param user - the user object representation for this player + * @param amount - the amount of votes to spend + */ + public void spendVote(Player player, User user, int amount) { + if (Core.getSettings().getType() == ServerType.HUB) { + player.sendMessage(Lang.REWARDS.f("&7Please claim this reward on " + Core.getSettings().getServer_GTM_shortName() + " to receive extra money and rare rewards!")); + return; + } + if (user.getVotes() <= 0) { + player.sendMessage(Lang.VOTE.f("&7You don't have any votes left to claim!")); + return; + } + for (int i = 0; i < amount; i++) { + this.spendVote(player, user); + } + } + + /** + * Spend only one vote for the given player. + * + * @param player - the player claiming the reward + * @param user - the user object representation for this player + */ + public void spendVote(Player player, User user) { + if (Core.getSettings().getType() == ServerType.HUB) { + player.sendMessage(Lang.REWARDS.f("&7Please claim this reward on " + Core.getSettings().getServer_GTM_shortName() + " to receive extra money and rare rewards!")); + return; + } + if (user.getVotes() <= 0) { + player.sendMessage(Lang.VOTE.f("&7You don't have any votes left to claim!")); + return; + } + user.removeVote(); + player.sendMessage(Lang.VOTE.f("&7Thank you for voting! Here are your rewards:")); + for (VoteReward reward : this.voteRewards) + if (reward.getChance() == 100.0000 || Utils.calculateChance(reward.getChance())) + reward.give(player, user); + MenuManager.updateMenu(player, "vote"); + } + + /** + * Spend all the votes possible for the given player. + * + * @param player - the player claiming the reward + * @param user - the user object representation for this player + */ + public void spendAllVotes(Player player, User user) { + if (user.getVotes() <= 0) { + player.sendMessage(Lang.VOTE.f("&7You don't have any votes left to claim!")); + return; + } + for (int i = 0; i < user.getVotes(); i++) { + this.spendVote(player, user); + } + } + + /** + * Get the voter based off the username from the voters list. + * + * @param username - the username to lookup + * + * @return The voter, if one exists, otherwise {@code null} + */ + public Voter getVoter(String username) { + return this.voters.stream().filter(voter -> Objects.equals(voter.getName(), username)).findFirst().orElse(null); + } + + /** + * Create the voter in the voters list, if they don't already exist. + * + * @param username - the username for the voter + * + * @return The voter object. + */ + public Voter createVoter(String username) { + for (Voter voter : this.voters) + if (Objects.equals(voter.getName(), username)) + return voter; + Voter v = new Voter(username); + this.voters.add(v); + return v; + } + + /** + * Save the settings of the vote manager. + * <p> + * This will save the last reset timing to the voting.yml. + * + * @param shutdown - {@code true} if this is called via shutdown, {@code false} otherwise. + */ + public void save(boolean shutdown) { + if (Core.getSettings().getType() == ServerType.HUB) { + Core.getSettings().getVotingConfig().set("lastreset", this.lastMonthlyReset); + Utils.saveConfig(Core.getSettings().getVotingConfig(), "voting"); + } + } + + /** + * Load the rewards from the yml files. + */ + public void loadLinksAndRewards() { + this.voters.clear(); + YamlConfiguration c = Core.getSettings().getVotingConfig(); + if (c.get("votelink") != null) + this.voteLink = c.getString("votelink"); +// this.lastMonthlyReset = c.get("lastreset") == null ? 0 : c.getLong("lastreset"); +// if (Core.getSettings().getType() == ServerType.HUB) { +// if (this.lastMonthlyReset + TimeUnit.DAYS.toMillis(30) < System.currentTimeMillis()) { +// this.resetMonthlyVotes(); +// this.setLastMonthlyReset(System.currentTimeMillis()); +// } +// } + this.voteRewards.clear(); + if (c.get("rewards") != null) + for (String name : c.getConfigurationSection("rewards").getKeys(false)) { + try { + double chance = c.get("rewards." + name + ".chance") == null ? 100 : c.getDouble("rewards." + name + ".chance"); + String item = c.getString("rewards." + name + ".item"); + RewardPack pack = this.getRewardPack(c, name, "rewards." + name); + if (pack == null) + Core.error("Error while loading RewardPack for vote reward: " + name); + else + this.voteRewards.add(new VoteReward(pack, item, chance)); + } + catch (Exception ex) { + Core.error("Error while loading vote reward: " + name); + ex.printStackTrace(); + } + } + this.dailyRewards.clear(); + this.luckyDailyRewards.clear(); + this.monthlyRewards.clear(); + c = Core.getSettings().getRewardsConfig(); + if (c.get("daily") != null) + for (String name : c.getConfigurationSection("daily").getKeys(false)) { + try { + RewardPack pack = this.getRewardPack(c, name, "daily." + name); + if (pack == null) + Core.error("Error while loading RewardPack for daily reward: " + name); + else + this.dailyRewards.add(pack); + } + catch (Exception e) { + Core.error("Error while loading daily reward: " + name); + e.printStackTrace(); + } + } + if (c.get("luckyDaily") != null) + for (String name : c.getConfigurationSection("luckyDaily").getKeys(false)) { + try { + RewardPack pack = this.getRewardPack(c, name, "luckyDaily." + name); + if (pack == null) + Core.error("Error while loading RewardPack for luckyDaily reward: " + name); + else + this.luckyDailyRewards.add(pack); + } + catch (Exception e) { + Core.error("Error while loading luckyDaily reward: " + name); + e.printStackTrace(); + } + } + if (c.get("monthly") != null) + for (String rankName : c.getConfigurationSection("monthly").getKeys(false)) { + try { + UserRank rank = UserRank.getUserRankOrNull(rankName); + if (rank == null) { + Core.error("Error while loading monthly reward with invalid name: " + rankName); + continue; + } + List<RewardPack> packs = new ArrayList<>(); + for (String name : c.getConfigurationSection("monthly." + rankName).getKeys(false)) { + RewardPack pack = this.getRewardPack(c, name, "monthly." + rankName + '.' + name); + if (pack == null) + Core.error("Error while loading RewardPack for monthly reward for " + rank + ": " + name); + else + packs.add(pack); + } + if (packs.isEmpty()) + Core.log("Error while loading monthly reward for rank: " + rankName + " has no rewards"); + else + this.monthlyRewards.put(rank, packs); + } + catch (Exception e) { + Core.error("Error while loading monthly reward for rank: " + rankName); + e.printStackTrace(); + } + } + } + + /** + * Get the reward pack from the given yaml config with the given name and path. + * + * @param c - the yaml config to read from + * @param name - the name of the reward + * @param path - the path to look for the reward + * + * @return The reward pack, if one was found, otherwise {@code null}. + */ + public RewardPack getRewardPack(YamlConfiguration c, String name, String path) { + if (c.getString(path + ".list") == null) + return new RewardPack(this.getReward(c, name, path), c.getString(path + ".description")); + List<Reward> rewards = c.getConfigurationSection(path + ".list").getKeys(false).stream().map(s -> this.getReward(c, s, path + ".list." + s)).filter(Objects::nonNull).collect(Collectors.toList()); + if (rewards.isEmpty()) + return null; + if (rewards.size() == 1) + return new RewardPack(rewards.get(0), c.getString(path + ".description")); + return new RewardPack(name, rewards, c.getString(path + ".description")); + } + + /** + * Get the reward object from the given yaml config, name, and path. + * + * @param c - the yaml config + * @param name - the name of the reward + * @param path - the path to lookup + * + * @return The reward object, if one was found, otherwise {@code null}. + */ + public Reward getReward(YamlConfiguration c, String name, String path) { + Reward.RewardType type = Reward.RewardType.fromString(c.getString(path + ".type")); + String disp = Utils.f(name); + switch (type) { + case CHEATCODE: + return new Reward(disp, Reward.RewardType.CHEATCODE, c.getString(path + ".cheatcode")); + case BUCKS: + case TOKENS: + case MONEY: + case CROWBARS: + return new Reward(disp, c.getDouble(path + ".amount"), type); + case CUSTOM: + String customType = c.getString(path + ".customType"); + if (c.get(path + ".customList") != null) + return new Reward(disp, customType, c.getStringList(path + ".customList")); + return new Reward(disp, customType, c.getString(path + ".customName"), c.get(path + ".amount") == null ? 1 : c.getDouble(path + ".amount")); + case ITEMS: + List<ItemStack> items = c.getStringList(path + ".items").stream().map(Parsing::parseItemStack).collect(Collectors.toList()); + return new Reward(disp, Utils.toArray(items)); +// case COSMETIC: +// String ct = c.getString(path + ".cosmeticType"); +// CosmeticType cosmeticType = CosmeticType.getType(c.getString(path + ".cosmeticType")); +// if (ct == null) { +// int minTokens = c.get(path + ".minTokens") == null ? 0 : c.getInt(path + ".minTokens"); +// int maxTokens = c.get(path + ".maxTokens") == null ? -1 : c.getInt(path + ".maxTokens"); +// return new Reward(disp, null, minTokens, maxTokens); +// } +// if (cosmeticType == null) { +// Core.error("Error while loading vote reward " + name + "! The type is not a valid CosmeticType."); +// return null; +// } +// String co = c.getString(path + ".cosmetic"); +// if (co == null || "random".equalsIgnoreCase(co)) { +// int minTokens = c.get(path + ".minTokens") == null ? 0 : c.getInt(path + ".minTokens"); +// int maxTokens = c.get(path + ".maxTokens") == null ? -1 : c.getInt(path + ".maxTokens"); +// return new Reward(disp, cosmeticType, minTokens, maxTokens); +// } +// Cosmetic cos = cosmeticType.getCosmetic(co); +// if (cos == null) { +// Core.error("Error while loading vote reward " + name + "! The cosmetic is not a valid cosmetic of CosmeticType " + type + '!'); +// return null; +// } +// return new Reward(disp, cos); + + case TRIAL_RANK: { + UserRank rank = UserRank.getUserRankOrNull(c.getString(path + ".rank")); + if (rank == null) { + Core.error("Error while loading shop item " + name + "! The rank is not a valid UserRank!"); + return null; + } + int days = c.get(path + ".days") == null ? 1 : c.getInt(path + ".days"); + return new Reward(name, rank, days); + } + case NAMETAG: + Nametag tag = Core.getNametagManager().getNametag(c.getString(path + ".nametag")); + if (tag == null) { + Core.error("Error while loading shop item " + name + "! The nametag is not a valid Nametag!"); + return null; + } + return new Reward(disp, tag); + case PERMISSION: + String permission = c.getString(path + ".permission"); + if (permission == null) { + Core.error("Error while loading shop item " + name + "! The permission was not specified!"); + return null; + } + return new Reward(disp, permission, Reward.RewardType.PERMISSION); + case RANK: + UserRank rank = UserRank.getUserRankOrNull(c.getString(path + ".rank")); + if (rank == null) { + Core.error("Error while loading shop item " + name + "! The rank is not a valid UserRank!"); + return null; + } + return new Reward(name, rank); + case COMMAND: + String command = c.getString(path + ".command"); + if (command == null) { + Core.error("Error while loading shop item " + name + "! The command was not specified!"); + return null; + } + return new Reward(disp, command, Reward.RewardType.COMMAND); + case ACHIEVEMENT: + Achievement achievement = Achievement.valueOf(c.get(path + ".achievement") == null ? null : c.getString(path + ".achievement").toUpperCase()); + if (achievement == null) { + Core.error("Error while loading shop item " + name + "! The command was not specified!"); + return null; + } + return new Reward(disp, achievement); + case VEHICLE: + String vehicleIdentifier = c.getString(path + ".customName"); + return new Reward(disp, vehicleIdentifier, Reward.RewardType.VEHICLE); + case WEAPON: + String weaponName = c.getString(path + ".name"); + int stars = c.getInt(path + ".stars"); + short weaponSkinID = (short) c.getInt(path + ".weaponSkinId", 0); + return new Reward(weaponName, disp, stars, weaponSkinID, Reward.RewardType.WEAPON); + case SKIN: + return new Reward(name, Reward.RewardType.SKIN, c.getString(path + ".customName")); + } + return null; + } + + /** + * Load the token shop items from the token shop config. + */ + public void loadTokenShop() { + YamlConfiguration c = Core.getSettings().getTokenShopConfig(); + this.shopItems.clear(); + if (c.get("shopItems") != null) + for (String name : c.getConfigurationSection("shopItems").getKeys(false)) { + try { + int price = c.get("shopItems." + name + ".price") == null ? 1 : c.getInt("shopItems." + name + ".price"); + String item = c.get("shopItems." + name + ".item") == null ? "1" : c.getString("shopItems." + name + ".item"); + RewardPack pack = this.getRewardPack(c, name, "shopItems." + name); + if (pack == null) + Core.log("Error while loading RewardPack for tokenshop item: " + name); + else + this.shopItems.add(new ShopItem(name, price, item, pack)); + } + catch (Exception e) { + Core.error("Error while loading tokenshop item " + name); + e.printStackTrace(); + } + } + } + + /** + * Get the voting link. + * + * @return The full http link that users can click to go to vote. + */ + public String getVoteLink() { + return this.voteLink; + } + + /** + * Get the list of rewards that are possible for voting. + * + * @return The list of rewards for voting. + */ + public List<VoteReward> getVoteRewards() { + return this.voteRewards; + } + + /** + * Get the vote rewards they are guaranteed to get. + * + * @return The list of vote rewards they are guaranteed to receive. + */ + public List<VoteReward> getGuaranteedVoteRewards() { + return this.voteRewards.stream().filter(v -> v.getChance() == 100).collect(Collectors.toList()); + } + + /** + * Get the rewards that are based off chance. + * + * @return The possible rewards that they can get but must roll for the chance. + */ + public List<VoteReward> getChanceVoteRewards() { + return this.voteRewards.stream().filter(v -> v.getChance() != 100).collect(Collectors.toList()); + } + + /** + * Get the daily rewards. + * + * @return The list of daily rewards. + */ + public List<RewardPack> getDailyRewards() { + return this.dailyRewards; + } + + /** + * Get the lucky daily rewards. + * + * @return The list of daily rewards that are considered lucky. + */ + public List<RewardPack> getLuckyDailyRewards() { + return this.luckyDailyRewards; + } + + /** + * Get the monthly rewards. + * + * @return The monthly rewards mapped by key userrank. + */ + public Map<UserRank, List<RewardPack>> getMonthlyRewards() { + return this.monthlyRewards; + } + + /** + * Get the vote reward based off the given name. + * + * @param name - the name to lookup + * + * @return The vote reward with the given name, if one exists, otherwise {@code null} + */ + public VoteReward getVoteReward(String name) { + return this.voteRewards.stream().filter(reward -> reward.getName().equalsIgnoreCase(name)).findFirst().orElse(null); + } + + /** + * Get the shop items for the token shop. + * + * @return + */ + public List<ShopItem> getShopItems() { + return this.shopItems; + } + + /** + * Get the shop item based off the name. + * + * @param s - the name to lookup + * + * @return The shop item that was found with the given name, otherwise {@code null}. + */ + public ShopItem getShopItem(String s) { + return this.shopItems.stream().filter(item -> ChatColor.stripColor(Utils.f(item.getName())).equalsIgnoreCase(ChatColor.stripColor(s))).findFirst().orElse(null); + } + + /** + * Get the long representation of the timestamp of when the monthly reset occurred. + * + * @return The long timestamp of when the last monthly reset was. + */ + public Long getLastMonthlyReset() { + return this.lastMonthlyReset; + } + + /** + * Set the last monthly reset to the given long representation. + * + * @param time - the new last monthly reset. + */ + public void setLastMonthlyReset(Long time) { + this.lastMonthlyReset = time; + this.save(false); + } + + /** + * Get the owning plugin. + * + * @return The plugin that owns this manager. + */ + @Override + public Plugin getPlugin() { + return plugin; + } + + /** + * Get the locally cached result of the top voters. + * + * @return The top voters, in order, where element 1 is the first place top voter. + */ + public VoteDAO.VoteUser[] getTopVoters() { + return topVoters; + } + + /** + * Get the locally cached result of the last months top voters. + * + * @return The last top voters, in order, where element 1 is the first place top voter. + */ + public VoteDAO.VoteUser[] getLastTopVoters() { + return lastTopVoters; + } + + /** + * Check whether or not the specified vote record and the specified voteSite + * are on cooldown. + * + * @param vr - the vote record in question + * @param voteSite - the vote site that is attempting to be voted on + * @param userName - the name of the user doing the voting + * + * @return {@code true} if the vote site is on cooldown, {@code false} + * otherwise. + */ + protected boolean isVoteSiteCooldown(VoteRecord vr, VoteSite voteSite, String userName) { + + // ALL votes site cannot ensure valid votes + // VoteSite.FOUR is a 12 hour cooldown + // Ask Stephen for details, but there was a lot of data mining required + + // get the last voting time for THIS site + long lastVote = vr.getSiteTimestamps().get(voteSite) != null ? vr.getSiteTimestamps().get(voteSite).getTime() : 0; + long current = System.currentTimeMillis(); + + // VoteSite.FOUR is 12 hours, so lets check for 8 + if (voteSite.equals(VoteSite.FOUR)) { + + // if less 8 hours between the votes + if (current - lastVote < 28800000) { + Core.log("[VoteManager] Player '" + userName + "' has voted on site=" + voteSite.getName() + " #" + voteSite.getId() + " within the last 8 hours. Disregarding vote. Difference between now and last vote (in msec) is: " + (current - lastVote)); + return true; + } + } + // all others are 24 hours, but lets check for 16 + else { + // if less 16 hours between the votes + if (current - lastVote < 57600000) { + Core.log("[VoteManager] Player '" + userName + "' has voted on site=" + voteSite.getName() + " #" + voteSite.getId() + " within the last 16 hours. Disregarding vote. Difference between now and last vote (in msec) is: " + (current - lastVote)); + return true; + } + } + + return false; + } + + /** + * Handle whether or not to increment or reset the voting streak. + * + * @param conn - the database connection thread + * @param vr - the vote record + */ + protected void handleVoteStreakIncrement(Connection conn, VoteRecord vr) { + + // the uuid of the user + UUID uuid = vr.getOwner(); + + // have they voted EVER + if (vr.getLastVoted().isPresent()) { + + // determine if this is a different day + Timestamp lastVoted = vr.getLastVoted().get(); + Timestamp current = new Timestamp(System.currentTimeMillis()); + + // don't count same days as vote streak increment + boolean isDiff = TimeUtil.isDifferentDay(current, lastVoted); + if (isDiff) { + + // if voted within timeframe + int hoursDiff = TimeUtil.getDifferenceInHours(current, lastVoted); + if (hoursDiff <= 48) { + VoteDAO.incrementVoteStreak(conn, uuid); + } + else { + + int maxStreak = vr.getStreak(); + if (maxStreak > vr.getMaxStreak()) { + VoteDAO.updateMaxStreak(conn, uuid, maxStreak); + } + + // reset streak + VoteDAO.resetVoteStreak(conn, uuid); + VoteDAO.incrementVoteStreak(conn, uuid); + } + } + } + else { + // if never voted before, increment vote streak + VoteDAO.incrementVoteStreak(conn, uuid); + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/VoteRecord.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/VoteRecord.java new file mode 100644 index 0000000..a9102e3 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/VoteRecord.java @@ -0,0 +1,149 @@ +package net.grandtheftmc.core.voting; + +import java.sql.Timestamp; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; + +/** + * Note: This class is designed as a read only response from the database. + */ +public class VoteRecord { + + /** Owner of the vote record */ + private final UUID owner; + /** The total amount of votes the user has */ + private final int totalVotes; + /** Current streak they are on */ + private final int streak; + /** Max streak they ever received */ + private final int maxStreak; + /** Timestamp for when they last voted */ + private final Timestamp lastVoted; + /** Maps VoteSite to when they last voted */ + private final Map<VoteSite, Timestamp> siteToLastVote; + + /** + * Create a new VoteRecord. + * <p> + * This holds all cumulative information about a player's votes, and is read + * from the database. + * + * @param owner - the owner of the vote record + * @param totalVotes - the total votes for the player + * @param streak - the current streak of voting + * @param maxStreak - the max streak that this player has + * @param lastVoted - the timestamp when the player last voted + */ + public VoteRecord(UUID owner, int totalVotes, int streak, int maxStreak, Timestamp lastVoted) { + this.owner = owner; + this.totalVotes = totalVotes; + this.streak = streak; + this.maxStreak = maxStreak; + this.lastVoted = lastVoted; + this.siteToLastVote = new HashMap<>(); + } + + /** + * Create a new VoteRecord. + * <p> + * This holds all cumulative information about a player's votes, and is read + * from the database. + * <p> + * Note: This has all null values, as the player has never voted before. + * + * @param owner - the owner of the vote record + */ + public VoteRecord(UUID owner) { + this(owner, 0, 0, 0, null); + } + + /** + * Get the UUID of the owner of this record. + * + * @return The UUID of the owner of this vote record. + */ + public UUID getOwner() { + return owner; + } + + /** + * Get the total votes the user has. + * + * @return The total number of votes the user has. + */ + public int getTotalVotes() { + return totalVotes; + } + + /** + * Get the voting streak that this record currently has. + * + * @return The streak that this record currently has. + */ + public int getStreak() { + return streak; + } + + /** + * Get the max streak for this voting record. + * + * @return The max streak for this voting record. + */ + public int getMaxStreak() { + return maxStreak; + } + + /** + * Get the timestamp of when this user last voted, in general. + * + * @return The timestamp of when this user last voted, if one exists. + */ + public Optional<Timestamp> getLastVoted() { + return Optional.ofNullable(lastVoted); + } + + /** + * Get the timestamp of the specified last vote site. + * + * @param voteSite - the site that was voted on + * + * @return The Timestamp for the site that was last voted, if it exists, + * otherwise {@code null}. + */ + public Timestamp getVoteTimestamp(VoteSite voteSite) { + if (siteToLastVote.containsKey(voteSite)) { + return siteToLastVote.get(voteSite); + } + + return null; + } + + /** + * Set the voting timestamp of the specified vote site and timestamp. + * + * @param voteSite - the site that was voted on + * @param timestamp - the timestamp that it was voted + */ + public void setVoteTimestamp(VoteSite voteSite, Timestamp timestamp) { + siteToLastVote.put(voteSite, timestamp); + } + + /** + * Get the mapping of vote site to timestamps. + * + * @return The mapping of each vote site to the last vote. + */ + public Map<VoteSite, Timestamp> getSiteTimestamps() { + return siteToLastVote; + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return "VoteRecord [owner=" + getOwner().toString() + ", streak=" + getStreak() + ", maxStreak=" + getMaxStreak() + ", lastVoted=" + lastVoted + "]"; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/VoteReward.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/VoteReward.java new file mode 100644 index 0000000..f0cbba9 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/VoteReward.java @@ -0,0 +1,52 @@ +package net.grandtheftmc.core.voting; + +import com.j0ach1mmall3.jlib.methods.Parsing; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +/** + * Created by Liam on 23/04/2017. + */ +public class VoteReward { + + private final ItemStack item; + private final RewardPack pack; + private final double chance; + + public VoteReward(RewardPack pack, String item, double chance) { + this.pack = pack; + this.item = item == null ? null : Parsing.parseItemStack(item); + this.chance = chance; + } + + public String getName() { + return this.pack.getName(); + } + + public ItemStack getItem() { + return this.item == null ? this.pack.get().get(0).getDisplayItem() : this.item; + } + + + public String getDisplayName() { + return this.pack.getDisplayName(); + } + + public RewardPack getRewardPack() { + return this.pack; + } + + public double getChance() { + return this.chance; + } + + public void give(Player player, User user) { + if (chance != 100) + Utils.broadcastExcept(player, Lang.VOTE.f(user.getColoredName(player) + "&7 won a rare reward while &e&lvoting&7: " + this.pack.getDisplayName() + "&7 (&a" + this.chance + "%)")); + this.pack.give(player, user, chance == 100 ? null : "voteReward", 0, true); + + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/VoteSite.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/VoteSite.java new file mode 100644 index 0000000..435ed7f --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/VoteSite.java @@ -0,0 +1,50 @@ +package net.grandtheftmc.core.voting; + +import java.util.Optional; + +public enum VoteSite { + ONE(1, "http://minecraft-mp.com/server/14659/vote/", "minecraft-mp.com"), + TWO(2, "http://minecraftservers.org/vote/102886", "minecraftservers.org"), + THREE(3, "http://minecraft-server-list.com/server/210232/vote/", "mcsl"), + FOUR(4, "http://topg.org/Minecraft/in-365133", "topg.org"), + FIVE(5, "https://topminecraftservers.org/vote/1822", "TopMinecraftServers"); + + /** The id of the vote site */ + private final int id; + /** The url for the vote site */ + private final String url; + /** The name for the vote site */ + private final String name; + + VoteSite(int id, String url, String name) { + this.id = id; + this.url = url; + this.name = name; + } + + public static Optional<VoteSite> find(String search) { + for (VoteSite voteSite : VoteSite.values()) { + if (voteSite.name.equalsIgnoreCase(search) + || voteSite.url.equalsIgnoreCase(search)) { + return Optional.of(voteSite); + } + } + return Optional.empty(); + } + + public int getId(){ + return this.id; + } + + public String getURL() { + return this.url; + } + + public String getName() { + return this.name; + } + + public int getImportance() { + return this.ordinal(); + } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/Voter.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/Voter.java new file mode 100644 index 0000000..614fcef --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/Voter.java @@ -0,0 +1,33 @@ +package net.grandtheftmc.core.voting; + +public class Voter { + + private final String name; + private int votes; + private long lastVote = -1; + + public Voter(String name) { + this.name = name; + } + + public String getName() { + return this.name; + } + + public int getVotes() { + return this.votes; + } + + public void addVote() { + this.votes++; + this.lastVote = System.currentTimeMillis(); + } + + public void setVotes(int i) { + this.votes = i; + } + +// public long getLastVote() { +// return this.lastVote; +// } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/crates/Crate.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/crates/Crate.java new file mode 100644 index 0000000..3d1a3ef --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/crates/Crate.java @@ -0,0 +1,853 @@ +package net.grandtheftmc.core.voting.crates; + +import com.gmail.filoghost.holographicdisplays.api.Hologram; +import com.gmail.filoghost.holographicdisplays.api.HologramsAPI; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.servers.ServerType; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.listeners.Move; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.factory.ItemFactory; +import org.bukkit.*; +import org.bukkit.entity.*; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.FireworkMeta; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; +import us.myles.ViaVersion.api.Via; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; + +/** + * Created by Timothy Lampen on 2017-04-24. + */ +public class Crate { + + private final Location loc; + private final CrateStars rank; + private final Location selected; + private Hologram hologram; + private UUID openingCrate; + private ArmorStand gravityArmorStand, hologramArmorStand, stand; + private CrateReward determinedCrateReward; + private boolean finished; + private Item item; + + //@param loc should be a BLOCK location. + public Crate(Location loc, int stars) { + this.loc = loc; + this.selected = loc.clone().add(.5, 0, .5); + this.rank = CrateStars.getCrateStars(stars); + this.generate(); + } + + public CrateStars getCrateStars() { + return this.rank; + } + + public Location getLocation() { + return this.loc; + } + + private void generate() { + this.loc.getBlock().setType(Material.AIR); + this.hologram = HologramsAPI.createHologram(Core.getInstance(), this.loc.clone().add(0, this.rank.getHeight(), 0)); + this.hologram.appendTextLine(this.rank.getDisplayName()); + this.hologram.appendTextLine(this.rank.getStarsString()); + this.hologram.appendTextLine(Utils.f("&9&l" + this.rank.getCrowbars() + " Crowbar" + (this.rank.getCrowbars() == 1 ? "" : "s"))); + this.hologram.appendTextLine(Utils.f("&7Right click to see rewards!")); + + this.stand = (ArmorStand) this.loc.getWorld().spawnEntity(this.loc, EntityType.ARMOR_STAND); + this.stand.setVisible(false); + this.stand.setGravity(false); +// this.stand.setHelmet(new ItemStack(Material.DIAMOND_SWORD, 1, this.rank.getClosedHead())); + this.stand.setHelmet(new ItemFactory(Core.getSettings().getType() != ServerType.VICE ? Material.DIAMOND_SWORD : Material.DIAMOND_SWORD, (short) this.rank.getClosedHead()).setUnbreakable(true).build()); + this.stand.setRemoveWhenFarAway(false); + this.stand.setMetadata("CRATE", new FixedMetadataValue(Core.getInstance(), true)); + + //In the future we can use this to check how many armour stands are spawned in the world when the server starts up. + System.out.println("Crate count now spawned in world: " + loc.getWorld().getEntitiesByClass(ArmorStand.class).stream().filter(ent -> ent.hasMetadata("CRATE")).count()); + } + + public void startAnimation(Player player, User user) { + this.openingCrate = player.getUniqueId(); + + //Store as a crate being opened + if (rank.getStars() > 2) { + Move.setOpening(player.getUniqueId(), this.loc); + } + + // While the animation is playing, any players except 'player' should be bounced away from the crate + for (Entity e : this.loc.getWorld().getNearbyEntities(this.loc, 4, 4, 4)) { + if (e instanceof Player && !Objects.equals(e.getUniqueId(), player.getUniqueId())) { + e.setVelocity(e.getLocation().getDirection().setY(2).multiply(-2)); + } + } + + this.determinedCrateReward = Core.getCrateManager().determineCrateReward(player, user, this.rank); + ItemStack is = determinedCrateReward.getItem(); + ItemMeta im = is.getItemMeta(); + im.setDisplayName(determinedCrateReward.getDisplayName()); + is.setItemMeta(im); + + switch (rank.getStars()) { + case 1: + startAnimationFirst(player, stand.getLocation(), is); + break; + case 2: + startAnimationSecond(player, stand.getLocation(), is); + break; + case 3: + startAnimationThird(player, stand.getLocation(), is); + break; + case 4: + startAnimationFourth(player, stand.getLocation(), is); + break; + case 5: + startAnimationFifth(player, stand.getLocation(), is); + break; + case 6: + startAnimationThird(player, stand.getLocation(), is); + break; + } + + this.hologram.getVisibilityManager().setVisibleByDefault(false); + this.hologram.getVisibilityManager().resetVisibilityAll(); + //change to how long the animation is, or include with the ending of the animation + } + + public void activateReward() { + Player player = this.getOpeningCrate(); + CrateReward crateReward = this.determinedCrateReward; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + user.setSelectedCrate(null); + if (crateReward.getRewardPack().hasAllRewards(player, user)) { + user.addCrowbars(this.rank.getCrowbars()); + player.sendMessage(Lang.CRATES.f("&7Sorry, it seems that you already won this package. Your crowbars have been returned. Feel free to try again.")); + return; + } + + if (crateReward.getRewardPack().hasAnyReward(player, user)) { + player.sendMessage(Lang.CRATES.f("&7You seem to have &a" + crateReward.getRewardPack().hasAnyRewardSize(player, user) + "&7/&a" + crateReward.getRewardPack().get().size() + "&7 rewards in this package already. You can chose between accepting the remaining rewards or having your crowbars returned.")); + user.setConfirmingCrateReward(crateReward); + MenuManager.openMenu(player, "confirmcratereward"); + return; + } + + player.sendMessage(Utils.f("&7You won the following reward" + (crateReward.getRewardPack().get().size() == 1 ? "" : "s") + " by opening this " + this.rank.getDisplayName() + "&7:")); + crateReward.give(player, user, this.rank); + user.insertLog(player, "CrateReward", "CRATE-" + this.getCrateStars().getStars(), crateReward.getName(), 1, this.getCrateStars().getCrowbars()); + } + + public void destroy() { + this.hologram.delete(); + this.stand.remove(); + + if (this.gravityArmorStand != null) + this.gravityArmorStand.remove(); + + if (this.hologramArmorStand != null) + this.hologramArmorStand.remove(); + + if (this.item != null) + this.item.remove(); + } + + public UUID getOpeningCrateUUID() { + return this.openingCrate; + } + + public Player getOpeningCrate() { + Player player = this.openingCrate == null ? null : Bukkit.getPlayer(this.openingCrate); + if (this.openingCrate != null && player == null) this.openingCrate = null; + return player; + } + + public boolean isBeingOpened() { + return this.getOpeningCrate() != null; + } + + public ArmorStand getStand() { + return this.stand; + } + + /* + * + * + * + * Crate Effects + * + * + * */ + + public void startAnimationFirst(Player player, Location location, ItemStack reward) { + this.gravityArmorStand = (ArmorStand) location.getWorld().spawnEntity(location.clone().subtract(0, 0.7, 0), EntityType.ARMOR_STAND); + this.gravityArmorStand.setGravity(false); + this.gravityArmorStand.setVisible(false); + play(player, "VILLAGER_HAPPY", location, 0.5F, 0F, 0.5F, 0.1F, 40); + + new BukkitRunnable() { + @Override + public void run() { + startAnimation(player, stand.getLocation().clone().add(0, 1, 0), new Callback<Location>() { + @Override + public void execute(Location response) { +// stand.setHelmet(new ItemStack(Material.DIAMOND_SWORD, 1, Crate.this.rank.getOpenHead())); + stand.setHelmet(new ItemFactory(Core.getSettings().getType() != ServerType.VICE ? Material.DIAMOND_SWORD : Material.DIAMOND_SWORD, (short) Crate.this.rank.getOpenHead()).setUnbreakable(true).build()); + final Item b = response.clone().getWorld().dropItem(response.clone().add(0, 1, 0), reward); + b.setVelocity(new Vector(0, 0.2, 0)); + b.setTicksLived(8000); + b.setPickupDelay(Integer.MAX_VALUE); + + new BukkitRunnable() { + @Override + public void run() { + gravityArmorStand.setPassenger(b); + hologramArmorStand = (ArmorStand) b.getLocation().getWorld().spawnEntity(b.getLocation().clone().add(0, -2.3, 0), EntityType.ARMOR_STAND); + hologramArmorStand.setMetadata("crateItemDisplay", new FixedMetadataValue(Core.getInstance(), true)); + hologramArmorStand.setCustomName(Utils.f(reward.getItemMeta().getDisplayName())); + hologramArmorStand.setCustomNameVisible(true); + hologramArmorStand.setGravity(false); + hologramArmorStand.setVisible(false); + Crate.this.activateReward(); + + new BukkitRunnable() { + @Override + public void run() { + resetAnimationFirst(b); + } + }.runTaskLater(Core.getInstance(), 100); + } + }.runTaskLater(Core.getInstance(), 11); + + player.playSound(player.getLocation(), Sound.BLOCK_ANVIL_USE, 1, 1); + player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 1); + } + }); + } + }.runTaskLater(Core.getInstance(), 30); + } + + public void resetAnimationFirst(Item item) { + this.hologramArmorStand.remove(); + this.gravityArmorStand.remove(); + item.remove(); +// this.stand.setHelmet(new ItemStack(Material.DIAMOND_SWORD, 1, this.rank.getClosedHead())); + this.stand.setHelmet(new ItemFactory(Core.getSettings().getType() != ServerType.VICE ? Material.DIAMOND_SWORD : Material.DIAMOND_SWORD, (short) this.rank.getClosedHead()).setUnbreakable(true).build()); + this.openingCrate = null; + this.hologram.getVisibilityManager().setVisibleByDefault(true); + this.hologram.getVisibilityManager().resetVisibilityAll(); + } + + public void startAnimationSecond(final Player player, final Location location, final ItemStack reward) { + gravityArmorStand = (ArmorStand) location.getWorld().spawnEntity(location.clone().subtract(0, 0.6, 0), EntityType.ARMOR_STAND); + gravityArmorStand.setGravity(false); + gravityArmorStand.setVisible(false); + play(player, "VILLAGER_HAPPY", location, 0.5F, 0F, 0.5F, 0.1F, 40); + + new BukkitRunnable() { + int times = 0; + + @Override + public void run() { + if (times == 5) { + cancel(); + new BukkitRunnable() { + @Override + public void run() { +// stand.setHelmet(new ItemStack(Material.DIAMOND_SWORD, 1, Crate.this.rank.getOpenHead())); + stand.setHelmet(new ItemFactory(Core.getSettings().getType() != ServerType.VICE ? Material.DIAMOND_SWORD : Material.DIAMOND_SWORD, (short) Crate.this.rank.getOpenHead()).setUnbreakable(true).build()); + final Item b = location.clone().getWorld().dropItem(location.clone().add(0, 1, 0), reward); + b.setVelocity(new Vector(0, 0.2, 0)); + b.setTicksLived(8000); + b.setPickupDelay(Integer.MAX_VALUE); + + new BukkitRunnable() { + @Override + public void run() { + gravityArmorStand.setPassenger(b); + hologramArmorStand = (ArmorStand) b.getLocation().getWorld().spawnEntity(b.getLocation().clone().add(0, -2.2, 0), EntityType.ARMOR_STAND); + hologramArmorStand.setMetadata("crateItemDisplay", new FixedMetadataValue(Core.getInstance(), true)); + hologramArmorStand.setCustomName(Utils.f(reward.getItemMeta().getDisplayName())); + hologramArmorStand.setCustomNameVisible(true); + hologramArmorStand.setGravity(false); + hologramArmorStand.setVisible(false); + Crate.this.activateReward(); + new BukkitRunnable() { + @Override + public void run() { + resetAnimationSecond(b); + } + }.runTaskLater(Core.getInstance(), 100); + } + }.runTaskLater(Core.getInstance(), 11); + + player.playSound(player.getLocation(), Sound.BLOCK_ANVIL_USE, 1, 1); + player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 1); + } + }.runTask(Core.getInstance()); + } + + play(player, "SMOKE_LARGE", location, 0.3F, 0.1F, 0.3F, 0.1F, 50); + player.playSound(player.getLocation(), Sound.BLOCK_GRAVEL_FALL, 1, 1); + player.playSound(player.getLocation(), Sound.BLOCK_ANVIL_BREAK, 1, 1); + player.playSound(player.getLocation(), Sound.BLOCK_GRASS_BREAK, 1, 1); + + if (ThreadLocalRandom.current().nextInt(2) == 1) { + player.playSound(player.getLocation(), Sound.BLOCK_GRASS_BREAK, 1, 1); + player.playSound(player.getLocation(), Sound.BLOCK_GRAVEL_FALL, 1, 1); + } else { + player.playSound(player.getLocation(), Sound.BLOCK_ANVIL_BREAK, 1, 1); + player.playSound(player.getLocation(), Sound.BLOCK_GRASS_BREAK, 1, 1); + } + + times++; + } + }.runTaskTimerAsynchronously(Core.getInstance(), 0, 10); + } + + public void resetAnimationSecond(Item item) { + this.hologramArmorStand.remove(); + this.gravityArmorStand.remove(); + item.remove(); +// this.stand.setHelmet(new ItemStack(Material.DIAMOND_SWORD, 1, this.rank.getClosedHead())); + this.stand.setHelmet(new ItemFactory(Core.getSettings().getType() != ServerType.VICE ? Material.DIAMOND_SWORD : Material.DIAMOND_SWORD, (short) this.rank.getClosedHead()).setUnbreakable(true).build()); + this.openingCrate = null; + this.hologram.getVisibilityManager().setVisibleByDefault(true); + this.hologram.getVisibilityManager().resetVisibilityAll(); + } + + public void startAnimationThird(final Player player, final Location location, ItemStack reward) { + gravityArmorStand = (ArmorStand) location.getWorld().spawnEntity(location.clone().subtract(0, 0.8, 0), EntityType.ARMOR_STAND); + gravityArmorStand.setGravity(false); + gravityArmorStand.setVisible(false); + play(player, "VILLAGER_HAPPY", location, 0.5F, 0F, 0.5F, 0.1F, 40); + new BukkitRunnable() { + int times = 0; + + @Override + public void run() { + if (times == 4) { + cancel(); + new BukkitRunnable() { + @Override + public void run() { + play(player, "EXPLOSION_NORMAL", location, 0.2F, 0F, 0.2F, 0.1F, 70); +// stand.setHelmet(new ItemStack(Material.DIAMOND_SWORD, 1, Crate.this.rank.getOpenHead())); + stand.setHelmet(new ItemFactory(Core.getSettings().getType() != ServerType.VICE ? Material.DIAMOND_SWORD : Material.DIAMOND_SWORD, (short) Crate.this.rank.getOpenHead()).setUnbreakable(true).build()); + item = location.clone().getWorld().dropItem(location.clone().add(0, 0.2, 0), reward); + item.setVelocity(new Vector(0, 0, 0)); + item.setTicksLived(8000); + item.setPickupDelay(Integer.MAX_VALUE); + gravityArmorStand.setPassenger(item); + Crate.this.activateReward(); + new BukkitRunnable() { + @Override + public void run() { + hologramArmorStand = (ArmorStand) item.getLocation().getWorld().spawnEntity(item.getLocation().clone().add(0, -1.3, 0), EntityType.ARMOR_STAND); + hologramArmorStand.setMetadata("crateItemDisplay", new FixedMetadataValue(Core.getInstance(), true)); + hologramArmorStand.setCustomName(Utils.f(reward.getItemMeta().getDisplayName())); + hologramArmorStand.setCustomNameVisible(true); + hologramArmorStand.setGravity(false); + hologramArmorStand.setVisible(false); + new BukkitRunnable() { + @Override + public void run() { + resetCrateThird(player); + } + }.runTaskLater(Core.getInstance(), 20 * 7); + } + }.runTaskLater(Core.getInstance(), 8); + player.playSound(player.getLocation(), Sound.BLOCK_ANVIL_USE, 1, 1); + player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 1); + } + }.runTask(Core.getInstance()); + } + + play(player, "CLOUD", location, 0.2F, 0.1F, 0.2F, 0.1F, 2); + play(player, "SMOKE_NORMAL", location, 0.2F, 0.1F, 0.2F, 0.1F, 20); + if (ThreadLocalRandom.current().nextInt(2) == 1) { + player.playSound(player.getLocation(), Sound.BLOCK_GRASS_BREAK, 1, 1); + player.playSound(player.getLocation(), Sound.BLOCK_ANVIL_BREAK, 1, 1); + } else { + player.playSound(player.getLocation(), Sound.ENTITY_BLAZE_BURN, 1, 1); + player.playSound(player.getLocation(), Sound.ENTITY_BLAZE_HURT, 1, 1); + } + times++; + } + }.runTaskTimerAsynchronously(Core.getInstance(), 0, 10); + } + + public void resetCrateThird(final Player player) { + new BukkitRunnable() { + int times = 0; + + @Override + public void run() { + if (times == 3) { + Move.stopOpening(Crate.this.openingCrate, Crate.this.loc); + Crate.this.openingCrate = null; + cancel(); + item.remove(); + Crate.this.hologram.getVisibilityManager().setVisibleByDefault(true); + Crate.this.hologram.getVisibilityManager().resetVisibilityAll(); + gravityArmorStand.remove(); + hologramArmorStand.remove(); +// stand.setHelmet(new ItemStack(Material.DIAMOND_SWORD, 1, (short) 14)); + stand.setHelmet(new ItemFactory(Core.getSettings().getType() != ServerType.VICE ? Material.DIAMOND_SWORD : Material.DIAMOND_SWORD, (short) Crate.this.getCrateStars().getClosedHead()).setUnbreakable(true).build()); + } + + if (ThreadLocalRandom.current().nextInt(2) == 1) { + play(player, "SLIME", item.getLocation().clone().add(0, 0.2, 0), 0.2F, 0F, 0.2F, 0.1F, 40); + play(player, "CLOUD", item.getLocation().add(0, -0.2, 0), 0.3F, 0F, 0.3F, 0.1F, 40); + } else { + play(player, "CRIT", item.getLocation().clone().add(0, 0.2, 0), 0.2F, 0F, 0.2F, 0.1F, 40); + play(player, "SMOKE_NORMAL", item.getLocation().add(0, -0.2, 0), 0.3F, 0F, 0.3F, 0.1F, 40); + } + + if (ThreadLocalRandom.current().nextInt(2) == 1) { + player.playSound(player.getLocation(), Sound.BLOCK_NOTE_PLING, 1, 1); + player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_ATTACK_SWEEP, 1, 1); + } else { + player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_BOTTLE_THROW, 1, 1); + player.playSound(player.getLocation(), Sound.BLOCK_SLIME_HIT, 1, 1); + } + + times++; + } + }.runTaskTimerAsynchronously(Core.getInstance(), 0, 20); + } + + public void startAnimationFourth(final Player player, final Location location, ItemStack reward) { + gravityArmorStand = (ArmorStand) location.getWorld().spawnEntity(location.clone().subtract(0, 0.6, 0), EntityType.ARMOR_STAND); + gravityArmorStand.setGravity(false); + gravityArmorStand.setVisible(false); + play(player, "VILLAGER_HAPPY", location, 0.5F, 0F, 0.5F, 0.1F, 40); + if (selected != null) { + player.playSound(player.getLocation(), Sound.BLOCK_ANVIL_BREAK, 1, 1); + player.playSound(player.getLocation(), Sound.ENTITY_BLAZE_HURT, 1, 1); + new BukkitRunnable() { + int times = 0; + + @Override + public void run() { + if (times == 3) { + new BukkitRunnable() { + @Override + public void run() { + play(player, "EXPLOSION_HUGE", location, 0.2F, 0F, 0.2F, 0.1F, 1); +// stand.setHelmet(new ItemStack(Material.DIAMOND_SWORD, 1, Crate.this.rank.getOpenHead())); + stand.setHelmet(new ItemFactory(Core.getSettings().getType() != ServerType.VICE ? Material.DIAMOND_SWORD : Material.DIAMOND_SWORD, (short) Crate.this.rank.getOpenHead()).setUnbreakable(true).build()); + item = location.clone().getWorld().dropItem(location.clone().add(0, 0.2, 0), reward); + item.setVelocity(new Vector(0, 0, 0)); + item.setTicksLived(8000); + item.setPickupDelay(Integer.MAX_VALUE); + gravityArmorStand.setPassenger(item); + Crate.this.activateReward(); + hologramArmorStand = (ArmorStand) item.getLocation().getWorld().spawnEntity(item.getLocation().clone().add(0, -0.4, 0), EntityType.ARMOR_STAND); + hologramArmorStand.setMetadata("crateItemDisplay", new FixedMetadataValue(Core.getInstance(), true)); + hologramArmorStand.setCustomName(Utils.f(reward.getItemMeta().getDisplayName())); + hologramArmorStand.setCustomNameVisible(true); + hologramArmorStand.setGravity(false); + hologramArmorStand.setVisible(false); + new BukkitRunnable() { + + @Override + public void run() { + resetCrateFourth(player); + } + }.runTaskLater(Core.getInstance(), 20 * 7); + player.playSound(player.getLocation(), Sound.ENTITY_BLAZE_HURT, 1, 1); + player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 1); + } + }.runTaskLater(Core.getInstance(), 20); + cancel(); + } + + if (times <= 2) { +// stand.setHelmet(new ItemStack(Material.DIAMOND_SWORD, 1, (short) 17)); + stand.setHelmet(new ItemFactory(Core.getSettings().getType() != ServerType.VICE ? Material.DIAMOND_SWORD : Material.DIAMOND_SWORD, Core.getSettings().getType() != ServerType.VICE ? (short) 17 : (short) 809).setUnbreakable(true).build()); + } else if (times == 3) { + // stand.setHelmet(new ItemStack(Material.DIAMOND_SWORD, 1, (short)18));//TODO: Change back to 18 once it comes in + } + + player.playSound(player.getLocation(), Sound.BLOCK_NOTE_HAT, 1, 1); + times++; + } + }.runTaskTimerAsynchronously(Core.getInstance(), 0, 20); + } + } + + public void resetCrateFourth(final Player player) { + new BukkitRunnable() { + int times = 0; + + @Override + public void run() { + if (times == 3) { + Move.stopOpening(Crate.this.openingCrate, Crate.this.loc); + Crate.this.openingCrate = null; + cancel(); + item.remove(); + gravityArmorStand.remove(); + hologramArmorStand.remove(); + Crate.this.hologram.getVisibilityManager().setVisibleByDefault(true); + Crate.this.hologram.getVisibilityManager().resetVisibilityAll(); +// stand.setHelmet(new ItemStack(Material.DIAMOND_SWORD, 1, Crate.this.rank.getClosedHead())); + stand.setHelmet(new ItemFactory(Core.getSettings().getType() != ServerType.VICE ? Material.DIAMOND_SWORD : Material.DIAMOND_SWORD, (short) Crate.this.rank.getClosedHead()).setUnbreakable(true).build()); + } + if (ThreadLocalRandom.current().nextInt(2) == 1) { + play(player, "SLIME", item.getLocation().clone().add(0, 0.2, 0), 0.2F, 0F, 0.2F, 0.1F, 40); + play(player, "CLOUD", item.getLocation().add(0, -0.2, 0), 0.3F, 0F, 0.3F, 0.1F, 40); + } else { + play(player, "CRIT", item.getLocation().clone().add(0, 0.2, 0), 0.2F, 0F, 0.2F, 0.1F, 40); + play(player, "SMOKE_NORMAL", item.getLocation().add(0, -0.2, 0), 0.3F, 0F, 0.3F, 0.1F, 40); + } + if (ThreadLocalRandom.current().nextInt(2) == 1) { + player.playSound(player.getLocation(), Sound.BLOCK_NOTE_PLING, 1, 1); + player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_ATTACK_SWEEP, 1, 1); + } else { + player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_BOTTLE_THROW, 1, 1); + player.playSound(player.getLocation(), Sound.BLOCK_SLIME_HIT, 1, 1); + } + times++; + } + }.runTaskTimerAsynchronously(Core.getInstance(), 0, 20); + } + + public void startAnimationFifth(final Player player, final Location location, ItemStack reward) { + gravityArmorStand = (ArmorStand) location.getWorld().spawnEntity(location.clone().subtract(0, 1.2, 0), EntityType.ARMOR_STAND); + gravityArmorStand.setGravity(false); + gravityArmorStand.setVisible(false); + play(player, "VILLAGER_HAPPY", location, 0.5F, 0F, 0.5F, 0.1F, 40); + if (selected != null) { + new BukkitRunnable() { + int times = 0; + + @Override + public void run() { + if (finished) { + cancel(); + } + play(player, "CLOUD", location, 0.2F, 0.1F, 0.2F, 0.1F, 2); + } + }.runTaskTimerAsynchronously(Core.getInstance(), 0, 10); +// stand.setHelmet(new ItemStack(Material.DIAMOND_SWORD, 1, (short) 21)); + this.stand.setHelmet(new ItemFactory(Core.getSettings().getType() != ServerType.VICE ? Material.DIAMOND_SWORD : Material.DIAMOND_SWORD, Core.getSettings().getType() != ServerType.VICE ? (short) 21 : (short) 813).setUnbreakable(true).build()); + launchBills(5, 20, location, 1); + launchFireworks(location, 8, 8); + new BukkitRunnable() { + @Override + public void run() { + launchBills(15, 20, location, 2); + new BukkitRunnable() { + @Override + public void run() { + launchBills(25, 20, location, 3); + new BukkitRunnable() { + int times = 0; + @Override + public void run() { + if (times == 5) { + stand.setHelmet(new ItemStack(Material.DIAMOND_SWORD, 1, Crate.this.rank.getOpenHead())); + stand.setHelmet(new ItemFactory(Core.getSettings().getType() != ServerType.VICE ? Material.DIAMOND_SWORD : Material.DIAMOND_SWORD, (short) Crate.this.rank.getOpenHead()).setUnbreakable(true).build()); + cancel(); + finished = true; + item = location.clone().getWorld().dropItem(location.clone().add(0, 0.2, 0), reward); + item.setVelocity(new Vector(0, 0.2, 0)); + item.setTicksLived(8000); + item.setPickupDelay(Integer.MAX_VALUE); + gravityArmorStand.setPassenger(item); + Crate.this.activateReward(); + new BukkitRunnable() { + @Override + public void run() { + hologramArmorStand = (ArmorStand) item.getLocation().getWorld().spawnEntity(item.getLocation().clone().add(0, -1.6, 0), EntityType.ARMOR_STAND); + hologramArmorStand.setMetadata("crateItemDisplay", new FixedMetadataValue(Core.getInstance(), true)); + hologramArmorStand.setCustomName(Utils.f(reward.getItemMeta().getDisplayName())); + hologramArmorStand.setCustomNameVisible(true); + hologramArmorStand.setGravity(false); + hologramArmorStand.setVisible(false); + new BukkitRunnable() { + @Override + public void run() { + resetCrateFifth(player); + } + }.runTaskLater(Core.getInstance(), 20 * 5); + } + }.runTaskLater(Core.getInstance(), 8); + player.playSound(player.getLocation(), Sound.BLOCK_ANVIL_USE, 1, 1); + player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 1); + } else { + launchBills(5, 20, location, 3); + } + if (times <= 2) { +// stand.setHelmet(new ItemStack(Material.DIAMOND_SWORD, 1, (short) 22)); + stand.setHelmet(new ItemFactory(Core.getSettings().getType() != ServerType.VICE ? Material.DIAMOND_SWORD : Material.DIAMOND_SWORD, Core.getSettings().getType() != ServerType.VICE ? (short) 22 : (short) 814).setUnbreakable(true).build()); + + } else if (times <= 4) { +// stand.setHelmet(new ItemStack(Material.DIAMOND_SWORD, 1, (short) 23)); + stand.setHelmet(new ItemFactory(Core.getSettings().getType() != ServerType.VICE ? Material.DIAMOND_SWORD : Material.DIAMOND_SWORD, Core.getSettings().getType() != ServerType.VICE ? (short) 23 : (short) 815).setUnbreakable(true).build()); + } + times++; + } + }.runTaskTimer(Core.getInstance(), 0, 20); + + new BukkitRunnable() { + @Override + public void run() { + play(player, "EXPLOSION_HUGE", location, 0.2F, 0.1F, 0.2F, 0.1F, 1); + launchFireworks(location, 8, 8); + } + }.runTaskLater(Core.getInstance(), 60); + } + }.runTaskLater(Core.getInstance(), 10); + } + }.runTaskLater(Core.getInstance(), 10); + } + } + + public void resetCrateFifth(final Player player) { + new BukkitRunnable() { + int times = 0; + + @Override + public void run() { + if (times == 3) { + cancel(); + Move.stopOpening(Crate.this.openingCrate, Crate.this.loc); + Crate.this.openingCrate = null; + item.remove(); + gravityArmorStand.remove(); + hologramArmorStand.remove(); + Crate.this.hologram.getVisibilityManager().setVisibleByDefault(true); + Crate.this.hologram.getVisibilityManager().resetVisibilityAll(); +// stand.setHelmet(new ItemStack(Material.DIAMOND_SWORD, 1, (short) 20)); + stand.setHelmet(new ItemFactory(Core.getSettings().getType() != ServerType.VICE ? Material.DIAMOND_SWORD : Material.DIAMOND_SWORD, (short) Crate.this.getCrateStars().getClosedHead()).setUnbreakable(true).build()); + } + if (ThreadLocalRandom.current().nextInt(2) == 1) { + play(player, "SLIME", item.getLocation().clone().add(0, 0.2, 0), 0.2F, 0F, 0.2F, 0.1F, 40); + play(player, "CLOUD", item.getLocation().add(0, -0.2, 0), 0.3F, 0F, 0.3F, 0.1F, 40); + } else { + play(player, "CRIT", item.getLocation().clone().add(0, 0.2, 0), 0.2F, 0F, 0.2F, 0.1F, 40); + play(player, "SMOKE_NORMAL", item.getLocation().add(0, -0.2, 0), 0.3F, 0F, 0.3F, 0.1F, 40); + } + if (ThreadLocalRandom.current().nextInt(2) == 1) { + player.playSound(player.getLocation(), Sound.BLOCK_NOTE_PLING, 1, 1); + player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_ATTACK_SWEEP, 1, 1); + } else { + player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_BOTTLE_THROW, 1, 1); + player.playSound(player.getLocation(), Sound.BLOCK_SLIME_HIT, 1, 1); + } + times++; + } + }.runTaskTimerAsynchronously(Core.getInstance(), 0, 20); + } + + public void startAnimationSixth(final Player player, final Location location, ItemStack reward) { + gravityArmorStand = (ArmorStand) location.getWorld().spawnEntity(location.clone().subtract(0, 0.8, 0), EntityType.ARMOR_STAND); + gravityArmorStand.setGravity(false); + gravityArmorStand.setVisible(false); + play(player, "VILLAGER_HAPPY", location, 0.5F, 0F, 0.5F, 0.1F, 40); + new BukkitRunnable() { + int times = 0; + + @Override + public void run() { + if (times == 4) { + cancel(); + new BukkitRunnable() { + @Override + public void run() { + play(player, "EXPLOSION_NORMAL", location, 0.2F, 0F, 0.2F, 0.1F, 70); +// stand.setHelmet(new ItemStack(Material.DIAMOND_SWORD, 1, Crate.this.rank.getOpenHead())); + stand.setHelmet(new ItemFactory(Core.getSettings().getType() != ServerType.VICE ? Material.DIAMOND_SWORD : Material.DIAMOND_SWORD, (short) Crate.this.rank.getOpenHead()).setUnbreakable(true).build()); + item = location.clone().getWorld().dropItem(location.clone().add(0, 0.2, 0), reward); + item.setVelocity(new Vector(0, 0, 0)); + item.setTicksLived(8000); + item.setPickupDelay(Integer.MAX_VALUE); + gravityArmorStand.setPassenger(item); + Crate.this.activateReward(); + new BukkitRunnable() { + @Override + public void run() { + hologramArmorStand = (ArmorStand) item.getLocation().getWorld().spawnEntity(item.getLocation().clone().add(0, -1.3, 0), EntityType.ARMOR_STAND); + hologramArmorStand.setMetadata("crateItemDisplay", new FixedMetadataValue(Core.getInstance(), true)); + hologramArmorStand.setCustomName(Utils.f(reward.getItemMeta().getDisplayName())); + hologramArmorStand.setCustomNameVisible(true); + hologramArmorStand.setGravity(false); + hologramArmorStand.setVisible(false); + new BukkitRunnable() { + @Override + public void run() { + resetCrateThird(player); + } + }.runTaskLater(Core.getInstance(), 20 * 7); + } + }.runTaskLater(Core.getInstance(), 8); + player.playSound(player.getLocation(), Sound.BLOCK_ANVIL_USE, 1, 1); + player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 1); + } + }.runTask(Core.getInstance()); + } + + play(player, "CLOUD", location, 0.2F, 0.1F, 0.2F, 0.1F, 2); + play(player, "SMOKE_NORMAL", location, 0.2F, 0.1F, 0.2F, 0.1F, 20); + if (ThreadLocalRandom.current().nextInt(2) == 1) { + player.playSound(player.getLocation(), Sound.BLOCK_GRASS_BREAK, 1, 1); + player.playSound(player.getLocation(), Sound.BLOCK_ANVIL_BREAK, 1, 1); + } else { + player.playSound(player.getLocation(), Sound.ENTITY_BLAZE_BURN, 1, 1); + player.playSound(player.getLocation(), Sound.ENTITY_BLAZE_HURT, 1, 1); + } + times++; + } + }.runTaskTimerAsynchronously(Core.getInstance(), 0, 10); + } + + public void resetCrateSixth(final Player player) { + new BukkitRunnable() { + int times = 0; + + @Override + public void run() { + if (times == 3) { + Move.stopOpening(Crate.this.openingCrate, Crate.this.loc); + Crate.this.openingCrate = null; + cancel(); + item.remove(); + Crate.this.hologram.getVisibilityManager().setVisibleByDefault(true); + Crate.this.hologram.getVisibilityManager().resetVisibilityAll(); + gravityArmorStand.remove(); + hologramArmorStand.remove(); +// stand.setHelmet(new ItemStack(Material.DIAMOND_SWORD, 1, (short) 14)); + stand.setHelmet(new ItemFactory(Core.getSettings().getType() != ServerType.VICE ? Material.DIAMOND_SWORD : Material.DIAMOND_SWORD, (short) Crate.this.getCrateStars().getClosedHead()).setUnbreakable(true).build()); + } + + if (ThreadLocalRandom.current().nextInt(2) == 1) { + play(player, "SLIME", item.getLocation().clone().add(0, 0.2, 0), 0.2F, 0F, 0.2F, 0.1F, 40); + play(player, "CLOUD", item.getLocation().add(0, -0.2, 0), 0.3F, 0F, 0.3F, 0.1F, 40); + } else { + play(player, "CRIT", item.getLocation().clone().add(0, 0.2, 0), 0.2F, 0F, 0.2F, 0.1F, 40); + play(player, "SMOKE_NORMAL", item.getLocation().add(0, -0.2, 0), 0.3F, 0F, 0.3F, 0.1F, 40); + } + + if (ThreadLocalRandom.current().nextInt(2) == 1) { + player.playSound(player.getLocation(), Sound.BLOCK_NOTE_PLING, 1, 1); + player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_ATTACK_SWEEP, 1, 1); + } else { + player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_BOTTLE_THROW, 1, 1); + player.playSound(player.getLocation(), Sound.BLOCK_SLIME_HIT, 1, 1); + } + + times++; + } + }.runTaskTimerAsynchronously(Core.getInstance(), 0, 20); + } + + public void launchBills(int bills, final long despawnTime, Location location, final int maxLaunchRange) { + final Location launch = location.clone().add(0, 0.1, 0); + final ItemStack paper = new ItemStack(Material.PAPER); + for (int i = 0; i < bills; i++) { + new BukkitRunnable() { + + @Override + public void run() { + final Item item = launch.getWorld().dropItemNaturally(launch.clone(), paper); + item.setPickupDelay(Integer.MAX_VALUE); + item.getVelocity().multiply(maxLaunchRange).setY(0.6); + launch.getWorld().playSound(launch.clone(), Sound.ENTITY_EGG_THROW, 1, 1); + new BukkitRunnable() { + + @Override + public void run() { + item.remove(); + } + }.runTaskLater(Core.getInstance(), despawnTime); + } + + }.runTaskLater(Core.getInstance(), 10 * i); + } + } + + public void launchFireworks(Location center, int radius, int pointAmounts) { + List<Location> pointsToLaunch = getCircle(center, radius, pointAmounts); + for (Location launch : pointsToLaunch) { + Firework fw = (Firework) center.getWorld().spawnEntity(launch, EntityType.FIREWORK); + FireworkMeta fwm = fw.getFireworkMeta(); + int shape = ThreadLocalRandom.current().nextInt(4) + 1; + FireworkEffect.Type type = FireworkEffect.Type.BALL; + if (shape == 1) type = FireworkEffect.Type.BALL; + if (shape == 2) type = FireworkEffect.Type.BALL_LARGE; + if (shape == 3) type = FireworkEffect.Type.BURST; + if (shape == 4) type = FireworkEffect.Type.CREEPER; + if (shape == 5) type = FireworkEffect.Type.STAR; + Color color = (ThreadLocalRandom.current().nextInt(2) == 1) ? Color.RED : Color.ORANGE; + FireworkEffect effect = FireworkEffect.builder().flicker(ThreadLocalRandom.current().nextBoolean()).withColor(color).withFade(Color.AQUA).with(type).trail(ThreadLocalRandom.current().nextBoolean()).build(); + fwm.addEffect(effect); + fwm.setPower(1); + fw.setFireworkMeta(fwm); + } + } + + public void startAnimation(final Player player, final Location location, final Callback<Location> callback) { + if (selected != null) { + new BukkitRunnable() { + int times = 0; + + @Override + public void run() { + if (times == 4) { + cancel(); + new BukkitRunnable() { + + @Override + public void run() { + callback.execute(location); + } + }.runTask(Core.getInstance()); + } + play(player, "SMOKE_NORMAL", location, 0.2F, 0.1F, 0.2F, 0.1F, 70); + if (ThreadLocalRandom.current().nextInt(2) == 1) { + player.playSound(player.getLocation(), Sound.ENTITY_CREEPER_HURT, 1, 1); + player.playSound(player.getLocation(), Sound.BLOCK_ANVIL_BREAK, 1, 1); + } else { + player.playSound(player.getLocation(), Sound.ENTITY_BLAZE_BURN, 1, 1); + player.playSound(player.getLocation(), Sound.BLOCK_ANVIL_BREAK, 1, 1); + } + times++; + } + }.runTaskTimerAsynchronously(Core.getInstance(), 0, 10); + } + } + + public ArrayList<Location> getCircle(Location center, double radius, int amount) { + World world = center.getWorld(); + double increment = (2 * Math.PI) / amount; + ArrayList<Location> locations = new ArrayList<Location>(); + for (int i = 0; i < amount; i++) { + double angle = i * increment; + double x = center.getX() + (radius * Math.cos(angle)); + double z = center.getZ() + (radius * Math.sin(angle)); + locations.add(new Location(world, x, center.getY(), z)); + } + return locations; + } + + public void play(Player p, String effect, Location loc, float xOffset, float yOffset, float zOffset, float speed, int amount) { + p.getWorld().spawnParticle(Particle.valueOf(effect), loc, amount, xOffset, yOffset, zOffset, speed); + } + + public interface Callback<T> { + void execute(T response); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/crates/CrateManager.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/crates/CrateManager.java new file mode 100644 index 0000000..4c657bd --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/crates/CrateManager.java @@ -0,0 +1,273 @@ +package net.grandtheftmc.core.voting.crates; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Item; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.Component; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.util.WeightedRandomCollection; +import net.grandtheftmc.core.voting.RewardPack; +import net.grandtheftmc.core.voting.crates.events.CrateNearbyPlayerEvent; + + +/** + * Created by Liam on 25/04/2017. + */ +public class CrateManager implements Component<CrateManager, Core> { + + private final Set<Crate> crates = new HashSet<>(); + private final Map<CrateStars, List<CrateReward>> rewards = new HashMap<>(); + private final Map<CrateStars, Double> totalWeights = new HashMap<>(); + + private int taskId = -1; + + // TODO crate locations, etc etc + + // public CrateManager() { + // this.load(); + // } + + public void load() { + this.loadRewards(); + this.loadCrates(); + this.startSchedule(); + } + + /** + * This will run when the plugin (T) is enabled. + * + * @param plugin The JavaPlugin + */ + @Override + public CrateManager onEnable(Core plugin) { + World world = Bukkit.getWorld("spawn"); + if (world == null) return this; + Core.log("Removing ArmorStand Crate Entities"); + + world.getEntitiesByClass(ArmorStand.class).stream().filter(ent -> ent.getHelmet() != null && ent.getHelmet().getType() == Material.FLINT_AND_STEEL && ent.hasMetadata("CRATE")).forEach(entity -> { + entity.getNearbyEntities(2, 2, 2).stream().filter(nearby -> nearby instanceof ArmorStand).forEach(Entity::remove); + entity.remove(); + }); + + load(); + return this; + } + + /** + * This will run when the plugin (T) is disabling. + * + * @param plugin The JavaPlugin + */ + @Override + public CrateManager onDisable(Core plugin) { + World world = Bukkit.getWorld("spawn"); + if (world == null) return this; + + Core.log("Removing ArmorStand Crate Entities."); + if (!this.crates.isEmpty()) { + this.crates.forEach(crate -> { + + if (crate.isBeingOpened()) { + + switch (crate.getCrateStars().getStars()){ + case 1: + crate.getLocation().getWorld().getNearbyEntities(crate.getLocation(), 1, 3, 1).stream().filter(ent -> ent instanceof Item).forEach(item -> crate.resetAnimationFirst((Item) item)); + break; + case 2: + crate.getLocation().getWorld().getNearbyEntities(crate.getLocation(), 1, 3, 1).stream().filter(ent -> ent instanceof Item).forEach(item -> crate.resetAnimationSecond((Item) item)); + break; + case 3: + Bukkit.getOnlinePlayers().forEach(crate::resetCrateThird); + break; + case 4: + Bukkit.getOnlinePlayers().forEach(crate::resetCrateFourth); + break; + case 5: + Bukkit.getOnlinePlayers().forEach(crate::resetCrateFifth); + break; + case 6: + Bukkit.getOnlinePlayers().forEach(crate::resetCrateThird); + break; + } + } + + crate.destroy(); + }); + + this.crates.clear(); + } + + if (!this.rewards.isEmpty()) this.rewards.clear(); + if (!this.totalWeights.isEmpty()) this.totalWeights.clear(); + return this; + } + + public void loadCrates() { + Core.log("Loading crates..."); + YamlConfiguration c = Core.getSettings().getCratesConfig(); + for (Crate crate : this.crates) crate.destroy(); + this.crates.clear(); + + for (String s : c.getKeys(false)) { + try { + Location loc = Utils.teleportLocationFromString(c.getString(s + ".loc")); + for(Entity en : loc.getWorld().getEntities()) { + if(en instanceof ArmorStand && en.getLocation().distance(loc) < 2) + en.remove(); + } + + int stars = c.getInt(s + ".stars"); + this.crates.add(new Crate(loc, stars)); + } catch (Exception e) { + Core.error("There was an error while loading Crate with id " + s); + e.printStackTrace(); + } + } + Core.log("Finished loading crates!"); + } + + public void loadRewards() { + YamlConfiguration c = Core.getSettings().getCrateRewardsConfig(); + this.rewards.clear(); + for (String s : c.getKeys(false)) { + CrateStars stars; + double totalWeight = 0; + try { + stars = CrateStars.getCrateStars(Integer.parseInt(s)); + } catch (NumberFormatException e) { + Core.error("There was an error while loading Crate Rewards for crate with " + s + " star(s)"); + e.printStackTrace(); + continue; + } + List<CrateReward> packs = new ArrayList<>(); + for (String name : c.getConfigurationSection(s).getKeys(false)) { + try { + String item = c.getString(s + '.' + name + ".item"); + double weight = c.get(s + '.' + name + ".weight") == null ? 1 : c.getDouble(s + '.' + name + ".weight"); + boolean announce = c.get(s + '.' + name + ".announce") != null && c.getBoolean(s + '.' + name + ".announce"); + RewardPack pack = Core.getVoteManager().getRewardPack(c, name, s + '.' + name); + if (pack == null) Core.error("Error while loading RewardPack for crate reward: " + name); + else { + packs.add(new CrateReward(pack, item, weight, announce)); + totalWeight += weight; + } + } catch (Exception e) { + Core.error("There was an error while loading Crate Reward " + name + " for crate with " + s + " star(s)"); + e.printStackTrace(); + } + } + this.totalWeights.put(stars, totalWeight); + this.rewards.put(stars, packs); + } + } + + public void save(boolean shutdown) { + YamlConfiguration c = Core.getSettings().getCratesConfig(); + for (String s : c.getKeys(false)) c.set(s, null); + int i = 0; + for (Crate crate : this.crates) { + c.set(i + ".loc", Utils.teleportLocationToString(crate.getLocation())); + c.set(i + ".stars", crate.getCrateStars().getStars()); + i++; + } + Utils.saveConfig(c, "crates"); + + if (shutdown) { + crates.forEach(Crate::destroy); + } + } + + public CrateReward determineCrateReward(Player player, User user, CrateStars rank) { + WeightedRandomCollection<CrateReward> rewards = new WeightedRandomCollection<>(); + this.getRewards(rank).stream().filter(r -> !r.getRewardPack().hasAllRewards(player, user)).collect(Collectors.toList()).forEach(r -> rewards.add(r.getWeight(), r)); + + return rewards.next(); + } + + public Optional<Crate> getCrate(LivingEntity entity) { + return entity == null ? null : this.crates.stream().filter(crate -> Objects.equals(crate.getLocation(), entity.getLocation())).findFirst(); + } + + public void addCrate(Crate crate) { + this.crates.add(crate); + } + + public boolean removeCrate(Crate crate) { + if (this.crates.contains(crate)) { + crate.destroy(); + this.crates.remove(crate); + return true; + } + return false; + } + + public void startSchedule() { + if (this.taskId != -1) { + Bukkit.getScheduler().cancelTask(this.taskId); + } + + this.taskId = new BukkitRunnable() { + @Override + public void run() { + + getCrates().forEach(create -> { + + for (Entity nearby : create.getStand().getNearbyEntities(0.4, 1, 0.4)) { + + if (nearby instanceof Player) { + Player nearbyPlayer = (Player) nearby; + + CrateNearbyPlayerEvent event = new CrateNearbyPlayerEvent(nearbyPlayer, create); + + if (event.isCancelled()) { + return; + } + + Bukkit.getPluginManager().callEvent(event); + } + } + }); + } + }.runTaskTimerAsynchronously(Core.getInstance(), 0L, 5).getTaskId(); + } + + /** + * @return the next id of the list of crates( used to remove a crate) + */ + public int getNextAvaliableCrateID() { + return this.crates.size(); + } + + public List<CrateReward> getRewards(CrateStars rank) { + return this.rewards.containsKey(rank) ? this.rewards.get(rank) : new ArrayList<>(); + } + + public Set<Crate> getCrates() { + return this.crates; + } + + public double getTotalWeight(CrateStars stars) { + return this.totalWeights.get(stars); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/crates/CrateReward.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/crates/CrateReward.java new file mode 100644 index 0000000..a77a0a7 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/crates/CrateReward.java @@ -0,0 +1,55 @@ +package net.grandtheftmc.core.voting.crates; + +import com.j0ach1mmall3.jlib.methods.Parsing; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.voting.RewardPack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; + +/** + * Created by Liam on 25/04/2017. + */ +public class CrateReward { + + private final ItemStack item; + private final RewardPack pack; + private final double weight; + private final boolean announce; + + public CrateReward(RewardPack pack, String item, double weight, boolean announce) { + this.pack = pack; + this.item = item == null ? null : Utils.addItemFlags(Parsing.parseItemStack(item), ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ATTRIBUTES); + this.weight = weight; + this.announce = announce; + } + + public String getName() { + return this.pack.getName(); + } + + public ItemStack getItem() { + return this.item == null ? this.pack.get().get(0).getDisplayItem() : this.item; + } + + public String getDisplayName() { + return this.pack.getDisplayName(); + } + + public RewardPack getRewardPack() { + return this.pack; + } + + public double getWeight() { + return this.weight; + } + + public void give(Player player, User user, CrateStars rank) { + if (this.announce) + Utils.broadcastExcept(player, Lang.CRATES.f(user.getColoredName(player) + "&7 won a rare reward while opening a " + rank.getDisplayName() + "&7: " + this.pack.getDisplayName() + "&7!")); + this.pack.give(player, user, this.announce ? null : "crateReward", rank.getCrowbars(), true); + + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/crates/CrateStars.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/crates/CrateStars.java new file mode 100644 index 0000000..9c3717b --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/crates/CrateStars.java @@ -0,0 +1,80 @@ +package net.grandtheftmc.core.voting.crates; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.servers.ServerType; +import net.grandtheftmc.core.util.Utils; + +/** + * Created by Liam on 24/04/2017. + */ +public enum CrateStars { + + + ONE(1, 1, "&6"), + TWO(2, 5, "&a"), + THREE(3, 50, "&b"), + FOUR(4, 250, "&5"), + FIVE(5, 1000, "&c"), + SIX(6, 45, null); + + private final int stars; + private final int crowbars; + private final String color; + + + CrateStars(int stars, int crowbars, String color) { + this.stars = stars; + this.crowbars = crowbars; + this.color = color; + } + + public int getStars() { + return this.stars; + } + + public int getCrowbars() { + return this.crowbars; + } + + public String getColor() { + return this.color; + } + + public String getDisplayName() { + return this.stars == 6 ? Utils.f("&c&lSkin Crate") : Utils.f( this.color + "&l" + this.stars + " Star " + (this.stars == 5 ? "Briefcase" : this.stars >= 3 ? "Vault" : "Crate")); + } + + public String getStarsString() { + return new String[]{"✩✩✩✩✩", "✮✩✩✩✩", "✮✮✩✩✩", "✮✮✮✩✩", "✮✮✮✮✩", "✮✮✮✮✮", ""}[this.stars]; + } + + public short getOpenHead() { + return Core.getSettings().getType() != ServerType.VICE ? new short[]{0, 803, 805, 807, 811, 816, 824}[this.stars] : new short[]{0, 803, 805, 807, 811, 816, 824}[this.stars]; + } + + public double getHeight(){ + return new double[]{0, 2, 2, 2.5, 3.75, 1.5, 2}[this.stars]; + } + + public short getClosedHead() { + return Core.getSettings().getType() != ServerType.VICE ? new short[]{0, 802, 804, 806, 808, 812, 823}[this.stars] : new short[]{0, 802, 804, 806, 808, 812, 823}[this.stars]; + } + + public static CrateStars getCrateStars(int stars) { + return CrateStars.values()[stars - 1]; + } + + public String getType(){ + switch (this.stars){ + case 1: + case 2: + return "Crate"; + case 3: + case 4: + return "Vault"; + case 5: + return "Briefcase"; + } + return "Crate"; + } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/crates/events/CrateNearbyPlayerEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/crates/events/CrateNearbyPlayerEvent.java new file mode 100644 index 0000000..8857f67 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/crates/events/CrateNearbyPlayerEvent.java @@ -0,0 +1,55 @@ +package net.grandtheftmc.core.voting.crates.events; + +import net.grandtheftmc.core.voting.crates.Crate; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * Created by ThatAbstractWolf on 2017-08-08. + */ +public class CrateNearbyPlayerEvent extends Event implements Cancellable { + + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private boolean cancelled; + + private final Player player; + private final Crate crate; + + public CrateNearbyPlayerEvent(Player player, Crate crate) { + + this.player = player; + this.crate = crate; + + this.cancelled = false; + } + + public Player getPlayer() { + return player; + } + + public Crate getCrate() { + return crate; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/crates/events/CrateOpenEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/crates/events/CrateOpenEvent.java new file mode 100644 index 0000000..8fd78c6 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/crates/events/CrateOpenEvent.java @@ -0,0 +1,35 @@ +package net.grandtheftmc.core.voting.crates.events; + +import net.grandtheftmc.core.voting.Reward; +import net.grandtheftmc.core.voting.crates.Crate; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; + +/** + * Created by Timothy Lampen on 2017-04-28. + */ +public class CrateOpenEvent extends PlayerEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final Crate crate; + + public CrateOpenEvent(Player player, Crate crate) { + super(player); + this.crate = crate; + } + + public Crate getCrate() { + return crate; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/crates/listeners/CrateNearbyListener.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/crates/listeners/CrateNearbyListener.java new file mode 100644 index 0000000..2c75e98 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/crates/listeners/CrateNearbyListener.java @@ -0,0 +1,28 @@ +package net.grandtheftmc.core.voting.crates.listeners; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +import net.grandtheftmc.core.voting.crates.events.CrateNearbyPlayerEvent; +import org.bukkit.util.Vector; + +/** + * Created by ThatAbstractWolf on 2017-08-08. + */ +public class CrateNearbyListener implements Listener { + + @EventHandler + public void playerNearCrate(CrateNearbyPlayerEvent event) { + + Player player = event.getPlayer(); + + if (event.getCrate() != null && event.getCrate().isBeingOpened() && event.getCrate().getOpeningCrateUUID().equals(player.getUniqueId())) return; + + Vector velocity = player.getLocation().getDirection(); + + velocity.setY(0.2); + + player.setVelocity(velocity.multiply(-0.3)); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/crates/listeners/CrateOpenListener.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/crates/listeners/CrateOpenListener.java new file mode 100644 index 0000000..6e6fb63 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/crates/listeners/CrateOpenListener.java @@ -0,0 +1,168 @@ +package net.grandtheftmc.core.voting.crates.listeners; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.voting.crates.Crate; +import net.grandtheftmc.core.voting.crates.CrateReward; +import net.grandtheftmc.core.voting.crates.CrateStars; +import net.grandtheftmc.core.voting.crates.events.CrateOpenEvent; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerInteractAtEntityEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.List; + +public class CrateOpenListener implements Listener { + + @EventHandler + public void onCrateOpen(CrateOpenEvent event) { + Crate crate = event.getCrate(); + CrateStars stars = crate.getCrateStars(); + Player player = event.getPlayer(); + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (crate.isBeingOpened()) { + player.sendMessage(Lang.CRATES.f("&7This crate is already being opened!")); + return; + } + if (user.getCrowbars() == -1) { + user.setCrowbars(5); + player.sendMessage(Lang.CRATES.f("&7You are using crates for the first time! You have been given &9&l5 Crowbars&7 as a welcome gift. Use them to buy five &6&l1 Star Crates&7 or one &a&l2 Star Crate&7! You can earn more crowbars by &e&lvoting&7!")); + return; + } + player.openInventory(generateCratePreview(user, stars)); + Core.getUserManager().getLoadedUser(player.getUniqueId()).setSelectedCrate(crate); + } + + @EventHandler + public void onInteract(InventoryClickEvent event) { + Player player = (Player) event.getWhoClicked(); + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + ItemStack item = event.getCurrentItem(); + Inventory inv = event.getClickedInventory(); + Crate crate = user.getSelectedCrate(); + if (inv == null || !ChatColor.stripColor(inv.getTitle()).contains(" Rewards")) { + return; + } + + event.setCancelled(true); + + if (crate == null) { + user.setSelectedCrate(null); + player.closeInventory(); + player.sendMessage(Lang.CRATES.f("&7Unable to find selected crate while in crate menu. Crate==" + crate + ". Report this error to an admin immediately.")); + return; + } + + if (crate.isBeingOpened()) { + user.setSelectedCrate(null); + player.closeInventory(); + player.sendMessage(Lang.CRATES.f("&7This " + crate.getCrateStars().getType().toLowerCase() + " is already being opened!")); + return; + } + + if (item.getType() != Material.FLINT_AND_STEEL) return; + + if (!user.hasCrowbars(crate.getCrateStars().getCrowbars())) { + user.setSelectedCrate(null); + player.closeInventory(); + player.sendMessage(Lang.CRATES.f("&7You do not have enough crowbars to open this " + crate.getCrateStars().getType().toLowerCase() + "! You need &9&l" + crate.getCrateStars().getCrowbars() + " Crowbar" + (crate.getCrateStars().getCrowbars() == 1 ? "" : "s") + "&7!")); + return; + } + + if (crate.getCrateStars().getStars() >= 4) { + MenuManager.openMenu(player, "confirmexpensivecrate"); + return; + } + + player.closeInventory(); + user.takeCrowbars(crate.getCrateStars().getCrowbars()); + crate.startAnimation(player, user); + } + + @EventHandler + protected final void onEntityInteract(PlayerInteractAtEntityEvent event) { + if (event.getRightClicked() == null) return; + if (event.getRightClicked().getType() != EntityType.ARMOR_STAND) return; + if (!event.getRightClicked().hasMetadata("CRATE")) return; + + Core.getCrateManager().getCrate((LivingEntity) event.getRightClicked()).ifPresent(crate -> { + CrateOpenEvent openEvent = new CrateOpenEvent(event.getPlayer(), crate); + Bukkit.getPluginManager().callEvent(openEvent); + }); + } + + private static int getDisplayCaseSize(CrateStars rank) {//TODO: use actual math to figure this out. + int items = rank == null ? 63:Core.getCrateManager().getRewards(rank).size(); + if (items <= 7) + return 27; + if (items <= 14) + return 36; + if (items <= 21) + return 45; + if (items <= 28) + return 54; + return 63; + } + + public static Inventory generateCratePreview(User user, CrateStars crateStars){ + List<CrateReward> rewards = Core.getCrateManager().getRewards(crateStars); + int totalRows = getDisplayCaseSize(crateStars) / 9; + int currentRewardIndex = 0; + Inventory inv = Bukkit.createInventory(null, totalRows * 9, Utils.f("&e&l" + crateStars.getType() + " Rewards")); + DecimalFormat df = new DecimalFormat("#.##"); + for (int row = 0; row < totalRows; row++) { + for (int slot = 0; slot < 9; slot++) { + if (row == totalRows - 1 && slot == 4) { + ItemStack is = Utils.addItemFlags(Utils.createItem(Material.FLINT_AND_STEEL, 45, + Utils.f("&9&lCosts " + crateStars.getCrowbars() + " Crowbar" + (crateStars.getCrowbars()==1 ? "" : "s")), user.getCrowbars() > 64 ? 64 : user.getCrowbars() + , "&7You have &a&l" + user.getCrowbars() + " &7Crowbar" + (crateStars.getCrowbars() == 1 ? "" : "s"), "", + "&7Click to open the " + crateStars.getDisplayName() + "&7!")); + ItemMeta im = is.getItemMeta(); + im.addItemFlags(ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ATTRIBUTES); + is.setItemMeta(im); + inv.setItem(row * 9 + 4, is); + } else if (row == 0 || row == totalRows - 1 || slot == 0 || slot == 8) { + inv.setItem(row * 9 + slot, Utils.createItem(Material.STAINED_GLASS_PANE, 7, " ")); + } else if (currentRewardIndex < rewards.size()) { + CrateReward reward = rewards.get(currentRewardIndex); + ItemStack is = rewards.get(currentRewardIndex).getItem().clone(); + ItemMeta im = is.getItemMeta(); + im.setDisplayName(Utils.f(reward.getDisplayName())); + List<String> lore = new ArrayList<>(); + lore.add(Utils.f("&7Chance: &a&l" + df.format(reward.getWeight() / Core.getCrateManager().getTotalWeight(crateStars) * 100) + "&a%")); + if (reward.getRewardPack().get().size() > 1) { + lore.add(""); + lore.add(Utils.f("&7Contains:")); + reward.getRewardPack().get().forEach(item -> lore.add(Utils.f(item.getDisplayName()))); + } + if (reward.getRewardPack().getDescription() != null && !reward.getRewardPack().getDescription().isEmpty()) { + lore.add(""); + lore.add(Utils.f("&7" + reward.getRewardPack().getDescription())); + } + im.setLore(lore); + is.setItemMeta(im); + inv.setItem(row * 9 + slot, is); + currentRewardIndex += 1; + } + } + } + return inv; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/events/PlayerVoteEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/events/PlayerVoteEvent.java new file mode 100644 index 0000000..9300032 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/events/PlayerVoteEvent.java @@ -0,0 +1,59 @@ +package net.grandtheftmc.core.voting.events; + +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import java.util.UUID; + +public class PlayerVoteEvent extends Event implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + + private final UUID uuid; + private final String timestamp; + private final String address; + private final String serviceName; + private boolean cancelled; + + public PlayerVoteEvent(UUID uuid, String timestamp, String address, String serviceName) { + this.uuid = uuid; + this.timestamp = timestamp; + this.address = address; + this.serviceName = serviceName; + } + + public UUID getUUID() { + return uuid; + } + + public String getTimestamp() { + return timestamp; + } + + public String getAddress() { + return address; + } + + public String getServiceName() { + return serviceName; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/events/RewardCheckEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/events/RewardCheckEvent.java new file mode 100644 index 0000000..9604994 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/events/RewardCheckEvent.java @@ -0,0 +1,51 @@ +package net.grandtheftmc.core.voting.events; + +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +import net.grandtheftmc.core.voting.Reward; + +public class RewardCheckEvent extends RewardEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final Player player; + private final String identifier; + private boolean result; + + public RewardCheckEvent(Player player, Reward.RewardType rewardType, String identifier) { + super(rewardType); + this.player = player; + this.identifier = identifier; + } + + public RewardCheckEvent(Player player, Reward reward, Reward.RewardType rewardType, String identifier) { + super(reward, rewardType); + this.player = player; + this.identifier = identifier; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } + + public Player getPlayer() { + return this.player; + } + + public String getIdentifier() { + return identifier; + } + + public boolean getResult() { + return result; + } + + public void setResult(boolean result) { + this.result = result; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/events/RewardEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/events/RewardEvent.java new file mode 100644 index 0000000..baf861c --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/events/RewardEvent.java @@ -0,0 +1,42 @@ +package net.grandtheftmc.core.voting.events; + +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; + +import net.grandtheftmc.core.voting.Reward; +import net.grandtheftmc.core.voting.Reward.RewardType; + +public abstract class RewardEvent extends Event implements Cancellable { + + /** The reward involve in this event */ + private Reward reward; + private Reward.RewardType rewardType; + private boolean cancelled; + + protected RewardEvent(Reward reward, RewardType rewardType) { + this.reward = reward; + this.rewardType = rewardType; + } + + protected RewardEvent(Reward.RewardType rewardType) { + this.rewardType = rewardType; + } + + public Reward getReward() { + return reward; + } + + public Reward.RewardType getRewardType() { + return rewardType; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/events/RewardGiveEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/events/RewardGiveEvent.java new file mode 100644 index 0000000..9762187 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/events/RewardGiveEvent.java @@ -0,0 +1,42 @@ +package net.grandtheftmc.core.voting.events; + +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +import net.grandtheftmc.core.voting.Reward; + +public final class RewardGiveEvent extends RewardEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final Player player; + private final String identifier; + + public RewardGiveEvent(Player player, Reward.RewardType rewardType, String identifier) { + super(rewardType); + this.player = player; + this.identifier = identifier; + } + + public RewardGiveEvent(Player player, Reward reward, Reward.RewardType rewardType, String identifier) { + super(reward, rewardType); + this.player = player; + this.identifier = identifier; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } + + public Player getPlayer() { + return this.player; + } + + public String getIdentifier() { + return identifier; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/events/RewardInfoEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/events/RewardInfoEvent.java new file mode 100644 index 0000000..b72a7ab --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/voting/events/RewardInfoEvent.java @@ -0,0 +1,46 @@ +package net.grandtheftmc.core.voting.events; + +import org.bukkit.Material; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.ItemStack; + +import net.grandtheftmc.core.voting.Reward; + +public class RewardInfoEvent extends RewardEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + private final String identifier; + private ItemStack displayItem; + + public RewardInfoEvent(Reward.RewardType rewardType, String identifier) { + super(rewardType); + this.displayItem = new ItemStack(Material.BARRIER); + this.identifier = identifier; + } + + public RewardInfoEvent(Reward reward, Reward.RewardType rewardType, String identifier) { + super(reward, rewardType); + this.displayItem = new ItemStack(Material.BARRIER); + this.identifier = identifier; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } + + public ItemStack getDisplayItem() { + return displayItem; + } + + public void setDisplayItem(ItemStack displayItem) { + this.displayItem = displayItem; + } + + public String getIdentifier() { + return identifier; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } +} \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/whitelist/WhitelistManager.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/whitelist/WhitelistManager.java new file mode 100644 index 0000000..f214692 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/whitelist/WhitelistManager.java @@ -0,0 +1,122 @@ +package net.grandtheftmc.core.whitelist; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.Component; +import org.bukkit.Bukkit; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.scheduler.BukkitScheduler; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import java.util.stream.Collectors; + +public class WhitelistManager implements Component<WhitelistManager, Core> { + + private final List<WhitelistedUser> whitelistedUsers = new ArrayList<>(); + private boolean enabled; + private UserRank bypassRank; + + public WhitelistManager() { + this.load(); + this.startSchedule(); + } + + @Override + public WhitelistManager onDisable(Core plugin) { + if(!this.whitelistedUsers.isEmpty()) + this.whitelistedUsers.clear(); + return this; + } + + public void whitelist(String name) { + if (this.isWhitelisted(name)) + return; + WhitelistedUser wu = new WhitelistedUser(null, name); + this.whitelistedUsers.add(wu); + } + + public void unwhitelist(String name) { + WhitelistedUser wu = this.getWhitelistedUser(name); + if (wu != null) + this.whitelistedUsers.remove(wu); + + } + + private boolean isWhitelisted(String name) { + return this.getWhitelistedUser(name) != null; + } + + public void updateUUID(String name, UUID uuid) { + WhitelistedUser wu = this.getWhitelistedUser(name); + wu.setUuid(uuid); + } + + public boolean isEnabled() { + return this.enabled; + } + + public void setEnabled(boolean en) { + this.enabled = en; + } + + public List<WhitelistedUser> getWhitelistedUsers() { + return this.whitelistedUsers; + } + + public WhitelistedUser getWhitelistedUser(String name) { + return this.whitelistedUsers.stream().filter(wu -> wu.getName().equalsIgnoreCase(name)).findFirst().orElse(null); + } + + public WhitelistedUser getWhitelistedUser(UUID uuid) { + return this.whitelistedUsers.stream().filter(wu -> Objects.equals(uuid, wu.getUuid())).findFirst().orElse(null); + } + + public void save(boolean shutdown) { + YamlConfiguration c = Core.getSettings().getWhitelistConfig(); + for (String key : c.getKeys(false)) + c.set(key, null); + List<String> whitelistedNames = new ArrayList<>(); + c.set("enabled", this.enabled); + c.set("bypassRank", this.bypassRank == null ? null : this.bypassRank.getName()); + for (WhitelistedUser wu : this.whitelistedUsers) { + if (wu.getUuid() == null) { + whitelistedNames.add(wu.getName()); + continue; + } + c.set("whitelist." + wu.getUuid(), wu.getName()); + } + c.set("whitelistedNames", whitelistedNames); + Utils.saveConfig(c, "whitelist"); + + } + + public void load() { + YamlConfiguration c = Core.getSettings().getWhitelistConfig(); + if (c.get("enabled") != null) + this.enabled = c.getBoolean("enabled"); + if (c.get("bypassRank") != null) this.bypassRank = UserRank.getUserRankOrNull(c.getString("bypassRank")); + if (c.get("whitelistedNames") != null) + this.whitelistedUsers.addAll(c.getStringList("whitelistedNames").stream().map(s -> new WhitelistedUser(null, s)).collect(Collectors.toList())); + if (c.get("whitelist") != null) + this.whitelistedUsers.addAll(c.getConfigurationSection("whitelist").getKeys(false).stream().map(uuidString -> new WhitelistedUser(UUID.fromString(uuidString), c.getString("whitelist." + uuidString))).collect(Collectors.toList())); + Utils.saveConfig(c, "whitelist"); + + } + + public void startSchedule() { + BukkitScheduler sched = Bukkit.getScheduler(); + sched.scheduleSyncRepeatingTask(Core.getInstance(), () -> Core.getWhitelistManager().save(false), 72000, 72000); + } + + public UserRank getBypassRank() { + return this.bypassRank; + } + + public void setBypassRank(UserRank bypassRank) { + this.bypassRank = bypassRank; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/whitelist/WhitelistedUser.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/whitelist/WhitelistedUser.java new file mode 100644 index 0000000..2c2eaf1 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/whitelist/WhitelistedUser.java @@ -0,0 +1,31 @@ +package net.grandtheftmc.core.whitelist; + +import java.util.UUID; + +public class WhitelistedUser { + + private UUID uuid; + private String name; + + public WhitelistedUser(UUID uuid, String name) { + this.uuid = uuid; + this.name = name; + } + + public UUID getUuid() { + return this.uuid; + } + + public void setUuid(UUID uuid) { + this.uuid = uuid; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/Wrapper.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/Wrapper.java new file mode 100644 index 0000000..1ad9864 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/Wrapper.java @@ -0,0 +1,7 @@ +package net.grandtheftmc.core.wrapper; + +/** + * Created by Luke Bingham on 15/09/2017. + */ +public interface Wrapper { +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/entity/AbstractEntity.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/entity/AbstractEntity.java new file mode 100644 index 0000000..8598c9a --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/entity/AbstractEntity.java @@ -0,0 +1,19 @@ +package net.grandtheftmc.core.wrapper.entity; + +import net.grandtheftmc.core.wrapper.Wrapper; + +/** + * Created by Luke Bingham on 15/09/2017. + */ +public abstract class AbstractEntity<T extends CoreEntity> implements Wrapper { + + /** + * (!) + * + * DON'T USE THIS, STILL TRYING TO FIND THE BEST WAY TO WRAP ENTITIES. + * + * (!) + */ + + public abstract T getCoreEntity(); +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/entity/CoreEntity.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/entity/CoreEntity.java new file mode 100644 index 0000000..f220e92 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/entity/CoreEntity.java @@ -0,0 +1,7 @@ +package net.grandtheftmc.core.wrapper.entity; + +/** + * Created by Luke Bingham on 15/09/2017. + */ +public interface CoreEntity { +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/entity/pig/CorePig.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/entity/pig/CorePig.java new file mode 100644 index 0000000..e7c3bd2 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/entity/pig/CorePig.java @@ -0,0 +1,13 @@ +package net.grandtheftmc.core.wrapper.entity.pig; + +import net.grandtheftmc.core.wrapper.entity.CoreEntity; + +/** + * Created by Luke Bingham on 15/09/2017. + */ +public interface CorePig extends CoreEntity { + + void setEntityName(String name); + + void setEntityNameVisible(boolean visible); +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/entity/pig/CorePig_1_12.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/entity/pig/CorePig_1_12.java new file mode 100644 index 0000000..0c4db4e --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/entity/pig/CorePig_1_12.java @@ -0,0 +1,24 @@ +package net.grandtheftmc.core.wrapper.entity.pig; + +import org.bukkit.World; +import org.bukkit.craftbukkit.v1_12_R1.CraftWorld; + +/** + * Created by Luke Bingham on 15/09/2017. + */ +public class CorePig_1_12 extends net.minecraft.server.v1_12_R1.EntityPig implements CorePig { + + public CorePig_1_12(World world) { + super(((CraftWorld) world).getHandle()); + } + + @Override + public void setEntityName(String name) { + //TODO Set entity name + } + + @Override + public void setEntityNameVisible(boolean visible) { + //TODO set entity name visible + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/entity/pig/WrappedPig.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/entity/pig/WrappedPig.java new file mode 100644 index 0000000..1730368 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/entity/pig/WrappedPig.java @@ -0,0 +1,20 @@ +package net.grandtheftmc.core.wrapper.entity.pig; + +import net.grandtheftmc.core.wrapper.entity.AbstractEntity; + +/** + * Created by Luke Bingham on 15/09/2017. + */ +public class WrappedPig extends AbstractEntity<CorePig> { + + private CorePig corePig; + + public WrappedPig(CorePig pig) { + this.corePig = pig; + } + + @Override + public CorePig getCoreEntity() { + return this.corePig; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/AbstractPacket.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/AbstractPacket.java new file mode 100644 index 0000000..fbf1c90 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/AbstractPacket.java @@ -0,0 +1,87 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet; + +import java.lang.reflect.InvocationTargetException; + +import net.grandtheftmc.core.wrapper.Wrapper; +import org.bukkit.entity.Player; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.events.PacketContainer; +import com.google.common.base.Objects; + +public abstract class AbstractPacket implements Wrapper { + // The packet we will be modifying + protected PacketContainer handle; + + /** + * Constructs a new strongly typed wrapper for the given packet. + * + * @param handle - handle to the raw packet data. + * @param type - the packet type. + */ + protected AbstractPacket(PacketContainer handle, PacketType type) { + // Make sure we're given a valid packet + if (handle == null) + throw new IllegalArgumentException("Packet handle cannot be NULL."); + if (!Objects.equal(handle.getType(), type)) + throw new IllegalArgumentException(handle.getHandle() + " is not a packet of type " + type); + + this.handle = handle; + } + + /** + * Retrieve a handle to the raw packet data. + * + * @return Raw packet data. + */ + public PacketContainer getHandle() { + return handle; + } + + /** + * Send the current packet to the given receiver. + * + * @param receiver - the receiver. + * @throws RuntimeException If the packet cannot be sent. + */ + public void sendPacket(Player receiver) { + try { + ProtocolLibrary.getProtocolManager().sendServerPacket(receiver, getHandle()); + } catch (InvocationTargetException e) { + throw new RuntimeException("Cannot send packet.", e); + } + } + + /** + * Simulate receiving the current packet from the given sender. + * + * @param sender - the sender. + * @throws RuntimeException if the packet cannot be received. + */ + public void receivePacket(Player sender) { + try { + ProtocolLibrary.getProtocolManager().recieveClientPacket(sender, getHandle()); + } catch (Exception e) { + throw new RuntimeException("Cannot recieve packet.", e); + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/ChunkPacketProcessor.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/ChunkPacketProcessor.java new file mode 100644 index 0000000..d62c3fd --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/ChunkPacketProcessor.java @@ -0,0 +1,388 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet; + +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.World.Environment; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.reflect.StructureModifier; + +/** + * Used to process a chunk. + * + * @author Kristian + */ +public class ChunkPacketProcessor { + /** + * Contains the offset of the different block data in a chunk packet. + * + * @author Kristian + */ + public static class ChunkOffsets { + private int blockIdOffset; + private int dataOffset; + private int lightOffset; + private int skylightOffset; + private int extraOffset; + + private ChunkOffsets(int blockIdOffset, int dataOffset, + int lightOffset, int skylightOffset, int extraOffset) { + this.blockIdOffset = blockIdOffset; + this.dataOffset = dataOffset; + this.lightOffset = lightOffset; + this.skylightOffset = skylightOffset; + this.extraOffset = extraOffset; + } + + private void incrementIdIndex() { + blockIdOffset += ChunkPacketProcessor.BLOCK_ID_LENGHT; + dataOffset += ChunkPacketProcessor.BYTES_PER_NIBBLE_PART; + dataOffset += ChunkPacketProcessor.BYTES_PER_NIBBLE_PART; + + if (skylightOffset >= 0) { + skylightOffset += ChunkPacketProcessor.BYTES_PER_NIBBLE_PART; + } + } + + private void incrementExtraIndex() { + if (extraOffset >= 0) { + extraOffset += ChunkPacketProcessor.BYTES_PER_NIBBLE_PART; + } + } + + /** + * Retrieve the starting index of the block ID data. + * <p> + * This will be 4096 bytes in lenght, one byte for each block in the + * 16x16x16 chunklet. + * + * @return The starting location of the block ID data. + */ + public int getBlockIdOffset() { + return blockIdOffset; + } + + /** + * Retrieve the starting index of the meta data (4 bit per block). + * <p> + * This will be 2048 bytes in lenght, one nibblet for each block in the + * 16x16x16 chunklet. + * + * @return The starting location of the block meta data. + */ + public int getDataOffset() { + return dataOffset; + } + + /** + * Retrieve the starting index of the torch light data (4 bit per + * block). + * <p> + * This will be 2048 bytes in lenght, one nibblet for each block in the + * 16x16x16 chunklet. + * + * @return The starting location of the torch light data. + */ + public int getLightOffset() { + return lightOffset; + } + + /** + * Retrieve the starting index of the skylight data (4 bit per block). + * <p> + * This will be 2048 bytes in lenght if the skylight data exists (see + * {@link #hasSkylightOffset()}), no bytes if not. + * + * @return The starting location of the skylight data. + */ + public int getSkylightOffset() { + return skylightOffset; + } + + /** + * Determine if the current chunklet contains skylight data. + * + * @return TRUE if it does, FALSE otherwise. + */ + public boolean hasSkylightOffset() { + return skylightOffset >= 0; + } + + /** + * Retrieve the extra 4 bits in each block ID, if necessary. + * <p> + * This will be 2048 bytes in lenght if the extra data exists, no bytes + * if not. + * + * @return The starting location of the extra data. + */ + public int getExtraOffset() { + return extraOffset; + } + + /** + * Determine if the current chunklet contains any extra block ID data. + * + * @return TRUE if it does, FALSE otherwise. + */ + public boolean hasExtraOffset() { + return extraOffset > 0; + } + } + + /** + * Process the content of a single 16x16x16 chunklet in a 16x256x16 chunk. + * + * @author Kristian + */ + public interface ChunkletProcessor { + /** + * Process a given chunklet (16x16x16). + * + * @param origin - the block with the lowest x, y and z coordinate in + * the chunklet. + * @param data - the data array. + * @param offsets - the offsets with the data for the given chunklet. + */ + public void processChunklet(Location origin, byte[] data, + ChunkOffsets offsets); + + /** + * Process the biome array for a chunk (16x256x16). + * <p> + * This method will not be called if the chunk is missing biome + * information. + * + * @param origin - the block with the lowest x, y and z coordinate in + * the chunk. + * @param data - the data array. + * @param biomeIndex - the starting index of the biome data (256 bytes + * in lenght). + */ + public void processBiomeArray(Location origin, byte[] data, + int biomeIndex); + } + + // Useful Minecraft constants + protected static final int BYTES_PER_NIBBLE_PART = 2048; + protected static final int CHUNK_SEGMENTS = 16; + protected static final int NIBBLES_REQUIRED = 4; + + public static final int BLOCK_ID_LENGHT = 4096; + public static final int DATA_LENGHT = 2048; + public static final int BIOME_ARRAY_LENGTH = 256; + + private int chunkX; + private int chunkZ; + private int chunkMask; + private int extraMask; + private int chunkSectionNumber; + private int extraSectionNumber; + private boolean hasContinous = true; + + private int startIndex; + private int size; + + private byte[] data; + private World world; + + private ChunkPacketProcessor() { + // Use factory methods + } + + /** + * Construct a chunk packet processor from a givne MAP_CHUNK packet. + * + * @param packet - the map chunk packet. + * @return The chunk packet processor. + */ + public static ChunkPacketProcessor fromMapPacket(PacketContainer packet, + World world) { + if (!packet.getType().equals(PacketType.Play.Server.MAP_CHUNK)) + throw new IllegalArgumentException(packet + + " must be a MAP_CHUNK packet."); + + StructureModifier<Integer> ints = packet.getIntegers(); + StructureModifier<byte[]> byteArray = packet.getByteArrays(); + + // Create an info objects + ChunkPacketProcessor processor = new ChunkPacketProcessor(); + processor.world = world; + processor.chunkX = ints.read(0); // packet.a; + processor.chunkZ = ints.read(1); // packet.b; + processor.chunkMask = ints.read(2); // packet.c; + processor.extraMask = ints.read(3); // packet.d; + processor.data = byteArray.read(1); // packet.inflatedBuffer; + processor.startIndex = 0; + + if (packet.getBooleans().size() > 0) { + processor.hasContinous = packet.getBooleans().read(0); + } + return processor; + } + + /** + * Construct an array of chunk packet processors from a given MAP_CHUNK_BULK + * packet. + * + * @param packet - the map chunk bulk packet. + * @return The chunk packet processors. + */ + // The MAP_CHUNK_BULK packet no longer exists + /* + * public static ChunkPacketProcessor[] fromMapBulkPacket(PacketContainer + * packet, World world) { + * if (!packet.getType().equals(PacketType.Play.Server.MAP_CHUNK_BULK)) + * throw new IllegalArgumentException(packet + + * " must be a MAP_CHUNK_BULK packet."); + * StructureModifier<int[]> intArrays = packet.getIntegerArrays(); + * StructureModifier<byte[]> byteArrays = packet.getByteArrays(); + * int[] x = intArrays.read(0); // packet.c; + * int[] z = intArrays.read(1); // packet.d; + * ChunkPacketProcessor[] processors = new ChunkPacketProcessor[x.length]; + * int[] chunkMask = intArrays.read(2); // packet.a; + * int[] extraMask = intArrays.read(3); // packet.b; + * int dataStartIndex = 0; + * for (int chunkNum = 0; chunkNum < processors.length; chunkNum++) { + * // Create an info objects + * ChunkPacketProcessor processor = new ChunkPacketProcessor(); + * processors[chunkNum] = processor; + * processor.world = world; + * processor.chunkX = x[chunkNum]; + * processor.chunkZ = z[chunkNum]; + * processor.chunkMask = chunkMask[chunkNum]; + * processor.extraMask = extraMask[chunkNum]; + * processor.hasContinous = true; // Always true + * processor.data = byteArrays.read(1); //packet.buildBuffer; + * // Check for Spigot + * if (processor.data == null || processor.data.length == 0) { + * processor.data = + * packet.getSpecificModifier(byte[][].class).read(0)[chunkNum]; + * } else { + * processor.startIndex = dataStartIndex; + * } + * dataStartIndex += processor.size; + * } + * return processors; + * } + */ + + /** + * Begin processing the current chunk with the provided processor. + * + * @param processor - the processor that will process the chunk. + */ + public void process(ChunkletProcessor processor) { + // Compute chunk number + for (int i = 0; i < CHUNK_SEGMENTS; i++) { + if ((chunkMask & (1 << i)) > 0) { + chunkSectionNumber++; + } + if ((extraMask & (1 << i)) > 0) { + extraSectionNumber++; + } + } + + int skylightCount = getSkylightCount(); + + // The total size of a chunk is the number of blocks sent (depends on the number of sections) multiplied by the + // amount of bytes per block. This last figure can be calculated by adding together all the data parts: + // For any block: + // * Block ID - 8 bits per block (byte) + // * Block metadata - 4 bits per block (nibble) + // * Block light array - 4 bits per block + // If 'worldProvider.skylight' is TRUE + // * Sky light array - 4 bits per block + // If the segment has extra data: + // * Add array - 4 bits per block + // Biome array - only if the entire chunk (has continous) is sent: + // * Biome array - 256 bytes + // + // A section has 16 * 16 * 16 = 4096 blocks. + size = + BYTES_PER_NIBBLE_PART + * ((NIBBLES_REQUIRED + skylightCount) + * chunkSectionNumber + extraSectionNumber) + + (hasContinous ? BIOME_ARRAY_LENGTH : 0); + + if ((getOffset(2) - startIndex) > data.length) { + return; + } + + // Make sure the chunk is loaded + if (isChunkLoaded(world, chunkX, chunkZ)) { + translate(processor); + } + } + + /** + * Retrieve the number of 2048 byte segments per chunklet. + * <p< + * This is usually one for The Overworld, and zero for both The End and The + * Nether. + * + * @return Number of skylight byte segments. + */ + protected int getSkylightCount() { + // There's no sun/moon in the end or in the nether, so Minecraft doesn't sent any skylight information + // This optimization was added in 1.4.6. Note that ideally you should get this from the "f" (skylight) field. + return world.getEnvironment() == Environment.NORMAL ? 1 : 0; + } + + private int getOffset(int nibbles) { + return startIndex + + (nibbles * chunkSectionNumber * ChunkPacketProcessor.BYTES_PER_NIBBLE_PART); + } + + private void translate(ChunkletProcessor processor) { + // Loop over 16x16x16 chunks in the 16x256x16 column + int current = 4; + ChunkOffsets offsets = + new ChunkOffsets(getOffset(0), getOffset(2), getOffset(3), + getSkylightCount() > 0 ? getOffset(current++) : -1, + extraSectionNumber > 0 ? getOffset(current++) : -1); + + for (int i = 0; i < 16; i++) { + // If the bitmask indicates this chunk is sent + if ((chunkMask & 1 << i) > 0) { + // The lowest block (in x, y, z) in this chunklet + Location origin = + new Location(world, chunkX << 4, i * 16, chunkZ << 4); + + processor.processChunklet(origin, data, offsets); + offsets.incrementIdIndex(); + } + if ((extraMask & 1 << i) > 0) { + offsets.incrementExtraIndex(); + } + } + + if (hasContinous) { + processor.processBiomeArray(new Location(world, chunkX << 4, 0, + chunkZ << 4), data, startIndex + size - BIOME_ARRAY_LENGTH); + } + } + + private boolean isChunkLoaded(World world, int x, int z) { + return world.isChunkLoaded(x, z); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperHandshakingClientSetProtocol.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperHandshakingClientSetProtocol.java new file mode 100644 index 0000000..6741f21 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperHandshakingClientSetProtocol.java @@ -0,0 +1,119 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.PacketType.Protocol; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperHandshakingClientSetProtocol extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Handshake.Client.SET_PROTOCOL; + + public WrapperHandshakingClientSetProtocol() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperHandshakingClientSetProtocol(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Protocol Version. + * <p> + * Notes: (4 as of 1.7.2) + * + * @return The current Protocol Version + */ + public int getProtocolVersion() { + return handle.getIntegers().read(0); + } + + /** + * Set Protocol Version. + * + * @param value - new value. + */ + public void setProtocolVersion(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve Server Address (hostname or IP). + * <p> + * Notes: localhost + * + * @return The current Server Address (hostname or IP) + */ + public String getServerAddressHostnameOrIp() { + return handle.getStrings().read(0); + } + + /** + * Set Server Address (hostname or IP). + * + * @param value - new value. + */ + public void setServerAddressHostnameOrIp(String value) { + handle.getStrings().write(0, value); + } + + /** + * Retrieve Server Port. + * <p> + * Notes: 25565 + * + * @return The current Server Port + */ + public int getServerPort() { + return handle.getIntegers().read(1); + } + + /** + * Set Server Port. + * + * @param value - new value. + */ + public void setServerPort(int value) { + handle.getIntegers().write(1, value); + } + + /** + * Retrieve Next state. + * <p> + * Notes: 1 for status, 2 for login + * + * @return The current Next state + */ + public Protocol getNextState() { + return handle.getProtocols().read(0); + } + + /** + * Set Next state. + * + * @param value - new value. + */ + public void setNextState(Protocol value) { + handle.getProtocols().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperLoginClientEncryptionBegin.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperLoginClientEncryptionBegin.java new file mode 100644 index 0000000..847a087 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperLoginClientEncryptionBegin.java @@ -0,0 +1,73 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperLoginClientEncryptionBegin extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Login.Client.ENCRYPTION_BEGIN; + + public WrapperLoginClientEncryptionBegin() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperLoginClientEncryptionBegin(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Shared Secret. + * + * @return The current Shared Secret + */ + public byte[] getSharedSecret() { + return handle.getByteArrays().read(0); + } + + /** + * Set Shared Secret. + * + * @param value - new value. + */ + public void setSharedSecret(byte[] value) { + handle.getByteArrays().write(0, value); + } + + /** + * Retrieve Verify Token. + * + * @return The current Verify Token + */ + public byte[] getVerifyToken() { + return handle.getByteArrays().read(1); + } + + /** + * Set Verify Token. + * + * @param value - new value. + */ + public void setVerifyToken(byte[] value) { + handle.getByteArrays().write(1, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperLoginClientStart.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperLoginClientStart.java new file mode 100644 index 0000000..5f0f5bf --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperLoginClientStart.java @@ -0,0 +1,55 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.WrappedGameProfile; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperLoginClientStart extends AbstractPacket { + public static final PacketType TYPE = PacketType.Login.Client.START; + + public WrapperLoginClientStart() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperLoginClientStart(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Profile. + * + * @return The current Profile + */ + public WrappedGameProfile getProfile() { + return handle.getGameProfiles().read(0); + } + + /** + * Set Name. + * + * @param value - new value. + */ + public void setProfile(WrappedGameProfile value) { + handle.getGameProfiles().write(0, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientAbilities.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientAbilities.java new file mode 100644 index 0000000..4f93825 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientAbilities.java @@ -0,0 +1,84 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayClientAbilities extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Client.ABILITIES; + + public WrapperPlayClientAbilities() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientAbilities(PacketContainer packet) { + super(packet, TYPE); + } + + public boolean isInvulnurable() { + return handle.getBooleans().read(0); + } + + public void setInvulnurable(boolean value) { + handle.getBooleans().write(0, value); + } + + public boolean isFlying() { + return handle.getBooleans().read(1); + } + + public void setFlying(boolean value) { + handle.getBooleans().write(1, value); + } + + public boolean canFly() { + return handle.getBooleans().read(2); + } + + public void setCanFly(boolean value) { + handle.getBooleans().write(2, value); + } + + public boolean canInstantlyBuild() { + return handle.getBooleans().read(3); + } + + public void setCanInstantlyBuild(boolean value) { + handle.getBooleans().write(3, value); + } + + public float getFlyingSpeed() { + return handle.getFloat().read(0); + } + + public void setFlyingSpeed(float value) { + handle.getFloat().write(0, value); + } + + public float getWalkingSpeed() { + return handle.getFloat().read(1); + } + + public void setWalkingSpeed(float value) { + handle.getFloat().write(1, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientAdvancements.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientAdvancements.java new file mode 100644 index 0000000..9e31df6 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientAdvancements.java @@ -0,0 +1,78 @@ +/** + * This file is part of PacketWrapper. + * Copyright (C) 2012-2015 Kristian S. Strangeland + * Copyright (C) 2015 dmulloy2 + * + * PacketWrapper is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PacketWrapper is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with PacketWrapper. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.MinecraftKey; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayClientAdvancements extends AbstractPacket { + + public static final PacketType TYPE = PacketType.Play.Client.ADVANCEMENTS; + + public WrapperPlayClientAdvancements() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientAdvancements(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Action. + * <p> + * Notes: 0: Opened tab, 1: Closed screen + * @return The current Action + */ + public Status getAction() { + return handle.getEnumModifier(Status.class, 0).readSafely(0); + } + + /** + * Set Action. + * @param value - new value. + */ + public void setAction(Status value) { + handle.getEnumModifier(Status.class, 0).writeSafely(0, value); + } + /** + * Retrieve Tab ID. + * <p> + * Notes: only present if action is Opened tab + * @return The current Tab ID + */ + public MinecraftKey getTabId() { + return handle.getMinecraftKeys().readSafely(0); + } + + /** + * Set Tab ID. + * @param value - new value. + */ + public void setTabId(MinecraftKey value) { + handle.getMinecraftKeys().writeSafely(0, value); + } + + public enum Status { + OPENED_TAB, + CLOSED_SCREEN; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientArmAnimation.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientArmAnimation.java new file mode 100644 index 0000000..b5bf1b9 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientArmAnimation.java @@ -0,0 +1,36 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayClientArmAnimation extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Client.ARM_ANIMATION; + + public WrapperPlayClientArmAnimation() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientArmAnimation(PacketContainer packet) { + super(packet, TYPE); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientAutoRecipe.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientAutoRecipe.java new file mode 100644 index 0000000..f31a822 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientAutoRecipe.java @@ -0,0 +1,65 @@ +/** + * This file is part of PacketWrapper. + * Copyright (C) 2012-2015 Kristian S. Strangeland + * Copyright (C) 2015 dmulloy2 + * + * PacketWrapper is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PacketWrapper is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with PacketWrapper. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayClientAutoRecipe extends AbstractPacket { + + public static final PacketType TYPE = PacketType.Play.Client.AUTO_RECIPE; + + public WrapperPlayClientAutoRecipe() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientAutoRecipe(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Window ID. + * <p> + * Notes: the window id. + * @return The current Window ID + */ + public int getWindowId() { + return handle.getIntegers().read(0); + } + + /** + * Set Window ID. + * @param value - new value. + */ + public void setWindowId(int value) { + handle.getIntegers().write(0, value); + } + + // Modifier for recipe can be created upon request + + public boolean isMakeAll() { + return handle.getBooleans().read(0); + } + + public void setMakeAll(boolean value) { + handle.getBooleans().write(0, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientBlockDig.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientBlockDig.java new file mode 100644 index 0000000..13da8e6 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientBlockDig.java @@ -0,0 +1,87 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.BlockPosition; +import com.comphenix.protocol.wrappers.EnumWrappers.Direction; +import com.comphenix.protocol.wrappers.EnumWrappers.PlayerDigType; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayClientBlockDig extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Client.BLOCK_DIG; + + public WrapperPlayClientBlockDig() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientBlockDig(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Location. + * <p> + * Notes: block position + * + * @return The current Location + */ + public BlockPosition getLocation() { + return handle.getBlockPositionModifier().read(0); + } + + /** + * Set Location. + * + * @param value - new value. + */ + public void setLocation(BlockPosition value) { + handle.getBlockPositionModifier().write(0, value); + } + + public Direction getDirection() { + return handle.getDirections().read(0); + } + + public void setDirection(Direction value) { + handle.getDirections().write(0, value); + } + + /** + * Retrieve Status. + * <p> + * Notes: the action the player is taking against the block (see below) + * + * @return The current Status + */ + public PlayerDigType getStatus() { + return handle.getPlayerDigTypes().read(0); + } + + /** + * Set Status. + * + * @param value - new value. + */ + public void setStatus(PlayerDigType value) { + handle.getPlayerDigTypes().write(0, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientBlockPlace.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientBlockPlace.java new file mode 100644 index 0000000..3fc367a --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientBlockPlace.java @@ -0,0 +1,54 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.EnumWrappers.Hand; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayClientBlockPlace extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Client.BLOCK_PLACE; + + public WrapperPlayClientBlockPlace() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientBlockPlace(PacketContainer packet) { + super(packet, TYPE); + } + + public Hand getHand() { + return handle.getHands().read(0); + } + + public void setHand(Hand value) { + handle.getHands().write(0, value); + } + + public long getTimestamp() { + return handle.getLongs().read(0); + } + + public void setTimestamp(long value) { + handle.getLongs().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientBoatMove.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientBoatMove.java new file mode 100644 index 0000000..593978d --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientBoatMove.java @@ -0,0 +1,54 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayClientBoatMove extends AbstractPacket { + + public static final PacketType TYPE = PacketType.Play.Client.BOAT_MOVE; + + public WrapperPlayClientBoatMove() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientBoatMove(PacketContainer packet) { + super(packet, TYPE); + } + + public boolean getLeftOar() { + return handle.getBooleans().read(0); + } + + public void setLeftOar(boolean value) { + handle.getBooleans().write(0, value); + } + + public boolean getRightOar() { + return handle.getBooleans().read(1); + } + + public void setRightOar(boolean value) { + handle.getBooleans().write(1, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientChat.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientChat.java new file mode 100644 index 0000000..c185d0d --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientChat.java @@ -0,0 +1,55 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayClientChat extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Client.CHAT; + + public WrapperPlayClientChat() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientChat(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Message. + * + * @return The current Message + */ + public String getMessage() { + return handle.getStrings().read(0); + } + + /** + * Set Message. + * + * @param value - new value. + */ + public void setMessage(String value) { + handle.getStrings().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientClientCommand.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientClientCommand.java new file mode 100644 index 0000000..acb95b8 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientClientCommand.java @@ -0,0 +1,58 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.EnumWrappers.ClientCommand; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayClientClientCommand extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Client.CLIENT_COMMAND; + + public WrapperPlayClientClientCommand() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientClientCommand(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Action ID. + * <p> + * Notes: see below + * + * @return The current Action ID + */ + public ClientCommand getAction() { + return handle.getClientCommands().read(0); + } + + /** + * Set Action ID. + * + * @param value - new value. + */ + public void setAction(ClientCommand value) { + handle.getClientCommands().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientCloseWindow.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientCloseWindow.java new file mode 100644 index 0000000..dd32d28 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientCloseWindow.java @@ -0,0 +1,57 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayClientCloseWindow extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Client.CLOSE_WINDOW; + + public WrapperPlayClientCloseWindow() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientCloseWindow(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Window id. + * <p> + * Notes: this is the id of the window that was closed. 0 for inventory. + * + * @return The current Window id + */ + public int getWindowId() { + return handle.getIntegers().read(0); + } + + /** + * Set Window id. + * + * @param value - new value. + */ + public void setWindowId(int value) { + handle.getIntegers().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientCustomPayload.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientCustomPayload.java new file mode 100644 index 0000000..f780630 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientCustomPayload.java @@ -0,0 +1,104 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.utility.MinecraftReflection; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayClientCustomPayload extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Client.CUSTOM_PAYLOAD; + + public WrapperPlayClientCustomPayload() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientCustomPayload(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Channel. + * <p> + * Notes: name of the "channel" used to send the data. + * + * @return The current Channel + */ + public String getChannel() { + return handle.getStrings().read(0); + } + + /** + * Set Channel. + * + * @param value - new value. + */ + public void setChannel(String value) { + handle.getStrings().write(0, value); + } + + /** + * Retrieve payload contents as a raw Netty buffer + * + * @return Payload contents as a Netty buffer + */ + public ByteBuf getContentsBuffer() { + return (ByteBuf) handle.getModifier().withType(ByteBuf.class).read(0); + } + + /** + * Retrieve payload contents + * + * @return Payload contents as a byte array + */ + public byte[] getContents() { + ByteBuf buffer = getContentsBuffer(); + byte[] array = new byte[buffer.readableBytes()]; + buffer.readBytes(array); + return array; + } + + /** + * Update payload contents with a Netty buffer + * + * @param content - new payload content + */ + public void setContentsBuffer(ByteBuf contents) { + if (MinecraftReflection.is(MinecraftReflection.getPacketDataSerializerClass(), contents)) { + handle.getModifier().withType(ByteBuf.class).write(0, contents); + } else { + Object serializer = MinecraftReflection.getPacketDataSerializer(contents); + handle.getModifier().withType(ByteBuf.class).write(0, serializer); + } + } + + /** + * Update payload contents with a byte array + * + * @param content - new payload content + */ + public void setContents(byte[] content) { + setContentsBuffer(Unpooled.copiedBuffer(content)); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientEnchantItem.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientEnchantItem.java new file mode 100644 index 0000000..8416c77 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientEnchantItem.java @@ -0,0 +1,78 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayClientEnchantItem extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Client.ENCHANT_ITEM; + + public WrapperPlayClientEnchantItem() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientEnchantItem(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Window ID. + * <p> + * Notes: the ID sent by Open Window + * + * @return The current Window ID + */ + public int getWindowId() { + return handle.getIntegers().read(0); + } + + /** + * Set Window ID. + * + * @param value - new value. + */ + public void setWindowId(byte value) { + handle.getIntegers().write(0, (int) value); + } + + /** + * Retrieve Enchantment. + * <p> + * Notes: the position of the enchantment on the enchantment table window, + * starting with 0 as the topmost one. + * + * @return The current Enchantment + */ + public int getEnchantment() { + return handle.getIntegers().read(1); + } + + /** + * Set Enchantment. + * + * @param value - new value. + */ + public void setEnchantment(int value) { + handle.getIntegers().write(1, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientEntityAction.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientEntityAction.java new file mode 100644 index 0000000..0870a6d --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientEntityAction.java @@ -0,0 +1,122 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.World; +import org.bukkit.entity.Entity; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.wrappers.EnumWrappers.PlayerAction; + +public class WrapperPlayClientEntityAction extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Client.ENTITY_ACTION; + + public WrapperPlayClientEntityAction() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientEntityAction(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Entity ID. + * <p> + * Notes: entity's ID + * + * @return The current Entity ID + */ + public int getEntityID() { + return handle.getIntegers().read(0); + } + + /** + * Set Entity ID. + * + * @param value - new value. + */ + public void setEntityID(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param world - the current world of the entity. + * @return The spawned entity. + */ + public Entity getEntity(World world) { + return handle.getEntityModifier(world).read(0); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param event - the packet event. + * @return The spawned entity. + */ + public Entity getEntity(PacketEvent event) { + return getEntity(event.getPlayer().getWorld()); + } + + /** + * Retrieve Action ID. + * <p> + * Notes: the ID of the action, see below. + * + * @return The current Action ID + */ + public PlayerAction getAction() { + return handle.getPlayerActions().read(0); + } + + /** + * Set Action ID. + * + * @param value - new value. + */ + public void setAction(PlayerAction value) { + handle.getPlayerActions().write(0, value); + } + + /** + * Retrieve Jump Boost. + * <p> + * Notes: horse jump boost. Ranged from 0 -> 100. + * + * @return The current Jump Boost + */ + public int getJumpBoost() { + return handle.getIntegers().read(1); + } + + /** + * Set Jump Boost. + * + * @param value - new value. + */ + public void setJumpBoost(int value) { + handle.getIntegers().write(1, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientFlying.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientFlying.java new file mode 100644 index 0000000..07a44a5 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientFlying.java @@ -0,0 +1,57 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayClientFlying extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Client.FLYING; + + public WrapperPlayClientFlying() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientFlying(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve On Ground. + * <p> + * Notes: true if the client is on the ground, False otherwise + * + * @return The current On Ground + */ + public boolean getOnGround() { + return handle.getBooleans().read(0); + } + + /** + * Set On Ground. + * + * @param value - new value. + */ + public void setOnGround(boolean value) { + handle.getBooleans().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientHeldItemSlot.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientHeldItemSlot.java new file mode 100644 index 0000000..b490059 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientHeldItemSlot.java @@ -0,0 +1,57 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayClientHeldItemSlot extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Client.HELD_ITEM_SLOT; + + public WrapperPlayClientHeldItemSlot() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientHeldItemSlot(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Slot. + * <p> + * Notes: the slot which the player has selected (0-8) + * + * @return The current Slot + */ + public int getSlot() { + return handle.getIntegers().read(0); + } + + /** + * Set Slot. + * + * @param value - new value. + */ + public void setSlot(int value) { + handle.getIntegers().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientKeepAlive.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientKeepAlive.java new file mode 100644 index 0000000..dece266 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientKeepAlive.java @@ -0,0 +1,55 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayClientKeepAlive extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Client.KEEP_ALIVE; + + public WrapperPlayClientKeepAlive() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientKeepAlive(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Keep Alive ID. + * + * @return The current Keep Alive ID + */ + public int getKeepAliveId() { + return handle.getIntegers().read(0); + } + + /** + * Set Keep Alive ID. + * + * @param value - new value. + */ + public void setKeepAliveId(int value) { + handle.getIntegers().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientLook.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientLook.java new file mode 100644 index 0000000..70ca611 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientLook.java @@ -0,0 +1,97 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayClientLook extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Client.LOOK; + + public WrapperPlayClientLook() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientLook(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Yaw. + * <p> + * Notes: absolute rotation on the X Axis, in degrees + * + * @return The current Yaw + */ + public float getYaw() { + return handle.getFloat().read(0); + } + + /** + * Set Yaw. + * + * @param value - new value. + */ + public void setYaw(float value) { + handle.getFloat().write(0, value); + } + + /** + * Retrieve Pitch. + * <p> + * Notes: absolute rotation on the Y Axis, in degrees + * + * @return The current Pitch + */ + public float getPitch() { + return handle.getFloat().read(1); + } + + /** + * Set Pitch. + * + * @param value - new value. + */ + public void setPitch(float value) { + handle.getFloat().write(1, value); + } + + /** + * Retrieve On Ground. + * <p> + * Notes: true if the client is on the ground, False otherwise + * + * @return The current On Ground + */ + public boolean getOnGround() { + return handle.getBooleans().read(0); + } + + /** + * Set On Ground. + * + * @param value - new value. + */ + public void setOnGround(boolean value) { + handle.getBooleans().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientPosition.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientPosition.java new file mode 100644 index 0000000..9b1c85c --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientPosition.java @@ -0,0 +1,118 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayClientPosition extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Client.POSITION; + + public WrapperPlayClientPosition() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientPosition(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve X. + * <p> + * Notes: absolute position + * + * @return The current X + */ + public double getX() { + return handle.getDoubles().read(0); + } + + /** + * Set X. + * + * @param value - new value. + */ + public void setX(double value) { + handle.getDoubles().write(0, value); + } + + /** + * Retrieve FeetY. + * <p> + * Notes: absolute feet position, normally HeadY - 1.62. Used to modify the + * players bounding box when going up stairs, crouching, etc… + * + * @return The current FeetY + */ + public double getY() { + return handle.getDoubles().read(1); + } + + /** + * Set FeetY. + * + * @param value - new value. + */ + public void setY(double value) { + handle.getDoubles().write(1, value); + } + + /** + * Retrieve Z. + * <p> + * Notes: absolute position + * + * @return The current Z + */ + public double getZ() { + return handle.getDoubles().read(2); + } + + /** + * Set Z. + * + * @param value - new value. + */ + public void setZ(double value) { + handle.getDoubles().write(2, value); + } + + /** + * Retrieve On Ground. + * <p> + * Notes: true if the client is on the ground, False otherwise + * + * @return The current On Ground + */ + public boolean getOnGround() { + return handle.getBooleans().read(0); + } + + /** + * Set On Ground. + * + * @param value - new value. + */ + public void setOnGround(boolean value) { + handle.getBooleans().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientPositionLook.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientPositionLook.java new file mode 100644 index 0000000..ab1b1a6 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientPositionLook.java @@ -0,0 +1,158 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayClientPositionLook extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Client.POSITION_LOOK; + + public WrapperPlayClientPositionLook() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientPositionLook(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve X. + * <p> + * Notes: absolute position + * + * @return The current X + */ + public double getX() { + return handle.getDoubles().read(0); + } + + /** + * Set X. + * + * @param value - new value. + */ + public void setX(double value) { + handle.getDoubles().write(0, value); + } + + /** + * Retrieve Feet Y. + * <p> + * Notes: absolute feet position. Is normally HeadY - 1.62. Used to modify + * the players bounding box when going up stairs, crouching, etc… + * + * @return The current FeetY + */ + public double getY() { + return handle.getDoubles().read(1); + } + + /** + * Set Feet Y. + * + * @param value - new value. + */ + public void setY(double value) { + handle.getDoubles().write(1, value); + } + + /** + * Retrieve Z. + * <p> + * Notes: absolute position + * + * @return The current Z + */ + public double getZ() { + return handle.getDoubles().read(2); + } + + /** + * Set Z. + * + * @param value - new value. + */ + public void setZ(double value) { + handle.getDoubles().write(2, value); + } + + /** + * Retrieve Yaw. + * <p> + * Notes: absolute rotation on the X Axis, in degrees + * + * @return The current Yaw + */ + public float getYaw() { + return handle.getFloat().read(0); + } + + /** + * Set Yaw. + * + * @param value - new value. + */ + public void setYaw(float value) { + handle.getFloat().write(0, value); + } + + /** + * Retrieve Pitch. + * <p> + * Notes: absolute rotation on the Y Axis, in degrees + * + * @return The current Pitch + */ + public float getPitch() { + return handle.getFloat().read(1); + } + + /** + * Set Pitch. + * + * @param value - new value. + */ + public void setPitch(float value) { + handle.getFloat().write(1, value); + } + + /** + * Retrieve On Ground. + * <p> + * Notes: true if the client is on the ground, False otherwise + * + * @return The current On Ground + */ + public boolean getOnGround() { + return handle.getBooleans().read(0); + } + + /** + * Set On Ground. + * + * @param value - new value. + */ + public void setOnGround(boolean value) { + handle.getBooleans().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientRecipeDisplayed.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientRecipeDisplayed.java new file mode 100644 index 0000000..476b5ec --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientRecipeDisplayed.java @@ -0,0 +1,67 @@ +/** + * This file is part of PacketWrapper. + * Copyright (C) 2012-2015 Kristian S. Strangeland + * Copyright (C) 2015 dmulloy2 + * + * PacketWrapper is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PacketWrapper is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with PacketWrapper. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayClientRecipeDisplayed extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Client.RECIPE_DISPLAYED; + + public WrapperPlayClientRecipeDisplayed() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientRecipeDisplayed(PacketContainer packet) { + super(packet, TYPE); + } + + public Status getStatus() { + return handle.getEnumModifier(Status.class, 0).readSafely(0); + } + + public void setStatus(Status value) { + handle.getEnumModifier(Status.class, 0).writeSafely(0, value); + } + + // Modifier for recipe can be created upon request + + public boolean isBookOpen() { + return handle.getBooleans().read(0); + } + + public void setBookOpen(boolean value) { + handle.getBooleans().write(0, value); + } + + public boolean isFilterActive() { + return handle.getBooleans().read(1); + } + + public void setFilterActive(boolean value) { + handle.getBooleans().write(1, value); + } + + public enum Status { + SHOWN, + SETTINGS; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientResourcePackStatus.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientResourcePackStatus.java new file mode 100644 index 0000000..8be39c8 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientResourcePackStatus.java @@ -0,0 +1,59 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.EnumWrappers.ResourcePackStatus; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayClientResourcePackStatus extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Play.Client.RESOURCE_PACK_STATUS; + + public WrapperPlayClientResourcePackStatus() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientResourcePackStatus(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Result. + * <p> + * Notes: successfully loaded: 0, Declined: 1, Failed download: 2, Accepted: + * 3 + * + * @return The current Result + */ + public ResourcePackStatus getResult() { + return handle.getResourcePackStatus().read(0); + } + + /** + * Set Result. + * + * @param value - new value. + */ + public void setResult(ResourcePackStatus value) { + handle.getResourcePackStatus().write(0, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientSetCreativeSlot.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientSetCreativeSlot.java new file mode 100644 index 0000000..22d31b6 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientSetCreativeSlot.java @@ -0,0 +1,78 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.inventory.ItemStack; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; + +public class WrapperPlayClientSetCreativeSlot extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Play.Client.SET_CREATIVE_SLOT; + + public WrapperPlayClientSetCreativeSlot() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientSetCreativeSlot(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Slot. + * <p> + * Notes: inventory slot + * + * @return The current Slot + */ + public int getSlot() { + return handle.getIntegers().read(0); + } + + /** + * Set Slot. + * + * @param value - new value. + */ + public void setSlot(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve Clicked item. + * + * @return The current Clicked item + */ + public ItemStack getClickedItem() { + return handle.getItemModifier().read(0); + } + + /** + * Set Clicked item. + * + * @param value - new value. + */ + public void setClickedItem(ItemStack value) { + handle.getItemModifier().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientSettings.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientSettings.java new file mode 100644 index 0000000..3cf6de1 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientSettings.java @@ -0,0 +1,138 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.EnumWrappers.ChatVisibility; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayClientSettings extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Client.SETTINGS; + + public WrapperPlayClientSettings() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientSettings(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Locale. + * <p> + * Notes: en_GB + * + * @return The current Locale + */ + public String getLocale() { + return handle.getStrings().read(0); + } + + /** + * Set Locale. + * + * @param value - new value. + */ + public void setLocale(String value) { + handle.getStrings().write(0, value); + } + + /** + * Retrieve View distance. + * <p> + * Notes: client-side render distance(chunks) + * + * @return The current View distance + */ + public int getViewDistance() { + return handle.getIntegers().read(0); + } + + /** + * Set View distance. + * + * @param value - new value. + */ + public void setViewDistance(byte value) { + handle.getIntegers().write(0, (int) value); + } + + /** + * Retrieve Chat flags. + * <p> + * Notes: chat settings. See notes below. + * + * @return The current Chat flags + */ + public ChatVisibility getChatFlags() { + return handle.getChatVisibilities().read(0); + } + + /** + * Set Chat flags. + * + * @param value - new value. + */ + public void setChatFlags(ChatVisibility value) { + handle.getChatVisibilities().write(0, value); + } + + /** + * Retrieve Chat colours. + * <p> + * Notes: "Colours" multiplayer setting + * + * @return The current Chat colours + */ + public boolean getChatColours() { + return handle.getBooleans().read(0); + } + + /** + * Set Chat colours. + * + * @param value - new value. + */ + public void setChatColours(boolean value) { + handle.getBooleans().write(0, value); + } + + /** + * Retrieve Displayed skin parts. + * <p> + * Notes: skin parts. See note below + * + * @return The current Displayed skin parts + */ + public int getDisplayedSkinParts() { + return handle.getIntegers().read(1); + } + + /** + * Set Displayed skin parts. + * + * @param value - new value. + */ + public void setDisplayedSkinParts(int value) { + handle.getIntegers().write(1, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientSpectate.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientSpectate.java new file mode 100644 index 0000000..42c822b --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientSpectate.java @@ -0,0 +1,57 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import java.util.UUID; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayClientSpectate extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Client.SPECTATE; + + public WrapperPlayClientSpectate() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientSpectate(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Target Player. + * + * @return The current Target Player + */ + public UUID getTargetPlayer() { + return handle.getUUIDs().read(0); + } + + /** + * Set Target Player. + * + * @param value - new value. + */ + public void setTargetPlayer(UUID value) { + handle.getUUIDs().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientSteerVehicle.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientSteerVehicle.java new file mode 100644 index 0000000..589eb81 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientSteerVehicle.java @@ -0,0 +1,93 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayClientSteerVehicle extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Client.STEER_VEHICLE; + + public WrapperPlayClientSteerVehicle() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientSteerVehicle(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Sideways. + * <p> + * Notes: positive to the left of the player + * + * @return The current Sideways + */ + public float getSideways() { + return handle.getFloat().read(0); + } + + /** + * Set Sideways. + * + * @param value - new value. + */ + public void setSideways(float value) { + handle.getFloat().write(0, value); + } + + /** + * Retrieve Forward. + * <p> + * Notes: positive forward + * + * @return The current Forward + */ + public float getForward() { + return handle.getFloat().read(1); + } + + /** + * Set Forward. + * + * @param value - new value. + */ + public void setForward(float value) { + handle.getFloat().write(1, value); + } + + public boolean isJump() { + return handle.getBooleans().read(0); + } + + public void setJump(boolean value) { + handle.getBooleans().write(0, value); + } + + public boolean isUnmount() { + return handle.getBooleans().read(1); + } + + public void setUnmount(boolean value) { + handle.getBooleans().write(1, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientTabComplete.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientTabComplete.java new file mode 100644 index 0000000..a7158a1 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientTabComplete.java @@ -0,0 +1,95 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.BlockPosition; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayClientTabComplete extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Client.TAB_COMPLETE; + + public WrapperPlayClientTabComplete() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientTabComplete(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Text. + * + * @return The current Text + */ + public String getText() { + return handle.getStrings().read(0); + } + + /** + * Set Text. + * + * @param value - new value. + */ + public void setText(String value) { + handle.getStrings().write(0, value); + } + + /** + * Retrieve Has Position. + * + * @return The current Has Position + */ + public BlockPosition getHasPosition() { + return handle.getBlockPositionModifier().read(0); + } + + /** + * Set Has Position. + * + * @param value - new value. + */ + public void setHasPosition(BlockPosition value) { + handle.getBlockPositionModifier().write(0, value); + } + + /** + * Retrieve Looked at block. + * <p> + * Notes: the position of the block being looked at. Only sent if the + * previous field is true + * + * @return The current Looked at block + */ + public BlockPosition getLookedAtBlock() { + return handle.getBlockPositionModifier().read(0); + } + + /** + * Set Looked at block. + * + * @param value - new value. + */ + public void setLookedAtBlock(BlockPosition value) { + handle.getBlockPositionModifier().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientTeleportAccept.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientTeleportAccept.java new file mode 100644 index 0000000..37ff4df --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientTeleportAccept.java @@ -0,0 +1,59 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayClientTeleportAccept extends AbstractPacket { + + public static final PacketType TYPE = + PacketType.Play.Client.TELEPORT_ACCEPT; + + public WrapperPlayClientTeleportAccept() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientTeleportAccept(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Teleport ID. + * <p> + * Notes: the ID given by the Player Position And Look packet + * + * @return The current Teleport ID + */ + public int getTeleportId() { + return handle.getIntegers().read(0); + } + + /** + * Set Teleport ID. + * + * @param value - new value. + */ + public void setTeleportId(int value) { + handle.getIntegers().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientTransaction.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientTransaction.java new file mode 100644 index 0000000..18a5383 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientTransaction.java @@ -0,0 +1,98 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayClientTransaction extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Client.TRANSACTION; + + public WrapperPlayClientTransaction() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientTransaction(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Window ID. + * <p> + * Notes: the id of the window that the action occurred in. + * + * @return The current Window ID + */ + public int getWindowId() { + return handle.getIntegers().read(0); + } + + /** + * Set Window ID. + * + * @param value - new value. + */ + public void setWindowId(byte value) { + handle.getIntegers().write(0, (int) value); + } + + /** + * Retrieve Action number. + * <p> + * Notes: every action that is to be accepted has a unique number. This + * field corresponds to that number. + * + * @return The current Action number + */ + public short getActionNumber() { + return handle.getShorts().read(0); + } + + /** + * Set Action number. + * + * @param value - new value. + */ + public void setActionNumber(short value) { + handle.getShorts().write(0, value); + } + + /** + * Retrieve Accepted. + * <p> + * Notes: whether the action was accepted. + * + * @return The current Accepted + */ + public boolean getAccepted() { + return handle.getBooleans().read(0); + } + + /** + * Set Accepted. + * + * @param value - new value. + */ + public void setAccepted(boolean value) { + handle.getBooleans().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientUpdateSign.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientUpdateSign.java new file mode 100644 index 0000000..6c46d43 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientUpdateSign.java @@ -0,0 +1,80 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.BlockPosition; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayClientUpdateSign extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Client.UPDATE_SIGN; + + public WrapperPlayClientUpdateSign() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientUpdateSign(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Location. + * <p> + * Notes: block Coordinates + * + * @return The current Location + */ + public BlockPosition getLocation() { + return handle.getBlockPositionModifier().read(0); + } + + /** + * Set Location. + * + * @param value - new value. + */ + public void setLocation(BlockPosition value) { + handle.getBlockPositionModifier().write(0, value); + } + + /** + * Retrieve this sign's lines of text. + * + * @return The current lines + */ + public String[] getLines() { + return handle.getStringArrays().read(0); + } + + /** + * Set this sign's lines of text. + * + * @param value - Lines, must be 4 elements long + */ + public void setLines(String[] value) { + if (value == null) + throw new IllegalArgumentException("value cannot be null!"); + if (value.length != 4) + throw new IllegalArgumentException("value must have 4 elements!"); + + handle.getStringArrays().write(0, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientUseEntity.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientUseEntity.java new file mode 100644 index 0000000..8e6e2ed --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientUseEntity.java @@ -0,0 +1,118 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.util.Vector; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.wrappers.EnumWrappers.EntityUseAction; + +public class WrapperPlayClientUseEntity extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Client.USE_ENTITY; + + public WrapperPlayClientUseEntity() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientUseEntity(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve entity ID of the target. + * + * @return The current entity ID + */ + public int getTargetID() { + return handle.getIntegers().read(0); + } + + /** + * Retrieve the entity that was targeted. + * + * @param world - the current world of the entity. + * @return The targeted entity. + */ + public Entity getTarget(World world) { + return handle.getEntityModifier(world).read(0); + } + + /** + * Retrieve the entity that was targeted. + * + * @param event - the packet event. + * @return The targeted entity. + */ + public Entity getTarget(PacketEvent event) { + return getTarget(event.getPlayer().getWorld()); + } + + /** + * Set entity ID of the target. + * + * @param value - new value. + */ + public void setTargetID(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve Type. + * + * @return The current Type + */ + public EntityUseAction getType() { + return handle.getEntityUseActions().read(0); + } + + /** + * Set Type. + * + * @param value - new value. + */ + public void setType(EntityUseAction value) { + handle.getEntityUseActions().write(0, value); + } + + /** + * Retrieve the target vector. + * <p> + * Notes: Only if {@link #getType()} is {@link EntityUseAction#INTERACT_AT}. + * + * @return The target vector or null + */ + public Vector getTargetVector() { + return handle.getVectors().read(0); + } + + /** + * Set the target vector. + * + * @param value - new value. + */ + public void setTargetVector(Vector value) { + handle.getVectors().write(0, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientUseItem.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientUseItem.java new file mode 100644 index 0000000..d7fc2c4 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientUseItem.java @@ -0,0 +1,139 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.BlockPosition; +import com.comphenix.protocol.wrappers.EnumWrappers.Direction; +import com.comphenix.protocol.wrappers.EnumWrappers.Hand; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayClientUseItem extends AbstractPacket { + + public static final PacketType TYPE = PacketType.Play.Client.USE_ITEM; + + public WrapperPlayClientUseItem() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientUseItem(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Location. + * <p> + * Notes: block position + * + * @return The current Location + */ + public BlockPosition getLocation() { + return handle.getBlockPositionModifier().read(0); + } + + /** + * Set Location. + * + * @param value - new value. + */ + public void setLocation(BlockPosition value) { + handle.getBlockPositionModifier().write(0, value); + } + + public Direction getFace() { + return handle.getDirections().read(0); + } + + public void setFace(Direction value) { + handle.getDirections().write(0, value); + } + + public Hand getHand() { + return handle.getHands().read(0); + } + + public void setHand(Hand value) { + handle.getHands().write(0, value); + } + + /** + * Retrieve Cursor Position X. + * <p> + * Notes: the position of the crosshair on the block, from 0 to 15 + * increasing from west to east + * + * @return The current Cursor Position X + */ + public float getCursorPositionX() { + return handle.getFloat().read(0); + } + + /** + * Set Cursor Position X. + * + * @param value - new value. + */ + public void setCursorPositionX(float value) { + handle.getFloat().write(0, value); + } + + /** + * Retrieve Cursor Position Y. + * <p> + * Notes: the position of the crosshair on the block, from 0 to 15 + * increasing from bottom to top + * + * @return The current Cursor Position Y + */ + public float getCursorPositionY() { + return handle.getFloat().read(1); + } + + /** + * Set Cursor Position Y. + * + * @param value - new value. + */ + public void setCursorPositionY(float value) { + handle.getFloat().write(1, value); + } + + /** + * Retrieve Cursor Position Z. + * <p> + * Notes: the position of the crosshair on the block, from 0 to 15 + * increasing from north to south + * + * @return The current Cursor Position Z + */ + public float getCursorPositionZ() { + return handle.getFloat().read(2); + } + + /** + * Set Cursor Position Z. + * + * @param value - new value. + */ + public void setCursorPositionZ(float value) { + handle.getFloat().write(2, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientVehicleMove.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientVehicleMove.java new file mode 100644 index 0000000..8139b71 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientVehicleMove.java @@ -0,0 +1,138 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayClientVehicleMove extends AbstractPacket { + + public static final PacketType TYPE = PacketType.Play.Client.VEHICLE_MOVE; + + public WrapperPlayClientVehicleMove() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientVehicleMove(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve X. + * <p> + * Notes: absolute position (X coordinate) + * + * @return The current X + */ + public double getX() { + return handle.getDoubles().read(0); + } + + /** + * Set X. + * + * @param value - new value. + */ + public void setX(double value) { + handle.getDoubles().write(0, value); + } + + /** + * Retrieve Y. + * <p> + * Notes: absolute position (Y coordinate) + * + * @return The current Y + */ + public double getY() { + return handle.getDoubles().read(1); + } + + /** + * Set Y. + * + * @param value - new value. + */ + public void setY(double value) { + handle.getDoubles().write(1, value); + } + + /** + * Retrieve Z. + * <p> + * Notes: absolute position (Z coordinate) + * + * @return The current Z + */ + public double getZ() { + return handle.getDoubles().read(2); + } + + /** + * Set Z. + * + * @param value - new value. + */ + public void setZ(double value) { + handle.getDoubles().write(2, value); + } + + /** + * Retrieve Yaw. + * <p> + * Notes: absolute rotation on the vertical axis, in degrees + * + * @return The current Yaw + */ + public float getYaw() { + return handle.getFloat().read(0); + } + + /** + * Set Yaw. + * + * @param value - new value. + */ + public void setYaw(float value) { + handle.getFloat().write(0, value); + } + + /** + * Retrieve Pitch. + * <p> + * Notes: absolute rotation on the horizontal axis, in degrees + * + * @return The current Pitch + */ + public float getPitch() { + return handle.getFloat().read(1); + } + + /** + * Set Pitch. + * + * @param value - new value. + */ + public void setPitch(float value) { + handle.getFloat().write(1, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientWindowClick.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientWindowClick.java new file mode 100644 index 0000000..ae5463a --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperPlayClientWindowClick.java @@ -0,0 +1,149 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.inventory.ItemStack; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; + +public class WrapperPlayClientWindowClick extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Client.WINDOW_CLICK; + + public WrapperPlayClientWindowClick() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayClientWindowClick(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Window ID. + * <p> + * Notes: the id of the window which was clicked. 0 for player inventory. + * + * @return The current Window ID + */ + public int getWindowId() { + return handle.getIntegers().read(0); + } + + /** + * Set Window ID. + * + * @param value - new value. + */ + public void setWindowId(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve Slot. + * <p> + * Notes: the clicked slot. See below. + * + * @return The current Slot + */ + public int getSlot() { + return handle.getIntegers().read(1); + } + + /** + * Set Slot. + * + * @param value - new value. + */ + public void setSlot(int value) { + handle.getIntegers().write(1, value); + } + + /** + * Retrieve Button. + * <p> + * Notes: the button used in the click. See below. + * + * @return The current Button + */ + public int getButton() { + return handle.getIntegers().read(2); + } + + /** + * Set Button. + * + * @param value - new value. + */ + public void setButton(int value) { + handle.getIntegers().write(2, value); + } + + /** + * Retrieve Action number. + * <p> + * Notes: a unique number for the action, used for transaction handling (See + * the Transaction packet). + * + * @return The current Action number + */ + public short getActionNumber() { + return handle.getShorts().read(0); + } + + /** + * Set Action number. + * + * @param value - new value. + */ + public void setActionNumber(short value) { + handle.getShorts().write(0, value); + } + + /** + * Retrieve Clicked item. + * + * @return The current Clicked item + */ + public ItemStack getClickedItem() { + return handle.getItemModifier().read(0); + } + + /** + * Set Clicked item. + * + * @param value - new value. + */ + public void setClickedItem(ItemStack value) { + handle.getItemModifier().write(0, value); + } + + public InventoryClickType getShift() { + return handle.getEnumModifier(InventoryClickType.class, 5).read(0); + } + + public void setShift(InventoryClickType value) { + handle.getEnumModifier(InventoryClickType.class, 5).write(0, value); + } + + public enum InventoryClickType { + PICKUP, QUICK_MOVE, SWAP, CLONE, THROW, QUICK_CRAFT, PICKUP_ALL; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperStatusClientPing.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperStatusClientPing.java new file mode 100644 index 0000000..613cf4e --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperStatusClientPing.java @@ -0,0 +1,55 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperStatusClientPing extends AbstractPacket { + public static final PacketType TYPE = PacketType.Status.Client.PING; + + public WrapperStatusClientPing() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperStatusClientPing(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Time. + * + * @return The current Time + */ + public long getTime() { + return handle.getLongs().read(0); + } + + /** + * Set Time. + * + * @param value - new value. + */ + public void setTime(long value) { + handle.getLongs().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperStatusClientStart.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperStatusClientStart.java new file mode 100644 index 0000000..f13cd32 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/in/WrapperStatusClientStart.java @@ -0,0 +1,36 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.in; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperStatusClientStart extends AbstractPacket { + public static final PacketType TYPE = PacketType.Status.Client.START; + + public WrapperStatusClientStart() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperStatusClientStart(PacketContainer packet) { + super(packet, TYPE); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperLoginServerDisconnect.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperLoginServerDisconnect.java new file mode 100644 index 0000000..4d3e00d --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperLoginServerDisconnect.java @@ -0,0 +1,65 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.WrappedChatComponent; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperLoginServerDisconnect extends AbstractPacket { + public static final PacketType TYPE = PacketType.Login.Server.DISCONNECT; + + public WrapperLoginServerDisconnect() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperLoginServerDisconnect(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve reason. + * + * @return The current reason + */ + public WrappedChatComponent getReason() { + return handle.getChatComponents().read(0); + } + + @Deprecated + public WrappedChatComponent getJsonData() { + return getReason(); + } + + /** + * Set reason. + * + * @param value - new value. + */ + public void setReason(WrappedChatComponent value) { + handle.getChatComponents().write(0, value); + } + + @Deprecated + public void setJsonData(WrappedChatComponent value) { + setReason(value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperLoginServerEncryptionBegin.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperLoginServerEncryptionBegin.java new file mode 100644 index 0000000..8017e13 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperLoginServerEncryptionBegin.java @@ -0,0 +1,95 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import java.security.PublicKey; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperLoginServerEncryptionBegin extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Login.Server.ENCRYPTION_BEGIN; + + public WrapperLoginServerEncryptionBegin() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperLoginServerEncryptionBegin(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Server ID. + * <p> + * Notes: appears to be empty as of 1.7.x + * + * @return The current Server ID + */ + public String getServerId() { + return handle.getStrings().read(0); + } + + /** + * Set Server ID. + * + * @param value - new value. + */ + public void setServerId(String value) { + handle.getStrings().write(0, value); + } + + /** + * Retrieve Public Key. + * + * @return The current Public Key + */ + public PublicKey getPublicKey() { + return handle.getSpecificModifier(PublicKey.class).read(0); + } + + /** + * Set Public Key. + * + * @param value - new value. + */ + public void setPublicKey(PublicKey value) { + handle.getSpecificModifier(PublicKey.class).write(0, value); + } + + /** + * Retrieve Verify Token. + * + * @return The current Verify Token + */ + public byte[] getVerifyToken() { + return handle.getByteArrays().read(0); + } + + /** + * Set Verify Token. + * + * @param value - new value. + */ + public void setVerifyToken(byte[] value) { + handle.getByteArrays().write(0, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperLoginServerSetCompression.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperLoginServerSetCompression.java new file mode 100644 index 0000000..5fcc702 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperLoginServerSetCompression.java @@ -0,0 +1,58 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperLoginServerSetCompression extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Login.Server.SET_COMPRESSION; + + public WrapperLoginServerSetCompression() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperLoginServerSetCompression(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Threshold. + * <p> + * Notes: threshold is the max size of a packet before its compressed + * + * @return The current Threshold + */ + public int getThreshold() { + return handle.getIntegers().read(0); + } + + /** + * Set Threshold. + * + * @param value - new value. + */ + public void setThreshold(int value) { + handle.getIntegers().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperLoginServerSuccess.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperLoginServerSuccess.java new file mode 100644 index 0000000..11f29ef --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperLoginServerSuccess.java @@ -0,0 +1,55 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.WrappedGameProfile; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperLoginServerSuccess extends AbstractPacket { + public static final PacketType TYPE = PacketType.Login.Server.SUCCESS; + + public WrapperLoginServerSuccess() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperLoginServerSuccess(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve the UUID and player name of the connected client. + * + * @return The current client profile. + */ + public WrappedGameProfile getProfile() { + return handle.getGameProfiles().read(0); + } + + /** + * Set the UUID and player name of the connected client as a game profile. + * + * @param value - new profile. + */ + public void setProfile(WrappedGameProfile value) { + handle.getGameProfiles().write(0, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerAbilities.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerAbilities.java new file mode 100644 index 0000000..69fda22 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerAbilities.java @@ -0,0 +1,84 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerAbilities extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.ABILITIES; + + public WrapperPlayServerAbilities() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerAbilities(PacketContainer packet) { + super(packet, TYPE); + } + + public boolean isInvulnurable() { + return handle.getBooleans().read(0); + } + + public void setInvulnurable(boolean value) { + handle.getBooleans().write(0, value); + } + + public boolean isFlying() { + return handle.getBooleans().read(1); + } + + public void setFlying(boolean value) { + handle.getBooleans().write(1, value); + } + + public boolean canFly() { + return handle.getBooleans().read(2); + } + + public void setCanFly(boolean value) { + handle.getBooleans().write(2, value); + } + + public boolean canInstantlyBuild() { + return handle.getBooleans().read(3); + } + + public void setCanInstantlyBuild(boolean value) { + handle.getBooleans().write(3, value); + } + + public float getFlyingSpeed() { + return handle.getFloat().read(0); + } + + public void setFlyingSpeed(float value) { + handle.getFloat().write(0, value); + } + + public float getWalkingSpeed() { + return handle.getFloat().read(1); + } + + public void setWalkingSpeed(float value) { + handle.getFloat().write(1, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerAdvancements.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerAdvancements.java new file mode 100644 index 0000000..1bcb090 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerAdvancements.java @@ -0,0 +1,149 @@ +/** + * This file is part of PacketWrapper. + * Copyright (C) 2012-2015 Kristian S. Strangeland + * Copyright (C) 2015 dmulloy2 + * + * PacketWrapper is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PacketWrapper is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with PacketWrapper. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import java.util.Date; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.*; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.advancement.Advancement; +import org.bukkit.inventory.ItemStack; + +import static com.comphenix.protocol.utility.MinecraftReflection.getMinecraftClass; + +public class WrapperPlayServerAdvancements extends AbstractPacket { + + public static final PacketType TYPE = PacketType.Play.Server.ADVANCEMENTS; + + public WrapperPlayServerAdvancements() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerAdvancements(PacketContainer packet) { + super(packet, TYPE); + } + + public static class SerializedAdvancement { + public MinecraftKey key; + public Advancement advancement; + public AdvancementDisplay display; + public Object rewards; + public Map<String, Object> criteria; + public String[][] requirements; + } + + public static class AdvancementDisplay { + public WrappedChatComponent title; + public WrappedChatComponent description; + public ItemStack icon; + public MinecraftKey background; + public FrameType frame; + public boolean showToast; + public boolean announceToChat; + public boolean hidden; + public float xCoord; + public float yCoord; + } + + public enum FrameType { + TASK, + CHALLENGE, + GOAL + } + + public static class AdvancementProgress { + public Map<String, CriterionProgress> progress; + public String[][] array2d; + } + + public static class CriterionProgress { + public AdvancementProgress progress; + public Date date; + } + + private static final AutoWrapper<AdvancementDisplay> DISPLAY = AutoWrapper + .wrap(AdvancementDisplay.class, "AdvancementDisplay") + .field(0, BukkitConverters.getWrappedChatComponentConverter()) + .field(1, BukkitConverters.getWrappedChatComponentConverter()) + .field(2, BukkitConverters.getItemStackConverter()) + .field(3, MinecraftKey.getConverter()) + .field(4, EnumWrappers.getGenericConverter(getMinecraftClass("AdvancementFrameType"), FrameType.class)); + + private static final AutoWrapper<SerializedAdvancement> WRAPPER = AutoWrapper + .wrap(SerializedAdvancement.class,"Advancement$SerializedAdvancement") + .field(0, MinecraftKey.getConverter()) + .field(1, BukkitConverters.getAdvancementConverter()) + .field(2, DISPLAY); + + private static final AutoWrapper<CriterionProgress> CRITERION = AutoWrapper + .wrap(CriterionProgress.class, "CriterionProgress"); + + private static final AutoWrapper<AdvancementProgress> PROGRESS = AutoWrapper + .wrap(AdvancementProgress.class, "AdvancementProgress") + .field(0, BukkitConverters.getMapConverter(Converters.passthrough(String.class), CRITERION)); + + static { + CRITERION.field(0, PROGRESS); + } + + /** + * Retrieve Reset/Clear. + * <p> + * Notes: whether to reset/clear the current advancements + * @return The current Reset/Clear + */ + public boolean isReset() { + return handle.getBooleans().read(0); + } + + /** + * Set Reset/Clear. + * @param value - new value. + */ + public void setReset(boolean value) { + handle.getBooleans().write(0, value); + } + + public Optional<Map<MinecraftKey, SerializedAdvancement>> getAdvancements() { + return handle.getMaps(MinecraftKey.getConverter(), WRAPPER).optionRead(0); + } + + public void setAdvancements(Map<MinecraftKey, SerializedAdvancement> value) { + handle.getMaps(MinecraftKey.getConverter(), WRAPPER).writeSafely(0, value); + } + + public Optional<Set<MinecraftKey>> getKeys() { + return handle.getSets(MinecraftKey.getConverter()).optionRead(0); + } + + public void setKeys(Set<MinecraftKey> value) { + handle.getSets(MinecraftKey.getConverter()).writeSafely(0, value); + } + + public Optional<Map<MinecraftKey, AdvancementProgress>> getProgress() { + return handle.getMaps(MinecraftKey.getConverter(), PROGRESS).optionRead(1); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerAnimation.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerAnimation.java new file mode 100644 index 0000000..2e2e33f --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerAnimation.java @@ -0,0 +1,101 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.World; +import org.bukkit.entity.Entity; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; + +public class WrapperPlayServerAnimation extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.ANIMATION; + + public WrapperPlayServerAnimation() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerAnimation(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Entity ID. + * <p> + * Notes: entity's ID + * + * @return The current Entity ID + */ + public int getEntityID() { + return handle.getIntegers().read(0); + } + + /** + * Set Entity ID. + * + * @param value - new value. + */ + public void setEntityID(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param world - the current world of the entity. + * @return The spawned entity. + */ + public Entity getEntity(World world) { + return handle.getEntityModifier(world).read(0); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param event - the packet event. + * @return The spawned entity. + */ + public Entity getEntity(PacketEvent event) { + return getEntity(event.getPlayer().getWorld()); + } + + /** + * Retrieve Animation. + * <p> + * Notes: animation ID + * + * @return The current Animation + */ + public int getAnimation() { + return handle.getIntegers().read(1); + } + + /** + * Set Animation. + * + * @param value - new value. + */ + public void setAnimation(int value) { + handle.getIntegers().write(1, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerAttachEntity.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerAttachEntity.java new file mode 100644 index 0000000..b6d6c17 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerAttachEntity.java @@ -0,0 +1,102 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.World; +import org.bukkit.entity.Entity; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; + +public class WrapperPlayServerAttachEntity extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.ATTACH_ENTITY; + + public WrapperPlayServerAttachEntity() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerAttachEntity(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Entity ID. + * <p> + * Notes: entity's ID + * + * @return The current Entity ID + */ + public int getEntityID() { + return handle.getIntegers().read(0); + } + + /** + * Set Entity ID. + * + * @param value - new value. + */ + public WrapperPlayServerAttachEntity setEntityID(int value) { + handle.getIntegers().write(0, value); + return this; + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param world - the current world of the entity. + * @return The spawned entity. + */ + public Entity getEntity(World world) { + return handle.getEntityModifier(world).read(0); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param event - the packet event. + * @return The spawned entity. + */ + public Entity getEntity(PacketEvent event) { + return getEntity(event.getPlayer().getWorld()); + } + + /** + * Retrieve Vehicle ID. + * <p> + * Notes: vechicle's Entity ID + * + * @return The current Vehicle ID + */ + public int getVehicleId() { + return handle.getIntegers().read(1); + } + + /** + * Set Vehicle ID. + * + * @param value - new value. + */ + public WrapperPlayServerAttachEntity setVehicleId(int value) { + handle.getIntegers().write(1, value); + return this; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerAutoRecipe.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerAutoRecipe.java new file mode 100644 index 0000000..25001b4 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerAutoRecipe.java @@ -0,0 +1,55 @@ +/** + * This file is part of PacketWrapper. + * Copyright (C) 2012-2015 Kristian S. Strangeland + * Copyright (C) 2015 dmulloy2 + * + * PacketWrapper is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PacketWrapper is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with PacketWrapper. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerAutoRecipe extends AbstractPacket { + + public static final PacketType TYPE = PacketType.Play.Server.AUTO_RECIPE; + + public WrapperPlayServerAutoRecipe() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerAutoRecipe(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Window ID. + * @return The current Window ID + */ + public int getWindowId() { + return handle.getIntegers().read(0); + } + + /** + * Set Window ID. + * @param value - new value. + */ + public void setWindowId(int value) { + handle.getIntegers().write(0, value); + } + + // Wrapper for recipe can be created upon request +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerBed.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerBed.java new file mode 100644 index 0000000..928e816 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerBed.java @@ -0,0 +1,102 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.World; +import org.bukkit.entity.Entity; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.wrappers.BlockPosition; + +public class WrapperPlayServerBed extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.BED; + + public WrapperPlayServerBed() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerBed(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Entity ID. + * <p> + * Notes: entity's ID + * + * @return The current Entity ID + */ + public int getEntityID() { + return handle.getIntegers().read(0); + } + + /** + * Set Entity ID. + * + * @param value - new value. + */ + public void setEntityID(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param world - the current world of the entity. + * @return The spawned entity. + */ + public Entity getEntity(World world) { + return handle.getEntityModifier(world).read(0); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param event - the packet event. + * @return The spawned entity. + */ + public Entity getEntity(PacketEvent event) { + return getEntity(event.getPlayer().getWorld()); + } + + /** + * Retrieve Location. + * <p> + * Notes: block location of the head part of the bed + * + * @return The current Location + */ + public BlockPosition getLocation() { + return handle.getBlockPositionModifier().read(0); + } + + /** + * Set Location. + * + * @param value - new value. + */ + public void setLocation(BlockPosition value) { + handle.getBlockPositionModifier().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerBlockAction.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerBlockAction.java new file mode 100644 index 0000000..5f3c52e --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerBlockAction.java @@ -0,0 +1,120 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.Material; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.BlockPosition; + +public class WrapperPlayServerBlockAction extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.BLOCK_ACTION; + + public WrapperPlayServerBlockAction() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerBlockAction(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Location. + * <p> + * Notes: block Coordinates + * + * @return The current Location + */ + public BlockPosition getLocation() { + return handle.getBlockPositionModifier().read(0); + } + + /** + * Set Location. + * + * @param value - new value. + */ + public void setLocation(BlockPosition value) { + handle.getBlockPositionModifier().write(0, value); + } + + /** + * Retrieve Byte 1. + * <p> + * Notes: varies depending on block - see Block_Actions + * + * @return The current Byte 1 + */ + public int getByte1() { + return handle.getIntegers().read(0); + } + + /** + * Set Byte 1. + * + * @param value - new value. + */ + public void setByte1(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve Byte 2. + * <p> + * Notes: varies depending on block - see Block_Actions + * + * @return The current Byte 2 + */ + public int getByte2() { + return handle.getIntegers().read(1); + } + + /** + * Set Byte 2. + * + * @param value - new value. + */ + public void setByte2(int value) { + handle.getIntegers().write(1, value); + } + + /** + * Retrieve Block Type. + * <p> + * Notes: the block type for the block + * + * @return The current Block Type + */ + public Material getBlockType() { + return handle.getBlocks().read(0); + } + + /** + * Set Block Type. + * + * @param value - new value. + */ + public void setBlockType(Material value) { + handle.getBlocks().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerBlockBreakAnimation.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerBlockBreakAnimation.java new file mode 100644 index 0000000..6cde7b3 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerBlockBreakAnimation.java @@ -0,0 +1,123 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.World; +import org.bukkit.entity.Entity; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.wrappers.BlockPosition; + +public class WrapperPlayServerBlockBreakAnimation extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Play.Server.BLOCK_BREAK_ANIMATION; + + public WrapperPlayServerBlockBreakAnimation() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerBlockBreakAnimation(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Entity ID. + * <p> + * Notes: entity's ID + * + * @return The current Entity ID + */ + public int getEntityID() { + return handle.getIntegers().read(0); + } + + /** + * Set Entity ID. + * + * @param value - new value. + */ + public void setEntityID(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param world - the current world of the entity. + * @return The spawned entity. + */ + public Entity getEntity(World world) { + return handle.getEntityModifier(world).read(0); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param event - the packet event. + * @return The spawned entity. + */ + public Entity getEntity(PacketEvent event) { + return getEntity(event.getPlayer().getWorld()); + } + + /** + * Retrieve Location. + * <p> + * Notes: block Position + * + * @return The current Location + */ + public BlockPosition getLocation() { + return handle.getBlockPositionModifier().read(0); + } + + /** + * Set Location. + * + * @param value - new value. + */ + public void setLocation(BlockPosition value) { + handle.getBlockPositionModifier().write(0, value); + } + + /** + * Retrieve Destroy Stage. + * <p> + * Notes: 0 - 9 + * + * @return The current Destroy Stage + */ + public int getDestroyStage() { + return handle.getIntegers().read(1); + } + + /** + * Set Destroy Stage. + * + * @param value - new value. + */ + public void setDestroyStage(int value) { + handle.getIntegers().write(1, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerBlockChange.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerBlockChange.java new file mode 100644 index 0000000..8e2844b --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerBlockChange.java @@ -0,0 +1,89 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.Location; +import org.bukkit.World; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.BlockPosition; +import com.comphenix.protocol.wrappers.WrappedBlockData; + +public class WrapperPlayServerBlockChange extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.BLOCK_CHANGE; + + public WrapperPlayServerBlockChange() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerBlockChange(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Location. + * <p> + * Notes: block Coordinates + * + * @return The current Location + */ + public BlockPosition getLocation() { + return handle.getBlockPositionModifier().read(0); + } + + /** + * Set Location. + * + * @param value - new value. + */ + public void setLocation(BlockPosition value) { + handle.getBlockPositionModifier().write(0, value); + } + + /** + * Retrieve the Bukkit Location. + * + * @param world World for the location + * @return Bukkit Location + */ + public Location getBukkitLocation(World world) { + return getLocation().toVector().toLocation(world); + } + + /** + * Retrieve Block Data. + * + * @return The current Block Data + */ + public WrappedBlockData getBlockData() { + return handle.getBlockData().read(0); + } + + /** + * Set Block Data. + * + * @param value - new value. + */ + public void setBlockData(WrappedBlockData value) { + handle.getBlockData().write(0, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerBoss.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerBoss.java new file mode 100644 index 0000000..d78498d --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerBoss.java @@ -0,0 +1,134 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import java.util.UUID; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.boss.BarColor; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.WrappedChatComponent; + +public class WrapperPlayServerBoss extends AbstractPacket { + + public static final PacketType TYPE = PacketType.Play.Server.BOSS; + + public WrapperPlayServerBoss() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerBoss(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve UUID. + * <p> + * Notes: unique ID for this bar + * + * @return The current UUID + */ + public UUID getUniqueId() { + return handle.getUUIDs().read(0); + } + + /** + * Set UUID. + * + * @param value - new value. + */ + public void setUniqueId(UUID value) { + handle.getUUIDs().write(0, value); + } + + public Action getAction() { + return handle.getEnumModifier(Action.class, 1).read(0); + } + + public void setAction(Action value) { + handle.getEnumModifier(Action.class, 1).write(0, value); + } + + public WrappedChatComponent getTitle() { + return handle.getChatComponents().read(0); + } + + public void setTitle(WrappedChatComponent value) { + handle.getChatComponents().write(0, value); + } + + public float getHealth() { + return handle.getFloat().read(0); + } + + public void setHealth(float value) { + handle.getFloat().write(0, value); + } + + public BarColor getColor() { + return handle.getEnumModifier(BarColor.class, 4).read(0); + } + + public void setColor(BarColor value) { + handle.getEnumModifier(BarColor.class, 4).write(0, value); + } + + public BarStyle getStyle() { + return handle.getEnumModifier(BarStyle.class, 5).read(0); + } + + public void setStyle(BarStyle value) { + handle.getEnumModifier(BarStyle.class, 5).write(0, value); + } + + public boolean isDarkenSky() { + return handle.getBooleans().read(0); + } + + public void setDarkenSky(boolean value) { + handle.getBooleans().write(0, value); + } + + public boolean isPlayMusic() { + return handle.getBooleans().read(1); + } + + public void setPlayMusic(boolean value) { + handle.getBooleans().write(1, value); + } + + public boolean isCreateFog() { + return handle.getBooleans().read(2); + } + + public void setCreateFog(boolean value) { + handle.getBooleans().write(2, value); + } + + public static enum Action { + ADD, REMOVE, UPDATE_PCT, UPDATE_NAME, UPDATE_STYLE, UPDATE_PROPERTIES; + } + + public static enum BarStyle { + PROGRESS, NOTCHED_6, NOTCHED_10, NOTCHED_12, NOTCHED_20; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerCamera.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerCamera.java new file mode 100644 index 0000000..2d2775d --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerCamera.java @@ -0,0 +1,55 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerCamera extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.CAMERA; + + public WrapperPlayServerCamera() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerCamera(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Camera ID. + * + * @return The current Camera ID + */ + public int getCameraId() { + return handle.getIntegers().read(0); + } + + /** + * Set Camera ID. + * + * @param value - new value. + */ + public void setCameraId(int value) { + handle.getIntegers().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerChat.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerChat.java new file mode 100644 index 0000000..832169f --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerChat.java @@ -0,0 +1,101 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import java.util.Arrays; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.EnumWrappers; +import com.comphenix.protocol.wrappers.EnumWrappers.ChatType; +import com.comphenix.protocol.wrappers.WrappedChatComponent; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerChat extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.CHAT; + + public WrapperPlayServerChat() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerChat(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve the chat message. + * <p> + * Limited to 32767 bytes + * + * @return The current message + */ + public WrappedChatComponent getMessage() { + return handle.getChatComponents().read(0); + } + + /** + * Set the message. + * + * @param value - new value. + */ + public WrapperPlayServerChat setMessage(WrappedChatComponent value) { + handle.getChatComponents().write(0, value); + return this; + } + + public ChatType getChatType() { + return handle.getChatTypes().read(0); + } + + public WrapperPlayServerChat setChatType(ChatType type) { + handle.getChatTypes().write(0, type); + return this; + } + + /** + * Retrieve Position. + * <p> + * Notes: 0 - Chat (chat box) ,1 - System Message (chat box), 2 - Above + * action bar + * + * @return The current Position + * @deprecated Magic values replaced by enum + */ + @Deprecated + public byte getPosition() { + Byte position = handle.getBytes().readSafely(0); + return position != null ? position : getChatType().getId(); + } + + /** + * Set Position. + * + * @param value - new value. + * @deprecated Magic values replaced by enum + */ + @Deprecated + public WrapperPlayServerChat setPosition(byte value) { + handle.getBytes().writeSafely(0, value); + if (EnumWrappers.getChatTypeClass() != null) + Arrays.stream(ChatType.values()).filter(t -> t.getId() == value).findAny().ifPresent(t -> handle.getChatTypes().writeSafely(0, t)); + + return this; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerCloseWindow.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerCloseWindow.java new file mode 100644 index 0000000..f515842 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerCloseWindow.java @@ -0,0 +1,57 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerCloseWindow extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.CLOSE_WINDOW; + + public WrapperPlayServerCloseWindow() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerCloseWindow(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Window ID. + * <p> + * Notes: this is the id of the window that was closed. 0 for inventory. + * + * @return The current Window ID + */ + public int getWindowId() { + return handle.getIntegers().read(0); + } + + /** + * Set Window ID. + * + * @param value - new value. + */ + public void setWindowId(int value) { + handle.getIntegers().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerCollect.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerCollect.java new file mode 100644 index 0000000..b8bf75c --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerCollect.java @@ -0,0 +1,73 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerCollect extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.COLLECT; + + public WrapperPlayServerCollect() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerCollect(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Collected Entity ID. + * + * @return The current Collected Entity ID + */ + public int getCollectedEntityId() { + return handle.getIntegers().read(0); + } + + /** + * Set Collected Entity ID. + * + * @param value - new value. + */ + public void setCollectedEntityId(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve Collector Entity ID. + * + * @return The current Collector Entity ID + */ + public int getCollectorEntityId() { + return handle.getIntegers().read(1); + } + + /** + * Set Collector Entity ID. + * + * @param value - new value. + */ + public void setCollectorEntityId(int value) { + handle.getIntegers().write(1, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerCombatEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerCombatEvent.java new file mode 100644 index 0000000..5e38042 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerCombatEvent.java @@ -0,0 +1,137 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.EnumWrappers.CombatEventType; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerCombatEvent extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.COMBAT_EVENT; + + public WrapperPlayServerCombatEvent() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerCombatEvent(PacketContainer packet) { + super(packet, TYPE); + } + + // ---- All + + /** + * Retrieve Event. + * <p> + * Notes: 0 ENTER_COMBAT, 1 END_COMBAT, 2 ENTITY_DEAD + * + * @return The current Event + */ + public CombatEventType getEvent() { + return handle.getCombatEvents().read(0); + } + + /** + * Set Event. + * + * @param value - new value. + */ + public void setEvent(CombatEventType value) { + handle.getCombatEvents().write(0, value); + } + + // ---- END_COMBAT + + public int getDuration() { + if (getEvent() != CombatEventType.END_COMBAT) + throw new IllegalStateException( + "Duration only exists for END_COMBAT"); + + return handle.getIntegers().read(0); + } + + public void setDuration(int value) { + if (getEvent() != CombatEventType.END_COMBAT) + throw new IllegalStateException( + "Duration only exists for END_COMBAT"); + + handle.getIntegers().write(0, value); + } + + // ---- ENTITY_DIED + + public int getPlayerID() { + if (getEvent() != CombatEventType.ENTITY_DIED) + throw new IllegalStateException( + "Player ID only exists for ENTITY_DEAD"); + + return handle.getIntegers().read(0); + } + + public void setPlayerId(int value) { + if (getEvent() != CombatEventType.ENTITY_DIED) + throw new IllegalStateException( + "Player ID only exists for ENTITY_DEAD"); + + handle.getIntegers().write(0, value); + } + + public int getEntityID() { + CombatEventType event = getEvent(); + switch (event) { + case END_COMBAT: + case ENTITY_DIED: + return handle.getIntegers().read(1); + default: + throw new IllegalStateException("Entity ID does not exist for " + + event); + + } + } + + public void setEntityId(int value) { + CombatEventType event = getEvent(); + switch (event) { + case END_COMBAT: + case ENTITY_DIED: + handle.getIntegers().write(1, value); + default: + throw new IllegalStateException("Entity ID does not exist for " + + event); + + } + } + + public String getMessage() { + if (getEvent() != CombatEventType.ENTITY_DIED) + throw new IllegalStateException( + "Message only exists for ENTITY_DEAD"); + + return handle.getStrings().read(0); + } + + public void setMessage(String value) { + if (getEvent() != CombatEventType.ENTITY_DIED) + throw new IllegalStateException( + "Message only exists for ENTITY_DEAD"); + + handle.getStrings().write(0, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerCustomPayload.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerCustomPayload.java new file mode 100644 index 0000000..4c652f0 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerCustomPayload.java @@ -0,0 +1,104 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.utility.MinecraftReflection; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerCustomPayload extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.CUSTOM_PAYLOAD; + + public WrapperPlayServerCustomPayload() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerCustomPayload(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Channel. + * <p> + * Notes: name of the "channel" used to send the data. + * + * @return The current Channel + */ + public String getChannel() { + return handle.getStrings().read(0); + } + + /** + * Set Channel. + * + * @param value - new value. + */ + public void setChannel(String value) { + handle.getStrings().write(0, value); + } + + /** + * Retrieve payload contents as a raw Netty buffer + * + * @return Payload contents as a Netty buffer + */ + public ByteBuf getContentsBuffer() { + return (ByteBuf) handle.getModifier().withType(ByteBuf.class).read(0); + } + + /** + * Retrieve payload contents + * + * @return Payload contents as a byte array + */ + public byte[] getContents() { + ByteBuf buffer = getContentsBuffer(); + byte[] array = new byte[buffer.readableBytes()]; + buffer.readBytes(array); + return array; + } + + /** + * Update payload contents with a Netty buffer + * + * @param contents - new payload content + */ + public void setContentsBuffer(ByteBuf contents) { + if (MinecraftReflection.is(MinecraftReflection.getPacketDataSerializerClass(), contents)) { + handle.getModifier().withType(ByteBuf.class).write(0, contents); + } else { + Object serializer = MinecraftReflection.getPacketDataSerializer(contents); + handle.getModifier().withType(ByteBuf.class).write(0, serializer); + } + } + + /** + * Update payload contents with a byte array + * + * @param content - new payload content + */ + public void setContents(byte[] content) { + setContentsBuffer(Unpooled.copiedBuffer(content)); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerCustomSoundEffect.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerCustomSoundEffect.java new file mode 100644 index 0000000..ad0747c --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerCustomSoundEffect.java @@ -0,0 +1,183 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.EnumWrappers.SoundCategory; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerCustomSoundEffect extends AbstractPacket { + + public static final PacketType TYPE = + PacketType.Play.Server.CUSTOM_SOUND_EFFECT; + + public WrapperPlayServerCustomSoundEffect() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerCustomSoundEffect(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Sound Name. + * <p> + * Notes: all known sound effect names can be seen here. + * + * @return The current Sound Name + */ + public String getSoundName() { + return handle.getStrings().read(0); + } + + /** + * Set Sound Name. + * + * @param value - new value. + */ + public void setSoundName(String value) { + handle.getStrings().write(0, value); + } + + /** + * Retrieve Sound Category. + * <p> + * Notes: the category that this sound will be played from (current + * categories) + * + * @return The current Sound Category + */ + public SoundCategory getSoundCategory() { + return handle.getSoundCategories().read(0); + } + + /** + * Set Sound Category. + * + * @param value - new value. + */ + public void setSoundCategory(SoundCategory value) { + handle.getSoundCategories().write(0, value); + } + + /** + * Retrieve Effect Position X. + * <p> + * Notes: effect X multiplied by 8 (fixed-point number with only 3 bits + * dedicated to the fractional part) + * + * @return The current Effect Position X + */ + public int getX() { + return handle.getIntegers().read(0); + } + + /** + * Set Effect Position X. + * + * @param value - new value. + */ + public void setX(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve Effect Position Y. + * <p> + * Notes: effect Y multiplied by 8 (fixed-point number with only 3 bits + * dedicated to the fractional part) + * + * @return The current Effect Position Y + */ + public int getY() { + return handle.getIntegers().read(1); + } + + /** + * Set Effect Position Y. + * + * @param value - new value. + */ + public void setY(int value) { + handle.getIntegers().write(1, value); + } + + /** + * Retrieve Effect Position Z. + * <p> + * Notes: effect Z multiplied by 8 (fixed-point number with only 3 bits + * dedicated to the fractional part) + * + * @return The current Effect Position Z + */ + public int getZ() { + return handle.getIntegers().read(2); + } + + /** + * Set Effect Position Z. + * + * @param value - new value. + */ + public void setZ(int value) { + handle.getIntegers().write(2, value); + } + + /** + * Retrieve Volume. + * <p> + * Notes: 1 is 100%, can be more + * + * @return The current Volume + */ + public float getVolume() { + return handle.getFloat().read(0); + } + + /** + * Set Volume. + * + * @param value - new value. + */ + public void setVolume(float value) { + handle.getFloat().write(0, value); + } + + /** + * Retrieve Pitch. + * <p> + * Notes: 63 is 100%, can be more + * + * @return The current Pitch + */ + public float getPitch() { + return handle.getFloat().read(1); + } + + /** + * Set Pitch. + * + * @param value - new value. + */ + public void setPitch(float value) { + handle.getFloat().write(1, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerEntity.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerEntity.java new file mode 100644 index 0000000..11b7820 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerEntity.java @@ -0,0 +1,80 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.World; +import org.bukkit.entity.Entity; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; + +public class WrapperPlayServerEntity extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.ENTITY; + + public WrapperPlayServerEntity() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerEntity(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Entity ID. + * <p> + * Notes: entity's ID + * + * @return The current Entity ID + */ + public int getEntityID() { + return handle.getIntegers().read(0); + } + + /** + * Set Entity ID. + * + * @param value - new value. + */ + public void setEntityID(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param world - the current world of the entity. + * @return The spawned entity. + */ + public Entity getEntity(World world) { + return handle.getEntityModifier(world).read(0); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param event - the packet event. + * @return The spawned entity. + */ + public Entity getEntity(PacketEvent event) { + return getEntity(event.getPlayer().getWorld()); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerEntityDestroy.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerEntityDestroy.java new file mode 100644 index 0000000..cae29f2 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerEntityDestroy.java @@ -0,0 +1,78 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerEntityDestroy extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.ENTITY_DESTROY; + + public WrapperPlayServerEntityDestroy() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerEntityDestroy(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Count. + * <p> + * Notes: length of following array + * + * @return The current Count + */ + public int getCount() { + return handle.getIntegerArrays().read(0).length; + } + + /** + * Retrieve Entity IDs. + * <p> + * Notes: the list of entities of destroy + * + * @return The current Entity IDs + */ + public int[] getEntityIDs() { + return handle.getIntegerArrays().read(0); + } + + /** + * Set Entity IDs. + * + * @param value - new value. + */ + public WrapperPlayServerEntityDestroy setEntityIds(int[] value) { + handle.getIntegerArrays().write(0, value); + return this; + } + + /** + * Set Entity IDs. + * + * @param value - new value. + */ + public WrapperPlayServerEntityDestroy setEntityId(int... value) { + handle.getIntegerArrays().write(0, value); + return this; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerEntityEffect.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerEntityEffect.java new file mode 100644 index 0000000..ca68070 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerEntityEffect.java @@ -0,0 +1,155 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.World; +import org.bukkit.entity.Entity; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; + +public class WrapperPlayServerEntityEffect extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.ENTITY_EFFECT; + + public WrapperPlayServerEntityEffect() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerEntityEffect(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Entity ID. + * <p> + * Notes: entity's ID + * + * @return The current Entity ID + */ + public int getEntityID() { + return handle.getIntegers().read(0); + } + + /** + * Set Entity ID. + * + * @param value - new value. + */ + public void setEntityID(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param world - the current world of the entity. + * @return The spawned entity. + */ + public Entity getEntity(World world) { + return handle.getEntityModifier(world).read(0); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param event - the packet event. + * @return The spawned entity. + */ + public Entity getEntity(PacketEvent event) { + return getEntity(event.getPlayer().getWorld()); + } + + /** + * Retrieve Effect ID. + * <p> + * Notes: see [[1]] + * + * @return The current Effect ID + */ + public byte getEffectID() { + return handle.getBytes().read(0); + } + + /** + * Set Effect ID. + * + * @param value - new value. + */ + public void setEffectID(byte value) { + handle.getBytes().write(0, (byte) (value & 255)); + } + + /** + * Retrieve Amplifier. + * + * @return The current Amplifier + */ + public byte getAmplifier() { + return handle.getBytes().read(1); + } + + /** + * Set Amplifier. + * + * @param value - new value. + */ + public void setAmplifier(byte value) { + handle.getBytes().write(1, (byte) (value & 255)); + } + + /** + * Retrieve Duration. + * + * @return The current Duration + */ + public int getDuration() { + return handle.getIntegers().read(1); + } + + /** + * Set Duration. + * + * @param value - new value. + */ + public void setDuration(int value) { + handle.getIntegers().write(1, value); + } + + /** + * Retrieve Hide Particles. + * + * @return The current Hide Particles + */ + public boolean getHideParticles() { + return handle.getBytes().read(2) == 0; + } + + /** + * Set Hide Particles. + * + * @param value - new value. + */ + public void setHideParticles(boolean value) { + handle.getBytes().write(2, (byte) (value ? 0 : 1)); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerEntityEquipment.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerEntityEquipment.java new file mode 100644 index 0000000..90f7697 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerEntityEquipment.java @@ -0,0 +1,111 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.inventory.ItemStack; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.wrappers.EnumWrappers.ItemSlot; + +public class WrapperPlayServerEntityEquipment extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Play.Server.ENTITY_EQUIPMENT; + + public WrapperPlayServerEntityEquipment() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerEntityEquipment(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Entity ID. + * <p> + * Notes: entity's ID + * + * @return The current Entity ID + */ + public int getEntityID() { + return handle.getIntegers().read(0); + } + + /** + * Set Entity ID. + * + * @param value - new value. + */ + public void setEntityID(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param world - the current world of the entity. + * @return The spawned entity. + */ + public Entity getEntity(World world) { + return handle.getEntityModifier(world).read(0); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param event - the packet event. + * @return The spawned entity. + */ + public Entity getEntity(PacketEvent event) { + return getEntity(event.getPlayer().getWorld()); + } + + public ItemSlot getSlot() { + return handle.getItemSlots().read(0); + } + + public void setSlot(ItemSlot value) { + handle.getItemSlots().write(0, value); + } + + /** + * Retrieve Item. + * <p> + * Notes: item in slot format + * + * @return The current Item + */ + public ItemStack getItem() { + return handle.getItemModifier().read(0); + } + + /** + * Set Item. + * + * @param value - new value. + */ + public void setItem(ItemStack value) { + handle.getItemModifier().write(0, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerEntityHeadRotation.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerEntityHeadRotation.java new file mode 100644 index 0000000..93890c4 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerEntityHeadRotation.java @@ -0,0 +1,101 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.World; +import org.bukkit.entity.Entity; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; + +public class WrapperPlayServerEntityHeadRotation extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Play.Server.ENTITY_HEAD_ROTATION; + + public WrapperPlayServerEntityHeadRotation() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerEntityHeadRotation(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Entity ID. + * <p> + * Notes: entity's ID + * + * @return The current Entity ID + */ + public int getEntityID() { + return handle.getIntegers().read(0); + } + + /** + * Set Entity ID. + * + * @param value - new value. + */ + public void setEntityID(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param world - the current world of the entity. + * @return The spawned entity. + */ + public Entity getEntity(World world) { + return handle.getEntityModifier(world).read(0); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param event - the packet event. + * @return The spawned entity. + */ + public Entity getEntity(PacketEvent event) { + return getEntity(event.getPlayer().getWorld()); + } + + /** + * Retrieve Head Yaw. + * <p> + * Notes: head yaw in steps of 2p/256 + * + * @return The current Head Yaw + */ + public byte getHeadYaw() { + return handle.getBytes().read(0); + } + + /** + * Set Head Yaw. + * + * @param value - new value. + */ + public void setHeadYaw(byte value) { + handle.getBytes().write(0, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerEntityLook.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerEntityLook.java new file mode 100644 index 0000000..ebc6ad9 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerEntityLook.java @@ -0,0 +1,134 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.World; +import org.bukkit.entity.Entity; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; + +public class WrapperPlayServerEntityLook extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.ENTITY_LOOK; + + public WrapperPlayServerEntityLook() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerEntityLook(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Entity ID. + * <p> + * Notes: entity's ID + * + * @return The current Entity ID + */ + public int getEntityID() { + return handle.getIntegers().read(0); + } + + /** + * Set Entity ID. + * + * @param value - new value. + */ + public void setEntityID(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param world - the current world of the entity. + * @return The spawned entity. + */ + public Entity getEntity(World world) { + return handle.getEntityModifier(world).read(0); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param event - the packet event. + * @return The spawned entity. + */ + public Entity getEntity(PacketEvent event) { + return getEntity(event.getPlayer().getWorld()); + } + + /** + * Retrieve the yaw of the current entity. + * + * @return The current Yaw + */ + public float getYaw() { + return (handle.getBytes().read(0) * 360.F) / 256.0F; + } + + /** + * Set the yaw of the current entity. + * + * @param value - new yaw. + */ + public void setYaw(float value) { + handle.getBytes().write(0, (byte) (value * 256.0F / 360.0F)); + } + + /** + * Retrieve the pitch of the current entity. + * + * @return The current pitch + */ + public float getPitch() { + return (handle.getBytes().read(1) * 360.F) / 256.0F; + } + + /** + * Set the pitch of the current entity. + * + * @param value - new pitch. + */ + public void setPitch(float value) { + handle.getBytes().write(1, (byte) (value * 256.0F / 360.0F)); + } + + /** + * Retrieve On Ground. + * + * @return The current On Ground + */ + public boolean getOnGround() { + return handle.getBooleans().read(0); + } + + /** + * Set On Ground. + * + * @param value - new value. + */ + public void setOnGround(boolean value) { + handle.getBooleans().write(0, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerEntityMetadata.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerEntityMetadata.java new file mode 100644 index 0000000..ca4e4e1 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerEntityMetadata.java @@ -0,0 +1,102 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import java.util.List; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.World; +import org.bukkit.entity.Entity; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.wrappers.WrappedWatchableObject; + +public class WrapperPlayServerEntityMetadata extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Play.Server.ENTITY_METADATA; + + public WrapperPlayServerEntityMetadata() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerEntityMetadata(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Entity ID. + * <p> + * Notes: entity's ID + * + * @return The current Entity ID + */ + public int getEntityID() { + return handle.getIntegers().read(0); + } + + /** + * Set Entity ID. + * + * @param value - new value. + */ + public void setEntityID(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param world - the current world of the entity. + * @return The spawned entity. + */ + public Entity getEntity(World world) { + return handle.getEntityModifier(world).read(0); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param event - the packet event. + * @return The spawned entity. + */ + public Entity getEntity(PacketEvent event) { + return getEntity(event.getPlayer().getWorld()); + } + + /** + * Retrieve Metadata. + * + * @return The current Metadata + */ + public List<WrappedWatchableObject> getMetadata() { + return handle.getWatchableCollectionModifier().read(0); + } + + /** + * Set Metadata. + * + * @param value - new value. + */ + public void setMetadata(List<WrappedWatchableObject> value) { + handle.getWatchableCollectionModifier().write(0, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerEntityStatus.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerEntityStatus.java new file mode 100644 index 0000000..ad0d88b --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerEntityStatus.java @@ -0,0 +1,100 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.World; +import org.bukkit.entity.Entity; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; + +public class WrapperPlayServerEntityStatus extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.ENTITY_STATUS; + + public WrapperPlayServerEntityStatus() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerEntityStatus(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Entity ID. + * <p> + * Notes: entity's ID + * + * @return The current Entity ID + */ + public int getEntityID() { + return handle.getIntegers().read(0); + } + + /** + * Set Entity ID. + * + * @param value - new value. + */ + public void setEntityID(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param world - the current world of the entity. + * @return The spawned entity. + */ + public Entity getEntity(World world) { + return handle.getEntityModifier(world).read(0); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param event - the packet event. + * @return The spawned entity. + */ + public Entity getEntity(PacketEvent event) { + return getEntity(event.getPlayer().getWorld()); + } + + /** + * Retrieve Entity Status. + * <p> + * Notes: see below + * + * @return The current Entity Status + */ + public byte getEntityStatus() { + return handle.getBytes().read(0); + } + + /** + * Set Entity Status. + * + * @param value - new value. + */ + public void setEntityStatus(byte value) { + handle.getBytes().write(0, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerEntityTeleport.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerEntityTeleport.java new file mode 100644 index 0000000..8a6f2ac --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerEntityTeleport.java @@ -0,0 +1,147 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.World; +import org.bukkit.entity.Entity; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; + +public class WrapperPlayServerEntityTeleport extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Play.Server.ENTITY_TELEPORT; + + public WrapperPlayServerEntityTeleport() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerEntityTeleport(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve entity ID. + * + * @return The current EID + */ + public int getEntityID() { + return handle.getIntegers().read(0); + } + + /** + * Set entity ID. + * + * @param value - new value. + */ + public void setEntityID(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve the entity. + * + * @param world - the current world of the entity. + * @return The entity. + */ + public Entity getEntity(World world) { + return handle.getEntityModifier(world).read(0); + } + + /** + * Retrieve the entity. + * + * @param event - the packet event. + * @return The entity. + */ + public Entity getEntity(PacketEvent event) { + return getEntity(event.getPlayer().getWorld()); + } + + public double getX() { + return handle.getDoubles().read(0); + } + + public void setX(double value) { + handle.getDoubles().write(0, value); + } + + public double getY() { + return handle.getDoubles().read(1); + } + + public void setY(double value) { + handle.getDoubles().write(1, value); + } + + public double getZ() { + return handle.getDoubles().read(2); + } + + public void setZ(double value) { + handle.getDoubles().write(2, value); + } + + /** + * Retrieve the yaw of the current entity. + * + * @return The current Yaw + */ + public float getYaw() { + return (handle.getBytes().read(0) * 360.F) / 256.0F; + } + + /** + * Set the yaw of the current entity. + * + * @param value - new yaw. + */ + public void setYaw(float value) { + handle.getBytes().write(0, (byte) (value * 256.0F / 360.0F)); + } + + /** + * Retrieve the pitch of the current entity. + * + * @return The current pitch + */ + public float getPitch() { + return (handle.getBytes().read(1) * 360.F) / 256.0F; + } + + /** + * Set the pitch of the current entity. + * + * @param value - new pitch. + */ + public void setPitch(float value) { + handle.getBytes().write(1, (byte) (value * 256.0F / 360.0F)); + } + + public boolean getOnGround() { + return handle.getBooleans().read(0); + } + + public void setOnGround(boolean value) { + handle.getBooleans().write(0, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerEntityVelocity.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerEntityVelocity.java new file mode 100644 index 0000000..edf1785 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerEntityVelocity.java @@ -0,0 +1,135 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.World; +import org.bukkit.entity.Entity; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; + +public class WrapperPlayServerEntityVelocity extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Play.Server.ENTITY_VELOCITY; + + public WrapperPlayServerEntityVelocity() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerEntityVelocity(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Entity ID. + * <p> + * Notes: entity's ID + * + * @return The current Entity ID + */ + public int getEntityID() { + return handle.getIntegers().read(0); + } + + /** + * Set Entity ID. + * + * @param value - new value. + */ + public void setEntityID(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param world - the current world of the entity. + * @return The spawned entity. + */ + public Entity getEntity(World world) { + return handle.getEntityModifier(world).read(0); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param event - the packet event. + * @return The spawned entity. + */ + public Entity getEntity(PacketEvent event) { + return getEntity(event.getPlayer().getWorld()); + } + + /** + * Retrieve the velocity in the x axis. + * + * @return The current velocity X + */ + public double getVelocityX() { + return handle.getIntegers().read(1) / 8000.0D; + } + + /** + * Set the velocity in the x axis. + * + * @param value - new value. + */ + public void setVelocityX(double value) { + handle.getIntegers().write(1, (int) (value * 8000.0D)); + } + + /** + * Retrieve the velocity in the y axis. + * + * @return The current velocity y + */ + public double getVelocityY() { + return handle.getIntegers().read(2) / 8000.0D; + } + + /** + * Set the velocity in the y axis. + * + * @param value - new value. + */ + public void setVelocityY(double value) { + handle.getIntegers().write(2, (int) (value * 8000.0D)); + } + + /** + * Retrieve the velocity in the z axis. + * + * @return The current velocity z + */ + public double getVelocityZ() { + return handle.getIntegers().read(3) / 8000.0D; + } + + /** + * Set the velocity in the z axis. + * + * @param value - new value. + */ + public void setVelocityZ(double value) { + handle.getIntegers().write(3, (int) (value * 8000.0D)); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerExperience.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerExperience.java new file mode 100644 index 0000000..b5b7d83 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerExperience.java @@ -0,0 +1,93 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerExperience extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.EXPERIENCE; + + public WrapperPlayServerExperience() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerExperience(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Experience bar. + * <p> + * Notes: between 0 and 1 + * + * @return The current Experience bar + */ + public float getExperienceBar() { + return handle.getFloat().read(0); + } + + /** + * Set Experience bar. + * + * @param value - new value. + */ + public void setExperienceBar(float value) { + handle.getFloat().write(0, value); + } + + /** + * Retrieve Level. + * + * @return The current Level + */ + public int getLevel() { + return handle.getIntegers().read(1); + } + + /** + * Set Level. + * + * @param value - new value. + */ + public void setLevel(int value) { + handle.getIntegers().write(1, value); + } + + /** + * Retrieve Total Experience. + * + * @return The current Total Experience + */ + public int getTotalExperience() { + return handle.getIntegers().read(0); + } + + /** + * Set Total Experience. + * + * @param value - new value. + */ + public void setTotalExperience(int value) { + handle.getIntegers().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerExplosion.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerExplosion.java new file mode 100644 index 0000000..2ac9383 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerExplosion.java @@ -0,0 +1,158 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import java.util.List; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.BlockPosition; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerExplosion extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.EXPLOSION; + + public WrapperPlayServerExplosion() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerExplosion(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve X. + * + * @return The current X + */ + public double getX() { + return handle.getDoubles().read(0); + } + + /** + * Set X. + * + * @param value - new value. + */ + public void setX(double value) { + handle.getDoubles().write(0, value); + } + + /** + * Retrieve Y. + * + * @return The current Y + */ + public double getY() { + return handle.getDoubles().read(1); + } + + /** + * Set Y. + * + * @param value - new value. + */ + public void setY(double value) { + handle.getDoubles().write(1, value); + } + + /** + * Retrieve Z. + * + * @return The current Z + */ + public double getZ() { + return handle.getDoubles().read(2); + } + + /** + * Set Z. + * + * @param value - new value. + */ + public void setZ(double value) { + handle.getDoubles().write(2, value); + } + + /** + * Retrieve Radius. + * <p> + * Notes: currently unused in the client + * + * @return The current Radius + */ + public float getRadius() { + return handle.getFloat().read(0); + } + + /** + * Set Radius. + * + * @param value - new value. + */ + public void setRadius(float value) { + handle.getFloat().write(0, value); + } + + /** + * Retrieve Record count. + * <p> + * Notes: this is the count, not the size. The size is 3 times this value. + * + * @return The current Record count + */ + public List<BlockPosition> getRecors() { + return handle.getBlockPositionCollectionModifier().read(0); + } + + /** + * Set Record count. + * + * @param value - new value. + */ + public void setRecords(List<BlockPosition> value) { + handle.getBlockPositionCollectionModifier().write(0, value); + } + + public float getPlayerVelocityX() { + return handle.getFloat().read(0); + } + + public void setPlayerVelocityX(float value) { + handle.getFloat().write(0, value); + } + + public float getPlayerVelocityY() { + return handle.getFloat().read(1); + } + + public void setPlayerVelocityY(float value) { + handle.getFloat().write(1, value); + } + + public float getPlayerVelocityZ() { + return handle.getFloat().read(2); + } + + public void setPlayerVelocityZ(float value) { + handle.getFloat().write(2, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerGameStateChange.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerGameStateChange.java new file mode 100644 index 0000000..c9aba4f --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerGameStateChange.java @@ -0,0 +1,76 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerGameStateChange extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Play.Server.GAME_STATE_CHANGE; + + public WrapperPlayServerGameStateChange() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerGameStateChange(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Reason. + * + * @return The current Reason + */ + public int getReason() { + return handle.getIntegers().read(0); + } + + /** + * Set Reason. + * + * @param value - new value. + */ + public void setReason(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve Value. + * <p> + * Notes: depends on reason + * + * @return The current Value + */ + public float getValue() { + return handle.getFloat().read(0); + } + + /** + * Set Value. + * + * @param value - new value. + */ + public void setValue(float value) { + handle.getFloat().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerHeldItemSlot.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerHeldItemSlot.java new file mode 100644 index 0000000..fc3e715 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerHeldItemSlot.java @@ -0,0 +1,57 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerHeldItemSlot extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.HELD_ITEM_SLOT; + + public WrapperPlayServerHeldItemSlot() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerHeldItemSlot(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Slot. + * <p> + * Notes: the slot which the player has selected (0-8) + * + * @return The current Slot + */ + public int getSlot() { + return handle.getIntegers().read(0); + } + + /** + * Set Slot. + * + * @param value - new value. + */ + public void setSlot(int value) { + handle.getIntegers().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerKeepAlive.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerKeepAlive.java new file mode 100644 index 0000000..72fb793 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerKeepAlive.java @@ -0,0 +1,55 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerKeepAlive extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.KEEP_ALIVE; + + public WrapperPlayServerKeepAlive() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerKeepAlive(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Keep Alive ID. + * + * @return The current Keep Alive ID + */ + public int getKeepAliveId() { + return handle.getIntegers().read(0); + } + + /** + * Set Keep Alive ID. + * + * @param value - new value. + */ + public void setKeepAliveId(int value) { + handle.getIntegers().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerKickDisconnect.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerKickDisconnect.java new file mode 100644 index 0000000..92b548a --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerKickDisconnect.java @@ -0,0 +1,60 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.WrappedChatComponent; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerKickDisconnect extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Play.Server.KICK_DISCONNECT; + + public WrapperPlayServerKickDisconnect() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerKickDisconnect(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Reason. + * <p> + * Notes: displayed to the client when the connection terminates. Must be + * valid JSON. + * + * @return The current Reason + */ + public WrappedChatComponent getReason() { + return handle.getChatComponents().read(0); + } + + /** + * Set Reason. + * + * @param value - new value. + */ + public void setReason(WrappedChatComponent value) { + handle.getChatComponents().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerLogin.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerLogin.java new file mode 100644 index 0000000..660aeb9 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerLogin.java @@ -0,0 +1,202 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.World; +import org.bukkit.WorldType; +import org.bukkit.entity.Entity; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.wrappers.EnumWrappers.Difficulty; +import com.comphenix.protocol.wrappers.EnumWrappers.NativeGameMode; + +public class WrapperPlayServerLogin extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.LOGIN; + + public WrapperPlayServerLogin() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerLogin(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Entity ID. + * <p> + * Notes: entity's ID + * + * @return The current Entity ID + */ + public int getEntityID() { + return handle.getIntegers().read(0); + } + + /** + * Set Entity ID. + * + * @param value - new value. + */ + public void setEntityID(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param world - the current world of the entity. + * @return The spawned entity. + */ + public Entity getEntity(World world) { + return handle.getEntityModifier(world).read(0); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param event - the packet event. + * @return The spawned entity. + */ + public Entity getEntity(PacketEvent event) { + return getEntity(event.getPlayer().getWorld()); + } + + /** + * Retrieve Gamemode. + * <p> + * Notes: 0: survival, 1: creative, 2: adventure. Bit 3 (0x8) is the + * hardcore flag + * + * @return The current Gamemode + */ + public NativeGameMode getGamemode() { + return handle.getGameModes().read(0); + } + + /** + * Set Gamemode. + * + * @param value - new value. + */ + public void setGamemode(NativeGameMode value) { + handle.getGameModes().write(0, value); + } + + /** + * Retrieve Dimension. + * <p> + * Notes: -1: nether, 0: overworld, 1: end + * + * @return The current Dimension + */ + public int getDimension() { + return handle.getIntegers().read(0); + } + + /** + * Set Dimension. + * + * @param value - new value. + */ + public void setDimension(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve Difficulty. + * <p> + * Notes: 0 thru 3 for Peaceful, Easy, Normal, Hard + * + * @return The current Difficulty + */ + public Difficulty getDifficulty() { + return handle.getDifficulties().read(0); + } + + /** + * Set Difficulty. + * + * @param value - new value. + */ + public void setDifficulty(Difficulty value) { + handle.getDifficulties().write(0, value); + } + + /** + * Retrieve Max Players. + * <p> + * Notes: used by the client to draw the player list + * + * @return The current Max Players + */ + public int getMaxPlayers() { + return handle.getIntegers().read(1); + } + + /** + * Set Max Players. + * + * @param value - new value. + */ + public void setMaxPlayers(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve Level Type. + * <p> + * Notes: default, flat, largeBiomes, amplified, default_1_1 + * + * @return The current Level Type + */ + public WorldType getLevelType() { + return handle.getWorldTypeModifier().read(0); + } + + /** + * Set Level Type. + * + * @param value - new value. + */ + public void setLevelType(WorldType value) { + handle.getWorldTypeModifier().write(0, value); + } + + /** + * Retrieve Reduced Debug Info. + * + * @return The current Reduced Debug Info + */ + public boolean getReducedDebugInfo() { + return handle.getBooleans().read(0); + } + + /** + * Set Reduced Debug Info. + * + * @param value - new value. + */ + public void setReducedDebugInfo(boolean value) { + handle.getBooleans().write(0, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerMap.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerMap.java new file mode 100644 index 0000000..b945957 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerMap.java @@ -0,0 +1,130 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerMap extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.MAP; + + public WrapperPlayServerMap() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerMap(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Item Damage. + * <p> + * Notes: the damage value of the map being modified + * + * @return The current Item Damage + */ + public int getItemDamage() { + return handle.getIntegers().read(0); + } + + /** + * Set Item Damage. + * + * @param value - new value. + */ + public void setItemDamage(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve Scale. + * + * @return The current Scale + */ + public byte getScale() { + return handle.getBytes().read(0); + } + + /** + * Set Scale. + * + * @param value - new value. + */ + public void setScale(byte value) { + handle.getBytes().write(0, value); + } + + public boolean getTrackingPosition() { + return handle.getBooleans().read(0); + } + + public void setTrackingPosition(boolean value) { + handle.getBooleans().write(0, value); + } + + public Object[] getMapIcons() { + return (Object[]) handle.getModifier().read(3); + } + + public void setMapIcons(Object[] value) { + handle.getModifier().write(3, value); + } + + public int getColumns() { + return handle.getIntegers().read(3); + } + + public void setColumns(int value) { + handle.getIntegers().write(3, value); + } + + public int getRows() { + return handle.getIntegers().read(4); + } + + public void setRows(int value) { + handle.getIntegers().write(4, value); + } + + public int getX() { + return handle.getIntegers().read(1); + } + + public void setX(int value) { + handle.getIntegers().write(1, value); + } + + public int getZ() { + return handle.getIntegers().read(2); + } + + public void setZ(int value) { + handle.getIntegers().write(2, value); + } + + public byte[] getData() { + return handle.getByteArrays().read(0); + } + + public void setData(byte[] value) { + handle.getByteArrays().write(0, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerMapChunk.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerMapChunk.java new file mode 100644 index 0000000..7462228 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerMapChunk.java @@ -0,0 +1,106 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerMapChunk extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.MAP_CHUNK; + + public WrapperPlayServerMapChunk() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerMapChunk(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Chunk X. + * <p> + * Notes: chunk X coordinate + * + * @return The current Chunk X + */ + public int getChunkX() { + return handle.getIntegers().read(0); + } + + /** + * Set Chunk X. + * + * @param value - new value. + */ + public void setChunkX(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve Chunk Z. + * <p> + * Notes: chunk Z coordinate + * + * @return The current Chunk Z + */ + public int getChunkZ() { + return handle.getIntegers().read(1); + } + + /** + * Set Chunk Z. + * + * @param value - new value. + */ + public void setChunkZ(int value) { + handle.getIntegers().write(1, value); + } + + public Object getChunkMap() { + return handle.getModifier().read(2); + } + + public void setChunkMap(Object value) { + handle.getModifier().write(2, value); + } + + /** + * Retrieve Ground-Up continuous. + * <p> + * Notes: this is True if the packet represents all sections in this + * vertical column, where the primary bit map specifies exactly which + * sections are included, and which are air + * + * @return The current Ground-Up continuous + */ + public boolean getGroundUpContinuous() { + return handle.getBooleans().read(0); + } + + /** + * Set Ground-Up continuous. + * + * @param value - new value. + */ + public void setGroundUpContinuous(boolean value) { + handle.getBooleans().write(0, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerMount.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerMount.java new file mode 100644 index 0000000..90229ad --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerMount.java @@ -0,0 +1,125 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import java.util.ArrayList; +import java.util.List; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.World; +import org.bukkit.entity.Entity; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.ProtocolManager; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; + +public class WrapperPlayServerMount extends AbstractPacket { + + public static final PacketType TYPE = PacketType.Play.Server.MOUNT; + + public WrapperPlayServerMount() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerMount(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Entity ID. + * <p> + * Notes: vehicle's EID + * + * @return The current Entity ID + */ + public int getEntityID() { + return handle.getIntegers().read(0); + } + + /** + * Retrieve the entity involved in this event. + * + * @param world - the current world of the entity. + * @return The involved entity. + */ + public Entity getEntity(World world) { + return handle.getEntityModifier(world).read(0); + } + + /** + * Retrieve the entity involved in this event. + * + * @param event - the packet event. + * @return The involved entity. + */ + public Entity getEntity(PacketEvent event) { + return getEntity(event.getPlayer().getWorld()); + } + + /** + * Set Entity ID. + * + * @param value - new value. + */ + public WrapperPlayServerMount setEntityID(int value) { + handle.getIntegers().write(0, value); + return this; + } + + public int[] getPassengerIds() { + return handle.getIntegerArrays().read(0); + } + + public WrapperPlayServerMount setPassengerIds(int[] value) { + handle.getIntegerArrays().write(0, value); + return this; + } + + public List<Entity> getPassengers(PacketEvent event) { + return getPassengers(event.getPlayer().getWorld()); + } + + public List<Entity> getPassengers(World world) { + int[] ids = getPassengerIds(); + List<Entity> passengers = new ArrayList<>(); + ProtocolManager manager = ProtocolLibrary.getProtocolManager(); + + for (int id : ids) { + Entity entity = manager.getEntityFromID(world, id); + if (entity != null) { + passengers.add(entity); + } + } + + return passengers; + } + + public WrapperPlayServerMount setPassengers(List<Entity> value) { + int[] array = new int[value.size()]; + for (int i = 0; i < value.size(); i++) { + array[i] = value.get(i).getEntityId(); + } + + setPassengerIds(array); + return this; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerMultiBlockChange.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerMultiBlockChange.java new file mode 100644 index 0000000..15a6b2a --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerMultiBlockChange.java @@ -0,0 +1,75 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.ChunkCoordIntPair; +import com.comphenix.protocol.wrappers.MultiBlockChangeInfo; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerMultiBlockChange extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Play.Server.MULTI_BLOCK_CHANGE; + + public WrapperPlayServerMultiBlockChange() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerMultiBlockChange(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve the chunk that has been altered. + * + * @return The current chunk + */ + public ChunkCoordIntPair getChunk() { + return handle.getChunkCoordIntPairs().read(0); + } + + /** + * Set the chunk that has been altered. + * + * @param value - new value + */ + public void setChunk(ChunkCoordIntPair value) { + handle.getChunkCoordIntPairs().write(0, value); + } + + /** + * Retrieve a copy of the record data as a block change array. + * + * @return The copied block change array. + */ + public MultiBlockChangeInfo[] getRecords() { + return handle.getMultiBlockChangeInfoArrays().read(0); + } + + /** + * Set the record data using the given helper array. + * + * @param value - new value + */ + public void setRecords(MultiBlockChangeInfo[] value) { + handle.getMultiBlockChangeInfoArrays().write(0, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerNamedEntitySpawn.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerNamedEntitySpawn.java new file mode 100644 index 0000000..9808e7d --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerNamedEntitySpawn.java @@ -0,0 +1,205 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import java.util.UUID; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.util.Vector; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.wrappers.WrappedDataWatcher; + +public class WrapperPlayServerNamedEntitySpawn extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Play.Server.NAMED_ENTITY_SPAWN; + + public WrapperPlayServerNamedEntitySpawn() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerNamedEntitySpawn(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Entity ID. + * <p> + * Notes: entity's ID + * + * @return The current Entity ID + */ + public int getEntityID() { + return handle.getIntegers().read(0); + } + + /** + * Set Entity ID. + * + * @param value - new value. + */ + public void setEntityID(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param world - the current world of the entity. + * @return The spawned entity. + */ + public Entity getEntity(World world) { + return handle.getEntityModifier(world).read(0); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param event - the packet event. + * @return The spawned entity. + */ + public Entity getEntity(PacketEvent event) { + return getEntity(event.getPlayer().getWorld()); + } + + /** + * Retrieve Player UUID. + * <p> + * Notes: player's UUID + * + * @return The current Player UUID + */ + public UUID getPlayerUUID() { + return handle.getUUIDs().read(0); + } + + /** + * Set Player UUID. + * + * @param value - new value. + */ + public void setPlayerUUID(UUID value) { + handle.getUUIDs().write(0, value); + } + + /** + * Retrieve the position of the spawned entity as a vector. + * + * @return The position as a vector. + */ + public Vector getPosition() { + return new Vector(getX(), getY(), getZ()); + } + + /** + * Set the position of the spawned entity using a vector. + * + * @param position - the new position. + */ + public void setPosition(Vector position) { + setX(position.getX()); + setY(position.getY()); + setZ(position.getZ()); + } + + public double getX() { + return handle.getDoubles().read(0); + } + + public void setX(double value) { + handle.getDoubles().write(0, value); + } + + public double getY() { + return handle.getDoubles().read(1); + } + + public void setY(double value) { + handle.getDoubles().write(1, value); + } + + public double getZ() { + return handle.getDoubles().read(2); + } + + public void setZ(double value) { + handle.getDoubles().write(2, value); + } + + /** + * Retrieve the yaw of the spawned entity. + * + * @return The current Yaw + */ + public float getYaw() { + return (handle.getBytes().read(0) * 360.F) / 256.0F; + } + + /** + * Set the yaw of the spawned entity. + * + * @param value - new yaw. + */ + public void setYaw(float value) { + handle.getBytes().write(0, (byte) (value * 256.0F / 360.0F)); + } + + /** + * Retrieve the pitch of the spawned entity. + * + * @return The current pitch + */ + public float getPitch() { + return (handle.getBytes().read(1) * 360.F) / 256.0F; + } + + /** + * Set the pitch of the spawned entity. + * + * @param value - new pitch. + */ + public void setPitch(float value) { + handle.getBytes().write(1, (byte) (value * 256.0F / 360.0F)); + } + + /** + * Retrieve Metadata. + * <p> + * Notes: the client will crash if no metadata is sent + * + * @return The current Metadata + */ + public WrappedDataWatcher getMetadata() { + return handle.getDataWatcherModifier().read(0); + } + + /** + * Set Metadata. + * + * @param value - new value. + */ + public void setMetadata(WrappedDataWatcher value) { + handle.getDataWatcherModifier().write(0, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerNamedSoundEffect.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerNamedSoundEffect.java new file mode 100644 index 0000000..d47398a --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerNamedSoundEffect.java @@ -0,0 +1,157 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.Sound; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.EnumWrappers.SoundCategory; + +public class WrapperPlayServerNamedSoundEffect extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Play.Server.NAMED_SOUND_EFFECT; + + public WrapperPlayServerNamedSoundEffect() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerNamedSoundEffect(PacketContainer packet) { + super(packet, TYPE); + } + + public Sound getSoundEffect() { + return handle.getSoundEffects().read(0); + } + + public void setSoundEffect(Sound value) { + handle.getSoundEffects().write(0, value); + } + + public SoundCategory getSoundCategory() { + return handle.getSoundCategories().read(0); + } + + public void setSoundCategory(SoundCategory value) { + handle.getSoundCategories().write(0, value); + } + + /** + * Retrieve Effect position X. + * <p> + * Notes: effect X multiplied by 8 + * + * @return The current Effect position X + */ + public int getEffectPositionX() { + return handle.getIntegers().read(0); + } + + /** + * Set Effect position X. + * + * @param value - new value. + */ + public void setEffectPositionX(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve Effect position Y. + * <p> + * Notes: effect Y multiplied by 8 + * + * @return The current Effect position Y + */ + public int getEffectPositionY() { + return handle.getIntegers().read(1); + } + + /** + * Set Effect position Y. + * + * @param value - new value. + */ + public void setEffectPositionY(int value) { + handle.getIntegers().write(1, value); + } + + /** + * Retrieve Effect position Z. + * <p> + * Notes: effect Z multiplied by 8 + * + * @return The current Effect position Z + */ + public int getEffectPositionZ() { + return handle.getIntegers().read(2); + } + + /** + * Set Effect position Z. + * + * @param value - new value. + */ + public void setEffectPositionZ(int value) { + handle.getIntegers().write(2, value); + } + + /** + * Retrieve Volume. + * <p> + * Notes: 1 is 100%, can be more + * + * @return The current Volume + */ + public float getVolume() { + return handle.getFloat().read(0); + } + + /** + * Set Volume. + * + * @param value - new value. + */ + public void setVolume(float value) { + handle.getFloat().write(0, value); + } + + /** + * Retrieve Pitch. + * <p> + * Notes: 63 is 100%, can be more + * + * @return The current Pitch + */ + public float getPitch() { + return handle.getFloat().read(1); + } + + /** + * Set Pitch. + * + * @param value - new value. + */ + public void setPitch(float value) { + handle.getFloat().write(1, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerOpenSignEditor.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerOpenSignEditor.java new file mode 100644 index 0000000..e81f800 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerOpenSignEditor.java @@ -0,0 +1,58 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.BlockPosition; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerOpenSignEditor extends AbstractPacket { + + public static final PacketType TYPE = + PacketType.Play.Server.OPEN_SIGN_EDITOR; + + public WrapperPlayServerOpenSignEditor() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerOpenSignEditor(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Location. + * + * @return The current Location + */ + public BlockPosition getLocation() { + return handle.getBlockPositionModifier().read(0); + } + + /** + * Set Location. + * + * @param value - new value. + */ + public void setLocation(BlockPosition value) { + handle.getBlockPositionModifier().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerOpenWindow.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerOpenWindow.java new file mode 100644 index 0000000..9b135ed --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerOpenWindow.java @@ -0,0 +1,163 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.World; +import org.bukkit.entity.Entity; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.wrappers.WrappedChatComponent; + +public class WrapperPlayServerOpenWindow extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.OPEN_WINDOW; + + public WrapperPlayServerOpenWindow() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerOpenWindow(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Window id. + * <p> + * Notes: a unique id number for the window to be displayed. Notchian server + * implementation is a counter, starting at 1. + * + * @return The current Window id + */ + public int getWindowID() { + return handle.getIntegers().read(0); + } + + /** + * Set Window id. + * + * @param value - new value. + */ + public void setWindowID(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve Inventory Type. + * <p> + * Notes: the window type to use for display. Check below + * + * @return The current Inventory Type + */ + public String getInventoryType() { + return handle.getStrings().read(0); + } + + /** + * Set Inventory Type. + * + * @param value - new value. + */ + public void setInventoryType(String value) { + handle.getStrings().write(0, value); + } + + /** + * Retrieve Window title. + * <p> + * Notes: the title of the window. + * + * @return The current Window title + */ + public WrappedChatComponent getWindowTitle() { + return handle.getChatComponents().read(0); + } + + /** + * Set Window title. + * + * @param value - new value. + */ + public void setWindowTitle(WrappedChatComponent value) { + handle.getChatComponents().write(0, value); + } + + /** + * Retrieve Number of Slots. + * <p> + * Notes: number of slots in the window (excluding the number of slots in + * the player inventory). + * + * @return The current Number of Slots + */ + public int getNumberOfSlots() { + return handle.getIntegers().read(1); + } + + /** + * Set Number of Slots. + * + * @param value - new value. + */ + public void setNumberOfSlots(int value) { + handle.getIntegers().write(1, value); + } + + /** + * Retrieve Entity ID. + * <p> + * Notes: entity's ID + * + * @return The current Entity ID + */ + public int getEntityID() { + return handle.getIntegers().read(0); + } + + /** + * Set Entity ID. + * + * @param value - new value. + */ + public void setEntityID(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param world - the current world of the entity. + * @return The spawned entity. + */ + public Entity getEntity(World world) { + return handle.getEntityModifier(world).read(0); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param event - the packet event. + * @return The spawned entity. + */ + public Entity getEntity(PacketEvent event) { + return getEntity(event.getPlayer().getWorld()); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerPlayerInfo.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerPlayerInfo.java new file mode 100644 index 0000000..627c0b9 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerPlayerInfo.java @@ -0,0 +1,56 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import java.util.List; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.EnumWrappers.PlayerInfoAction; +import com.comphenix.protocol.wrappers.PlayerInfoData; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerPlayerInfo extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.PLAYER_INFO; + + public WrapperPlayServerPlayerInfo() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerPlayerInfo(PacketContainer packet) { + super(packet, TYPE); + } + + public PlayerInfoAction getAction() { + return handle.getPlayerInfoAction().read(0); + } + + public void setAction(PlayerInfoAction value) { + handle.getPlayerInfoAction().write(0, value); + } + + public List<PlayerInfoData> getData() { + return handle.getPlayerInfoDataLists().read(0); + } + + public void setData(List<PlayerInfoData> value) { + handle.getPlayerInfoDataLists().write(0, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerPlayerListHeaderFooter.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerPlayerListHeaderFooter.java new file mode 100644 index 0000000..9096724 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerPlayerListHeaderFooter.java @@ -0,0 +1,75 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.WrappedChatComponent; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerPlayerListHeaderFooter extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Play.Server.PLAYER_LIST_HEADER_FOOTER; + + public WrapperPlayServerPlayerListHeaderFooter() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerPlayerListHeaderFooter(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Header. + * + * @return The current Header + */ + public WrappedChatComponent getHeader() { + return handle.getChatComponents().read(0); + } + + /** + * Set Header. + * + * @param value - new value. + */ + public void setHeader(WrappedChatComponent value) { + handle.getChatComponents().write(0, value); + } + + /** + * Retrieve Footer. + * + * @return The current Footer + */ + public WrappedChatComponent getFooter() { + return handle.getChatComponents().read(1); + } + + /** + * Set Footer. + * + * @param value - new value. + */ + public void setFooter(WrappedChatComponent value) { + handle.getChatComponents().write(1, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerPosition.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerPosition.java new file mode 100644 index 0000000..93aa972 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerPosition.java @@ -0,0 +1,162 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import java.util.Set; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.reflect.StructureModifier; +import com.comphenix.protocol.utility.MinecraftReflection; +import com.comphenix.protocol.wrappers.EnumWrappers; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerPosition extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.POSITION; + + public WrapperPlayServerPosition() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerPosition(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve X. + * <p> + * Notes: absolute/Relative position + * + * @return The current X + */ + public double getX() { + return handle.getDoubles().read(0); + } + + /** + * Set X. + * + * @param value - new value. + */ + public void setX(double value) { + handle.getDoubles().write(0, value); + } + + /** + * Retrieve Y. + * <p> + * Notes: absolute/Relative position + * + * @return The current Y + */ + public double getY() { + return handle.getDoubles().read(1); + } + + /** + * Set Y. + * + * @param value - new value. + */ + public void setY(double value) { + handle.getDoubles().write(1, value); + } + + /** + * Retrieve Z. + * <p> + * Notes: absolute/Relative position + * + * @return The current Z + */ + public double getZ() { + return handle.getDoubles().read(2); + } + + /** + * Set Z. + * + * @param value - new value. + */ + public void setZ(double value) { + handle.getDoubles().write(2, value); + } + + /** + * Retrieve Yaw. + * <p> + * Notes: absolute/Relative rotation on the X Axis, in degrees + * + * @return The current Yaw + */ + public float getYaw() { + return handle.getFloat().read(0); + } + + /** + * Set Yaw. + * + * @param value - new value. + */ + public void setYaw(float value) { + handle.getFloat().write(0, value); + } + + /** + * Retrieve Pitch. + * <p> + * Notes: absolute/Relative rotation on the Y Axis, in degrees + * + * @return The current Pitch + */ + public float getPitch() { + return handle.getFloat().read(1); + } + + /** + * Set Pitch. + * + * @param value - new value. + */ + public void setPitch(float value) { + handle.getFloat().write(1, value); + } + + private static final Class<?> FLAGS_CLASS = MinecraftReflection + .getMinecraftClass("EnumPlayerTeleportFlags", + "PacketPlayOutPosition$EnumPlayerTeleportFlags"); + + public enum PlayerTeleportFlag { + X, Y, Z, Y_ROT, X_ROT + } + + private StructureModifier<Set<PlayerTeleportFlag>> getFlagsModifier() { + return handle.getSets( + EnumWrappers.getGenericConverter(FLAGS_CLASS, PlayerTeleportFlag.class)); + } + + public Set<PlayerTeleportFlag> getFlags() { + return getFlagsModifier().read(0); + } + + public void setFlags(Set<PlayerTeleportFlag> value) { + getFlagsModifier().write(0, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerRecipes.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerRecipes.java new file mode 100644 index 0000000..daeca99 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerRecipes.java @@ -0,0 +1,99 @@ +/** + * This file is part of PacketWrapper. + * Copyright (C) 2012-2015 Kristian S. Strangeland + * Copyright (C) 2015 dmulloy2 + * + * PacketWrapper is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PacketWrapper is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with PacketWrapper. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerRecipes extends AbstractPacket { + + public static final PacketType TYPE = PacketType.Play.Server.RECIPES; + + public WrapperPlayServerRecipes() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerRecipes(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Action. + * <p> + * Notes: 0: init, 1: add, 2: remove + * @return The current Action + */ + public Action getAction() { + return handle.getEnumModifier(Action.class, 0).readSafely(0); + } + + /** + * Set Action. + * @param value - new value. + */ + public void setAction(Action value) { + handle.getEnumModifier(Action.class, 0).writeSafely(0, value); + } + + /** + * Retrieve Crafting Book Open. + * <p> + * Notes: if true, then the crafting book will be open when the player opens its inventory. + * @return The current Crafting Book Open + */ + public boolean getCraftingBookOpen() { + return handle.getBooleans().read(0); + } + + /** + * Set Crafting Book Open. + * @param value - new value. + */ + public void setCraftingBookOpen(boolean value) { + handle.getBooleans().write(0, value); + } + + /** + * Retrieve Filtering Craftable. + * <p> + * Notes: if true, then the filtering option is active when the players opens its inventory. + * @return The current Filtering Craftable + */ + public boolean getFilteringCraftable() { + return handle.getBooleans().read(0); + } + + /** + * Set Filtering Craftable. + * @param value - new value. + */ + public void setFilteringCraftable(boolean value) { + handle.getBooleans().write(0, value); + } + + // recipe ids + + public enum Action { + INIT, + ADD, + REMOVE; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerRelEntityMove.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerRelEntityMove.java new file mode 100644 index 0000000..9cf3a54 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerRelEntityMove.java @@ -0,0 +1,123 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.World; +import org.bukkit.entity.Entity; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; + +public class WrapperPlayServerRelEntityMove extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Play.Server.REL_ENTITY_MOVE; + + public WrapperPlayServerRelEntityMove() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerRelEntityMove(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Entity ID. + * <p> + * Notes: entity's ID + * + * @return The current Entity ID + */ + public int getEntityID() { + return handle.getIntegers().read(0); + } + + /** + * Set Entity ID. + * + * @param value - new value. + */ + public void setEntityID(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param world - the current world of the entity. + * @return The spawned entity. + */ + public Entity getEntity(World world) { + return handle.getEntityModifier(world).read(0); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param event - the packet event. + * @return The spawned entity. + */ + public Entity getEntity(PacketEvent event) { + return getEntity(event.getPlayer().getWorld()); + } + + public int getDx() { + return handle.getIntegers().read(1); + } + + public void setDx(int value) { + handle.getIntegers().write(1, value); + } + + public int getDy() { + return handle.getIntegers().read(2); + } + + public void setDy(int value) { + handle.getIntegers().write(2, value); + } + + public int getDz() { + return handle.getIntegers().read(3); + } + + public void setDz(int value) { + handle.getIntegers().write(3, value); + } + + /** + * Retrieve On Ground. + * + * @return The current On Ground + */ + public boolean getOnGround() { + return handle.getBooleans().read(0); + } + + /** + * Set On Ground. + * + * @param value - new value. + */ + public void setOnGround(boolean value) { + handle.getBooleans().write(0, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerRelEntityMoveLook.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerRelEntityMoveLook.java new file mode 100644 index 0000000..27bb151 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerRelEntityMoveLook.java @@ -0,0 +1,189 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.World; +import org.bukkit.entity.Entity; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; + +public class WrapperPlayServerRelEntityMoveLook extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Play.Server.REL_ENTITY_MOVE_LOOK; + + public WrapperPlayServerRelEntityMoveLook() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerRelEntityMoveLook(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Entity ID. + * <p> + * Notes: entity's ID + * + * @return The current Entity ID + */ + public int getEntityID() { + return handle.getIntegers().read(0); + } + + /** + * Set Entity ID. + * + * @param value - new value. + */ + public void setEntityID(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param world - the current world of the entity. + * @return The spawned entity. + */ + public Entity getEntity(World world) { + return handle.getEntityModifier(world).read(0); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param event - the packet event. + * @return The spawned entity. + */ + public Entity getEntity(PacketEvent event) { + return getEntity(event.getPlayer().getWorld()); + } + + /** + * Retrieve DX. + * + * @return The current DX + */ + public double getDx() { + return handle.getIntegers().read(1) / 4096D; + } + + /** + * Set DX. + * + * @param value - new value. + */ + public void setDx(double value) { + handle.getIntegers().write(1, (int) (value * 4096)); + } + + /** + * Retrieve DY. + * + * @return The current DY + */ + public double getDy() { + return handle.getIntegers().read(2) / 4096D; + } + + /** + * Set DY. + * + * @param value - new value. + */ + public void setDy(double value) { + handle.getIntegers().write(2, (int) (value * 4096)); + } + + /** + * Retrieve DZ. + * + * @return The current DZ + */ + public double getDz() { + return handle.getIntegers().read(3) / 4096D; + } + + /** + * Set DZ. + * + * @param value - new value. + */ + public void setDz(double value) { + handle.getIntegers().write(3, (int) (value * 4096)); + } + + /** + * Retrieve the yaw of the current entity. + * + * @return The current Yaw + */ + public float getYaw() { + return (handle.getBytes().read(0) * 360.F) / 256.0F; + } + + /** + * Set the yaw of the current entity. + * + * @param value - new yaw. + */ + public void setYaw(float value) { + handle.getBytes().write(0, (byte) (value * 256.0F / 360.0F)); + } + + /** + * Retrieve the pitch of the current entity. + * + * @return The current pitch + */ + public float getPitch() { + return (handle.getBytes().read(1) * 360.F) / 256.0F; + } + + /** + * Set the pitch of the current entity. + * + * @param value - new pitch. + */ + public void setPitch(float value) { + handle.getBytes().write(1, (byte) (value * 256.0F / 360.0F)); + } + + /** + * Retrieve On Ground. + * + * @return The current On Ground + */ + public boolean getOnGround() { + return handle.getBooleans().read(0); + } + + /** + * Set On Ground. + * + * @param value - new value. + */ + public void setOnGround(boolean value) { + handle.getBooleans().write(0, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerRemoveEntityEffect.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerRemoveEntityEffect.java new file mode 100644 index 0000000..0b5af05 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerRemoveEntityEffect.java @@ -0,0 +1,90 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.potion.PotionEffectType; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; + +public class WrapperPlayServerRemoveEntityEffect extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Play.Server.REMOVE_ENTITY_EFFECT; + + public WrapperPlayServerRemoveEntityEffect() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerRemoveEntityEffect(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Entity ID. + * <p> + * Notes: entity's ID + * + * @return The current Entity ID + */ + public int getEntityID() { + return handle.getIntegers().read(0); + } + + /** + * Set Entity ID. + * + * @param value - new value. + */ + public void setEntityID(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param world - the current world of the entity. + * @return The spawned entity. + */ + public Entity getEntity(World world) { + return handle.getEntityModifier(world).read(0); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param event - the packet event. + * @return The spawned entity. + */ + public Entity getEntity(PacketEvent event) { + return getEntity(event.getPlayer().getWorld()); + } + + public PotionEffectType getEffect() { + return handle.getEffectTypes().read(0); + } + + public void setEffect(PotionEffectType value) { + handle.getEffectTypes().write(0, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerResourcePackSend.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerResourcePackSend.java new file mode 100644 index 0000000..4f36485 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerResourcePackSend.java @@ -0,0 +1,82 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerResourcePackSend extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Play.Server.RESOURCE_PACK_SEND; + + public WrapperPlayServerResourcePackSend() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerResourcePackSend(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve URL. + * <p> + * Notes: the URL to the resource pack. + * + * @return The current URL + */ + public String getUrl() { + return handle.getStrings().read(0); + } + + /** + * Set URL. + * + * @param value - new value. + */ + public void setUrl(String value) { + handle.getStrings().write(0, value); + } + + /** + * Retrieve Hash. + * <p> + * Notes: a 40 character hexadecimal and lower-case SHA-1 hash of the + * resource pack file. (must be lower case in order to work) If it's not a + * 40 character hexadecimal string, the client will not use it for hash + * verification and likely waste bandwidth - but it will still treat it as a + * unique id + * + * @return The current Hash + */ + public String getHash() { + return handle.getStrings().read(1); + } + + /** + * Set Hash. + * + * @param value - new value. + */ + public void setHash(String value) { + handle.getStrings().write(1, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerRespawn.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerRespawn.java new file mode 100644 index 0000000..7b0b21d --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerRespawn.java @@ -0,0 +1,122 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.WorldType; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.EnumWrappers.Difficulty; +import com.comphenix.protocol.wrappers.EnumWrappers.NativeGameMode; + +public class WrapperPlayServerRespawn extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.RESPAWN; + + public WrapperPlayServerRespawn() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerRespawn(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Dimension. + * <p> + * Notes: -1: The Nether, 0: The Overworld, 1: The End + * + * @return The current Dimension + */ + public int getDimension() { + return handle.getIntegers().read(0); + } + + /** + * Set Dimension. + * + * @param value - new value. + */ + public void setDimension(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve Difficulty. + * <p> + * Notes: 0 thru 3 for Peaceful, Easy, Normal, Hard. + * + * @return The current Difficulty + */ + public Difficulty getDifficulty() { + return handle.getDifficulties().read(0); + } + + /** + * Set Difficulty. + * + * @param value - new value. + */ + public void setDifficulty(Difficulty value) { + handle.getDifficulties().write(0, value); + } + + /** + * Retrieve Gamemode. + * <p> + * Notes: 0: survival, 1: creative, 2: adventure. The hardcore flag is not + * included + * + * @return The current Gamemode + */ + public NativeGameMode getGamemode() { + return handle.getGameModes().read(0); + } + + /** + * Set Gamemode. + * + * @param value - new value. + */ + public void setGamemode(NativeGameMode value) { + handle.getGameModes().write(0, value); + } + + /** + * Retrieve Level Type. + * <p> + * Notes: same as Join Game + * + * @return The current Level Type + */ + public WorldType getLevelType() { + return handle.getWorldTypeModifier().read(0); + } + + /** + * Set Level Type. + * + * @param value - new value. + */ + public void setLevelType(WorldType value) { + handle.getWorldTypeModifier().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerScoreboardDisplayObjective.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerScoreboardDisplayObjective.java new file mode 100644 index 0000000..1850c96 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerScoreboardDisplayObjective.java @@ -0,0 +1,79 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerScoreboardDisplayObjective extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Play.Server.SCOREBOARD_DISPLAY_OBJECTIVE; + + public WrapperPlayServerScoreboardDisplayObjective() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerScoreboardDisplayObjective(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Position. + * <p> + * Notes: the position of the scoreboard. 0 = list, 1 = sidebar, 2 = + * belowName. + * + * @return The current Position + */ + public int getPosition() { + return handle.getIntegers().read(0); + } + + /** + * Set Position. + * + * @param value - new value. + */ + public void setPosition(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve Score Name. + * <p> + * Notes: the unique name for the scoreboard to be displayed. + * + * @return The current Score Name + */ + public String getScoreName() { + return handle.getStrings().read(0); + } + + /** + * Set Score Name. + * + * @param value - new value. + */ + public void setScoreName(String value) { + handle.getStrings().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerScoreboardObjective.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerScoreboardObjective.java new file mode 100644 index 0000000..a6314d3 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerScoreboardObjective.java @@ -0,0 +1,141 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.reflect.IntEnum; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerScoreboardObjective extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Play.Server.SCOREBOARD_OBJECTIVE; + + public WrapperPlayServerScoreboardObjective() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerScoreboardObjective(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Enum containing all known packet modes. + * + * @author dmulloy2 + */ + public static class Mode extends IntEnum { + public static final int ADD_OBJECTIVE = 0; + public static final int REMOVE_OBJECTIVE = 1; + public static final int UPDATE_VALUE = 2; + + private static final Mode INSTANCE = new Mode(); + + public static Mode getInstance() { + return INSTANCE; + } + } + + /** + * Retrieve Objective name. + * <p> + * Notes: an unique name for the objective + * + * @return The current Objective name + */ + public String getName() { + return handle.getStrings().read(0); + } + + /** + * Set Objective name. + * + * @param value - new value. + */ + public void setName(String value) { + handle.getStrings().write(0, value); + } + + /** + * Retrieve Objective DisplayName. + * <p> + * Notes: only if mode is 0 or 2. The text to be displayed for the score. + * + * @return The current Objective value + */ + public String getDisplayName() { + return handle.getStrings().read(1); + } + + /** + * Set Objective DisplayName. + * + * @param value - new value. + */ + public void setDisplayName(String value) { + handle.getStrings().write(1, value); + } + + /** + * Retrieve health display. + * <p> + * Notes: Can be either INTEGER or HEARTS + * + * @return + */ + public HealthDisplay getHealthDisplay() { + return handle.getEnumModifier(HealthDisplay.class, 2).read(0); + } + + /** + * Set health display. + * + * @param value - value + * @see #getHealthDisplay() + */ + public void setHealthDisplay(HealthDisplay value) { + handle.getEnumModifier(HealthDisplay.class, 2).write(0, value); + } + + /** + * Retrieve Mode. + * <p> + * Notes: 0 to create the scoreboard. 1 to remove the scoreboard. 2 to + * update the display text. + * + * @return The current Mode + */ + public int getMode() { + return handle.getIntegers().read(0); + } + + /** + * Set Mode. + * + * @param value - new value. + */ + public void setMode(int value) { + handle.getIntegers().write(0, value); + } + + public static enum HealthDisplay { + INTEGER, HEARTS; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerScoreboardScore.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerScoreboardScore.java new file mode 100644 index 0000000..e815570 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerScoreboardScore.java @@ -0,0 +1,108 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.EnumWrappers.ScoreboardAction; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerScoreboardScore extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Play.Server.SCOREBOARD_SCORE; + + public WrapperPlayServerScoreboardScore() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerScoreboardScore(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Score name. + * <p> + * Notes: the name of the score to be updated or removed. + * + * @return The current Score name + */ + public String getScoreName() { + return handle.getStrings().read(0); + } + + /** + * Set Score name. + * + * @param value - new value. + */ + public void setScoreName(String value) { + handle.getStrings().write(0, value); + } + + /** + * Retrieve Objective Name. + * <p> + * Notes: the name of the objective the score belongs to. + * + * @return The current Objective Name + */ + public String getObjectiveName() { + return handle.getStrings().read(1); + } + + /** + * Set Objective Name. + * + * @param value - new value. + */ + public void setObjectiveName(String value) { + handle.getStrings().write(1, value); + } + + /** + * Retrieve Value. + * <p> + * Notes: the score to be displayed next to the entry. Only sent when + * Update/Remove does not equal 1. + * + * @return The current Value + */ + public int getValue() { + return handle.getIntegers().read(0); + } + + /** + * Set Value. + * + * @param value - new value. + */ + public void setValue(int value) { + handle.getIntegers().write(0, value); + } + + public ScoreboardAction getAction() { + return handle.getScoreboardActions().read(0); + } + + public void setScoreboardAction(ScoreboardAction value) { + handle.getScoreboardActions().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerScoreboardTeam.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerScoreboardTeam.java new file mode 100644 index 0000000..03461ff --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerScoreboardTeam.java @@ -0,0 +1,276 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import java.util.Collection; +import java.util.List; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.reflect.IntEnum; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerScoreboardTeam extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Play.Server.SCOREBOARD_TEAM; + + public WrapperPlayServerScoreboardTeam() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerScoreboardTeam(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Enum containing all known modes. + * + * @author dmulloy2 + */ + public static class Mode extends IntEnum { + public static final int TEAM_CREATED = 0; + public static final int TEAM_REMOVED = 1; + public static final int TEAM_UPDATED = 2; + public static final int PLAYERS_ADDED = 3; + public static final int PLAYERS_REMOVED = 4; + + private static final Mode INSTANCE = new Mode(); + + public static Mode getInstance() { + return INSTANCE; + } + } + + /** + * Retrieve Team Name. + * <p> + * Notes: a unique name for the team. (Shared with scoreboard). + * + * @return The current Team Name + */ + public String getName() { + return handle.getStrings().read(0); + } + + /** + * Set Team Name. + * + * @param value - new value. + */ + public void setName(String value) { + handle.getStrings().write(0, value); + } + + /** + * Retrieve Team Display Name. + * <p> + * Notes: only if Mode = 0 or 2. + * + * @return The current Team Display Name + */ + public String getDisplayName() { + return handle.getStrings().read(1); + } + + /** + * Set Team Display Name. + * + * @param value - new value. + */ + public void setDisplayName(String value) { + handle.getStrings().write(1, value); + } + + /** + * Retrieve Team Prefix. + * <p> + * Notes: only if Mode = 0 or 2. Displayed before the players' name that are + * part of this team. + * + * @return The current Team Prefix + */ + public String getPrefix() { + return handle.getStrings().read(2); + } + + /** + * Set Team Prefix. + * + * @param value - new value. + */ + public void setPrefix(String value) { + handle.getStrings().write(2, value); + } + + /** + * Retrieve Team Suffix. + * <p> + * Notes: only if Mode = 0 or 2. Displayed after the players' name that are + * part of this team. + * + * @return The current Team Suffix + */ + public String getSuffix() { + return handle.getStrings().read(3); + } + + /** + * Set Team Suffix. + * + * @param value - new value. + */ + public void setSuffix(String value) { + handle.getStrings().write(3, value); + } + + /** + * Retrieve Name Tag Visibility. + * <p> + * Notes: only if Mode = 0 or 2. always, hideForOtherTeams, hideForOwnTeam, + * never. + * + * @return The current Name Tag Visibility + */ + public String getNameTagVisibility() { + return handle.getStrings().read(4); + } + + /** + * Set Name Tag Visibility. + * + * @param value - new value. + */ + public void setNameTagVisibility(String value) { + handle.getStrings().write(4, value); + } + + /** + * Retrieve Color. + * <p> + * Notes: only if Mode = 0 or 2. Same as Chat colors. + * + * @return The current Color + */ + public int getColor() { + return handle.getIntegers().read(0); + } + + /** + * Set Color. + * + * @param value - new value. + */ + public void setColor(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Get the collision rule. + * Notes: only if Mode = 0 or 2. always, pushOtherTeams, pushOwnTeam, never. + * @return The current collision rule + */ + public String getCollisionRule() { + return handle.getStrings().read(5); + } + + /** + * Sets the collision rule. + * @param value - new value. + */ + public void setCollisionRule(String value) { + handle.getStrings().write(5, value); + } + + /** + * Retrieve Players. + * <p> + * Notes: only if Mode = 0 or 3 or 4. Players to be added/remove from the + * team. Max 40 characters so may be uuid's later + * + * @return The current Players + */ + @SuppressWarnings("unchecked") + public List<String> getPlayers() { + return (List<String>) handle.getSpecificModifier(Collection.class) + .read(0); + } + + /** + * Set Players. + * + * @param value - new value. + */ + public void setPlayers(List<String> value) { + handle.getSpecificModifier(Collection.class).write(0, value); + } + + /** + * Retrieve Mode. + * <p> + * Notes: if 0 then the team is created. If 1 then the team is removed. If 2 + * the team team information is updated. If 3 then new players are added to + * the team. If 4 then players are removed from the team. + * + * @return The current Mode + */ + public int getMode() { + return handle.getIntegers().read(1); + } + + /** + * Set Mode. + * + * @param value - new value. + */ + public void setMode(int value) { + handle.getIntegers().write(1, value); + } + + /** + * Retrieve pack option data. Pack data is calculated as follows: + * + * <pre> + * <code> + * int data = 0; + * if (team.allowFriendlyFire()) { + * data |= 1; + * } + * if (team.canSeeFriendlyInvisibles()) { + * data |= 2; + * } + * </code> + * </pre> + * + * @return The current pack option data + */ + public int getPackOptionData() { + return handle.getIntegers().read(2); + } + + /** + * Set pack option data. + * + * @param value - new value + * @see #getPackOptionData() + */ + public void setPackOptionData(int value) { + handle.getIntegers().write(2, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerSelectAdvancementTab.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerSelectAdvancementTab.java new file mode 100644 index 0000000..95d5ec5 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerSelectAdvancementTab.java @@ -0,0 +1,46 @@ +/** + * This file is part of PacketWrapper. + * Copyright (C) 2012-2015 Kristian S. Strangeland + * Copyright (C) 2015 dmulloy2 + * + * PacketWrapper is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PacketWrapper is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with PacketWrapper. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.MinecraftKey; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerSelectAdvancementTab extends AbstractPacket { + + public static final PacketType TYPE = PacketType.Play.Server.SELECT_ADVANCEMENT_TAB; + + public WrapperPlayServerSelectAdvancementTab() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerSelectAdvancementTab(PacketContainer packet) { + super(packet, TYPE); + } + + public MinecraftKey getKey() { + return handle.getMinecraftKeys().readSafely(0); + } + + public void setKey(MinecraftKey key) { + handle.getMinecraftKeys().writeSafely(0, key); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerServerDifficulty.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerServerDifficulty.java new file mode 100644 index 0000000..164aa13 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerServerDifficulty.java @@ -0,0 +1,59 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.EnumWrappers.Difficulty; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerServerDifficulty extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Play.Server.SERVER_DIFFICULTY; + + public WrapperPlayServerServerDifficulty() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerServerDifficulty(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Difficulty. + * <p> + * Notes: 0:PEACEFUL, 1:EASY, 2:NORMAL, 3: HARD + * + * @return The current Difficulty + */ + public Difficulty getDifficulty() { + return handle.getDifficulties().read(0); + } + + /** + * Set Difficulty. + * + * @param value - new value. + */ + public void setDifficulty(Difficulty value) { + handle.getDifficulties().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerSetCooldown.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerSetCooldown.java new file mode 100644 index 0000000..90ee1e7 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerSetCooldown.java @@ -0,0 +1,97 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.Material; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.reflect.EquivalentConverter; +import com.comphenix.protocol.reflect.accessors.Accessors; +import com.comphenix.protocol.reflect.accessors.MethodAccessor; +import com.comphenix.protocol.utility.MinecraftReflection; + +public class WrapperPlayServerSetCooldown extends AbstractPacket { + private static final Class<?> ITEM_CLASS = MinecraftReflection + .getMinecraftClass("Item"); + public static final PacketType TYPE = PacketType.Play.Server.SET_COOLDOWN; + + public WrapperPlayServerSetCooldown() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerSetCooldown(PacketContainer packet) { + super(packet, TYPE); + } + + public Material getItem() { + return handle.getModifier() + .<Material> withType(ITEM_CLASS, new ItemConverter()).read(0); + } + + public void setItem(Material value) { + handle.getModifier() + .<Material> withType(ITEM_CLASS, new ItemConverter()) + .write(0, value); + } + + public int getTicks() { + return handle.getIntegers().read(0); + } + + public void setTicks(int value) { + handle.getIntegers().write(0, value); + } + + private static class ItemConverter implements EquivalentConverter<Material> { + private static MethodAccessor getMaterial = null; + private static MethodAccessor getItem = null; + + @Override + public Material getSpecific(Object generic) { + if (getMaterial == null) { + getMaterial = + Accessors.getMethodAccessor(MinecraftReflection + .getCraftBukkitClass("util.CraftMagicNumbers"), + "getMaterial", ITEM_CLASS); + } + + return (Material) getMaterial.invoke(null, generic); + } + + @Override + public Object getGeneric(Material specific) { + if (getItem == null) { + getItem = + Accessors.getMethodAccessor(MinecraftReflection + .getCraftBukkitClass("util.CraftMagicNumbers"), + "getItem", Material.class); + } + + return getItem.invoke(null, specific); + } + + @Override + public Class<Material> getSpecificType() { + return Material.class; + } + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerSetSlot.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerSetSlot.java new file mode 100644 index 0000000..38e2f2f --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerSetSlot.java @@ -0,0 +1,102 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.inventory.ItemStack; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; + +public class WrapperPlayServerSetSlot extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.SET_SLOT; + + public WrapperPlayServerSetSlot() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerSetSlot(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Window ID. + * <p> + * Notes: the window which is being updated. 0 for player inventory. Note + * that all known window types include the player inventory. This packet + * will only be sent for the currently opened window while the player is + * performing actions, even if it affects the player inventory. After the + * window is closed, a number of these packets are sent to update the + * player's inventory window (0). + * + * @return The current Window ID + */ + public int getWindowId() { + return handle.getIntegers().read(0); + } + + /** + * Set Window ID. + * + * @param value - new value. + */ + public void setWindowId(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve Slot. + * <p> + * Notes: the slot that should be updated + * + * @return The current Slot + */ + public int getSlot() { + return handle.getIntegers().read(1); + } + + /** + * Set Slot. + * + * @param value - new value. + */ + public void setSlot(int value) { + handle.getIntegers().write(1, value); + } + + /** + * Retrieve Slot data. + * + * @return The current Slot data + */ + public ItemStack getSlotData() { + return handle.getItemModifier().read(0); + } + + /** + * Set Slot data. + * + * @param value - new value. + */ + public void setSlotData(ItemStack value) { + handle.getItemModifier().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerSpawnEntity.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerSpawnEntity.java new file mode 100644 index 0000000..545261d --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerSpawnEntity.java @@ -0,0 +1,379 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import java.util.UUID; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.World; +import org.bukkit.entity.Entity; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.injector.PacketConstructor; +import com.comphenix.protocol.reflect.IntEnum; + +public class WrapperPlayServerSpawnEntity extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.SPAWN_ENTITY; + + private static PacketConstructor entityConstructor; + + /** + * Represents the different object types. + * + * @author Kristian + */ + public static class ObjectTypes extends IntEnum { + public static final int BOAT = 1; + public static final int ITEM_STACK = 2; + public static final int AREA_EFFECT_CLOUD = 3; + public static final int MINECART = 10; + public static final int ACTIVATED_TNT = 50; + public static final int ENDER_CRYSTAL = 51; + public static final int TIPPED_ARROW_PROJECTILE = 60; + public static final int SNOWBALL_PROJECTILE = 61; + public static final int EGG_PROJECTILE = 62; + public static final int GHAST_FIREBALL = 63; + public static final int BLAZE_FIREBALL = 64; + public static final int THROWN_ENDERPEARL = 65; + public static final int WITHER_SKULL_PROJECTILE = 66; + public static final int SHULKER_BULLET = 67; + public static final int FALLING_BLOCK = 70; + public static final int ITEM_FRAME = 71; + public static final int EYE_OF_ENDER = 72; + public static final int THROWN_POTION = 73; + public static final int THROWN_EXP_BOTTLE = 75; + public static final int FIREWORK_ROCKET = 76; + public static final int LEASH_KNOT = 77; + public static final int ARMORSTAND = 78; + public static final int FISHING_FLOAT = 90; + public static final int SPECTRAL_ARROW = 91; + public static final int DRAGON_FIREBALL = 93; + + /** + * The singleton instance. Can also be retrieved from the parent class. + */ + private static ObjectTypes INSTANCE = new ObjectTypes(); + + /** + * Retrieve an instance of the object types enum. + * + * @return Object type enum. + */ + public static ObjectTypes getInstance() { + return INSTANCE; + } + } + + public WrapperPlayServerSpawnEntity() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerSpawnEntity(PacketContainer packet) { + super(packet, TYPE); + } + + public WrapperPlayServerSpawnEntity(Entity entity, int type, int objectData) { + super(fromEntity(entity, type, objectData), TYPE); + } + + // Useful constructor + private static PacketContainer fromEntity(Entity entity, int type, + int objectData) { + if (entityConstructor == null) + entityConstructor = + ProtocolLibrary.getProtocolManager() + .createPacketConstructor(TYPE, entity, type, + objectData); + return entityConstructor.createPacket(entity, type, objectData); + } + + /** + * Retrieve entity ID of the Object. + * + * @return The current EID + */ + public int getEntityID() { + return handle.getIntegers().read(0); + } + + /** + * Retrieve the entity that will be spawned. + * + * @param world - the current world of the entity. + * @return The spawned entity. + */ + public Entity getEntity(World world) { + return handle.getEntityModifier(world).read(0); + } + + /** + * Retrieve the entity that will be spawned. + * + * @param event - the packet event. + * @return The spawned entity. + */ + public Entity getEntity(PacketEvent event) { + return getEntity(event.getPlayer().getWorld()); + } + + /** + * Set entity ID of the Object. + * + * @param value - new value. + */ + public void setEntityID(int value) { + handle.getIntegers().write(0, value); + } + + public UUID getUniqueId() { + return handle.getUUIDs().read(0); + } + + public void setUniqueId(UUID value) { + handle.getUUIDs().write(0, value); + } + + /** + * Retrieve the x position of the object. + * <p> + * Note that the coordinate is rounded off to the nearest 1/32 of a meter. + * + * @return The current X + */ + public double getX() { + return handle.getDoubles().read(0); + } + + /** + * Set the x position of the object. + * + * @param value - new value. + */ + public void setX(double value) { + handle.getDoubles().write(0, value); + } + + /** + * Retrieve the y position of the object. + * <p> + * Note that the coordinate is rounded off to the nearest 1/32 of a meter. + * + * @return The current y + */ + public double getY() { + return handle.getDoubles().read(1); + } + + /** + * Set the y position of the object. + * + * @param value - new value. + */ + public void setY(double value) { + handle.getDoubles().write(1, value); + } + + /** + * Retrieve the z position of the object. + * <p> + * Note that the coordinate is rounded off to the nearest 1/32 of a meter. + * + * @return The current z + */ + public double getZ() { + return handle.getDoubles().read(2); + } + + /** + * Set the z position of the object. + * + * @param value - new value. + */ + public void setZ(double value) { + handle.getDoubles().write(2, value); + } + + /** + * Retrieve the optional speed x. + * <p> + * This is ignored if {@link #getObjectData()} is zero. + * + * @return The optional speed x. + */ + public double getOptionalSpeedX() { + return handle.getIntegers().read(1) / 8000.0D; + } + + /** + * Set the optional speed x. + * + * @param value - new value. + */ + public void setOptionalSpeedX(double value) { + handle.getIntegers().write(1, (int) (value * 8000.0D)); + } + + /** + * Retrieve the optional speed y. + * <p> + * This is ignored if {@link #getObjectData()} is zero. + * + * @return The optional speed y. + */ + public double getOptionalSpeedY() { + return handle.getIntegers().read(2) / 8000.0D; + } + + /** + * Set the optional speed y. + * + * @param value - new value. + */ + public void setOptionalSpeedY(double value) { + handle.getIntegers().write(2, (int) (value * 8000.0D)); + } + + /** + * Retrieve the optional speed z. + * <p> + * This is ignored if {@link #getObjectData()} is zero. + * + * @return The optional speed z. + */ + public double getOptionalSpeedZ() { + return handle.getIntegers().read(3) / 8000.0D; + } + + /** + * Set the optional speed z. + * + * @param value - new value. + */ + public void setOptionalSpeedZ(double value) { + handle.getIntegers().write(3, (int) (value * 8000.0D)); + } + + /** + * Retrieve the pitch. + * + * @return The current pitch. + */ + public float getPitch() { + return (handle.getIntegers().read(4) * 360.F) / 256.0F; + } + + /** + * Set the pitch. + * + * @param value - new pitch. + */ + public void setPitch(float value) { + handle.getIntegers().write(4, (int) (value * 256.0F / 360.0F)); + } + + /** + * Retrieve the yaw. + * + * @return The current Yaw + */ + public float getYaw() { + return (handle.getIntegers().read(5) * 360.F) / 256.0F; + } + + /** + * Set the yaw of the object spawned. + * + * @param value - new yaw. + */ + public void setYaw(float value) { + handle.getIntegers().write(5, (int) (value * 256.0F / 360.0F)); + } + + /** + * Retrieve the type of object. See {@link ObjectTypes} + * + * @return The current Type + */ + public int getType() { + return handle.getIntegers().read(6); + } + + /** + * Set the type of object. See {@link ObjectTypes}. + * + * @param value - new value. + */ + public void setType(int value) { + handle.getIntegers().write(6, value); + } + + /** + * Retrieve object data. + * <p> + * The content depends on the object type: + * <table border="1" cellpadding="4"> + * <tr> + * <th>Object Type:</th> + * <th>Name:</th> + * <th>Description</th> + * </tr> + * <tr> + * <td>ITEM_FRAME</td> + * <td>Orientation</td> + * <td>0-3: South, West, North, East</td> + * </tr> + * <tr> + * <td>FALLING_BLOCK</td> + * <td>Block Type</td> + * <td>BlockID | (Metadata << 0xC)</td> + * </tr> + * <tr> + * <td>Projectiles</td> + * <td>Entity ID</td> + * <td>The entity ID of the thrower</td> + * </tr> + * <tr> + * <td>Splash Potions</td> + * <td>Data Value</td> + * <td>Potion data value.</td> + * </tr> + * </table> + * + * @return The current object Data + */ + public int getObjectData() { + return handle.getIntegers().read(7); + } + + /** + * Set object Data. + * <p> + * The content depends on the object type. See {@link #getObjectData()} for + * more information. + * + * @param value - new object data. + */ + public void setObjectData(int value) { + handle.getIntegers().write(7, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerSpawnEntityExperienceOrb.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerSpawnEntityExperienceOrb.java new file mode 100644 index 0000000..eb12895 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerSpawnEntityExperienceOrb.java @@ -0,0 +1,161 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.World; +import org.bukkit.entity.Entity; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; + +public class WrapperPlayServerSpawnEntityExperienceOrb extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Play.Server.SPAWN_ENTITY_EXPERIENCE_ORB; + + public WrapperPlayServerSpawnEntityExperienceOrb() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerSpawnEntityExperienceOrb(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Entity ID. + * <p> + * Notes: entity's ID + * + * @return The current Entity ID + */ + public int getEntityID() { + return handle.getIntegers().read(0); + } + + /** + * Set Entity ID. + * + * @param value - new value. + */ + public void setEntityID(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param world - the current world of the entity. + * @return The spawned entity. + */ + public Entity getEntity(World world) { + return handle.getEntityModifier(world).read(0); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param event - the packet event. + * @return The spawned entity. + */ + public Entity getEntity(PacketEvent event) { + return getEntity(event.getPlayer().getWorld()); + } + + /** + * Retrieve the x position of the object. + * <p> + * Note that the coordinate is rounded off to the nearest 1/32 of a meter. + * + * @return The current X + */ + public double getX() { + return handle.getDoubles().read(0); + } + + /** + * Set the x position of the object. + * + * @param value - new value. + */ + public void setX(double value) { + handle.getDoubles().write(0, value); + } + + /** + * Retrieve the y position of the object. + * <p> + * Note that the coordinate is rounded off to the nearest 1/32 of a meter. + * + * @return The current y + */ + public double getY() { + return handle.getDoubles().read(1); + } + + /** + * Set the y position of the object. + * + * @param value - new value. + */ + public void setY(double value) { + handle.getDoubles().write(1, value); + } + + /** + * Retrieve the z position of the object. + * <p> + * Note that the coordinate is rounded off to the nearest 1/32 of a meter. + * + * @return The current z + */ + public double getZ() { + return handle.getDoubles().read(2); + } + + /** + * Set the z position of the object. + * + * @param value - new value. + */ + public void setZ(double value) { + handle.getDoubles().write(2, value); + } + + /** + * Retrieve Count. + * <p> + * Notes: the amount of experience this orb will reward once collected + * + * @return The current Count + */ + public int getCount() { + return handle.getIntegers().read(1); + } + + /** + * Set Count. + * + * @param value - new value. + */ + public void setCount(int value) { + handle.getIntegers().write(1, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerSpawnEntityLiving.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerSpawnEntityLiving.java new file mode 100644 index 0000000..5ba1639 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerSpawnEntityLiving.java @@ -0,0 +1,316 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import java.util.UUID; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.injector.PacketConstructor; +import com.comphenix.protocol.wrappers.WrappedDataWatcher; + +public class WrapperPlayServerSpawnEntityLiving extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Play.Server.SPAWN_ENTITY_LIVING; + + private static PacketConstructor entityConstructor; + + public WrapperPlayServerSpawnEntityLiving() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerSpawnEntityLiving(PacketContainer packet) { + super(packet, TYPE); + } + + public WrapperPlayServerSpawnEntityLiving(Entity entity) { + super(fromEntity(entity), TYPE); + } + + // Useful constructor + private static PacketContainer fromEntity(Entity entity) { + if (entityConstructor == null) + entityConstructor = + ProtocolLibrary.getProtocolManager() + .createPacketConstructor(TYPE, entity); + return entityConstructor.createPacket(entity); + } + + /** + * Retrieve entity ID. + * + * @return The current EID + */ + public int getEntityID() { + return handle.getIntegers().read(0); + } + + /** + * Retrieve the entity that will be spawned. + * + * @param world - the current world of the entity. + * @return The spawned entity. + */ + public Entity getEntity(World world) { + return handle.getEntityModifier(world).read(0); + } + + /** + * Retrieve the entity that will be spawned. + * + * @param event - the packet event. + * @return The spawned entity. + */ + public Entity getEntity(PacketEvent event) { + return getEntity(event.getPlayer().getWorld()); + } + + public UUID getUniqueId() { + return handle.getUUIDs().read(0); + } + + public void setUniqueId(UUID value) { + handle.getUUIDs().write(0, value); + } + + /** + * Set entity ID. + * + * @param value - new value. + */ + public void setEntityID(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve the type of mob. + * + * @return The current Type + */ + @SuppressWarnings("deprecation") + public EntityType getType() { + return EntityType.fromId(handle.getIntegers().read(1)); + } + + /** + * Set the type of mob. + * + * @param value - new value. + */ + @SuppressWarnings("deprecation") + public void setType(EntityType value) { + handle.getIntegers().write(1, (int) value.getTypeId()); + } + + /** + * Retrieve the x position of the object. + * <p> + * Note that the coordinate is rounded off to the nearest 1/32 of a meter. + * + * @return The current X + */ + public double getX() { + return handle.getDoubles().read(0); + } + + /** + * Set the x position of the object. + * + * @param value - new value. + */ + public void setX(double value) { + handle.getDoubles().write(0, value); + } + + /** + * Retrieve the y position of the object. + * <p> + * Note that the coordinate is rounded off to the nearest 1/32 of a meter. + * + * @return The current y + */ + public double getY() { + return handle.getDoubles().read(1); + } + + /** + * Set the y position of the object. + * + * @param value - new value. + */ + public void setY(double value) { + handle.getDoubles().write(1, value); + } + + /** + * Retrieve the z position of the object. + * <p> + * Note that the coordinate is rounded off to the nearest 1/32 of a meter. + * + * @return The current z + */ + public double getZ() { + return handle.getDoubles().read(2); + } + + /** + * Set the z position of the object. + * + * @param value - new value. + */ + public void setZ(double value) { + handle.getDoubles().write(2, value); + } + + /** + * Retrieve the yaw. + * + * @return The current Yaw + */ + public float getYaw() { + return (handle.getBytes().read(0) * 360.F) / 256.0F; + } + + /** + * Set the yaw of the spawned mob. + * + * @param value - new yaw. + */ + public void setYaw(float value) { + handle.getBytes().write(0, (byte) (value * 256.0F / 360.0F)); + } + + /** + * Retrieve the pitch. + * + * @return The current pitch + */ + public float getPitch() { + return (handle.getBytes().read(1) * 360.F) / 256.0F; + } + + /** + * Set the pitch of the spawned mob. + * + * @param value - new pitch. + */ + public void setPitch(float value) { + handle.getBytes().write(1, (byte) (value * 256.0F / 360.0F)); + } + + /** + * Retrieve the yaw of the mob's head. + * + * @return The current yaw. + */ + public float getHeadPitch() { + return (handle.getBytes().read(2) * 360.F) / 256.0F; + } + + /** + * Set the yaw of the mob's head. + * + * @param value - new yaw. + */ + public void setHeadPitch(float value) { + handle.getBytes().write(2, (byte) (value * 256.0F / 360.0F)); + } + + /** + * Retrieve the velocity in the x axis. + * + * @return The current velocity X + */ + public double getVelocityX() { + return handle.getIntegers().read(2) / 8000.0D; + } + + /** + * Set the velocity in the x axis. + * + * @param value - new value. + */ + public void setVelocityX(double value) { + handle.getIntegers().write(2, (int) (value * 8000.0D)); + } + + /** + * Retrieve the velocity in the y axis. + * + * @return The current velocity y + */ + public double getVelocityY() { + return handle.getIntegers().read(3) / 8000.0D; + } + + /** + * Set the velocity in the y axis. + * + * @param value - new value. + */ + public void setVelocityY(double value) { + handle.getIntegers().write(3, (int) (value * 8000.0D)); + } + + /** + * Retrieve the velocity in the z axis. + * + * @return The current velocity z + */ + public double getVelocityZ() { + return handle.getIntegers().read(4) / 8000.0D; + } + + /** + * Set the velocity in the z axis. + * + * @param value - new value. + */ + public void setVelocityZ(double value) { + handle.getIntegers().write(4, (int) (value * 8000.0D)); + } + + /** + * Retrieve the data watcher. + * <p> + * Content varies by mob, see Entities. + * + * @return The current Metadata + */ + public WrappedDataWatcher getMetadata() { + return handle.getDataWatcherModifier().read(0); + } + + /** + * Set the data watcher. + * + * @param value - new value. + */ + public void setMetadata(WrappedDataWatcher value) { + handle.getDataWatcherModifier().write(0, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerSpawnEntityPainting.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerSpawnEntityPainting.java new file mode 100644 index 0000000..9825642 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerSpawnEntityPainting.java @@ -0,0 +1,131 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.World; +import org.bukkit.entity.Entity; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.wrappers.BlockPosition; +import com.comphenix.protocol.wrappers.EnumWrappers.Direction; + +public class WrapperPlayServerSpawnEntityPainting extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Play.Server.SPAWN_ENTITY_PAINTING; + + public WrapperPlayServerSpawnEntityPainting() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerSpawnEntityPainting(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Entity ID. + * <p> + * Notes: entity's ID + * + * @return The current Entity ID + */ + public int getEntityID() { + return handle.getIntegers().read(0); + } + + /** + * Set Entity ID. + * + * @param value - new value. + */ + public void setEntityID(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param world - the current world of the entity. + * @return The spawned entity. + */ + public Entity getEntity(World world) { + return handle.getEntityModifier(world).read(0); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param event - the packet event. + * @return The spawned entity. + */ + public Entity getEntity(PacketEvent event) { + return getEntity(event.getPlayer().getWorld()); + } + + /** + * Retrieve Title. + * <p> + * Notes: name of the painting. Max length 13 + * + * @return The current Title + */ + public String getTitle() { + return handle.getStrings().read(0); + } + + /** + * Set Title. + * + * @param value - new value. + */ + public void setTitle(String value) { + handle.getStrings().write(0, value); + } + + /** + * Retrieve Location. + * <p> + * Notes: center coordinates + * + * @return The current Location + */ + public BlockPosition getLocation() { + return handle.getBlockPositionModifier().read(0); + } + + /** + * Set Location. + * + * @param value - new value. + */ + public void setLocation(BlockPosition value) { + handle.getBlockPositionModifier().write(0, value); + } + + public Direction getDirection() { + return handle.getDirections().read(0); + } + + public void setDirection(Direction value) { + handle.getDirections().write(0, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerSpawnEntityWeather.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerSpawnEntityWeather.java new file mode 100644 index 0000000..86387ca --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerSpawnEntityWeather.java @@ -0,0 +1,161 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.World; +import org.bukkit.entity.Entity; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; + +public class WrapperPlayServerSpawnEntityWeather extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Play.Server.SPAWN_ENTITY_WEATHER; + + public WrapperPlayServerSpawnEntityWeather() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerSpawnEntityWeather(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Entity ID. + * <p> + * Notes: entity's ID + * + * @return The current Entity ID + */ + public int getEntityID() { + return handle.getIntegers().read(0); + } + + /** + * Set Entity ID. + * + * @param value - new value. + */ + public void setEntityID(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param world - the current world of the entity. + * @return The spawned entity. + */ + public Entity getEntity(World world) { + return handle.getEntityModifier(world).read(0); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param event - the packet event. + * @return The spawned entity. + */ + public Entity getEntity(PacketEvent event) { + return getEntity(event.getPlayer().getWorld()); + } + + /** + * Retrieve Type. + * <p> + * Notes: the global entity type, currently always 1 for thunderbolt. + * + * @return The current Type + */ + public int getType() { + return handle.getIntegers().read(1); + } + + /** + * Set Type. + * + * @param value - new value. + */ + public void setType(int value) { + handle.getIntegers().write(1, value); + } + + /** + * Retrieve the x position of the object. + * <p> + * Note that the coordinate is rounded off to the nearest 1/32 of a meter. + * + * @return The current X + */ + public double getX() { + return handle.getDoubles().read(0); + } + + /** + * Set the x position of the object. + * + * @param value - new value. + */ + public void setX(double value) { + handle.getDoubles().write(0, value); + } + + /** + * Retrieve the y position of the object. + * <p> + * Note that the coordinate is rounded off to the nearest 1/32 of a meter. + * + * @return The current y + */ + public double getY() { + return handle.getDoubles().read(1); + } + + /** + * Set the y position of the object. + * + * @param value - new value. + */ + public void setY(double value) { + handle.getDoubles().write(1, value); + } + + /** + * Retrieve the z position of the object. + * <p> + * Note that the coordinate is rounded off to the nearest 1/32 of a meter. + * + * @return The current z + */ + public double getZ() { + return handle.getDoubles().read(2); + } + + /** + * Set the z position of the object. + * + * @param value - new value. + */ + public void setZ(double value) { + handle.getDoubles().write(2, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerSpawnPosition.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerSpawnPosition.java new file mode 100644 index 0000000..133368b --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerSpawnPosition.java @@ -0,0 +1,58 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.BlockPosition; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerSpawnPosition extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.SPAWN_POSITION; + + public WrapperPlayServerSpawnPosition() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerSpawnPosition(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Location. + * <p> + * Notes: spawn location + * + * @return The current Location + */ + public BlockPosition getLocation() { + return handle.getBlockPositionModifier().read(0); + } + + /** + * Set Location. + * + * @param value - new value. + */ + public void setLocation(BlockPosition value) { + handle.getBlockPositionModifier().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerStatistic.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerStatistic.java new file mode 100644 index 0000000..d60601f --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerStatistic.java @@ -0,0 +1,47 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import java.util.Map; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.WrappedStatistic; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerStatistic extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.STATISTIC; + + public WrapperPlayServerStatistic() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerStatistic(PacketContainer packet) { + super(packet, TYPE); + } + + public Map<WrappedStatistic, Integer> getStatistics() { + return handle.getStatisticMaps().read(0); + } + + public void setStatistics(Map<WrappedStatistic, Integer> value) { + handle.getStatisticMaps().write(0, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerTabComplete.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerTabComplete.java new file mode 100644 index 0000000..9583735 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerTabComplete.java @@ -0,0 +1,69 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerTabComplete extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.TAB_COMPLETE; + + public WrapperPlayServerTabComplete() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerTabComplete(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Count. + * <p> + * Notes: number of following strings + * + * @return The current Count + */ + public int getCount() { + return handle.getStringArrays().read(0).length; + } + + /** + * Retrieve Match. + * <p> + * Notes: one eligible command, note that each command is sent separately + * instead of in a single string, hence the need for Count + * + * @return The current Match + */ + public String[] getMatches() { + return handle.getStringArrays().read(0); + } + + /** + * Set Match. + * + * @param value - new value. + */ + public void setMatches(String[] value) { + handle.getStringArrays().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerTileEntityData.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerTileEntityData.java new file mode 100644 index 0000000..7eba379 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerTileEntityData.java @@ -0,0 +1,98 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.BlockPosition; +import com.comphenix.protocol.wrappers.nbt.NbtBase; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerTileEntityData extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Play.Server.TILE_ENTITY_DATA; + + public WrapperPlayServerTileEntityData() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerTileEntityData(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Location. + * + * @return The current Location + */ + public BlockPosition getLocation() { + return handle.getBlockPositionModifier().read(0); + } + + /** + * Set Location. + * + * @param value - new value. + */ + public void setLocation(BlockPosition value) { + handle.getBlockPositionModifier().write(0, value); + } + + /** + * Retrieve Action. + * <p> + * Notes: the type of update to perform + * + * @return The current Action + */ + public int getAction() { + return handle.getIntegers().read(0); + } + + /** + * Set Action. + * + * @param value - new value. + */ + public void setAction(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve NBT Data. + * <p> + * Notes: if not present then its TAG_END (0) + * + * @return The current NBT Data + */ + public NbtBase<?> getNbtData() { + return handle.getNbtModifier().read(0); + } + + /** + * Set NBT Data. + * + * @param value - new value. + */ + public void setNbtData(NbtBase<?> value) { + handle.getNbtModifier().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerTitle.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerTitle.java new file mode 100644 index 0000000..8292090 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerTitle.java @@ -0,0 +1,137 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.EnumWrappers.TitleAction; +import com.comphenix.protocol.wrappers.WrappedChatComponent; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerTitle extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.TITLE; + + public WrapperPlayServerTitle() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerTitle(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Action. + * + * @return The current Action + */ + public TitleAction getAction() { + return handle.getTitleActions().read(0); + } + + /** + * Set Action. + * + * @param value - new value. + */ + public WrapperPlayServerTitle setAction(TitleAction value) { + handle.getTitleActions().write(0, value); + return this; + } + + /** + * Retrieve 0 (TITLE). + * <p> + * Notes: chat + * + * @return The current 0 (TITLE) + */ + public WrappedChatComponent getTitle() { + return handle.getChatComponents().read(0); + } + + /** + * Set 0 (TITLE). + * + * @param value - new value. + */ + public WrapperPlayServerTitle setTitle(WrappedChatComponent value) { + handle.getChatComponents().write(0, value); + return this; + } + + /** + * Retrieve 2 (TIMES). + * <p> + * Notes: int + * + * @return The current 2 (TIMES) + */ + public int getFadeIn() { + return handle.getIntegers().read(0); + } + + /** + * Set 2 (TIMES). + * + * @param value - new value. + */ + public WrapperPlayServerTitle setFadeIn(int value) { + handle.getIntegers().write(0, value); + return this; + } + + /** + * Retrieve Stay. + * + * @return The current Stay + */ + public int getStay() { + return handle.getIntegers().read(1); + } + + /** + * Set Stay. + * + * @param value - new value. + */ + public WrapperPlayServerTitle setStay(int value) { + handle.getIntegers().write(1, value); + return this; + } + + /** + * Retrieve Fade Out. + * + * @return The current Fade Out + */ + public int getFadeOut() { + return handle.getIntegers().read(2); + } + + /** + * Set Fade Out. + * + * @param value - new value. + */ + public WrapperPlayServerTitle setFadeOut(int value) { + handle.getIntegers().write(2, value); + return this; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerTransaction.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerTransaction.java new file mode 100644 index 0000000..c9a737a --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerTransaction.java @@ -0,0 +1,98 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerTransaction extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.TRANSACTION; + + public WrapperPlayServerTransaction() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerTransaction(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Window ID. + * <p> + * Notes: the id of the window that the action occurred in. + * + * @return The current Window ID + */ + public int getWindowId() { + return handle.getIntegers().read(0); + } + + /** + * Set Window ID. + * + * @param value - new value. + */ + public void setWindowId(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve Action number. + * <p> + * Notes: every action that is to be accepted has a unique number. This + * field corresponds to that number. + * + * @return The current Action number + */ + public short getActionNumber() { + return handle.getShorts().read(0); + } + + /** + * Set Action number. + * + * @param value - new value. + */ + public void setActionNumber(short value) { + handle.getShorts().write(0, value); + } + + /** + * Retrieve Accepted. + * <p> + * Notes: whether the action was accepted. + * + * @return The current Accepted + */ + public boolean getAccepted() { + return handle.getBooleans().read(0); + } + + /** + * Set Accepted. + * + * @param value - new value. + */ + public void setAccepted(boolean value) { + handle.getBooleans().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerUnloadChunk.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerUnloadChunk.java new file mode 100644 index 0000000..f1a9f19 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerUnloadChunk.java @@ -0,0 +1,78 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerUnloadChunk extends AbstractPacket { + + public static final PacketType TYPE = PacketType.Play.Server.UNLOAD_CHUNK; + + public WrapperPlayServerUnloadChunk() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerUnloadChunk(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Chunk X. + * <p> + * Notes: block coordinate divided by 16, rounded down + * + * @return The current Chunk X + */ + public int getChunkX() { + return handle.getIntegers().read(0); + } + + /** + * Set Chunk X. + * + * @param value - new value. + */ + public void setChunkX(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve Chunk Z. + * <p> + * Notes: block coordinate divided by 16, rounded down + * + * @return The current Chunk Z + */ + public int getChunkZ() { + return handle.getIntegers().read(1); + } + + /** + * Set Chunk Z. + * + * @param value - new value. + */ + public void setChunkZ(int value) { + handle.getIntegers().write(1, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerUpdateAttributes.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerUpdateAttributes.java new file mode 100644 index 0000000..4cd2fb9 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerUpdateAttributes.java @@ -0,0 +1,102 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import java.util.List; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.World; +import org.bukkit.entity.Entity; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.wrappers.WrappedAttribute; + +public class WrapperPlayServerUpdateAttributes extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Play.Server.UPDATE_ATTRIBUTES; + + public WrapperPlayServerUpdateAttributes() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerUpdateAttributes(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Entity ID. + * <p> + * Notes: entity's ID + * + * @return The current Entity ID + */ + public int getEntityID() { + return handle.getIntegers().read(0); + } + + /** + * Set Entity ID. + * + * @param value - new value. + */ + public void setEntityID(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param world - the current world of the entity. + * @return The spawned entity. + */ + public Entity getEntity(World world) { + return handle.getEntityModifier(world).read(0); + } + + /** + * Retrieve the entity of the painting that will be spawned. + * + * @param event - the packet event. + * @return The spawned entity. + */ + public Entity getEntity(PacketEvent event) { + return getEntity(event.getPlayer().getWorld()); + } + + /** + * Retrieve the collection of attributes associated with the entity. + * + * @return The current attributes. + */ + public List<WrappedAttribute> getAttributes() { + return handle.getAttributeCollectionModifier().read(0); + } + + /** + * Set the new or updated attributes associated with the entity. + * + * @param value - new/updated attributes. + */ + public void setAttributes(List<WrappedAttribute> value) { + handle.getAttributeCollectionModifier().write(0, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerUpdateHealth.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerUpdateHealth.java new file mode 100644 index 0000000..fec5b2f --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerUpdateHealth.java @@ -0,0 +1,97 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerUpdateHealth extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.UPDATE_HEALTH; + + public WrapperPlayServerUpdateHealth() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerUpdateHealth(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Health. + * <p> + * Notes: 0 or less = dead, 20 = full HP + * + * @return The current Health + */ + public float getHealth() { + return handle.getFloat().read(0); + } + + /** + * Set Health. + * + * @param value - new value. + */ + public void setHealth(float value) { + handle.getFloat().write(0, value); + } + + /** + * Retrieve Food. + * <p> + * Notes: 0 - 20 + * + * @return The current Food + */ + public int getFood() { + return handle.getIntegers().read(0); + } + + /** + * Set Food. + * + * @param value - new value. + */ + public void setFood(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve Food Saturation. + * <p> + * Notes: seems to vary from 0.0 to 5.0 in integer increments + * + * @return The current Food Saturation + */ + public float getFoodSaturation() { + return handle.getFloat().read(1); + } + + /** + * Set Food Saturation. + * + * @param value - new value. + */ + public void setFoodSaturation(float value) { + handle.getFloat().write(1, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerUpdateTime.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerUpdateTime.java new file mode 100644 index 0000000..757150c --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerUpdateTime.java @@ -0,0 +1,78 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerUpdateTime extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.UPDATE_TIME; + + public WrapperPlayServerUpdateTime() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerUpdateTime(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Age of the world. + * <p> + * Notes: in ticks; not changed by server commands + * + * @return The current Age of the world + */ + public long getAgeOfTheWorld() { + return handle.getLongs().read(0); + } + + /** + * Set Age of the world. + * + * @param value - new value. + */ + public void setAgeOfTheWorld(long value) { + handle.getLongs().write(0, value); + } + + /** + * Retrieve Time of day. + * <p> + * Notes: the world (or region) time, in ticks. If negative the sun will + * stop moving at the Math.abs of the time + * + * @return The current Time of day + */ + public long getTimeOfDay() { + return handle.getLongs().read(1); + } + + /** + * Set Time of day. + * + * @param value - new value. + */ + public void setTimeOfDay(long value) { + handle.getLongs().write(1, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerVehicleMove.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerVehicleMove.java new file mode 100644 index 0000000..e572bd0 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerVehicleMove.java @@ -0,0 +1,138 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerVehicleMove extends AbstractPacket { + + public static final PacketType TYPE = PacketType.Play.Server.VEHICLE_MOVE; + + public WrapperPlayServerVehicleMove() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerVehicleMove(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve X. + * <p> + * Notes: absolute position (X coordinate) + * + * @return The current X + */ + public double getX() { + return handle.getDoubles().read(0); + } + + /** + * Set X. + * + * @param value - new value. + */ + public void setX(double value) { + handle.getDoubles().write(0, value); + } + + /** + * Retrieve Y. + * <p> + * Notes: absolute position (Y coordinate) + * + * @return The current Y + */ + public double getY() { + return handle.getDoubles().read(1); + } + + /** + * Set Y. + * + * @param value - new value. + */ + public void setY(double value) { + handle.getDoubles().write(1, value); + } + + /** + * Retrieve Z. + * <p> + * Notes: absolute position (Z coordinate) + * + * @return The current Z + */ + public double getZ() { + return handle.getDoubles().read(2); + } + + /** + * Set Z. + * + * @param value - new value. + */ + public void setZ(double value) { + handle.getDoubles().write(2, value); + } + + /** + * Retrieve Yaw. + * <p> + * Notes: absolute rotation on the vertical axis, in degrees + * + * @return The current Yaw + */ + public float getYaw() { + return handle.getFloat().read(0); + } + + /** + * Set Yaw. + * + * @param value - new value. + */ + public void setYaw(float value) { + handle.getFloat().write(0, value); + } + + /** + * Retrieve Pitch. + * <p> + * Notes: absolute rotation on the horizontal axis, in degrees + * + * @return The current Pitch + */ + public float getPitch() { + return handle.getFloat().read(1); + } + + /** + * Set Pitch. + * + * @param value - new value. + */ + public void setPitch(float value) { + handle.getFloat().write(1, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerWindowData.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerWindowData.java new file mode 100644 index 0000000..b089b64 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerWindowData.java @@ -0,0 +1,97 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerWindowData extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.WINDOW_DATA; + + public WrapperPlayServerWindowData() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerWindowData(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Window ID. + * <p> + * Notes: the id of the window. + * + * @return The current Window ID + */ + public int getWindowId() { + return handle.getIntegers().read(0); + } + + /** + * Set Window ID. + * + * @param value - new value. + */ + public void setWindowId(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve Property. + * <p> + * Notes: which property should be updated. + * + * @return The current Property + */ + public int getProperty() { + return handle.getIntegers().read(1); + } + + /** + * Set Property. + * + * @param value - new value. + */ + public void setProperty(int value) { + handle.getIntegers().write(1, value); + } + + /** + * Retrieve Value. + * <p> + * Notes: the new value for the property. + * + * @return The current Value + */ + public int getValue() { + return handle.getIntegers().read(2); + } + + /** + * Set Value. + * + * @param value - new value. + */ + public void setValue(int value) { + handle.getIntegers().write(2, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerWindowItems.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerWindowItems.java new file mode 100644 index 0000000..b157d25 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerWindowItems.java @@ -0,0 +1,80 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import java.util.List; + +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import org.bukkit.inventory.ItemStack; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; + +public class WrapperPlayServerWindowItems extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.WINDOW_ITEMS; + + public WrapperPlayServerWindowItems() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerWindowItems(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Window ID. + * <p> + * Notes: the id of window which items are being sent for. 0 for player + * inventory. + * + * @return The current Window ID + */ + public int getWindowId() { + return handle.getIntegers().read(0); + } + + /** + * Set Window ID. + * + * @param value - new value. + */ + public void setWindowId(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve Slot data. + * + * @return The current Slot data + */ + public List<ItemStack> getSlotData() { + return handle.getItemListModifier().read(0); + } + + /** + * Set Slot data. + * + * @param value - new value. + */ + public void setSlotData(List<ItemStack> value) { + handle.getItemListModifier().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerWorldBorder.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerWorldBorder.java new file mode 100644 index 0000000..79a8e96 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerWorldBorder.java @@ -0,0 +1,109 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.EnumWrappers.WorldBorderAction; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerWorldBorder extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.WORLD_BORDER; + + public WrapperPlayServerWorldBorder() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerWorldBorder(PacketContainer packet) { + super(packet, TYPE); + } + + public WorldBorderAction getAction() { + return handle.getWorldBorderActions().read(0); + } + + public void setAction(WorldBorderAction value) { + handle.getWorldBorderActions().write(0, value); + } + + public int getPortalTeleportBoundary() { + return handle.getIntegers().read(0); + } + + public void setPortalTeleportBoundary(int value) { + handle.getIntegers().write(0, value); + } + + public double getCenterX() { + return handle.getDoubles().read(0); + } + + public void setCenterX(double value) { + handle.getDoubles().write(0, value); + } + + public double getCenterZ() { + return handle.getDoubles().read(1); + } + + public void setCenterZ(double value) { + handle.getDoubles().write(1, value); + } + + public double getOldRadius() { + return handle.getDoubles().read(2); + } + + public void setOldRadius(double value) { + handle.getDoubles().write(2, value); + } + + public double getRadius() { + return handle.getDoubles().read(3); + } + + public void setRadius(double value) { + handle.getDoubles().write(3, value); + } + + public long getSpeed() { + return handle.getLongs().read(0); + } + + public void setSpeed(long value) { + handle.getLongs().write(0, value); + } + + public int getWarningTime() { + return handle.getIntegers().read(1); + } + + public void setWarningTime(int value) { + handle.getIntegers().write(1, value); + } + + public int getWarningDistance() { + return handle.getIntegers().read(2); + } + + public void setWarningDistance(int value) { + handle.getIntegers().write(2, value); + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerWorldEvent.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerWorldEvent.java new file mode 100644 index 0000000..c563896 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerWorldEvent.java @@ -0,0 +1,118 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.BlockPosition; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerWorldEvent extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.WORLD_EVENT; + + public WrapperPlayServerWorldEvent() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerWorldEvent(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Effect ID. + * <p> + * Notes: the ID of the effect, see below. + * + * @return The current Effect ID + */ + public int getEffectId() { + return handle.getIntegers().read(0); + } + + /** + * Set Effect ID. + * + * @param value - new value. + */ + public void setEffectId(int value) { + handle.getIntegers().write(0, value); + } + + /** + * Retrieve Location. + * <p> + * Notes: the location of the effect + * + * @return The current Location + */ + public BlockPosition getLocation() { + return handle.getBlockPositionModifier().read(0); + } + + /** + * Set Location. + * + * @param value - new value. + */ + public void setLocation(BlockPosition value) { + handle.getBlockPositionModifier().write(0, value); + } + + /** + * Retrieve Data. + * <p> + * Notes: extra data for certain effects, see below. + * + * @return The current Data + */ + public int getData() { + return handle.getIntegers().read(1); + } + + /** + * Set Data. + * + * @param value - new value. + */ + public void setData(int value) { + handle.getIntegers().write(1, value); + } + + /** + * Retrieve Disable relative volume. + * <p> + * Notes: see above + * + * @return The current Disable relative volume + */ + public boolean getDisableRelativeVolume() { + return handle.getBooleans().read(0); + } + + /** + * Set Disable relative volume. + * + * @param value - new value. + */ + public void setDisableRelativeVolume(boolean value) { + handle.getBooleans().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerWorldParticles.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerWorldParticles.java new file mode 100644 index 0000000..ec04ba5 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperPlayServerWorldParticles.java @@ -0,0 +1,272 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.EnumWrappers.Particle; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperPlayServerWorldParticles extends AbstractPacket { + public static final PacketType TYPE = + PacketType.Play.Server.WORLD_PARTICLES; + + public WrapperPlayServerWorldParticles() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayServerWorldParticles(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Particle type. + * + * @return The current Particle type + */ + public Particle getParticleType() { + return handle.getParticles().read(0); + } + + /** + * Set Particle type. + * + * @param value - new value. + */ + public WrapperPlayServerWorldParticles setParticleType(Particle value) { + handle.getParticles().write(0, value); + return this; + } + + /** + * Retrieve X. + * <p> + * Notes: x position of the particle + * + * @return The current X + */ + public float getX() { + return handle.getFloat().read(0); + } + + /** + * Set X. + * + * @param value - new value. + */ + public WrapperPlayServerWorldParticles setX(float value) { + handle.getFloat().write(0, value); + return this; + } + + /** + * Retrieve Y. + * <p> + * Notes: y position of the particle + * + * @return The current Y + */ + public float getY() { + return handle.getFloat().read(1); + } + + /** + * Set Y. + * + * @param value - new value. + */ + public WrapperPlayServerWorldParticles setY(float value) { + handle.getFloat().write(1, value); + return this; + } + + /** + * Retrieve Z. + * <p> + * Notes: z position of the particle + * + * @return The current Z + */ + public float getZ() { + return handle.getFloat().read(2); + } + + /** + * Set Z. + * + * @param value - new value. + */ + public WrapperPlayServerWorldParticles setZ(float value) { + handle.getFloat().write(2, value); + return this; + } + + /** + * Retrieve Offset X. + * <p> + * Notes: this is added to the X position after being multiplied by + * random.nextGaussian() + * + * @return The current Offset X + */ + public float getOffsetX() { + return handle.getFloat().read(3); + } + + /** + * Set Offset X. + * + * @param value - new value. + */ + public WrapperPlayServerWorldParticles setOffsetX(float value) { + handle.getFloat().write(3, value); + return this; + } + + /** + * Retrieve Offset Y. + * <p> + * Notes: this is added to the Y position after being multiplied by + * random.nextGaussian() + * + * @return The current Offset Y + */ + public float getOffsetY() { + return handle.getFloat().read(4); + } + + /** + * Set Offset Y. + * + * @param value - new value. + */ + public WrapperPlayServerWorldParticles setOffsetY(float value) { + handle.getFloat().write(4, value); + return this; + } + + /** + * Retrieve Offset Z. + * <p> + * Notes: this is added to the Z position after being multiplied by + * random.nextGaussian() + * + * @return The current Offset Z + */ + public float getOffsetZ() { + return handle.getFloat().read(5); + } + + /** + * Set Offset Z. + * + * @param value - new value. + */ + public WrapperPlayServerWorldParticles setOffsetZ(float value) { + handle.getFloat().write(5, value); + return this; + } + + /** + * Retrieve Particle data. + * <p> + * Notes: the data of each particle + * + * @return The current Particle data + */ + public float getParticleData() { + return handle.getFloat().read(6); + } + + /** + * Set Particle data. + * + * @param value - new value. + */ + public WrapperPlayServerWorldParticles setParticleData(float value) { + handle.getFloat().write(6, value); + return this; + } + + /** + * Retrieve Number of particles. + * <p> + * Notes: the number of particles to create + * + * @return The current Number of particles + */ + public int getNumberOfParticles() { + return handle.getIntegers().read(0); + } + + /** + * Set Number of particles. + * + * @param value - new value. + */ + public WrapperPlayServerWorldParticles setNumberOfParticles(int value) { + handle.getIntegers().write(0, value); + return this; + } + + /** + * Retrieve Long Distance. + * <p> + * Notes: if true, particle distance increases from 256 to 65536. + * + * @return The current Long Distance + */ + public boolean getLongDistance() { + return handle.getBooleans().read(0); + } + + /** + * Set Long Distance. + * + * @param value - new value. + */ + public WrapperPlayServerWorldParticles setLongDistance(boolean value) { + handle.getBooleans().write(0, value); + return this; + } + + /** + * Retrieve Data. + * <p> + * Notes: length depends on particle. IRON_CRACK has a length of 2, + * BLOCK_CRACK and BLOCK_DUST have lengths of 1, the rest have 0. + * + * @return The current Data + * @see Particle#getDataLength() + */ + public int[] getData() { + return handle.getIntegerArrays().read(0); + } + + /** + * Set Data. + * + * @param value - new value. + */ + public WrapperPlayServerWorldParticles setData(int[] value) { + handle.getIntegerArrays().write(0, value); + return this; + } +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperStatusServerPong.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperStatusServerPong.java new file mode 100644 index 0000000..055ffa4 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperStatusServerPong.java @@ -0,0 +1,57 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperStatusServerPong extends AbstractPacket { + public static final PacketType TYPE = PacketType.Status.Server.PONG; + + public WrapperStatusServerPong() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperStatusServerPong(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve Time. + * <p> + * Notes: should be the same as sent by the client + * + * @return The current Time + */ + public long getTime() { + return handle.getLongs().read(0); + } + + /** + * Set Time. + * + * @param value - new value. + */ + public void setTime(long value) { + handle.getLongs().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperStatusServerServerInfo.java b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperStatusServerServerInfo.java new file mode 100644 index 0000000..d20bb3a --- /dev/null +++ b/core-master@6ef85bb745a/src/main/java/net/grandtheftmc/core/wrapper/packet/out/WrapperStatusServerServerInfo.java @@ -0,0 +1,58 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 <http://dmulloy2.net> + * Copyright (C) Kristian S. Strangeland + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.grandtheftmc.core.wrapper.packet.out; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.WrappedServerPing; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; + +public class WrapperStatusServerServerInfo extends AbstractPacket { + public static final PacketType TYPE = PacketType.Status.Server.SERVER_INFO; + + public WrapperStatusServerServerInfo() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperStatusServerServerInfo(PacketContainer packet) { + super(packet, TYPE); + } + + /** + * Retrieve JSON Response. + * <p> + * Notes: https://gist.github.com/thinkofdeath/6927216 + * + * @return The current JSON Response + */ + public WrappedServerPing getJsonResponse() { + return handle.getServerPings().read(0); + } + + /** + * Set JSON Response. + * + * @param value - new value. + */ + public void setJsonResponse(WrappedServerPing value) { + handle.getServerPings().write(0, value); + } + +} diff --git a/core-master@6ef85bb745a/src/main/resources/core.yml b/core-master@6ef85bb745a/src/main/resources/core.yml new file mode 100644 index 0000000..9e92fd9 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/resources/core.yml @@ -0,0 +1,5 @@ +serverType: none +serverNumber: -1 +premium: true +editMode: true +maxplayers: 300 \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/resources/help.yml b/core-master@6ef85bb745a/src/main/resources/help.yml new file mode 100644 index 0000000..9efad9b --- /dev/null +++ b/core-master@6ef85bb745a/src/main/resources/help.yml @@ -0,0 +1,134 @@ +help: + Houses: + - "&a&lHouses &fare player-purchasable property." + - "&fThere are two types of houses available for players." + - "&fPremium houses are bought with permits, type &3/help premiumhouses &ffor more information" + - "&fNon-premium houses range from 2-14 chests, whilst premium houses do not have a chest limit" + - "&fFind houses in the PvP world by clicking on iron doors" + - "&fTo learn more about permits, type &3/help permits &ffor more for additional information" + Permits: + - "&a&lPermits &fare a nontradeable GTM currency used to buy premium houses" + - "&fPermits can be purchased from &2http://store.grandtheftmc.net/ &fand as a voting reward from &2http://grandtheftmc.net/vote" + - "&fPermits can be obtained from the tokenshop, type /help tokenshop for additional information" + - "&fType &3/help voting &ffor more information" + Tokenshop: + - "&a&lTokenshop &fgrants players the means to convert tokens into other GTM currencies and/or items" + - "&fThe command to open tokenshop is &3/tokenshop" + - "&fTo learn about tokens, type &3/help tokens &ffor additional information" + Tokens: + - "&a&lTokens &fare a nontradeable GTM currency used for a variety of purposes" + - "&fSpend tokens using &3/tokenshop" + - "&fTokens are a voting reward from &2http://grandtheftmc.net/vote &fand can purchased from &2http://store.grandtheftmc.net/" + - "&fType &3/help voting &ffor more information" + - "&fTokens can be used for cosmetic player auras, hats, and pets, do &3/help c &ffor more information" + Money: + - "&a&lMoney &fis stored in either the player's hand or bank, type &3/help hand &for &3/help bank2 for more information" + - "&fMoney is obtained by killing players or selling loot in trashcans, type &3/help trashcans &ffor more information" + - "&fMoney can be purchased from &2http://store.grandtheftmc.net/ &fand as a voting reward from &2http://grandtheftmc.net/vote" + - "&fType &3/help voting &ffor more information" + - "&fMoney can be used to buy guns at Ammunation, type &3/help Ammunation" + - "&fMoney can be used to buy food from food vendors, type &3/help Food &ffor more information" + - "&fMoney can be used to buy armor from Bincos, type &3/help Bincos &ffor more information" + - "&fUse the bank to transfer money from hand to bank, type &3/help bank2 &ffor more information" + Armor: + - "&a&lArmor &fprovides players a damage reduction from bullets, explosives, and melee attacks" + - "&fCertain armors in cases allow players to fly, type &3/help jetpacks &for &3/help wingsuits for more information" + - "&fArmor is bought from Bincos, type &3/help Bincos &ffor more information" + - "&fArmor in equippable in the armor slots of a player, opened by pressing e" + - "&fCertain armors can be obtained as a voting reward from &2http://grandtheftmc.net/vote" + Wingsuits: + - "&a&lWingsuits &fare chestplate armor worn that enable the player to fly" + - "&fWingsuits require fuel to operate, type &3/help fuel &ffor more information" + - "&fTo fly with a wingsuit, crouch and look up from an angled position, then press space repeatedly to take off" + - "&fWingsuits do not provide players with armor points, but function similarly to elytra flight, with the ability of lift" + - "&fIf more advanced help is needed for wingsuits, consult a staff member for additional information" + - "&fWingsuits obtainable as a premium rank reward, type &3/help premiumrank for additional information" + - "&fWingsuits are armor variants, type &3/help armor &ffor additional help" + Jetpacks: + - "&a&1Jetpacks &fare chestplate armor worn that enable the player to fly" + - "&fJetpacks require fuel to operate, type &3/help fuel &ffor more information" + - "&fJetpacks provide armor points, and function similarly to creativefly" + - "&fJetpacks are armor variants, type &3/help armor &ffor additional help" + - "&fJetpacks are purchasable from Bincos, type &3/help bincos &ffor additional information" + - "&fJetpacks are obtainable as a premium rank reward, type &3/help premiumrank &ffor additional information" + Fuel: + - "&a&1Fuel &fis purchasable from Bincos as a consumable item for jetpacks and wingsuits, type /help bincos for more help" + - "&fType &3/help wingsuits &for &3/help jetpacks &ffor additional information" + Bincos: + - "&a&1Bincos &fis an armor vendor that distributes armor for money, type &3/help armor &for &3/help money &ffor more information" + - "&fBincos is located in /spawn, for additional help type /help spawn" + - "&fBincos in addition sells jetpacks and fuel, for additional information type /help jetpacks or /help fuel" + - "&fGoods bought from the vendor must be paid with cash from hand, type /help hand for more help" + Spawn: + - "&a&1Spawn is the initial playerzone that is separate from the PvP world" + - "&fSpawn contains Bincos, Carshop, and Ammunation, type &3/help bincos, &3/help carshop, &3/help ammunation &ffor more information" + - "&fSpawn provides the standings for the lottery and the bank,type &3/help lottery &fand &3/help bank for more information" + - "&fSpawn is accessible through the command &2/spawn" + Bank: + - "&fThe &a&1bank &fis a building found in &3/spawn, &ftype &3/spawn &ffor more information" + - "&fPlayers here can store money from their hand to their bank, type &3/help hand or &3/help bank &ffor more information" + - "&fClicking itemframes with itemnames of ATM prompts the bank menu" + - "&fThe bank deals with the player currency of money, type &3/help money &ffor more information" + Carshop: + - "&a&1Carshop is an area found in /spawn, type /help spawn for more information" + - "&fPlayers spend money to purchase cars, helicopters, tanks, boats, and jets, type &3/help cars &ffor more information" + - "&fFor help on money, type &3/help money &ffor more information" + - "&fRepair costs for cars are 20% of their original price, once a player owns a vehicle it is owned until sold" + Cars: + - "&a&1Cars &fcan be purchased from the carshop, &3type /help carshop &ffor more information" + - "&fnce a car is destroyed, it can be repaired at the carshop" + - "&fGang members can enter the passenger seat of a car to transport multiple people at once" + - "&fCertain weapons can be used inside of cars, and sometimes cars are equipped with preset weapons" + Trashcans: + - "&a&1Trashcans &fare found in the PvP world, as well as in spawn, type &3/help spawn &ffor additional information" + - "&fTrashcans are dispensers with a custom UI that allows players to sell items for 50% of their valued price in stores" + - "&3/help Bincos &fand &3/help Ammunation, &ffor additional help for item vendors" + - "M&foney is granted to the hand, type &3/help hand vor &3/help money &ffor additional information" + Premiumranks: + - "&a&1Premium ranks are special ranks purchased here, &2http://grandtheftmc.net/vote &fand &2http://store.grandtheftmc.net/" + - "&fAll perks earned through premium ranks can be obtained through the basic rank system, type &3/help ranks &ffor more information" + - "&fPremium ranks give the player money and tokens, type &3/help money &for &3/help tokens &ffor more information" + - "&fPremium ranks give the ability to tpa and tpahere, type &3/help tpa &ffor more information" + - "&fPremium rank trials can be bought in tokenshop, type &3/help tokenshop &ffor more information" + C: + - "&a&1/c &fis a command that prompts a UI screen to manage, buy, and toggle cosmetics" + - "&fCosmetics are purchased with tokens, type &3/help tokenshop &ffor more information" + Ranks: + - "&a&1Ranks &fare obtained though the &2/rankup &fcommand" + - "&fMoney for &2/rankups &fmust be in the hand, type &3/help money &ffor more information" + - "&fRanking up allows players to access new weapons and armors, type &3/help armor &ffor more information" + Tpa: + - "&a&1Tpa is a command usable by premium rank players, use &3/help premiumranks &ffor more information" + - "&fTpa sends a teleport request to the player specified after the command, &2/tpa playername" + - "&fTpahere sends a teleport request for the player specified to teleport to you, &2/tpahere playername" + - "&fTpa commands can be accepted using &2/tpaccept &for &2/tpadeny" + - "&fPlayers combat tagged cannot accept or send teleport requests" + Hand: + - "&a&1Money &fin the hand can be transferred to the bank using the phone" + - "&ftype &3/help phone, /help bank, &for &3/help money &for more information" + - "&fUpon death, 50% of money in the hand will be dropped at the deathpoint" + Bank2: + - "&a&1The money in the bank can be transferred to the hand, type &3/help money &for &3/help hand &ffor more information" + - "&fUpon death, no money in the bank will be dropped at the deathpoint" + - "&fBank money can be transferred using the phone or ATMs, type &3/help bank &for &3/help phone for more information" + Food: + - "&a&1Food can be purchased from spawn using money, type &3/help spawn &for &3/help money &ffor additional information" + - "&fFood is sold in item vendors around the spawn map and throughout the PVP world" + Ammunation: + - "&a&1Ammunation &fis an item vendor that sells weapons and consumables for money, type &3/help money &ffor more information" + - "&fAmmunation is only found in spawn, type &3/help spawn &ffor more information" + - "&fTrashcans are located in ammunation and allow to sell weapons, type &3/help trashcans &ffor more information" + Voting: + - "&a&1Voting &fallows for the player to receive tokens, money, tokens, and rare items" + - "&fVote at &2http://grandtheftmc.net/vote" + Lottery: + - "&fThe &a&1lottery &fallows players to gamble money in a cumulative pot, at a chance to win shares of the pot" + - "&fMoney gambled gives players tickets for the weekly drawing, type &3/help tickets &for &3/help money &ffor more information" + - "&fMoney spent is nonrefundable, tickets bought are final" + Tickets: + - "&a&1Tickets &fare purchased for the lottery using money, type &3/help lottery &for &3/help money &ffor more information" + - "&fTickets are a currency that cannot be traded, and are used in the weekly lottery drawing" + About: + - "&a&1/help &fcommands were created by &9&1Presidentx, &4&1Cruee, and &dHqs" + - "&fThis project has taken around 8 hours to successfully compile" + - "&fAny suggestions for additions? Feel free to message us" diff --git a/core-master@6ef85bb745a/src/main/resources/joinSigns.yml b/core-master@6ef85bb745a/src/main/resources/joinSigns.yml new file mode 100644 index 0000000..8052729 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/resources/joinSigns.yml @@ -0,0 +1,2 @@ +codz1: {} +# - codzlobby,0,0,0 \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/resources/perms.yml b/core-master@6ef85bb745a/src/main/resources/perms.yml new file mode 100644 index 0000000..61da91c --- /dev/null +++ b/core-master@6ef85bb745a/src/main/resources/perms.yml @@ -0,0 +1,10 @@ +ranks: + default: + - test + - some.perm + - -denied.perm + vip: + - a.vip.perm +players: + qfqsdfjkqdsfjhjsfqd: + - some.random.perm.for.only.this.fgt \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/resources/plugin.yml b/core-master@6ef85bb745a/src/main/resources/plugin.yml new file mode 100644 index 0000000..0ee5b8b --- /dev/null +++ b/core-master@6ef85bb745a/src/main/resources/plugin.yml @@ -0,0 +1,58 @@ +name: Core +version: 1.0 +main: net.grandtheftmc.core.Core +depend: [JLib,BuycraftX] +softdepend: [WorldEdit,Votifier,HolographicDisplays,UltimateCosmetics,LibsDisguises] +commands: + socialspy: + config: + description: Reload/save the config + rank: + forumrank: + bucks: + tokens: + whitelist: + announcer: + aliases: [an, ann, announce] + message: + aliases: [msg, tell, whisper, m, w] + reply: + aliases: [r,rep,answer] + vote: + tutorial: + aliases: [tut,t] + next: + pets: + cosmetic: + aliases: [cos,cosmetics] + nametag: + petdata: + aliases: [pd, petd, pdata] + petname: + prefs: + aliases: [pref] + rewards: + ignore: + aliases: [ignored] + list: + clearchat: + aliases: [cc, chatclear] + globalmute: + aliases: [muteall, muteglobal] + rules: + save: + playtime: + info: + aliases: [how] + achievement: + aliases: [a] + crowbar: + aliases: [crowbars] + randomvoter: + crate: + maxplayers: + votestreak: + chatfilter: + aliases: [cf] + store: + event: \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/resources/redis.yml b/core-master@6ef85bb745a/src/main/resources/redis.yml new file mode 100644 index 0000000..5dbadbb --- /dev/null +++ b/core-master@6ef85bb745a/src/main/resources/redis.yml @@ -0,0 +1,3 @@ +server: 10.0.51.209 +port: 5555 +password: gtmredispass \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/resources/servers.yml b/core-master@6ef85bb745a/src/main/resources/servers.yml new file mode 100644 index 0000000..bad6bf6 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/resources/servers.yml @@ -0,0 +1,3 @@ +servers: {} +# - hub1 +# - codz1 \ No newline at end of file diff --git a/core-master@6ef85bb745a/src/main/resources/voting.yml b/core-master@6ef85bb745a/src/main/resources/voting.yml new file mode 100644 index 0000000..a48c0f6 --- /dev/null +++ b/core-master@6ef85bb745a/src/main/resources/voting.yml @@ -0,0 +1,36 @@ +links: + minecraftservers.org: + name: Minecraftservers.org + link: http://minecraftservers.org/vote/102886 + mcsl: + name: Minecraft-Server-List.com + link: http://minecraft-server-list.com/server/210232/vote/ + mc-index: + name: MC-Index + link: http://www.minecraft-index.com/12351-grandtheftminecart-8211-gta-in-minecraft/vote + topg.org: + name: TopG.org + link: http://topg.org/Minecraft/in-365133 + minestatus: + name: Minestatus + link: https://minestatus.net/76320-grandtheftminecart-gta-in-minecraft/vote + mcserverlist.com: + name: MCServerList.com + link: http://mc-serverlist.com/vote.php?id=3729 + mclistserv: + name: MCListServ + link: http://mclistserv.com/server/2054 + mcserverstatus: + name: MCServerStatus + link: https://mcserverstatus.com/vote/17821 + minecraft-mp.com: + name: Minecraft-MP + link: http://minecraft-mp.com/server/14659/vote/ + mineservers.com: + name: MineServers + link: https://mineservers.com/server/W6e3OH60/vote +rewards: + tokens: + type: TOKENS + chance: GUARANTEED + amount: 1 \ No newline at end of file diff --git a/creative-master@2baad30b473/.gitignore b/creative-master@2baad30b473/.gitignore new file mode 100644 index 0000000..ad7f541 --- /dev/null +++ b/creative-master@2baad30b473/.gitignore @@ -0,0 +1,8 @@ + +\.idea/ + +target/classes/ + +target/ + +*.iml \ No newline at end of file diff --git a/creative-master@2baad30b473/README.md b/creative-master@2baad30b473/README.md new file mode 100644 index 0000000..91b5899 --- /dev/null +++ b/creative-master@2baad30b473/README.md @@ -0,0 +1,4 @@ +# GTMCore +Link: https://circleci.com/gh/GrandTheftMinecart/GTMCore +<br> +Latest Artifact: https://github.com/GrandTheftMinecart/GTMCore/releases/latest \ No newline at end of file diff --git a/creative-master@2baad30b473/pom.xml b/creative-master@2baad30b473/pom.xml new file mode 100644 index 0000000..7751ffc --- /dev/null +++ b/creative-master@2baad30b473/pom.xml @@ -0,0 +1,95 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>net.grandtheftmc</groupId> + <artifactId>creative</artifactId> + <version>1.0.0.feature_buildteam</version> + <name>Creative</name> + + <repositories> + <repository> + <id>spigot-repo</id> + <url>https://hub.spigotmc.org/nexus/content/repositories/public/</url> + </repository> + <repository> + <id>nexus-release</id> + <url>http://nexus.grandtheftmc.net/content/repositories/releases</url> + </repository> + </repositories> + + <distributionManagement> + <repository> + <id>nexus-release</id> + <name>Internal Releases</name> + <url>http://nexus.grandtheftmc.net/content/repositories/releases</url> + </repository> + <snapshotRepository> + <id>nexus-snapshot</id> + <name>Internal Snapshots</name> + <url>http://nexus.grandtheftmc.net/content/repositories/snapshots</url> + </snapshotRepository> + </distributionManagement> + + <dependencies> + <dependency> + <groupId>org.spigotmc</groupId> + <artifactId>spigot-api</artifactId> + <version>LATEST</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>net.grandtheftmc</groupId> + <artifactId>core</artifactId> + <version>2.3.7.2</version> + <scope>provided</scope> + </dependency> + </dependencies> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <maven.compiler.source>1.8</maven.compiler.source> + <maven.compiler.target>1.8</maven.compiler.target> + </properties> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-shade-plugin</artifactId> + <configuration> + <finalName>Creative</finalName> + </configuration> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>shade</goal> + </goals> + </execution> + </executions> + </plugin> + + <!-- Nexus deploy --> + <plugin> + <groupId>org.sonatype.plugins</groupId> + <artifactId>nexus-staging-maven-plugin</artifactId> + <version>1.6.8</version> + <extensions>true</extensions> + <executions> + <execution> + <id>default-deploy</id> + <phase>deploy</phase> + <goals> + <goal>deploy</goal> + </goals> + </execution> + </executions> + <configuration> + <serverId>nexus</serverId> + <nexusUrl>http://nexus.grandtheftmc.net:8081/nexus/</nexusUrl> + <skipStaging>true</skipStaging> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/Creative.java b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/Creative.java new file mode 100644 index 0000000..a2931db --- /dev/null +++ b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/Creative.java @@ -0,0 +1,102 @@ +package net.grandtheftmc.Creative; + +import net.grandtheftmc.Creative.commands.CreativeCommand; +import net.grandtheftmc.Creative.commands.CreativeRankCommand; +import net.grandtheftmc.Creative.commands.WorldCommand; +import net.grandtheftmc.Creative.listeners.*; +import net.grandtheftmc.Creative.users.CreativeUserManager; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Settings; +import net.grandtheftmc.core.util.Utils; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.java.JavaPlugin; + +public class Creative extends JavaPlugin { + + private static Creative instance; + private static CreativeUserManager um; + + private static Location spawn; + + private static CreativeSettings settings; + + @Override + public void onEnable() { + instance = this; + this.load(); + um = new CreativeUserManager(); + this.registerListeners(); + this.registerCommands(); + } + + @Override + public void onDisable() { + this.save(); + Bukkit.getScheduler().cancelTasks(this); + } + + public void load() { + settings = new CreativeSettings(); + YamlConfiguration c = Utils.loadConfig("creative"); + settings.setCreativeConfig(c); + spawn = Utils.teleportLocationFromString(c.getString("spawn")); + this.loadSettings(); + + } + + private void loadSettings() { + Settings s = Core.getSettings(); + s.setUseEditMode(false); + s.setDefaultGameMode(GameMode.CREATIVE); + s.setServerWarperEnabled(false); + s.setStatsMenuEnabled(false); + s.setCanCraft(true); + s.setCanOpenChests(true); + s.setCanInteractInventory(true); + s.setLoadCosmetics(true); + } + + public void save() { + YamlConfiguration c = settings.getCreativeConfig(); + c.set("spawn", Utils.teleportLocationToString(spawn)); + Utils.saveConfig(c, "creative"); + } + + private void registerListeners() { + PluginManager pm = Bukkit.getPluginManager(); + pm.registerEvents(new BlockPlace(), this); + pm.registerEvents(new Join(), this); + pm.registerEvents(new Leave(), this); + pm.registerEvents(new Login(), this); + pm.registerEvents(new PotionUse(), this); + pm.registerEvents(new UpdateListener(), this); + pm.registerEvents(new SwitchWorld(), this); + } + + private void registerCommands() { + this.getCommand("creative").setExecutor(new CreativeCommand()); + this.getCommand("creativerank").setExecutor(new CreativeRankCommand()); + new WorldCommand(); + } + + public static Creative getInstance() { + return instance; + } + + public static CreativeUserManager getUserManager() { + return um; + } + + public static Location getSpawn() { + return spawn; + } + + public static CreativeSettings getSettings() { + return settings; + } + +} diff --git a/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/CreativeSettings.java b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/CreativeSettings.java new file mode 100644 index 0000000..af55b4c --- /dev/null +++ b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/CreativeSettings.java @@ -0,0 +1,17 @@ +package net.grandtheftmc.Creative; + +import org.bukkit.configuration.file.YamlConfiguration; + +public class CreativeSettings { + + private YamlConfiguration creativeConfig; + + public YamlConfiguration getCreativeConfig() { + return creativeConfig; + } + + public void setCreativeConfig(YamlConfiguration creativeConfig) { + this.creativeConfig = creativeConfig; + } + +} diff --git a/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/CreativeUtils.java b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/CreativeUtils.java new file mode 100644 index 0000000..2bf2132 --- /dev/null +++ b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/CreativeUtils.java @@ -0,0 +1,11 @@ +package net.grandtheftmc.Creative; + +import org.bukkit.entity.Player; + +public class CreativeUtils { + + public static void spawnPlayer(final Player p) { + p.teleport(Creative.getSpawn()); + } + +} diff --git a/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/commands/CreativeCommand.java b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/commands/CreativeCommand.java new file mode 100644 index 0000000..f61ff18 --- /dev/null +++ b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/commands/CreativeCommand.java @@ -0,0 +1,37 @@ +package net.grandtheftmc.Creative.commands; + +import net.grandtheftmc.Creative.Creative; +import net.grandtheftmc.core.util.Utils; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +public class CreativeCommand implements CommandExecutor { + + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!s.isOp()) { + s.sendMessage(Utils.f("&cYou do not have permission to execute this command!")); + return true; + } + if (args.length == 0) { + s.sendMessage(Utils.f("&c/creative reload")); + s.sendMessage(Utils.f("&c/creative save")); + return true; + } + switch (args[0].toLowerCase()) { + case "reload": { + Creative.getInstance().load(); + s.sendMessage(Utils.f("&7Creative config reloaded.")); + return true; + } + case "save": { + Creative.getInstance().save(); + s.sendMessage(Utils.f("&7Creative config saved.")); + return true; + } + } + s.sendMessage(Utils.f("&c/creative <reload>")); + return true; + } + +} diff --git a/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/commands/CreativeRankCommand.java b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/commands/CreativeRankCommand.java new file mode 100644 index 0000000..99ce41a --- /dev/null +++ b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/commands/CreativeRankCommand.java @@ -0,0 +1,68 @@ +package net.grandtheftmc.Creative.commands; + +import net.grandtheftmc.Creative.Creative; +import net.grandtheftmc.Creative.users.CreativeRank; +import net.grandtheftmc.Creative.users.CreativeUser; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.UserRank; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.entity.Player; + +public class CreativeRankCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof ConsoleCommandSender || (s instanceof Player && Core.getUserManager().getLoadedUser(((Player)s).getUniqueId()).isRank(UserRank.BUILDER)))) { + s.sendMessage(Utils.f("&cYou do not have permission to execute this command!")); + return true; + } + if (args.length == 0) { + s.sendMessage(Utils.f("&c/creativerank set <player> <rank>")); + return true; + } + switch (args[0].toLowerCase()) { + case "set": + if (args.length != 3) { + s.sendMessage(Utils.f("&c/creativerank set <player> <rank>")); + return true; + } + CreativeRank rank = CreativeRank.getRankOrNull(args[2]); + if (rank == null) { + StringBuilder msgBuilder = new StringBuilder(Lang.RANKS + "&7There is no creativerank with the name &a" + args[2] + "&7! Valid ranks: "); + for (CreativeRank r : CreativeRank.getCreativeRanks()) + msgBuilder.append("&a").append(r.getColoredNameBold()).append("&7, "); + String msg = msgBuilder.toString(); + if (msg.endsWith("&7, ")) + msg = msg.substring(0, msg.length() - 4); + msg += "&c."; + s.sendMessage(Utils.f(msg)); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player == null) { + +// Core.sql.updateAsyncLater("update "+ Core.name()+" set rank='" + rank.getName() + "' where name='" + args[1] + "';"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update "+ Core.name()+" set rank='" + rank.getName() + "' where name='" + args[1] + "';")); + + s.sendMessage(Utils.f(Lang.RANKS + "&7That player is not online, so his rank has been forcibly updated in the database.")); + return true; + } + CreativeUser u = Creative.getUserManager().getLoadedUser(player.getUniqueId()); + u.setRank(rank, player, Core.getUserManager().getLoadedUser(player.getUniqueId())); + s.sendMessage(Utils.f(Lang.RANKS + "&a" + player.getName() + " &7is now a &a" + u.getRank().getColoredNameBold() + "&7!")); + return true; + + default: + s.sendMessage(Utils.f("&c/creativerank set <player> <rank>")); + return true; + } + } +} diff --git a/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/commands/WorldCommand.java b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/commands/WorldCommand.java new file mode 100644 index 0000000..b432057 --- /dev/null +++ b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/commands/WorldCommand.java @@ -0,0 +1,95 @@ +package net.grandtheftmc.Creative.commands; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import net.grandtheftmc.Creative.Creative; +import net.grandtheftmc.Creative.users.CreativeRank; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.commands.CoreCommand; +import net.grandtheftmc.core.editmode.WorldConfig; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.Utils; + +public class WorldCommand extends CoreCommand { + public WorldCommand() { + super("world", "Switch worlds", "switchworld"); + } + + @Override + public void execute(CommandSender sender, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage(Lang.NOPERM.s()); + return; + } + if (args.length == 0) { + sender.sendMessage(Utils.f("&c/world tp <world> [x] [y] [z] [pitch] [yaw]")); + return; + } + Player p = (Player) sender; + switch (args[0].toLowerCase()) { + case "tp": { + if (args.length == 1) { + sender.sendMessage(Utils.f("&c/world tp <world> [x] [y] [z] [yaw] [pitch]")); + return; + } + World world = Bukkit.getWorld(args[1]); + if (world == null) { + p.sendMessage(Utils.f("&cThat world does not exist!")); + return; + } + WorldConfig config = Core.getWorldManager().getWorldConfig(world.getName()); + if (config.isRestricted()) { + switch (config.getType()) { + case USERRANK: { + UserRank rank = UserRank.getUserRank(config.getRestricted()); + if (!Core.getUserManager().getLoadedUser(p.getUniqueId()).isRank(rank)) { + p.sendMessage(Lang.RANKS.f("&7You must be " + rank.getColoredNameBold() + "&7 to enter this world!")); + return; + } + break; + } + case RESTRICTED: + p.sendMessage(Lang.NOPERM.s()); + return; + case GAMERANK: + CreativeRank rank = CreativeRank.getRankOrNull(config.getRestricted()); + if (rank == null) rank = CreativeRank.CREATOR; + if (!Creative.getUserManager().getLoadedUser(p.getUniqueId()).isRank(rank)) { + p.sendMessage(Lang.RANKS.f("&7You must be " + rank.getColoredNameBold() + "&7 to enter this world!")); + return; + } + break; + case NONE: + break; + } + + } + double x = 0, y = 0, z = 0; + float pitch = 0, yaw = 0; + if (args.length > 2) try { + x = Double.valueOf(args[2]); + if (args.length > 3) + y = Double.valueOf(args[3]); + if (args.length > 4) + z = Double.valueOf(args[4]); + if (args.length > 5) + yaw = Float.valueOf(args[5]); + if (args.length > 6) + pitch = Float.valueOf(args[6]); + + } catch (NumberFormatException e) { + p.sendMessage(Utils.f("&cMake sure all of the numbers are Doubles (e.g. 0, 90, 150.7, 6.969)")); + return; + } + p.sendMessage(Utils.f("&aTeleporting...")); + Location location = new Location(world, x, y, z, yaw, pitch); + p.teleport(location); + } + } + } +} diff --git a/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/listeners/BlockPlace.java b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/listeners/BlockPlace.java new file mode 100644 index 0000000..3b984f2 --- /dev/null +++ b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/listeners/BlockPlace.java @@ -0,0 +1,31 @@ +package net.grandtheftmc.Creative.listeners; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockFromToEvent; +import org.bukkit.event.block.BlockPlaceEvent; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.users.User; + +public class BlockPlace implements Listener { + + @EventHandler + public void onPlace(BlockPlaceEvent event) { + Block block = event.getBlockPlaced(); + Player player = event.getPlayer(); + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (!user.isStaff() && (block.getType().equals(Material.DRAGON_EGG) || block.getType().equals(Material.BARRIER) | block.getType().equals(Material.NETHER_PORTAL))) + event.setCancelled(true); + } + + @EventHandler + public void onBlockChange(BlockFromToEvent event) { + if (event.getToBlock().getType().equals(Material.NETHER_PORTAL)) { + event.setCancelled(true); + } + } +} diff --git a/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/listeners/Join.java b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/listeners/Join.java new file mode 100644 index 0000000..37e7f2b --- /dev/null +++ b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/listeners/Join.java @@ -0,0 +1,23 @@ +package net.grandtheftmc.Creative.listeners; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.Utils; +import org.bukkit.GameMode; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; + +public class Join implements Listener { + + @EventHandler + public void onJoin(PlayerJoinEvent event) { + Player player = event.getPlayer(); + if (player.getGameMode() != GameMode.CREATIVE) player.setGameMode(GameMode.CREATIVE); + player.sendMessage(Core.getAnnouncer().getHeader()); + player.sendMessage(Utils.f("&7Welcome to &aCreative!")); + player.sendMessage(Utils.f("&7Use &a/plot auto &7to get started with a plot.")); + player.sendMessage(Core.getAnnouncer().getFooter()); + } + +} diff --git a/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/listeners/Leave.java b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/listeners/Leave.java new file mode 100644 index 0000000..4c0f165 --- /dev/null +++ b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/listeners/Leave.java @@ -0,0 +1,20 @@ +package net.grandtheftmc.Creative.listeners; + +import net.grandtheftmc.Creative.Creative; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerQuitEvent; + +import java.util.UUID; + +/** + * Created by Liam on 22/07/2017. + */ +public class Leave implements Listener { + @EventHandler(priority = EventPriority.MONITOR) + public void onLeaveMonitor(PlayerQuitEvent e) { + UUID uuid = e.getPlayer().getUniqueId(); + Creative.getUserManager().unloadUser(uuid); + } +} diff --git a/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/listeners/Login.java b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/listeners/Login.java new file mode 100644 index 0000000..3a1cf90 --- /dev/null +++ b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/listeners/Login.java @@ -0,0 +1,41 @@ +package net.grandtheftmc.Creative.listeners; + +import net.grandtheftmc.Creative.Creative; +import net.grandtheftmc.Creative.users.CreativeUser; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.Utils; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerPreLoginEvent; +import org.bukkit.event.player.PlayerLoginEvent; +import org.bukkit.event.player.PlayerLoginEvent.Result; + +import java.util.UUID; + +public class Login implements Listener { + + @EventHandler + public void onLogin(AsyncPlayerPreLoginEvent e) { + CreativeUser user = Creative.getUserManager().getLoadedUser(e.getUniqueId()); + user.dataCheck(e.getName(), Core.getUserManager().getLoadedUser(e.getUniqueId()).getUserRank()); + if (!user.updateDataFromDb()) + e.disallow(org.bukkit.event.player.AsyncPlayerPreLoginEvent.Result.KICK_OTHER, + "&cAn error occured while trying to fetch your data from the database. Please try again in a few seconds!"); + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onLoginMonitor(PlayerLoginEvent e) { + Player player = e.getPlayer(); + UUID uuid = player.getUniqueId(); + CreativeUser user = Creative.getUserManager().getLoadedUser(uuid); + if (!user.hasUpdated()) + e.disallow(PlayerLoginEvent.Result.KICK_OTHER, Utils.f("&cThe server is still restarting! Please try again in a few seconds!")); + if (e.getResult() == Result.ALLOWED) + return; + Creative.getUserManager().unloadUser(uuid); + + } + +} diff --git a/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/listeners/PotionUse.java b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/listeners/PotionUse.java new file mode 100644 index 0000000..a83fe59 --- /dev/null +++ b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/listeners/PotionUse.java @@ -0,0 +1,29 @@ +package net.grandtheftmc.Creative.listeners; + +import org.bukkit.Material; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.PotionSplashEvent; +import org.bukkit.event.player.PlayerItemConsumeEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.PotionMeta; +import org.bukkit.potion.PotionEffect; + +public class PotionUse implements Listener { + + @EventHandler + public void onThrow(PotionSplashEvent event) { + event.setCancelled(true); + } + + @EventHandler + public void onDrink(PlayerItemConsumeEvent event) { + ItemStack item = event.getItem(); + if (!item.getType().equals(Material.POTION)) + return; + PotionMeta pot = (PotionMeta) item.getItemMeta(); + for (PotionEffect eff : pot.getCustomEffects()) { + if (eff.getAmplifier() < 0) event.setCancelled(true); + } + } +} diff --git a/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/listeners/SwitchWorld.java b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/listeners/SwitchWorld.java new file mode 100644 index 0000000..7003aeb --- /dev/null +++ b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/listeners/SwitchWorld.java @@ -0,0 +1,23 @@ +package net.grandtheftmc.Creative.listeners; + +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +import net.grandtheftmc.Creative.Creative; +import net.grandtheftmc.Creative.users.CreativeRank; +import net.grandtheftmc.core.editmode.WorldConfig; +import net.grandtheftmc.core.events.PlayerSwitchWorldEvent; + +public class SwitchWorld implements Listener { + + @EventHandler + public void onSwitchWorld(PlayerSwitchWorldEvent e) { + if (e.getToWorldConfig().isRestricted() && e.getToWorldConfig().getType() == WorldConfig.RestrictedType.GAMERANK) { + CreativeRank + rank = CreativeRank.getRankOrNull(e.getToWorldConfig().getRestricted()); + if (rank == null) rank = CreativeRank.CREATOR; + if (!Creative.getUserManager().getLoadedUser(e.getPlayer().getUniqueId()).isRank(rank)) + e.setCancelled(true); + } + } +} diff --git a/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/listeners/UpdateListener.java b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/listeners/UpdateListener.java new file mode 100644 index 0000000..a76644b --- /dev/null +++ b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/listeners/UpdateListener.java @@ -0,0 +1,45 @@ +package net.grandtheftmc.Creative.listeners; + +import net.grandtheftmc.Creative.Creative; +import net.grandtheftmc.Creative.users.CreativeRank; +import net.grandtheftmc.Creative.users.CreativeUser; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.events.DisplayNameUpdateEvent; +import net.grandtheftmc.core.events.GetPermsEvent; +import net.grandtheftmc.core.events.NametagUpdateEvent; +import net.grandtheftmc.core.users.User; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +public class UpdateListener implements Listener { + + + @EventHandler + public void onDisplayNameUpdate(DisplayNameUpdateEvent e) { + Player player = e.getPlayer(); + CreativeUser u = Creative.getUserManager().getLoadedUser(player.getUniqueId()); + if (u.isRank(CreativeRank.TRAINEE)) + e.setPrefix(u.getRank().getColoredNameBold()); + } + + @EventHandler + public void onGetPerms(GetPermsEvent e) { + CreativeUser user = Creative.getUserManager().getLoadedUser(e.getUUID()); + if (user != null && user.getRank() != null) + user.getRank().getAllPerms().forEach(e::addPerm); + } + + @EventHandler + public void onNametagChange(NametagUpdateEvent e) { + Player player = e.getPlayer(); + if (player == null) + return; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + CreativeUser creativeUser = Creative.getUserManager().getLoadedUser(player.getUniqueId()); + if (creativeUser.isRank(CreativeRank.TRAINEE)) + e.setSuffix(Utils.f(creativeUser.getRank().getColoredNameBold())); + } + +} diff --git a/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/users/CreativeRank.java b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/users/CreativeRank.java new file mode 100644 index 0000000..6494c85 --- /dev/null +++ b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/users/CreativeRank.java @@ -0,0 +1,202 @@ +package net.grandtheftmc.Creative.users; + +import net.grandtheftmc.core.util.Utils; +import org.bukkit.ChatColor; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +public enum CreativeRank { + + DEFAULT(), + TRAINEE("plots.limit.100", "plots.plot.100", "worldedit.navigation.thru.command", + "worldedit.wand", + "worldedit.history.undo", + "worldedit.region.set", + "worldedit.region.walls", + "worldedit.selection.pos", + "voxelsniper.sniper"), + NOVICE("plots.limit.200", "plots.plot.200", "worldedit.region.replace", + "worldedit.history.redo", + "worldedit.clipboard.copy", + "worldedit.clipboard.paste", + "worldedit.region.stack", + "worldedit.selection.expand", + "worldedit.clipboard.rotate", + "worldedit.region.move", + "worldeedit.generation.cylinder", + "worldedit.generation.sphere", + "worldedit.brush.smooth", + "worldedit.fill", + "worldedit.region.smooth"), + ARTIST("plots.limit.300", "plots.plot.300", "worldedit.*", + "voxelsniper.goto", + "voxelsniper.brush.ball", + "voxelsniper.brush.cylinder", + "voxelsniper.brush.voxel", + "voxelsniper.brush.stencil", + "voxelsniper.brush.stencillist", + "Voxelsniper.brush.ruler", + "voxelsniper.brush.generatetree", + "voxelsniper.sniper", + "voxelsniper.goto", + "voxelsniper.brush.ball", + "voxelsniper.brush.cylinder", + "voxelsniper.brush.voxel", + "voxelsniper.brush.set", + "voxelsniper.brush.blendball", + "voxelsniper.brush.blenddisc", + "voxelsniper.brush.blendvoxel", + "voxelsniper.brush.blendvoxeldisc", + "voxelsniper.brush.move", + "voxelsniper.brush.stencil", + "voxelsniper.brush.stencillist", + "voxelsniper.brush.rot2d", + "voxelsniper.brush.rot2dvert", + "voxelsniper.brush.rot3d", + "Voxelsniper.brush.ruler", + "Voxelsniper.brush.generatetree", + "voxelsniper.brush.eraser", + "Voxelsniper.brush.erode", + "voxelsniper.brush.disc", + "voxelsniper.brush.discface", + "voxelsniper.brush.biome", + "voxelsniper.brush.splatterball", + "voxelsniper.brush.splatterdisc", + "voxelsniper.brush.splatteroverlay", + "voxelsniper.brush.splattervoxel", + "voxelsniper.brush.splattervoxeldisc"), + CREATOR("plots.limit.1000", "plots.plot.1000", "Voxelsniper.sniper", + "voxelsniper.goto", + "voxelsniper.brush.blob", + "voxelsniper.brush.blockreset", + "voxelsniper.brush.blockresetsurface", + "voxelsniper.brush.canyon", + "voxelsniper.brush.canyonselection", + "voxelsniper.brush.checkervoxeldisc", + "voxelsniper.brush.cleansnow", + "voxelsniper.brush.clonestamp", + "voxelsniper.brush.copypasta", + "voxelsniper.brush.cylinder", + "voxelsniper.brush.dome", + "voxelsniper.brush.drain", + "voxelsniper.brush.ellipse", + "voxelsniper.brush.ellipsoid", + "voxelsniper.brush.extrude", + "voxelsniper.brush.filldown", + "voxelsniper.brush.flatocean", + "voxelsniper.brush.heatray", + "voxelsniper.brush.jaggedlinev", + "voxelsniper.brush.line", + "voxelsniper.brush.overlay", + "voxelsniper.brush.pull", + "voxelsniper.brush.randomerode", + "voxelsniper.brush.regeneratechunk", + "voxelsniper.brush.ring", + "voxelsniper.brush.scanner", + "voxelsniper.brush.set", + "voxelsniper.brush.setredstoneflip", + "voxelsniper.brush.setredstonerotate", + "voxelsniper.brush.shellball", + "voxelsniper.brush.shellset", + "voxelsniper.brush.shellvoxel", + "voxelsniper.brush.signoverwrite", + "voxelsniper.brush.snipe", + "voxelsniper.brush.snowcone", + "voxelsniper.brush.spiralstaircase", + "voxelsniper.brush.spline", + "voxelsniper.brush.stamp", + "voxelsniper.brush.threepointcircle", + "voxelsniper.brush.treesnipe", + "voxelsniper.brush.triangle", + "voxelsniper.brush.underlay", + "voxelsniper.brush.voltmeterv", + "voxelsniper.brush.voxel", + "voxelsniper.brush.voxeldisc", + "voxelsniper.brush.voxeldiscface", + "voxelsniper.brush.warp"); + + private final List<String> perms; + + CreativeRank(String... perms) { + this.perms = Arrays.asList(perms); + } + + public List<String> getAllPerms() { + List<String> permissions = new ArrayList<>(); + for (CreativeRank uc : getCreativeRanks()) { + permissions.addAll(uc.perms); + if (uc == this) + return permissions; + } + return permissions; + } + + private List<String> getPerms() { + return this.perms; + } + + public String getName() { + return this.toString(); + } + + public ChatColor getColor() { + return this == CreativeRank.DEFAULT ? ChatColor.GRAY : ChatColor.YELLOW; + } + + public String getColoredName() { + return Utils.f(this.getColor() + this.getName() + "&r"); + } + + public String getColoredNameBold() { + return Utils.f(this.getColor() + "&l" + this.getName() + "&r"); + } + + public CreativeRank getNext() { + String rankName = this.getName(); + if ("CREATOR".equalsIgnoreCase(rankName)) + return null; + int go = 0; + + CreativeRank rank = null; + for (CreativeRank r : getCreativeRanks()) + if (go == 0) { + if (Objects.equals(r.getName(), rankName)) { + go = 1; + } + } else if (go == 1) { + rank = r; + break; + } + return rank; + } + + public static CreativeRank[] getCreativeRanks() { + return CreativeRank.class.getEnumConstants(); + } + + public static CreativeRank fromString(String string) { + return Arrays.stream(CreativeRank.getCreativeRanks()).filter(uc -> uc.getName().equalsIgnoreCase(string)).findFirst().orElse(CreativeRank.DEFAULT); + } + + + public static CreativeRank getRankOrNull(String name) { + if (name == null) + return null; + return Arrays.stream(getCreativeRanks()).filter(r -> r.getName().equalsIgnoreCase(name)).findFirst().orElse(null); + } + + public boolean isHigherThan(CreativeRank rank) { + if (rank == null) + return false; + for (CreativeRank r : getCreativeRanks()) + if (r == this) + return false; + else if (r == rank) + return true; + return false; + } + +} diff --git a/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/users/CreativeUser.java b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/users/CreativeUser.java new file mode 100644 index 0000000..913c598 --- /dev/null +++ b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/users/CreativeUser.java @@ -0,0 +1,95 @@ +package net.grandtheftmc.Creative.users; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.nametags.NametagManager; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.ServerUtil; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.UUID; + +public class CreativeUser { + + private final UUID uuid; + private CreativeRank rank; + private boolean hasUpdated; + + public CreativeUser(UUID uuid) { + this.uuid = uuid; + } + + public UUID getUUID() { + return this.uuid; + } + + public void dataCheck(String name, UserRank rank) { +// sql.update("insert into " + Core.name() + "(uuid,name) values('" + this.uuid + "','" + name +// + "') on duplicate key update name='" + name + "';"); +// sql.update("update " + Core.name() + " set name='ERROR' where name='" + name + "' and uuid!='" + this.uuid +// + "';"); + + BaseDatabase.runCustomQuery("insert into " + Core.name() + "(uuid,name) values('" + this.uuid + "','" + name + + "') on duplicate key update name='" + name + "';"); + BaseDatabase.runCustomQuery("update " + Core.name() + " set name='ERROR' where name='" + name + "' and uuid!='" + this.uuid + "';"); + } + + public boolean updateDataFromDb() { + boolean b = true; +// try(ResultSet rs = sql.query("select * from " + Core.name() + " where uuid='" + this.uuid + "' LIMIT 1;")) { +// if (rs.next()) { +// this.rank = CreativeRank.fromString(rs.getString("rank")); +// } else +// b = false; +// rs.close(); +// } catch (SQLException e) { +// e.printStackTrace(); +// b = false; +// } + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("select * from " + Core.name() + " where uuid='" + this.uuid + "' LIMIT 1;")) { + try (ResultSet result = statement.executeQuery()) { + if(result.next()) this.rank = CreativeRank.fromString(result.getString("rank")); + else b = false; + } + } + } catch (SQLException e) { + e.printStackTrace(); + b = false; + } + + this.hasUpdated = b; + return b; + } + + public CreativeRank getRank() { + return this.rank; + } + + public boolean isRank(CreativeRank rank) { + return !(rank == null || this.rank == null) && (this.rank == rank || this.rank.isHigherThan(rank)); + } + + public void setRank(CreativeRank r, Player player, User u) { + this.rank = r; + +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set rank='" + r.getName() + "' where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + Core.name() + " set rank='" + r.getName() + "' where uuid='" + this.uuid + "';")); + + NametagManager.updateNametag(Bukkit.getPlayer(this.uuid)); + u.setPerms(player); + } + + + public boolean hasUpdated() { + return this.hasUpdated; + } +} \ No newline at end of file diff --git a/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/users/CreativeUserManager.java b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/users/CreativeUserManager.java new file mode 100644 index 0000000..cfefd36 --- /dev/null +++ b/creative-master@2baad30b473/src/main/java/net/grandtheftmc/Creative/users/CreativeUserManager.java @@ -0,0 +1,27 @@ +package net.grandtheftmc.Creative.users; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public class CreativeUserManager { + + private final Map<UUID, CreativeUser> loadedUsers = new HashMap<>(); + + public Collection<CreativeUser> getLoadedUsers() { + return this.loadedUsers.values(); + } + + public boolean unloadUser(UUID uuid) { + return this.loadedUsers.remove(uuid) != null; + } + + public CreativeUser getLoadedUser(UUID uuid) { + if (uuid == null) { + return null; + } + return this.loadedUsers.computeIfAbsent(uuid, CreativeUser::new); + } + +} \ No newline at end of file diff --git a/creative-master@2baad30b473/src/main/resources/creative.yml b/creative-master@2baad30b473/src/main/resources/creative.yml new file mode 100644 index 0000000..95b631d --- /dev/null +++ b/creative-master@2baad30b473/src/main/resources/creative.yml @@ -0,0 +1 @@ +spawn: 0,0,0,0,0 \ No newline at end of file diff --git a/creative-master@2baad30b473/src/main/resources/plugin.yml b/creative-master@2baad30b473/src/main/resources/plugin.yml new file mode 100644 index 0000000..da36c9d --- /dev/null +++ b/creative-master@2baad30b473/src/main/resources/plugin.yml @@ -0,0 +1,12 @@ + name: Creative + version: 1.0 + description: Grand Theft Minecart Creative + author: Presidentx + main: net.grandtheftmc.Creative.Creative + depend: [Core] + commands: + creative: + description: Reload the config of Creative + usage: /creative <reload> + creativerank: + aliases: [crank] diff --git a/fanciful-master@6fb8a853dd2/.gitignore b/fanciful-master@6fb8a853dd2/.gitignore new file mode 100644 index 0000000..05381b2 --- /dev/null +++ b/fanciful-master@6fb8a853dd2/.gitignore @@ -0,0 +1,22 @@ +# Eclipse stuff +/.classpath +/.project +/.settings + +# netbeans +/nbproject + +#IntelliJ +*.iml +/.idea + +# various other potential build files +/bin +/dist +/manifest.mf +/.fatjar + +# Mac filesystem dust +.DS_Store +.DS_Storetarget +/target \ No newline at end of file diff --git a/fanciful-master@6fb8a853dd2/.travis.yml b/fanciful-master@6fb8a853dd2/.travis.yml new file mode 100644 index 0000000..dff5f3a --- /dev/null +++ b/fanciful-master@6fb8a853dd2/.travis.yml @@ -0,0 +1 @@ +language: java diff --git a/fanciful-master@6fb8a853dd2/LICENSE b/fanciful-master@6fb8a853dd2/LICENSE new file mode 100644 index 0000000..5801ca2 --- /dev/null +++ b/fanciful-master@6fb8a853dd2/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2013-2015 Max Kreminski + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/fanciful-master@6fb8a853dd2/README.md b/fanciful-master@6fb8a853dd2/README.md new file mode 100644 index 0000000..426b8e9 --- /dev/null +++ b/fanciful-master@6fb8a853dd2/README.md @@ -0,0 +1,32 @@ +Fanciful [![Build Status](https://travis-ci.org/mkremins/fanciful.svg?branch=master)](https://travis-ci.org/mkremins/fanciful) +======== +Lightweight library offering pleasant chat message formatting for Bukkit plugins. A way to get at the good stuff offered by Minecraft 1.7's new chat protocol without dropping down to raw JSON. + +Installation +-------- +Use Maven. Add the Fanciful dependency entry to your `pom.xml`. + +```xml +<dependency> + <groupId>mkremins</groupId> + <artifactId>fanciful</artifactId> + <version>0.4.0-SNAPSHOT</version> +</dependency> +``` + +As of [October 2017](https://github.com/mkremins/fanciful/issues/83), the Maven repository that formerly hosted Fanciful artifacts has been shut down. You could continue using Fanciful by cloning this GitHub repository, building Fanciful as a JAR, and [installing it locally](http://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html), but this is not recommended unless you know what you're doing. + +Usage +-------- +See [Example.java](http://github.com/mkremins/fanciful/tree/master/src/example/java/mkremins/fanciful/Example.java) for a simple example. + +Status +-------- +Outdated, and largely superseded by newer libraries. No new development or ongoing support. If you're still using Fanciful or looking for something like it, consider one of the following Fanciful-inspired alternatives: + +* Spigot's [ChatComponent API](https://www.spigotmc.org/wiki/the-chat-component-api/) +* [KyoriPowered/text](https://github.com/KyoriPowered/text) + +License +-------- +[MIT License](http://opensource.org/licenses/MIT). Hack away. diff --git a/fanciful-master@6fb8a853dd2/pom.xml b/fanciful-master@6fb8a853dd2/pom.xml new file mode 100644 index 0000000..22c6de0 --- /dev/null +++ b/fanciful-master@6fb8a853dd2/pom.xml @@ -0,0 +1,116 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>mkremins</groupId> + <artifactId>fanciful</artifactId> + <version>0.4.0</version> + <packaging>jar</packaging> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <repositories> + <repository> + <id>spigot-repo</id> + <url>https://hub.spigotmc.org/nexus/content/groups/public/</url> + </repository> + <repository> + <id>nexus-release</id> + <url>https://nexus.grandtheftmc.net/content/repositories/releases/</url> + </repository> + </repositories> + + <dependencies> + <dependency> + <groupId>org.bukkit</groupId> + <artifactId>bukkit</artifactId> + <version>1.10-R0.1-SNAPSHOT</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + <version>2.1</version> + </dependency> + </dependencies> + + <distributionManagement> + <repository> + <id>nexus-release</id> + <name>Internal Releases</name> + <url>https://nexus.grandtheftmc.net/content/repositories/releases/</url> + </repository> + <snapshotRepository> + <id>nexus-snapshot</id> + <name>Internal Snapshots</name> + <url>https://nexus.grandtheftmc.net/content/repositories/snapshots/</url> + </snapshotRepository> + </distributionManagement> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.1</version> + <configuration> + <source>1.7</source> + <target>1.7</target> + <showDeprecation>true</showDeprecation> + <showWarnings>true</showWarnings> + </configuration> + </plugin> + <!-- Shade GSON because it's no longer in Spigot. --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-shade-plugin</artifactId> + <version>2.2</version> + <configuration> + <createDependencyReducedPom>false</createDependencyReducedPom> + <artifactSet> + <includes> + <include>com.google.code.gson:gson</include> + </includes> + </artifactSet> + <relocations> + <relocation> + <pattern>com.google.gson</pattern> + <shadedPattern>mkremins.fanciful.shaded.gson</shadedPattern> + </relocation> + </relocations> + </configuration> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>shade</goal> + </goals> + </execution> + </executions> + </plugin> + + <!-- Nexus deploy --> + <plugin> + <groupId>org.sonatype.plugins</groupId> + <artifactId>nexus-staging-maven-plugin</artifactId> + <version>1.6.8</version> + <extensions>true</extensions> + <executions> + <execution> + <id>default-deploy</id> + <phase>deploy</phase> + <goals> + <goal>deploy</goal> + </goals> + </execution> + </executions> + <configuration> + <serverId>nexus</serverId> + <nexusUrl>http://nexus.grandtheftmc.net/nexus/</nexusUrl> + <skipStaging>true</skipStaging> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/fanciful-master@6fb8a853dd2/src/example/java/mkremins/fanciful/Example.java b/fanciful-master@6fb8a853dd2/src/example/java/mkremins/fanciful/Example.java new file mode 100644 index 0000000..edb4ad4 --- /dev/null +++ b/fanciful-master@6fb8a853dd2/src/example/java/mkremins/fanciful/Example.java @@ -0,0 +1,70 @@ +package mkremins.fanciful; + +import static org.bukkit.ChatColor.*; +import mkremins.fanciful.FancyMessage; + +/** + * An example class demonstrating some of Fanciful's functionality. + * This is not a plugin, but a program. + */ +public final class Example { + + public static void main(String[] args) { + System.out.println(welcome("Orbixitron")); + System.out.println(advertisement()); + System.out.println(gui("Starbux42", 413000)); + } + + static String welcome(String playername) { + return new FancyMessage("Hello, ") + .color(YELLOW) + .then(playername) + .color(LIGHT_PURPLE) + .style(ITALIC, UNDERLINE) + .then("!") + .color(YELLOW) + .style(ITALIC) + .toJSONString(); + } + + static String advertisement() { + return new FancyMessage("Visit ") + .color(GREEN) + .then("our website") + .color(YELLOW) + .style(UNDERLINE) + .link("http://awesome-server.net") + .tooltip("AwesomeServer Forums") + .then(" to win ") + .color(GREEN) + .then("big prizes!") + .color(AQUA) + .style(BOLD) + .tooltip("Terms and conditions may apply. Offer not valid in Sweden.") + .toJSONString(); + } + + static String gui(String playername, int blocksEdited) { + return new FancyMessage("Player ") + .color(DARK_RED) + .then(playername) + .color(RED) + .style(ITALIC) + .then(" changed ").color(DARK_RED) + .then(Integer.toString(blocksEdited)).color(AQUA) + .then(" blocks. ").color(DARK_RED) + .then("Roll back?") + .color(GOLD) + .style(UNDERLINE) + .suggest("/rollenbacken " + playername) + .tooltip("Be careful, this might undo legitimate edits!") + .then(" ") + .then("Ban?") + .color(RED) + .style(UNDERLINE) + .suggest("/banhammer " + playername) + .tooltip("Remember: only ban if you have photographic evidence of grief.") + .toJSONString(); + } + +} diff --git a/fanciful-master@6fb8a853dd2/src/main/java/mkremins/fanciful/FancyMessage.java b/fanciful-master@6fb8a853dd2/src/main/java/mkremins/fanciful/FancyMessage.java new file mode 100644 index 0000000..dc524c5 --- /dev/null +++ b/fanciful-master@6fb8a853dd2/src/main/java/mkremins/fanciful/FancyMessage.java @@ -0,0 +1,655 @@ +package mkremins.fanciful; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.stream.JsonWriter; +import net.amoebaman.util.ArrayWrapper; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.configuration.serialization.ConfigurationSerialization; +import org.bukkit.entity.Player; +import java.io.IOException; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; + +import static mkremins.fanciful.TextualComponent.rawText; + +/** + * Represents a formattable message. Such messages can use elements such as colors, formatting codes, hover and click data, and other features provided by the vanilla Minecraft <a href="http://minecraft.gamepedia.com/Tellraw#Raw_JSON_Text">JSON message formatter</a>. + * This class allows plugins to emulate the functionality of the vanilla Minecraft <a href="http://minecraft.gamepedia.com/Commands#tellraw">tellraw command</a>. + * <p> + * This class follows the builder pattern, allowing for method chaining. + * It is set up such that invocations of property-setting methods will affect the current editing component, + * and a call to {@link #then()} or {@link #then(String)} will append a new editing component to the end of the message, + * optionally initializing it with text. Further property-setting method calls will affect that editing component. + * </p> + */ +public class FancyMessage implements JsonRepresentedObject, Cloneable, Iterable<MessagePart>, ConfigurationSerializable { + + static { + ConfigurationSerialization.registerClass(FancyMessage.class); + } + + private List<MessagePart> messageParts; + private String jsonString; + private boolean dirty; + + @Override + public FancyMessage clone() throws CloneNotSupportedException { + FancyMessage instance = (FancyMessage) super.clone(); + instance.messageParts = new ArrayList<MessagePart>(messageParts.size()); + for (int i = 0; i < messageParts.size(); i++) { + instance.messageParts.add(i, messageParts.get(i).clone()); + } + instance.dirty = false; + instance.jsonString = null; + return instance; + } + + /** + * Creates a JSON message with text. + * + * @param firstPartText The existing text in the message. + */ + public FancyMessage(final String firstPartText) { + this(rawText(firstPartText)); + } + + public FancyMessage(final TextualComponent firstPartText) { + messageParts = new ArrayList<MessagePart>(); + messageParts.add(new MessagePart(firstPartText)); + jsonString = null; + dirty = false; + } + + /** + * Creates a JSON message without text. + */ + public FancyMessage() { + this((TextualComponent) null); + } + + /** + * Sets the text of the current editing component to a value. + * + * @param text The new text of the current editing component. + * @return This builder instance. + */ + public FancyMessage text(String text) { + MessagePart latest = latest(); + latest.text = rawText(text); + dirty = true; + return this; + } + + /** + * Sets the text of the current editing component to a value. + * + * @param text The new text of the current editing component. + * @return This builder instance. + */ + public FancyMessage text(TextualComponent text) { + MessagePart latest = latest(); + latest.text = text; + dirty = true; + return this; + } + + /** + * Sets the color of the current editing component to a value. + * + * @param color The new color of the current editing component. + * @return This builder instance. + * @throws IllegalArgumentException If the specified {@code ChatColor} enumeration value is not a color (but a format value). + */ + public FancyMessage color(final ChatColor color) { + if (!color.isColor()) { + throw new IllegalArgumentException(color.name() + " is not a color"); + } + latest().color = color; + dirty = true; + return this; + } + + /** + * Sets the stylization of the current editing component. + * + * @param styles The array of styles to apply to the editing component. + * @return This builder instance. + * @throws IllegalArgumentException If any of the enumeration values in the array do not represent formatters. + */ + public FancyMessage style(ChatColor... styles) { + for (final ChatColor style : styles) { + if (!style.isFormat()) { + throw new IllegalArgumentException(style.name() + " is not a style"); + } + } + latest().styles.addAll(Arrays.asList(styles)); + dirty = true; + return this; + } + + /** + * Set the behavior of the current editing component to instruct the client to open a file on the client side filesystem when the currently edited part of the {@code FancyMessage} is clicked. + * + * @param path The path of the file on the client filesystem. + * @return This builder instance. + */ + public FancyMessage file(final String path) { + onClick("open_file", path); + return this; + } + + /** + * Set the behavior of the current editing component to instruct the client to open a webpage in the client's web browser when the currently edited part of the {@code FancyMessage} is clicked. + * + * @param url The URL of the page to open when the link is clicked. + * @return This builder instance. + */ + public FancyMessage link(final String url) { + onClick("open_url", url); + return this; + } + + /** + * Set the behavior of the current editing component to instruct the client to replace the chat input box content with the specified string when the currently edited part of the {@code FancyMessage} is clicked. + * The client will not immediately send the command to the server to be executed unless the client player submits the command/chat message, usually with the enter key. + * + * @param command The text to display in the chat bar of the client. + * @return This builder instance. + */ + public FancyMessage suggest(final String command) { + onClick("suggest_command", command); + return this; + } + + /** + * Set the behavior of the current editing component to instruct the client to append the chat input box content with the specified string when the currently edited part of the {@code FancyMessage} is SHIFT-CLICKED. + * The client will not immediately send the command to the server to be executed unless the client player submits the command/chat message, usually with the enter key. + * + * @param command The text to append to the chat bar of the client. + * @return This builder instance. + */ + public FancyMessage insert(final String command) { + latest().insertionData = command; + dirty = true; + return this; + } + + /** + * Set the behavior of the current editing component to instruct the client to send the specified string to the server as a chat message when the currently edited part of the {@code FancyMessage} is clicked. + * The client <b>will</b> immediately send the command to the server to be executed when the editing component is clicked. + * + * @param command The text to display in the chat bar of the client. + * @return This builder instance. + */ + public FancyMessage command(final String command) { + onClick("run_command", command); + return this; + } + + /** + * Set the behavior of the current editing component to display information about an achievement when the client hovers over the text. + * <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p> + * + * @param name The name of the achievement to display, excluding the "achievement." prefix. + * @return This builder instance. + */ + public FancyMessage achievementTooltip(final String name) { + onHover("show_achievement", new JsonString("achievement." + name)); + return this; + } + + /** + * Set the behavior of the current editing component to display raw text when the client hovers over the text. + * <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p> + * + * @param text The text, which supports newlines, which will be displayed to the client upon hovering. + * @return This builder instance. + */ + public FancyMessage tooltip(final String text) { + onHover("show_text", new JsonString(text)); + return this; + } + + /** + * Set the behavior of the current editing component to display raw text when the client hovers over the text. + * <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p> + * + * @param lines The lines of text which will be displayed to the client upon hovering. The iteration order of this object will be the order in which the lines of the tooltip are created. + * @return This builder instance. + */ + public FancyMessage tooltip(final Iterable<String> lines) { + tooltip(ArrayWrapper.toArray(lines, String.class)); + return this; + } + + /** + * Set the behavior of the current editing component to display raw text when the client hovers over the text. + * <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p> + * + * @param lines The lines of text which will be displayed to the client upon hovering. + * @return This builder instance. + */ + public FancyMessage tooltip(final String... lines) { + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < lines.length; i++) { + builder.append(lines[i]); + if (i != lines.length - 1) { + builder.append('\n'); + } + } + tooltip(builder.toString()); + return this; + } + + /** + * Set the behavior of the current editing component to display formatted text when the client hovers over the text. + * <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p> + * + * @param text The formatted text which will be displayed to the client upon hovering. + * @return This builder instance. + */ + public FancyMessage formattedTooltip(FancyMessage text) { + for (MessagePart component : text.messageParts) { + if (component.clickActionData != null && component.clickActionName != null) { + throw new IllegalArgumentException("The tooltip text cannot have click data."); + } else if (component.hoverActionData != null && component.hoverActionName != null) { + throw new IllegalArgumentException("The tooltip text cannot have a tooltip."); + } + } + onHover("show_text", text); + return this; + } + + /** + * Set the behavior of the current editing component to display the specified lines of formatted text when the client hovers over the text. + * <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p> + * + * @param lines The lines of formatted text which will be displayed to the client upon hovering. + * @return This builder instance. + */ + public FancyMessage formattedTooltip(FancyMessage... lines) { + if (lines.length < 1) { + onHover(null, null); // Clear tooltip + return this; + } + + FancyMessage result = new FancyMessage(); + result.messageParts.clear(); // Remove the one existing text component that exists by default, which destabilizes the object + + for (int i = 0; i < lines.length; i++) { + try { + for (MessagePart component : lines[i]) { + if (component.clickActionData != null && component.clickActionName != null) { + throw new IllegalArgumentException("The tooltip text cannot have click data."); + } else if (component.hoverActionData != null && component.hoverActionName != null) { + throw new IllegalArgumentException("The tooltip text cannot have a tooltip."); + } + if (component.hasText()) { + result.messageParts.add(component.clone()); + } + } + if (i != lines.length - 1) { + result.messageParts.add(new MessagePart(rawText("\n"))); + } + } catch (CloneNotSupportedException e) { + Bukkit.getLogger().log(Level.WARNING, "Failed to clone object", e); + return this; + } + } + return formattedTooltip(result.messageParts.isEmpty() ? null : result); // Throws NPE if size is 0, intended + } + + /** + * Set the behavior of the current editing component to display the specified lines of formatted text when the client hovers over the text. + * <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p> + * + * @param lines The lines of text which will be displayed to the client upon hovering. The iteration order of this object will be the order in which the lines of the tooltip are created. + * @return This builder instance. + */ + public FancyMessage formattedTooltip(final Iterable<FancyMessage> lines) { + return formattedTooltip(ArrayWrapper.toArray(lines, FancyMessage.class)); + } + + /** + * If the text is a translatable key, and it has replaceable values, this function can be used to set the replacements that will be used in the message. + * + * @param replacements The replacements, in order, that will be used in the language-specific message. + * @return This builder instance. + */ + public FancyMessage translationReplacements(final String... replacements) { + for (String str : replacements) { + latest().translationReplacements.add(new JsonString(str)); + } + dirty = true; + + return this; + } + /* + + /** + * If the text is a translatable key, and it has replaceable values, this function can be used to set the replacements that will be used in the message. + * @param replacements The replacements, in order, that will be used in the language-specific message. + * @return This builder instance. + */ /* ------------ + public FancyMessage translationReplacements(final Iterable<? extends CharSequence> replacements){ + for(CharSequence str : replacements){ + latest().translationReplacements.add(new JsonString(str)); + } + + return this; + } + + */ + + /** + * If the text is a translatable key, and it has replaceable values, this function can be used to set the replacements that will be used in the message. + * + * @param replacements The replacements, in order, that will be used in the language-specific message. + * @return This builder instance. + */ + public FancyMessage translationReplacements(final FancyMessage... replacements) { + for (FancyMessage str : replacements) { + latest().translationReplacements.add(str); + } + + dirty = true; + + return this; + } + + /** + * If the text is a translatable key, and it has replaceable values, this function can be used to set the replacements that will be used in the message. + * + * @param replacements The replacements, in order, that will be used in the language-specific message. + * @return This builder instance. + */ + public FancyMessage translationReplacements(final Iterable<FancyMessage> replacements) { + return translationReplacements(ArrayWrapper.toArray(replacements, FancyMessage.class)); + } + + /** + * Terminate construction of the current editing component, and begin construction of a new message component. + * After a successful call to this method, all setter methods will refer to a new message component, created as a result of the call to this method. + * + * @param text The text which will populate the new message component. + * @return This builder instance. + */ + public FancyMessage then(final String text) { + return then(rawText(text)); + } + + /** + * Terminate construction of the current editing component, and begin construction of a new message component. + * After a successful call to this method, all setter methods will refer to a new message component, created as a result of the call to this method. + * + * @param text The text which will populate the new message component. + * @return This builder instance. + */ + public FancyMessage then(final TextualComponent text) { + if (!latest().hasText()) { + throw new IllegalStateException("previous message part has no text"); + } + messageParts.add(new MessagePart(text)); + dirty = true; + return this; + } + + /** + * Terminate construction of the current editing component, and begin construction of a new message component. + * After a successful call to this method, all setter methods will refer to a new message component, created as a result of the call to this method. + * + * @return This builder instance. + */ + public FancyMessage then() { + if (!latest().hasText()) { + throw new IllegalStateException("previous message part has no text"); + } + messageParts.add(new MessagePart()); + dirty = true; + return this; + } + + @Override + public void writeJson(JsonWriter writer) throws IOException { + if (messageParts.size() == 1) { + latest().writeJson(writer); + } else { + writer.beginObject().name("text").value("").name("extra").beginArray(); + for (final MessagePart part : this) { + part.writeJson(writer); + } + writer.endArray().endObject(); + } + } + + /** + * Serialize this fancy message, converting it into syntactically-valid JSON using a {@link JsonWriter}. + * This JSON should be compatible with vanilla formatter commands such as {@code /tellraw}. + * + * @return The JSON string representing this object. + */ + public String toJSONString() { + if (!dirty && jsonString != null) { + return jsonString; + } + StringWriter string = new StringWriter(); + JsonWriter json = new JsonWriter(string); + try { + writeJson(json); + json.close(); + } catch (IOException e) { + throw new RuntimeException("invalid message"); + } + jsonString = string.toString(); + dirty = false; + return jsonString; + } + + /** + * Sends this message to a player. The player will receive the fully-fledged formatted display of this message. + * + * @param player The player who will receive the message. + */ + public void send(Player player) { + send(player, toJSONString()); + } + + private void send(CommandSender sender, String jsonString) { + if (!(sender instanceof Player)) { + sender.sendMessage(toOldMessageFormat()); + return; + } + Player player = (Player) sender; + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + player.getName() + " " + jsonString); + } + + /** + * Sends this message to a command sender. + * If the sender is a player, they will receive the fully-fledged formatted display of this message. + * Otherwise, they will receive a version of this message with less formatting. + * + * @param sender The command sender who will receive the message. + * @see #toOldMessageFormat() + */ + public void send(CommandSender sender) { + send(sender, toJSONString()); + } + + /** + * Sends this message to multiple command senders. + * + * @param senders The command senders who will receive the message. + * @see #send(CommandSender) + */ + public void send(final Iterable<? extends CommandSender> senders) { + String string = toJSONString(); + for (final CommandSender sender : senders) { + send(sender, string); + } + } + + /** + * Convert this message to a human-readable string with limited formatting. + * This method is used to send this message to clients without JSON formatting support. + * <p> + * Serialization of this message by using this message will include (in this order for each message part): + * <ol> + * <li>The color of each message part.</li> + * <li>The applicable stylizations for each message part.</li> + * <li>The core text of the message part.</li> + * </ol> + * The primary omissions are tooltips and clickable actions. Consequently, this method should be used only as a last resort. + * </p> + * <p> + * Color and formatting can be removed from the returned string by using {@link ChatColor#stripColor(String)}.</p> + * + * @return A human-readable string representing limited formatting in addition to the core text of this message. + */ + public String toOldMessageFormat() { + StringBuilder result = new StringBuilder(); + for (MessagePart part : this) { + result.append(part.color == null ? "" : part.color); + for (ChatColor formatSpecifier : part.styles) { + result.append(formatSpecifier); + } + result.append(part.text); + } + return result.toString(); + } + + private MessagePart latest() { + return messageParts.get(messageParts.size() - 1); + } + + private void onClick(final String name, final String data) { + final MessagePart latest = latest(); + latest.clickActionName = name; + latest.clickActionData = data; + dirty = true; + } + + private void onHover(final String name, final JsonRepresentedObject data) { + final MessagePart latest = latest(); + latest.hoverActionName = name; + latest.hoverActionData = data; + dirty = true; + } + + // Doc copied from interface + public Map<String, Object> serialize() { + HashMap<String, Object> map = new HashMap<String, Object>(); + map.put("messageParts", messageParts); +// map.put("JSON", toJSONString()); + return map; + } + + /** + * Deserializes a JSON-represented message from a mapping of key-value pairs. + * This is called by the Bukkit serialization API. + * It is not intended for direct public API consumption. + * + * @param serialized The key-value mapping which represents a fancy message. + */ + @SuppressWarnings("unchecked") + public static FancyMessage deserialize(Map<String, Object> serialized) { + FancyMessage msg = new FancyMessage(); + msg.messageParts = (List<MessagePart>) serialized.get("messageParts"); + msg.jsonString = serialized.containsKey("JSON") ? serialized.get("JSON").toString() : null; + msg.dirty = !serialized.containsKey("JSON"); + return msg; + } + + /** + * <b>Internally called method. Not for API consumption.</b> + */ + public Iterator<MessagePart> iterator() { + return messageParts.iterator(); + } + + private static JsonParser _stringParser = new JsonParser(); + + /** + * Deserializes a fancy message from its JSON representation. This JSON representation is of the format of + * that returned by {@link #toJSONString()}, and is compatible with vanilla inputs. + * + * @param json The JSON string which represents a fancy message. + * @return A {@code FancyMessage} representing the parameterized JSON message. + */ + public static FancyMessage deserialize(String json) { + JsonObject serialized = _stringParser.parse(json).getAsJsonObject(); + JsonArray extra = serialized.getAsJsonArray("extra"); // Get the extra component + FancyMessage returnVal = new FancyMessage(); + returnVal.messageParts.clear(); + for (JsonElement mPrt : extra) { + MessagePart component = new MessagePart(); + JsonObject messagePart = mPrt.getAsJsonObject(); + for (Map.Entry<String, JsonElement> entry : messagePart.entrySet()) { + // Deserialize text + if (TextualComponent.isTextKey(entry.getKey())) { + // The map mimics the YAML serialization, which has a "key" field and one or more "value" fields + Map<String, Object> serializedMapForm = new HashMap<String, Object>(); // Must be object due to Bukkit serializer API compliance + serializedMapForm.put("key", entry.getKey()); + if (entry.getValue().isJsonPrimitive()) { + // Assume string + serializedMapForm.put("value", entry.getValue().getAsString()); + } else { + // Composite object, but we assume each element is a string + for (Map.Entry<String, JsonElement> compositeNestedElement : entry.getValue().getAsJsonObject().entrySet()) { + serializedMapForm.put("value." + compositeNestedElement.getKey(), compositeNestedElement.getValue().getAsString()); + } + } + component.text = TextualComponent.deserialize(serializedMapForm); + } else if (MessagePart.stylesToNames.inverse().containsKey(entry.getKey())) { + if (entry.getValue().getAsBoolean()) { + component.styles.add(MessagePart.stylesToNames.inverse().get(entry.getKey())); + } + } else if (entry.getKey().equals("color")) { + component.color = ChatColor.valueOf(entry.getValue().getAsString().toUpperCase()); + } else if (entry.getKey().equals("clickEvent")) { + JsonObject object = entry.getValue().getAsJsonObject(); + component.clickActionName = object.get("action").getAsString(); + component.clickActionData = object.get("value").getAsString(); + } else if (entry.getKey().equals("hoverEvent")) { + JsonObject object = entry.getValue().getAsJsonObject(); + component.hoverActionName = object.get("action").getAsString(); + if (object.get("value").isJsonPrimitive()) { + // Assume string + component.hoverActionData = new JsonString(object.get("value").getAsString()); + } else { + // Assume composite type + // The only composite type we currently store is another FancyMessage + // Therefore, recursion time! + component.hoverActionData = deserialize(object.get("value").toString() /* This should properly serialize the JSON object as a JSON string */); + } + } else if (entry.getKey().equals("insertion")) { + component.insertionData = entry.getValue().getAsString(); + } else if (entry.getKey().equals("with")) { + for (JsonElement object : entry.getValue().getAsJsonArray()) { + if (object.isJsonPrimitive()) { + component.translationReplacements.add(new JsonString(object.getAsString())); + } else { + // Only composite type stored in this array is - again - FancyMessages + // Recurse within this function to parse this as a translation replacement + component.translationReplacements.add(deserialize(object.toString())); + } + } + } + } + returnVal.messageParts.add(component); + } + return returnVal; + } + +} diff --git a/fanciful-master@6fb8a853dd2/src/main/java/mkremins/fanciful/JsonRepresentedObject.java b/fanciful-master@6fb8a853dd2/src/main/java/mkremins/fanciful/JsonRepresentedObject.java new file mode 100644 index 0000000..7264111 --- /dev/null +++ b/fanciful-master@6fb8a853dd2/src/main/java/mkremins/fanciful/JsonRepresentedObject.java @@ -0,0 +1,19 @@ +package mkremins.fanciful; + +import com.google.gson.stream.JsonWriter; + +import java.io.IOException; + +/** + * Represents an object that can be serialized to a JSON writer instance. + */ +interface JsonRepresentedObject { + + /** + * Writes the JSON representation of this object to the specified writer. + * @param writer The JSON writer which will receive the object. + * @throws IOException If an error occurs writing to the stream. + */ + public void writeJson(JsonWriter writer) throws IOException; + +} diff --git a/fanciful-master@6fb8a853dd2/src/main/java/mkremins/fanciful/JsonString.java b/fanciful-master@6fb8a853dd2/src/main/java/mkremins/fanciful/JsonString.java new file mode 100644 index 0000000..67764c6 --- /dev/null +++ b/fanciful-master@6fb8a853dd2/src/main/java/mkremins/fanciful/JsonString.java @@ -0,0 +1,47 @@ +package mkremins.fanciful; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import com.google.gson.stream.JsonWriter; +import org.bukkit.configuration.serialization.ConfigurationSerializable; + +/** + * Represents a JSON string value. + * Writes by this object will not write name values nor begin/end objects in the JSON stream. + * All writes merely write the represented string value. + */ +final class JsonString implements JsonRepresentedObject, ConfigurationSerializable { + + private String _value; + + public JsonString(CharSequence value) { + _value = value == null ? null : value.toString(); + } + + @Override + public void writeJson(JsonWriter writer) throws IOException { + writer.value(getValue()); + } + + public String getValue() { + return _value; + } + + public Map<String, Object> serialize() { + HashMap<String, Object> theSingleValue = new HashMap<String, Object>(); + theSingleValue.put("stringValue", _value); + return theSingleValue; + } + + public static JsonString deserialize(Map<String, Object> map) { + return new JsonString(map.get("stringValue").toString()); + } + + @Override + public String toString() { + return _value; + } + +} diff --git a/fanciful-master@6fb8a853dd2/src/main/java/mkremins/fanciful/MessagePart.java b/fanciful-master@6fb8a853dd2/src/main/java/mkremins/fanciful/MessagePart.java new file mode 100644 index 0000000..037939a --- /dev/null +++ b/fanciful-master@6fb8a853dd2/src/main/java/mkremins/fanciful/MessagePart.java @@ -0,0 +1,155 @@ +package mkremins.fanciful; + +import com.google.common.collect.BiMap; +import com.google.common.collect.ImmutableBiMap; +import com.google.gson.stream.JsonWriter; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.configuration.serialization.ConfigurationSerialization; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Level; + +/** + * Internal class: Represents a component of a JSON-serializable {@link FancyMessage}. + */ +final class MessagePart implements JsonRepresentedObject, ConfigurationSerializable, Cloneable { + + ChatColor color = ChatColor.WHITE; + ArrayList<ChatColor> styles = new ArrayList<ChatColor>(); + String clickActionName = null, clickActionData = null, hoverActionName = null; + JsonRepresentedObject hoverActionData = null; + TextualComponent text = null; + String insertionData = null; + ArrayList<JsonRepresentedObject> translationReplacements = new ArrayList<JsonRepresentedObject>(); + + MessagePart(final TextualComponent text) { + this.text = text; + } + + MessagePart() { + this.text = null; + } + + boolean hasText() { + return text != null; + } + + @Override + @SuppressWarnings("unchecked") + public MessagePart clone() throws CloneNotSupportedException { + MessagePart obj = (MessagePart) super.clone(); + obj.styles = (ArrayList<ChatColor>) styles.clone(); + if (hoverActionData instanceof JsonString) { + obj.hoverActionData = new JsonString(((JsonString) hoverActionData).getValue()); + } else if (hoverActionData instanceof FancyMessage) { + obj.hoverActionData = ((FancyMessage) hoverActionData).clone(); + } + obj.translationReplacements = (ArrayList<JsonRepresentedObject>) translationReplacements.clone(); + return obj; + + } + + static final BiMap<ChatColor, String> stylesToNames; + + static { + ImmutableBiMap.Builder<ChatColor, String> builder = ImmutableBiMap.builder(); + for (final ChatColor style : ChatColor.values()) { + if (!style.isFormat()) { + continue; + } + + String styleName; + switch (style) { + case MAGIC: + styleName = "obfuscated"; + break; + case UNDERLINE: + styleName = "underlined"; + break; + default: + styleName = style.name().toLowerCase(); + break; + } + + builder.put(style, styleName); + } + stylesToNames = builder.build(); + } + + public void writeJson(JsonWriter json) { + try { + json.beginObject(); + text.writeJson(json); + json.name("color").value(color.name().toLowerCase()); + for (final ChatColor style : styles) { + json.name(stylesToNames.get(style)).value(true); + } + if (clickActionName != null && clickActionData != null) { + json.name("clickEvent") + .beginObject() + .name("action").value(clickActionName) + .name("value").value(clickActionData) + .endObject(); + } + if (hoverActionName != null && hoverActionData != null) { + json.name("hoverEvent") + .beginObject() + .name("action").value(hoverActionName) + .name("value"); + hoverActionData.writeJson(json); + json.endObject(); + } + if (insertionData != null) { + json.name("insertion").value(insertionData); + } + if (translationReplacements.size() > 0 && text != null && TextualComponent.isTranslatableText(text)) { + json.name("with").beginArray(); + for (JsonRepresentedObject obj : translationReplacements) { + obj.writeJson(json); + } + json.endArray(); + } + json.endObject(); + } catch (IOException e) { + Bukkit.getLogger().log(Level.WARNING, "A problem occured during writing of JSON string", e); + } + } + + public Map<String, Object> serialize() { + HashMap<String, Object> map = new HashMap<String, Object>(); + map.put("text", text); + map.put("styles", styles); + map.put("color", color.getChar()); + map.put("hoverActionName", hoverActionName); + map.put("hoverActionData", hoverActionData); + map.put("clickActionName", clickActionName); + map.put("clickActionData", clickActionData); + map.put("insertion", insertionData); + map.put("translationReplacements", translationReplacements); + return map; + } + + @SuppressWarnings("unchecked") + public static MessagePart deserialize(Map<String, Object> serialized) { + MessagePart part = new MessagePart((TextualComponent) serialized.get("text")); + part.styles = (ArrayList<ChatColor>) serialized.get("styles"); + part.color = ChatColor.getByChar(serialized.get("color").toString()); + part.hoverActionName = (String) serialized.get("hoverActionName"); + part.hoverActionData = (JsonRepresentedObject) serialized.get("hoverActionData"); + part.clickActionName = (String) serialized.get("clickActionName"); + part.clickActionData = (String) serialized.get("clickActionData"); + part.insertionData = (String) serialized.get("insertion"); + part.translationReplacements = (ArrayList<JsonRepresentedObject>) serialized.get("translationReplacements"); + return part; + } + + static { + ConfigurationSerialization.registerClass(MessagePart.class); + } + +} diff --git a/fanciful-master@6fb8a853dd2/src/main/java/mkremins/fanciful/TextualComponent.java b/fanciful-master@6fb8a853dd2/src/main/java/mkremins/fanciful/TextualComponent.java new file mode 100644 index 0000000..5e960eb --- /dev/null +++ b/fanciful-master@6fb8a853dd2/src/main/java/mkremins/fanciful/TextualComponent.java @@ -0,0 +1,297 @@ +package mkremins.fanciful; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; +import com.google.gson.stream.JsonWriter; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.configuration.serialization.ConfigurationSerialization; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +/** + * Represents a textual component of a message part. + * This can be used to not only represent string literals in a JSON message, + * but also to represent localized strings and other text values. + * <p>Different instances of this class can be created with static constructor methods.</p> + */ +public abstract class TextualComponent implements Cloneable { + + static { + ConfigurationSerialization.registerClass(TextualComponent.ArbitraryTextTypeComponent.class); + ConfigurationSerialization.registerClass(TextualComponent.ComplexTextTypeComponent.class); + } + + @Override + public String toString() { + return getReadableString(); + } + + /** + * @return The JSON key used to represent text components of this type. + */ + public abstract String getKey(); + + /** + * @return A readable String + */ + public abstract String getReadableString(); + + /** + * Clones a textual component instance. + * The returned object should not reference this textual component instance, but should maintain the same key and value. + */ + @Override + public abstract TextualComponent clone() throws CloneNotSupportedException; + + /** + * Writes the text data represented by this textual component to the specified JSON writer object. + * A new object within the writer is not started. + * + * @param writer The object to which to write the JSON data. + * @throws IOException If an error occurs while writing to the stream. + */ + public abstract void writeJson(JsonWriter writer) throws IOException; + + static TextualComponent deserialize(Map<String, Object> map) { + if (map.containsKey("key") && map.size() == 2 && map.containsKey("value")) { + // Arbitrary text component + return ArbitraryTextTypeComponent.deserialize(map); + } else if (map.size() >= 2 && map.containsKey("key") && !map.containsKey("value") /* It contains keys that START WITH value */) { + // Complex JSON object + return ComplexTextTypeComponent.deserialize(map); + } + + return null; + } + + static boolean isTextKey(String key) { + return key.equals("translate") || key.equals("text") || key.equals("score") || key.equals("selector"); + } + + static boolean isTranslatableText(TextualComponent component) { + return component instanceof ComplexTextTypeComponent && ((ComplexTextTypeComponent) component).getKey().equals("translate"); + } + + /** + * Internal class used to represent all types of text components. + * Exception validating done is on keys and values. + */ + private static final class ArbitraryTextTypeComponent extends TextualComponent implements ConfigurationSerializable { + + public ArbitraryTextTypeComponent(String key, String value) { + setKey(key); + setValue(value); + } + + @Override + public String getKey() { + return _key; + } + + public void setKey(String key) { + Preconditions.checkArgument(key != null && !key.isEmpty(), "The key must be specified."); + _key = key; + } + + public String getValue() { + return _value; + } + + public void setValue(String value) { + Preconditions.checkArgument(value != null, "The value must be specified."); + _value = value; + } + + private String _key; + private String _value; + + @Override + public TextualComponent clone() throws CloneNotSupportedException { + // Since this is a private and final class, we can just reinstantiate this class instead of casting super.clone + return new ArbitraryTextTypeComponent(getKey(), getValue()); + } + + @Override + public void writeJson(JsonWriter writer) throws IOException { + writer.name(getKey()).value(getValue()); + } + + @SuppressWarnings("serial") + public Map<String, Object> serialize() { + return new HashMap<String, Object>() {{ + put("key", getKey()); + put("value", getValue()); + }}; + } + + public static ArbitraryTextTypeComponent deserialize(Map<String, Object> map) { + return new ArbitraryTextTypeComponent(map.get("key").toString(), map.get("value").toString()); + } + + @Override + public String getReadableString() { + return getValue(); + } + } + + /** + * Internal class used to represent a text component with a nested JSON value. + * Exception validating done is on keys and values. + */ + private static final class ComplexTextTypeComponent extends TextualComponent implements ConfigurationSerializable { + + public ComplexTextTypeComponent(String key, Map<String, String> values) { + setKey(key); + setValue(values); + } + + @Override + public String getKey() { + return _key; + } + + public void setKey(String key) { + Preconditions.checkArgument(key != null && !key.isEmpty(), "The key must be specified."); + _key = key; + } + + public Map<String, String> getValue() { + return _value; + } + + public void setValue(Map<String, String> value) { + Preconditions.checkArgument(value != null, "The value must be specified."); + _value = value; + } + + private String _key; + private Map<String, String> _value; + + @Override + public TextualComponent clone() throws CloneNotSupportedException { + // Since this is a private and final class, we can just reinstantiate this class instead of casting super.clone + return new ComplexTextTypeComponent(getKey(), getValue()); + } + + @Override + public void writeJson(JsonWriter writer) throws IOException { + writer.name(getKey()); + writer.beginObject(); + for (Map.Entry<String, String> jsonPair : _value.entrySet()) { + writer.name(jsonPair.getKey()).value(jsonPair.getValue()); + } + writer.endObject(); + } + + @SuppressWarnings("serial") + public Map<String, Object> serialize() { + return new java.util.HashMap<String, Object>() {{ + put("key", getKey()); + for (Map.Entry<String, String> valEntry : getValue().entrySet()) { + put("value." + valEntry.getKey(), valEntry.getValue()); + } + }}; + } + + public static ComplexTextTypeComponent deserialize(Map<String, Object> map) { + String key = null; + Map<String, String> value = new HashMap<String, String>(); + for (Map.Entry<String, Object> valEntry : map.entrySet()) { + if (valEntry.getKey().equals("key")) { + key = (String) valEntry.getValue(); + } else if (valEntry.getKey().startsWith("value.")) { + value.put(((String) valEntry.getKey()).substring(6) /* Strips out the value prefix */, valEntry.getValue().toString()); + } + } + return new ComplexTextTypeComponent(key, value); + } + + @Override + public String getReadableString() { + return getKey(); + } + } + + /** + * Create a textual component representing a string literal. + * This is the default type of textual component when a single string literal is given to a method. + * + * @param textValue The text which will be represented. + * @return The text component representing the specified literal text. + */ + public static TextualComponent rawText(String textValue) { + return new ArbitraryTextTypeComponent("text", textValue); + } + + + /** + * Create a textual component representing a localized string. + * The client will see this text component as their localized version of the specified string <em>key</em>, which can be overridden by a resource pack. + * <p> + * If the specified translation key is not present on the client resource pack, the translation key will be displayed as a string literal to the client. + * </p> + * + * @param translateKey The string key which maps to localized text. + * @return The text component representing the specified localized text. + */ + public static TextualComponent localizedText(String translateKey) { + return new ArbitraryTextTypeComponent("translate", translateKey); + } + + private static void throwUnsupportedSnapshot() { + throw new UnsupportedOperationException("This feature is only supported in snapshot releases."); + } + + /** + * Create a textual component representing a scoreboard value. + * The client will see their own score for the specified objective as the text represented by this component. + * <p> + * <b>This method is currently guaranteed to throw an {@code UnsupportedOperationException} as it is only supported on snapshot clients.</b> + * </p> + * + * @param scoreboardObjective The name of the objective for which to display the score. + * @return The text component representing the specified scoreboard score (for the viewing player), or {@code null} if an error occurs during JSON serialization. + */ + public static TextualComponent objectiveScore(String scoreboardObjective) { + return objectiveScore("*", scoreboardObjective); + } + + /** + * Create a textual component representing a scoreboard value. + * The client will see the score of the specified player for the specified objective as the text represented by this component. + * <p> + * <b>This method is currently guaranteed to throw an {@code UnsupportedOperationException} as it is only supported on snapshot clients.</b> + * </p> + * + * @param playerName The name of the player whos score will be shown. If this string represents the single-character sequence "*", the viewing player's score will be displayed. + * Standard minecraft selectors (@a, @p, etc) are <em>not</em> supported. + * @param scoreboardObjective The name of the objective for which to display the score. + * @return The text component representing the specified scoreboard score for the specified player, or {@code null} if an error occurs during JSON serialization. + */ + public static TextualComponent objectiveScore(String playerName, String scoreboardObjective) { + throwUnsupportedSnapshot(); // Remove this line when the feature is released to non-snapshot versions, in addition to updating ALL THE OVERLOADS documentation accordingly + + return new ComplexTextTypeComponent("score", ImmutableMap.<String, String>builder() + .put("name", playerName) + .put("objective", scoreboardObjective) + .build()); + } + + /** + * Create a textual component representing a player name, retrievable by using a standard minecraft selector. + * The client will see the players or entities captured by the specified selector as the text represented by this component. + * <p> + * <b>This method is currently guaranteed to throw an {@code UnsupportedOperationException} as it is only supported on snapshot clients.</b> + * </p> + * + * @param selector The minecraft player or entity selector which will capture the entities whose string representations will be displayed in the place of this text component. + * @return The text component representing the name of the entities captured by the selector. + */ + public static TextualComponent selector(String selector) { + throwUnsupportedSnapshot(); // Remove this line when the feature is released to non-snapshot versions, in addition to updating ALL THE OVERLOADS documentation accordingly + + return new ArbitraryTextTypeComponent("selector", selector); + } +} diff --git a/fanciful-master@6fb8a853dd2/src/main/java/net/amoebaman/util/ArrayWrapper.java b/fanciful-master@6fb8a853dd2/src/main/java/net/amoebaman/util/ArrayWrapper.java new file mode 100644 index 0000000..4cd07bb --- /dev/null +++ b/fanciful-master@6fb8a853dd2/src/main/java/net/amoebaman/util/ArrayWrapper.java @@ -0,0 +1,111 @@ +package net.amoebaman.util; + +import org.apache.commons.lang.Validate; + +import java.lang.reflect.Array; +import java.util.Arrays; +import java.util.Collection; + +/** + * Represents a wrapper around an array class of an arbitrary reference type, + * which properly implements "value" hash code and equality functions. + * <p> + * This class is intended for use as a key to a map. + * </p> + * + * @param <E> The type of elements in the array. + * @author Glen Husman + * @see Arrays + */ +public final class ArrayWrapper<E> { + + /** + * Creates an array wrapper with some elements. + * + * @param elements The elements of the array. + */ + public ArrayWrapper(E... elements) { + setArray(elements); + } + + private E[] _array; + + /** + * Retrieves a reference to the wrapped array instance. + * + * @return The array wrapped by this instance. + */ + public E[] getArray() { + return _array; + } + + /** + * Set this wrapper to wrap a new array instance. + * + * @param array The new wrapped array. + */ + public void setArray(E[] array) { + Validate.notNull(array, "The array must not be null."); + _array = array; + } + + /** + * Determines if this object has a value equivalent to another object. + * + * @see Arrays#equals(Object[], Object[]) + */ + @SuppressWarnings("rawtypes") + @Override + public boolean equals(Object other) { + if (!(other instanceof ArrayWrapper)) { + return false; + } + return Arrays.equals(_array, ((ArrayWrapper) other)._array); + } + + /** + * Gets the hash code represented by this objects value. + * + * @return This object's hash code. + * @see Arrays#hashCode(Object[]) + */ + @Override + public int hashCode() { + return Arrays.hashCode(_array); + } + + /** + * Converts an iterable element collection to an array of elements. + * The iteration order of the specified object will be used as the array element order. + * + * @param list The iterable of objects which will be converted to an array. + * @param c The type of the elements of the array. + * @return An array of elements in the specified iterable. + */ + @SuppressWarnings("unchecked") + public static <T> T[] toArray(Iterable<? extends T> list, Class<T> c) { + int size = -1; + if (list instanceof Collection<?>) { + @SuppressWarnings("rawtypes") + Collection coll = (Collection) list; + size = coll.size(); + } + + + if (size < 0) { + size = 0; + // Ugly hack: Count it ourselves + for (@SuppressWarnings("unused") T element : list) { + size++; + } + } + + T[] result = (T[]) Array.newInstance(c, size); + int i = 0; + for (T element : list) { // Assumes iteration order is consistent + result[i++] = element; // Assign array element at index THEN increment counter + } + return result; + } + +} diff --git a/gtm-master@bf01c650f8f/.gitignore b/gtm-master@bf01c650f8f/.gitignore new file mode 100644 index 0000000..b1935ec --- /dev/null +++ b/gtm-master@bf01c650f8f/.gitignore @@ -0,0 +1,102 @@ + +\.idea/ + +target/classes/ + +target/ + +*.iml + +/bin/ +/build/ + +##### Gradle ##### +.gradle +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache + +# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 +# gradle/wrapper/gradle-wrapper.properties + +##### Eclipse ##### +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders + +.project + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# PyDev specific (Python IDE for Eclipse) +*.pydevproject + +# CDT-specific (C/C++ Development Tooling) +.cproject + +# JDT-specific (Eclipse Java Development Tools) +.classpath + +# Java annotation processor (APT) +.factorypath + +# PDT-specific (PHP Development Tools) +.buildpath + +# sbteclipse plugin +.target + +# Tern plugin +.tern-project + +# TeXlipse plugin +.texlipse + +# STS (Spring Tool Suite) +.springBeans + +# Code Recommenders +.recommenders/ + +*.class + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear + + +##### IntelliJ ##### +*.iml +*.ipr +*.iws +.idea/ + +##### NetBeans ##### +/.nb-gradle/ + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +##### MacOS ##### +.DS_Store diff --git a/gtm-master@bf01c650f8f/README.md b/gtm-master@bf01c650f8f/README.md new file mode 100644 index 0000000..fdaec0e --- /dev/null +++ b/gtm-master@bf01c650f8f/README.md @@ -0,0 +1 @@ +First commit. \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/pom.xml b/gtm-master@bf01c650f8f/pom.xml new file mode 100644 index 0000000..0f2afdb --- /dev/null +++ b/gtm-master@bf01c650f8f/pom.xml @@ -0,0 +1,187 @@ +<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>net.grandtheftmc</groupId> + <artifactId>gtm</artifactId> + <version>2.4.1</version> + <name>GTM</name> + + <repositories> + <repository> + <id>paperspigot-repo</id> + <url>https://repo.destroystokyo.com/repository/maven-public/</url> + </repository> + <repository> + <id>dmulloy2-repo</id> + <url>http://repo.dmulloy2.net/nexus/repository/public/</url> + </repository> + <repository> + <id>jitpack.io</id> + <url>https://jitpack.io</url> + </repository> + <repository> + <id>worldedit-repo</id> + <url>http://maven.sk89q.com/repo/</url> + </repository> + <repository> + <id>citizens-repo</id> + <url>http://repo.citizensnpcs.co/</url> + </repository> + <repository> + <id>viaversion-repo</id> + <url>https://repo.viaversion.com</url> + </repository> + <repository> + <id>nexus-release</id> + <url>http://nexus.grandtheftmc.net/content/repositories/releases</url> + </repository> + </repositories> + + <distributionManagement> + <repository> + <id>nexus-release</id> + <name>Internal Releases</name> + <url>http://nexus.grandtheftmc.net/content/repositories/releases</url> + </repository> + <snapshotRepository> + <id>nexus-snapshot</id> + <name>Internal Snapshots</name> + <url>http://nexus.grandtheftmc.net/content/repositories/snapshots</url> + </snapshotRepository> + </distributionManagement> + + <dependencies> + <dependency> + <groupId>net.citizensnpcs</groupId> + <artifactId>citizensapi</artifactId> + <version>2.0.22</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>us.myles</groupId> + <artifactId>viaversion</artifactId> + <version>1.0.3</version> + <scope>provided</scope> + </dependency> + <!--<dependency>--> + <!--<groupId>com.destroystokyo.paper</groupId>--> + <!--<artifactId>paper</artifactId>--> + <!--<version>1.10.2</version>--> + <!--<scope>provided</scope>--> + <!--</dependency>--> + <dependency> + <groupId>org.spigotmc.1.12</groupId> + <artifactId>spigot</artifactId> + <version>1.12.0</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>net.buycraft</groupId> + <artifactId>BuycraftX</artifactId> + <version>10.3.0</version> + </dependency> + <dependency> + <groupId>com.comphenix.protocol</groupId> + <artifactId>ProtocolLib-API</artifactId> + <version>4.2.1</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.github.j0ach1mmall3</groupId> + <artifactId>JLib</artifactId> + <version>LATEST</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>net.grandtheftmc</groupId> + <artifactId>wastedguns</artifactId> + <version>1.1.6</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>net.grandtheftmc</groupId> + <artifactId>wastedvehicles</artifactId> + <version>1.0.3.rewrite</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>net.grandtheftmc</groupId> + <artifactId>wastedcops</artifactId> + <version>1.0.1</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>net.grandtheftmc</groupId> + <artifactId>core</artifactId> + <version>2.3.10</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>net.grandtheftmc</groupId> + <artifactId>houses</artifactId> + <version>1.0.5</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.gmail.filoghost.holographicdisplays</groupId> + <artifactId>HolographicDisplays</artifactId> + <version>1.0.0</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.sk89q.worldedit</groupId> + <artifactId>worldedit-bukkit</artifactId> + <version>LATEST</version> + <scope>provided</scope> + </dependency> + </dependencies> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <maven.compiler.source>1.8</maven.compiler.source> + <maven.compiler.target>1.8</maven.compiler.target> + </properties> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-shade-plugin</artifactId> + <configuration> + <finalName>GTM</finalName> + </configuration> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>shade</goal> + </goals> + </execution> + </executions> + </plugin> + + <!-- Nexus deploy --> + <plugin> + <groupId>org.sonatype.plugins</groupId> + <artifactId>nexus-staging-maven-plugin</artifactId> + <version>1.6.8</version> + <extensions>true</extensions> + <executions> + <execution> + <id>default-deploy</id> + <phase>deploy</phase> + <goals> + <goal>deploy</goal> + </goals> + </execution> + </executions> + <configuration> + <serverId>nexus</serverId> + <nexusUrl>http://nexus.grandtheftmc.net/</nexusUrl> + <skipStaging>true</skipStaging> + </configuration> + </plugin> + </plugins> + </build> +</project> \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/setup/database_schema.txt b/gtm-master@bf01c650f8f/setup/database_schema.txt new file mode 100644 index 0000000..f5c4a5b --- /dev/null +++ b/gtm-master@bf01c650f8f/setup/database_schema.txt @@ -0,0 +1,211 @@ +/***** +** Table Description: +** Represents GTM gang information. +** +** id is primary auto increment so we can change gang names. +** server_key is the server that this gang is on +** name is the name of the server +** owner is the uuid of the player that owns this gang +** +** Reasoning for structure: +** PK is the (`id`) field, as every gang needs its own unique key. We +** index the server_key so we can lookup gangs by server_type. +*****/ +CREATE TABLE IF NOT EXISTS gtm_gang( +id INT NOT NULL AUTO_INCREMENT, +server_key VARCHAR(10) NOT NULL, +name VARCHAR(36) NOT NULL, +owner BINARY(16) NOT NULL, +description VARCHAR(255) NOT NULL, +max_members INT(11) NOT NULL, +PRIMARY KEY (id), +INDEX (server_key), +INDEX (name) +); + +/***** +** Table Description: +** Represents GTM gang member information, every gang will +** have multiple records, one for each member. +** +** gang_id is foreign key reference to gtm_gang table +** uuid is the uuid of the member +** +** Reasoning for structure: +** PK is the (`gang_id`, `uuid`) pair, as a member can only exist in that gang once. +*****/ +CREATE TABLE IF NOT EXISTS gtm_gang_member( +gang_id INT NOT NULL, +uuid BINARY(16) NOT NULL, +role SMALLINT(6) DEFAULT 1, +PRIMARY KEY (gang_id, uuid), +FOREIGN KEY (gang_id) REFERENCES gtm_gang(id) ON DELETE CASCADE +); + +/***** +** Table Description: +** Represents GTM gang relationships. +** +** gang_id is owner of the relationship +** other_id is the other gang in this relationship +** relation is the relationship they share +** +** Reasoning for structure: +** PK is the (`gang_id`, `other_id`) pair, as a gang can only have +** ONE unique relationship between them. +*****/ +CREATE TABLE IF NOT EXISTS gtm_gang_relation( +gang_id INT NOT NULL, +other_id INT NOT NULL, +relation VARCHAR(10), +PRIMARY KEY (gang_id, other_id), +FOREIGN KEY (gang_id) REFERENCES gtm_gang(id) ON DELETE CASCADE, +FOREIGN KEY (other_id) REFERENCES gtm_gang(id) ON DELETE CASCADE +); + +/***** +** Table Description: +** Represents basic information about a GTM house. +** +** id is determined by SQL, unique foreign key in other tables +** house_num is the id number of the house +** server_key is the server key that this is for +** premium is whether this is a premium house +** currency is the type of currency to use to buy this house +** price is the price of the currency for the purchase +** +** Reasoning for structure: +** PK is the auto increment field, as it has to be, but we have a +** unique constraint on the (house_num, server_key, premium) composite +** key as we want that to be unique lookup. +*****/ +CREATE TABLE IF NOT EXISTS gtm_house ( +id INT NOT NULL AUTO_INCREMENT, +house_num INT NOT NULL, +server_key VARCHAR(10) NOT NULL, +premium TINYINT(1) NOT NULL DEFAULT 0, +currency VARCHAR(10) NOT NULL, +price INT NOT NULL, +PRIMARY KEY (id), +UNIQUE INDEX (house_num, server_key, premium) +); + +/***** +** Table Description: +** Represents GTM house locations (chests, doors, signs). +** +** house_id is the foreign key reference to the gtm_house table +** hotspot_id is the unique id for the given data, removing attributes if needed. +** hotspot_type is the type of data this is +** data is the blob of JSON data for this hotspot +** +** Reasoning for structure: +** PK is the auto increment field, as it has to be, but we have an index +** on the house_id column for efficient lookups. +*****/ +CREATE TABLE IF NOT EXISTS gtm_house_data ( +house_id INT NOT NULL, +hotspot_id INT NOT NULL AUTO_INCREMENT, +hotspot_type VARCHAR(5) NOT NULL, +data BLOB DEFAULT NULL, +PRIMARY KEY (hotspot_id), +INDEX (house_id), +FOREIGN KEY (house_id) REFERENCES gtm_house(id) ON DELETE CASCADE +); + +/***** +** Table Description: +** Represents GTM house user data. +** +** house_id is the foreign key reference to the gtm_house table +** uuid is the uuid of the user +** owner is whether the user is the owner of the house +** +** Reasoning for structure: +** PK is the (`house_id`, `uuid`) pair, as we need an efficient lookup on house_id. +** We add an index on uuid so we can get all houses a player is in. +*****/ +CREATE TABLE IF NOT EXISTS gtm_house_user ( +house_id INT NOT NULL, +uuid BINARY(16) NOT NULL, +is_owner TINYINT(1) NOT NULL, +PRIMARY KEY (house_id, uuid), +INDEX(uuid), +FOREIGN KEY (house_id) REFERENCES gtm_house(id) ON DELETE CASCADE +); + +/***** +** Table Description: +** Represents GTM house user chest data. +** +** house_id is the foreign key reference to the gtm_house table +** uuid is the uuid of the user that owns this chest +** chest_id is the id of the chest +** content is the chest contents +** +** Reasoning for structure: +** PK is the (`house_id`, `uuid`) pair, as we need an efficient lookup on house_id. +** We add an index on uuid so we can get all chests for a player. +*****/ +CREATE TABLE IF NOT EXISTS gtm_house_chest ( +house_id INT NOT NULL, +uuid BINARY(16) NOT NULL, +chest_id INT NOT NULL, +content LONGBLOB DEFAULT NULL, +PRIMARY KEY (house_id, uuid, chest_id), +INDEX (uuid), +FOREIGN KEY (house_id) REFERENCES gtm_house(id) ON DELETE CASCADE, +FOREIGN KEY (house_id, uuid) REFERENCES gtm_house_user(house_id, uuid) ON DELETE CASCADE +); + +/***** +** Table Description: +** Represents event information, like halloween or something. +** +** event_type is the type of event +** data is the JSON object data for this event +** start/end time is when to start or end the event +** +** Reasoning for structure: +** PK is the `server_key` field, as it's a key lookup for each +** server. +*****/ +CREATE TABLE IF NOT EXISTS event( +server_key VARCHAR(40) NOT NULL, +event_type VARCHAR(40) NOT NULL, +data TEXT NOT NULL, +start_time TIMESTAMP NOT NULL, +end_time TIMESTAMP NOT NULL, +PRIMARY KEY (server_key) +); + +/***** +** Table Description: +** Represents halloween specific event information. Specifically, +** so that players cannot redeem multiple houses. +** +** uuid is the uuid of the user +** house_id is the premium house id that was interacted with +** +** Reasoning for structure: +** Index is the `uuid` field, so we can efficiently get a list +** of already redeemed houses for a user. +*****/ +CREATE TABLE IF NOT EXISTS event_halloween( +uuid BINARY(16) NOT NULL, +house_id INT NOT NULL, +creation TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, +INDEX (uuid) +); + + +/***** +** Add mutex columns to general tables +*****/ +ALTER TABLE gtm0 ADD COLUMN mutex TINYINT(1) NOT NULL DEFAULT 0 AFTER name; +ALTER TABLE gtm1 ADD COLUMN mutex TINYINT(1) NOT NULL DEFAULT 0 AFTER name; +ALTER TABLE gtm2 ADD COLUMN mutex TINYINT(1) NOT NULL DEFAULT 0 AFTER name; +ALTER TABLE gtm3 ADD COLUMN mutex TINYINT(1) NOT NULL DEFAULT 0 AFTER name; +ALTER TABLE gtm4 ADD COLUMN mutex TINYINT(1) NOT NULL DEFAULT 0 AFTER name; +ALTER TABLE gtm5 ADD COLUMN mutex TINYINT(1) NOT NULL DEFAULT 0 AFTER name; +ALTER TABLE gtm6 ADD COLUMN mutex TINYINT(1) NOT NULL DEFAULT 0 AFTER name; \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/GTM.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/GTM.java new file mode 100644 index 0000000..295c343 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/GTM.java @@ -0,0 +1,1069 @@ +package net.grandtheftmc.gtm; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.logging.Level; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Chunk; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.craftbukkit.v1_12_R1.CraftWorld; +import org.bukkit.craftbukkit.v1_12_R1.entity.CraftEntity; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.java.JavaPlugin; + +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.ProtocolManager; + +import de.slikey.effectlib.EffectManager; +import net.buycraft.plugin.bukkit.BuycraftPlugin; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Settings; +import net.grandtheftmc.core.casino.CoreCasino; +import net.grandtheftmc.core.casino.slot.SlotMachine; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.event.EventCommand; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.resourcepack.RSPack_1_12; +import net.grandtheftmc.core.resourcepack.ResourcePack; +import net.grandtheftmc.core.resourcepack.ResourcePackManager; +import net.grandtheftmc.core.util.ItemStackManager; +import net.grandtheftmc.core.util.NMSVersion; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.util.title.NMSTitle; +import net.grandtheftmc.gtm.armor.ArmorShopManager; +import net.grandtheftmc.gtm.bounties.BountyManager; +import net.grandtheftmc.gtm.commands.AmmoCommand; +import net.grandtheftmc.gtm.commands.AntiAuraCommand; +import net.grandtheftmc.gtm.commands.BackpackCommand; +import net.grandtheftmc.gtm.commands.BackupCommand; +import net.grandtheftmc.gtm.commands.BribeCommand; +import net.grandtheftmc.gtm.commands.CheatCodeCommand; +import net.grandtheftmc.gtm.commands.ChestCheckCommand; +import net.grandtheftmc.gtm.commands.ChristmasCommand; +import net.grandtheftmc.gtm.commands.ChunkUnloadCommand; +import net.grandtheftmc.gtm.commands.ClearCommand; +import net.grandtheftmc.gtm.commands.CoreNPCCommand; +import net.grandtheftmc.gtm.commands.DrugCheckCommand; +import net.grandtheftmc.gtm.commands.DrugDealerCommand; +import net.grandtheftmc.gtm.commands.FeedCommand; +import net.grandtheftmc.gtm.commands.FixCommand; +import net.grandtheftmc.gtm.commands.GTMAdminCommand; +import net.grandtheftmc.gtm.commands.GTMRankCommand; +import net.grandtheftmc.gtm.commands.GTMRanksCommand; +import net.grandtheftmc.gtm.commands.HalloweenCommand; +import net.grandtheftmc.gtm.commands.KillCommand; +import net.grandtheftmc.gtm.commands.LotteryCommand; +import net.grandtheftmc.gtm.commands.MoneyCommand; +import net.grandtheftmc.gtm.commands.NearCommand; +import net.grandtheftmc.gtm.commands.PayCommand; +import net.grandtheftmc.gtm.commands.PermitsCommand; +import net.grandtheftmc.gtm.commands.PickerCommand; +import net.grandtheftmc.gtm.commands.RankupCommand; +import net.grandtheftmc.gtm.commands.ResetCommand; +import net.grandtheftmc.gtm.commands.ResourcePackCommand; +import net.grandtheftmc.gtm.commands.SellCommand; +import net.grandtheftmc.gtm.commands.SetRarityCommand; +import net.grandtheftmc.gtm.commands.SettingsCommand; +import net.grandtheftmc.gtm.commands.SkinCommand; +import net.grandtheftmc.gtm.commands.SkinsCommand; +import net.grandtheftmc.gtm.commands.SpectatorCommand; +import net.grandtheftmc.gtm.commands.SpeedCommand; +import net.grandtheftmc.gtm.commands.StatsCommand; +import net.grandtheftmc.gtm.commands.TeleportCommand; +import net.grandtheftmc.gtm.commands.TokenShopCommand; +import net.grandtheftmc.gtm.commands.TopKillersCommand; +import net.grandtheftmc.gtm.commands.TransferCommand; +import net.grandtheftmc.gtm.commands.VehicleCommand; +import net.grandtheftmc.gtm.database.dao.MutexDAO; +import net.grandtheftmc.gtm.drugs.DrugCommand; +import net.grandtheftmc.gtm.drugs.DrugManager; +import net.grandtheftmc.gtm.drugs.events.listener.DrugListener; +import net.grandtheftmc.gtm.drugs.events.listener.DrugPlacementListener; +import net.grandtheftmc.gtm.event.EventManager; +import net.grandtheftmc.gtm.event.christmas.ChristmasListener; +import net.grandtheftmc.gtm.event.easter.EasterEggCommand; +import net.grandtheftmc.gtm.gang.GangManager; +import net.grandtheftmc.gtm.gang.command.GangAdminCommand; +import net.grandtheftmc.gtm.holidays.HolidayManager; +import net.grandtheftmc.gtm.items.BackpackManager; +import net.grandtheftmc.gtm.items.GameItemCommand; +import net.grandtheftmc.gtm.items.ItemManager; +import net.grandtheftmc.gtm.items.KitCommand; +import net.grandtheftmc.gtm.items.ShopCommand; +import net.grandtheftmc.gtm.items.ShopManager; +import net.grandtheftmc.gtm.listeners.ArmorEquip; +import net.grandtheftmc.gtm.listeners.BreakBlock; +import net.grandtheftmc.gtm.listeners.ChangeWorld; +import net.grandtheftmc.gtm.listeners.Chat; +import net.grandtheftmc.gtm.listeners.CommandPreProcess; +import net.grandtheftmc.gtm.listeners.Craft; +import net.grandtheftmc.gtm.listeners.Damage; +import net.grandtheftmc.gtm.listeners.Death; +import net.grandtheftmc.gtm.listeners.Dispense; +import net.grandtheftmc.gtm.listeners.Drop; +import net.grandtheftmc.gtm.listeners.DrugBlockRemovalListener; +import net.grandtheftmc.gtm.listeners.FireListener; +import net.grandtheftmc.gtm.listeners.FoodChange; +import net.grandtheftmc.gtm.listeners.GamemodeChange; +import net.grandtheftmc.gtm.listeners.Interact; +import net.grandtheftmc.gtm.listeners.InventoryClick; +import net.grandtheftmc.gtm.listeners.InventoryOpen; +import net.grandtheftmc.gtm.listeners.ItemBreak; +import net.grandtheftmc.gtm.listeners.Join; +import net.grandtheftmc.gtm.listeners.Leave; +import net.grandtheftmc.gtm.listeners.Login; +import net.grandtheftmc.gtm.listeners.MenuListener; +import net.grandtheftmc.gtm.listeners.MobSpawn; +import net.grandtheftmc.gtm.listeners.Move; +import net.grandtheftmc.gtm.listeners.MovementCheat; +import net.grandtheftmc.gtm.listeners.PetListener; +import net.grandtheftmc.gtm.listeners.Pickup; +import net.grandtheftmc.gtm.listeners.PortalEnter; +import net.grandtheftmc.gtm.listeners.PotionSplash; +import net.grandtheftmc.gtm.listeners.PrepareItemCraft; +import net.grandtheftmc.gtm.listeners.SwapHandItems; +import net.grandtheftmc.gtm.listeners.UpdateListener; +import net.grandtheftmc.gtm.listeners.VehicleUse; +import net.grandtheftmc.gtm.listeners.VoteReward; +import net.grandtheftmc.gtm.listeners.WeaponShoot; +import net.grandtheftmc.gtm.listeners.WeaponUse; +import net.grandtheftmc.gtm.lootcrates.CrateManager; +import net.grandtheftmc.gtm.lootcrates.LootCrateCommand; +import net.grandtheftmc.gtm.tasks.Lottery; +import net.grandtheftmc.gtm.tasks.TaskManager; +import net.grandtheftmc.gtm.trashcan.TrashCanManager; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.users.GTMUserManager; +import net.grandtheftmc.gtm.users.npcs.ArmorNPC; +import net.grandtheftmc.gtm.users.npcs.BankTellerNPC; +import net.grandtheftmc.gtm.users.npcs.CarNPC; +import net.grandtheftmc.gtm.users.npcs.CasinoNPC; +import net.grandtheftmc.gtm.users.npcs.CriminalNPC; +import net.grandtheftmc.gtm.users.npcs.FoodNPC; +import net.grandtheftmc.gtm.users.npcs.HeadSellerNPC; +import net.grandtheftmc.gtm.users.npcs.HitmanNPC; +import net.grandtheftmc.gtm.users.npcs.MechanicNPC; +import net.grandtheftmc.gtm.users.npcs.PoliceNPC; +import net.grandtheftmc.gtm.users.npcs.RewardsNPC; +import net.grandtheftmc.gtm.users.npcs.ShopNPC; +import net.grandtheftmc.gtm.users.npcs.SkinsNPC; +import net.grandtheftmc.gtm.users.npcs.TaxiNPC; +import net.grandtheftmc.gtm.warps.SpawnCommand; +import net.grandtheftmc.gtm.warps.TpaCommand; +import net.grandtheftmc.gtm.warps.WarpCommand; +import net.grandtheftmc.gtm.warps.WarpManager; +import net.grandtheftmc.gtm.wastedbarrels.BarrelListener; +import net.grandtheftmc.gtm.wastedbarrels.BarrelManager; +import net.grandtheftmc.gtm.weapon.WeaponRegistry; +import net.grandtheftmc.gtm.weapon.skins.WeaponSkinManager; +import net.grandtheftmc.guns.GTMGuns; +import net.minecraft.server.v1_12_R1.WorldServer; + +public class GTM extends JavaPlugin { + + private static final String[][] RES_PACKS = { +// {"http://cdn.grandtheftmc.net/GTM-2.4.12-1.10.zip", "9982D598B60D926F1CE6"}, //1.9 - 1.10 +// {"http://cdn.grandtheftmc.net/GTM-2.4.12-1.11.zip", "FA2C2DBEB6FF0CFB991D"} //1.11 - 1.12+ +// -- original is above + // SHA-1 hash is usually rendered as HEX (base16), 40 digits long. + // need to convert to 20 bytes long + {"http://cdn.grandtheftmc.net/GTM-2.4.12-1.10.zip", "2F0A69EBFB74C513B8371894BAC7C2FD0B8EE2A2"}, //1.9 - 1.10 + {"http://cdn.grandtheftmc.net/GTM-2.4.13-1.11.zip", "8E3C7FE3A16E00261C4054241BBC166BF23239DE"}, //1.11 - 1.12 + {"http://cdn.grandtheftmc.net/GTM-2.4.13-1.13.zip", "2A3BA442DA89B43DF6207C3DF829A1E6D9D43CD2"} //1.13+ + }; + + private final Set<UUID> transferingPlayers = new HashSet<UUID>(); + + private static DrugManager drugManager; + private static GTM instance; + private static GTMUserManager um; + private static WarpManager wm; + private static BountyManager bm; + private static TaskManager tm; + private static BackpackManager bam; + private static ItemManager im; + private static ShopManager sm; + private static GangManager gm; + private static CrateManager cm; + private static BarrelManager wbm; + private static EffectManager effectLib; + private static Lottery lottery; + private static HolidayManager hm; + private static WeaponSkinManager wsm; + /** The handler for all events, like christmas etc. */ + private EventManager eventManager; + private static GTMGuns wg; + private static com.j0ach1mmall3.wastedvehicles.Main wv; + private static com.j0ach1mmall3.wastedcops.Main wc; + private static ProtocolManager pm; + private static GTMSettings settings; + private static BuycraftPlugin bp; + private CoreCasino<GTM> coreCasino; + + public static boolean WEAPON_SKINS_FEATURE_FLAG = true; + + public Set<UUID> getTransferingPlayers() { + return transferingPlayers; + } + + public static GTM getInstance() { + return instance; + } + + /** + * @deprecated - Please use {@link GTMUserManager#getInstance} instead. + */ + @Deprecated + public static GTMUserManager getUserManager() { + return um; + } + + public static WarpManager getWarpManager() { + return wm; + } + + public static BountyManager getBountyManager() { + return bm; + } + + public static TaskManager getTaskManager() { + return tm; + } + + public static BackpackManager getBackpackManager() { + return bam; + } + + public static ItemManager getItemManager() { + return im; + } + + public static GTMSettings getSettings() { + return settings; + } + + public static ShopManager getShopManager() { + return sm; + } + + public static GangManager getGangManager() { + return gm; + } + + public static CrateManager getCrateManager() { + return cm; + } + + public static BarrelManager getBarrelManager() { + return wbm; + } + + public static ProtocolManager getProtocolManager() { + return pm; + } + + public static HolidayManager getHolidayManager() { + return hm; + } + + public static DrugManager getDrugManager() { + return drugManager; + } + + public static WeaponSkinManager getWeaponSkinManager() { + return wsm; + } + + public static GTMGuns getWastedGuns() { + return wg; + } + + public static com.j0ach1mmall3.wastedvehicles.Main getWastedVehicles() { + return wv; + } + + public static com.j0ach1mmall3.wastedcops.Main getWastedCops() { + return wc; + } + + public static Lottery getLottery() { + return lottery; + } + + public static void log(String s) { + GTM.getInstance().getLogger().log(Level.ALL, s); + } + + public static void error(String s) { + GTM.getInstance().getLogger().log(Level.SEVERE, s); + } + + public static EffectManager getEffectLib() { + return effectLib; + } + + public static BuycraftPlugin getBuycraftX() { + return bp; + } + + public static ResourcePackManager getResourcePackManager() { + return Core.resourcePackManager; + } + + @Override + public void onEnable() { + instance = this; + settings = new GTMSettings(); + + this.load(); + this.loadDependencies(); + + if (!Core.getSettings().isSister()) { + drugManager = new DrugManager(); + } + + effectLib = new EffectManager(this); + um = GTMUserManager.getInstance(); + wm = new WarpManager(); + bm = new BountyManager(); + tm = new TaskManager(); + bam = new BackpackManager(); + wsm = new WeaponSkinManager(); + new WeaponRegistry(this, wg.getWeaponManager()); + im = new ItemManager(); + sm = new ShopManager(); + gm = new GangManager(this); + cm = new CrateManager(); + wbm = new BarrelManager(); + lottery = new Lottery(); + hm = new HolidayManager(); + bp = (BuycraftPlugin) Bukkit.getPluginManager().getPlugin("BuycraftX"); + + if (!Core.getSettings().isSister()) { + drugManager.start(); + } + + Core.resourcePackManager = new ResourcePackManager(this, new RSPack_1_12(), new NMSTitle()); + Core.resourcePackManager.setResourcePack(NMSVersion.UNKNOWN, new ResourcePack(RES_PACKS[1][0], RES_PACKS[1][1])); + Core.resourcePackManager.setResourcePack(NMSVersion.MC_1_13, new ResourcePack(RES_PACKS[2][0], RES_PACKS[2][1])); + Core.resourcePackManager.setResourcePack(NMSVersion.MC_1_12_1, new ResourcePack(RES_PACKS[1][0], RES_PACKS[1][1])); + Core.resourcePackManager.setResourcePack(NMSVersion.MC_1_12, new ResourcePack(RES_PACKS[1][0], RES_PACKS[1][1])); + Core.resourcePackManager.setResourcePack(NMSVersion.MC_1_11_2, new ResourcePack(RES_PACKS[1][0], RES_PACKS[1][1])); + Core.resourcePackManager.setResourcePack(NMSVersion.MC_1_11, new ResourcePack(RES_PACKS[1][0], RES_PACKS[1][1])); + Core.resourcePackManager.setResourcePack(NMSVersion.MC_1_10, new ResourcePack(RES_PACKS[0][0], RES_PACKS[0][1])); + Core.resourcePackManager.setResourcePack(NMSVersion.MC_1_9_4, new ResourcePack(RES_PACKS[0][0], RES_PACKS[0][1])); + Core.resourcePackManager.setResourcePack(NMSVersion.MC_1_9_2, new ResourcePack(RES_PACKS[0][0], RES_PACKS[0][1])); + Core.resourcePackManager.setResourcePack(NMSVersion.MC_1_9_1, new ResourcePack(RES_PACKS[0][0], RES_PACKS[0][1])); + Core.resourcePackManager.setResourcePack(NMSVersion.MC_1_9, new ResourcePack(RES_PACKS[0][0], RES_PACKS[0][1])); + + this.coreCasino = new CoreCasino<GTM>(this, new NMSTitle(), NMSVersion.MC_1_12); + if (!Core.getSettings().isSister()) { + ServerUtil.runTaskLater(() -> { + coreCasino.addGame(new SlotMachine(coreCasino, new Location(Bukkit.getWorld("spawn"), -293, 29.1, 252.3, 0f, 0f))); + coreCasino.addGame(new SlotMachine(coreCasino, new Location(Bukkit.getWorld("spawn"), -293, 29.1, 263.7, -180f, 0f))); + coreCasino.addGame(new SlotMachine(coreCasino, new Location(Bukkit.getWorld("spawn"), -287, 29.1, 253.3, 0f, 0f))); + coreCasino.addGame(new SlotMachine(coreCasino, new Location(Bukkit.getWorld("spawn"), -287, 29.1, 262.7, -180f, 0f))); + coreCasino.addGame(new SlotMachine(coreCasino, new Location(Bukkit.getWorld("spawn"), -273.3, 29.1, 259, 90f, 0f))); + coreCasino.addGame(new SlotMachine(coreCasino, new Location(Bukkit.getWorld("spawn"), -270.3, 29.1, 271, 90f, 0f))); + coreCasino.addGame(new SlotMachine(coreCasino, new Location(Bukkit.getWorld("spawn"), -281.7, 29.1, 269, -90f, 0f))); + coreCasino.addGame(new SlotMachine(coreCasino, new Location(Bukkit.getWorld("spawn"), -270.3, 29.1, 275, 90f, 0f))); + coreCasino.addGame(new SlotMachine(coreCasino, new Location(Bukkit.getWorld("spawn"), -281.7, 29.1, 277, -90f, 0f))); + coreCasino.addGame(new SlotMachine(coreCasino, new Location(Bukkit.getWorld("spawn"), -273.3, 29.1, 288, 90f, 0f))); + coreCasino.addGame(new SlotMachine(coreCasino, new Location(Bukkit.getWorld("spawn"), -277, 29.1, 290.7, -180f, 0f))); + coreCasino.addGame(new SlotMachine(coreCasino, new Location(Bukkit.getWorld("spawn"), -289, 29.1, 292.7, -180f, 0f))); + coreCasino.addGame(new SlotMachine(coreCasino, new Location(Bukkit.getWorld("spawn"), -289, 29.1, 283.3, 0f, 0f))); + coreCasino.addGame(new SlotMachine(coreCasino, new Location(Bukkit.getWorld("spawn"), -298, 29.1, 294.7, -180f, 0f))); + coreCasino.addGame(new SlotMachine(coreCasino, new Location(Bukkit.getWorld("spawn"), -298, 29.1, 281.3, 0f, 0f))); +// coreCasino.addGame(new SlotMachine(coreCasino, new Location(Bukkit.getWorld("spawn"), -289, 29.1, 283.5, 0f, 0f))); + + coreCasino.enabledAllGames(); + }, 15 * 20); + } + + //Spawn NPC's + ServerUtil.runTaskLater(() -> { + World spawn = Bukkit.getWorld("spawn"); + Core.getNPCManager().registerCoreNPC(new TaxiNPC(new Location(spawn, -351.5, 25, 207.5))); + Core.getNPCManager().registerCoreNPC(new RewardsNPC(new Location(spawn, -319.5, 26, 183.5))); + Core.getNPCManager().registerCoreNPC(new CarNPC(new Location(spawn, -278.5, 26, 239.5))); + Core.getNPCManager().registerCoreNPC(new BankTellerNPC(new Location(spawn, -392.5, 27, 231.5))); + Core.getNPCManager().registerCoreNPC(new ShopNPC(wg.getWeaponManager(), new Location(spawn, -371.5, 26.6250, 239.5))); + Core.getNPCManager().registerCoreNPC(new FoodNPC(new Location(spawn, -361.5, 26, 255.5))); + Core.getNPCManager().registerCoreNPC(new ArmorNPC(new Location(spawn, -363.5, 26, 267.5))); + Core.getNPCManager().registerCoreNPC(new HeadSellerNPC(new Location(spawn, -292.5, 26, 312.5))); + Core.getNPCManager().registerCoreNPC(new PoliceNPC(new Location(spawn, -399.5, 26, 171.5))); + Core.getNPCManager().registerCoreNPC(new HitmanNPC(new Location(spawn, -410.5, 26, 160.5))); + Core.getNPCManager().registerCoreNPC(new CriminalNPC(new Location(spawn, -385.5, 25.5, 159.5))); + Core.getNPCManager().registerCoreNPC(new MechanicNPC(new Location(spawn, -306.5, 25, 224.5))); + Core.getNPCManager().registerCoreNPC(new CasinoNPC(new Location(spawn, -306.7, 29, 257.6))); + + if(WEAPON_SKINS_FEATURE_FLAG) { + Core.getNPCManager().registerCoreNPC(new SkinsNPC(new Location(spawn, -296.5, 25.5, 150.5))); + } + }, 40L); + + new ArmorShopManager(this, im); + new EasterEggCommand(null); + + if (Core.getSettings().isSister()) { + ProtocolLibrary.getProtocolManager().addPacketListener(new DrugBlockRemovalListener()); + } + + this.registerCommands(); + this.registerListeners(); + // this.loadShopMenus(); + + // initialize the event manager + EventManager.init(this, Core.getSettings().getType().toString().toUpperCase() + Core.getSettings().getNumber()); + +// This needs updating to 1.12 +// Utils.startEnchantmentShineRemover(Core.getProtocolLib(), this); + + new ItemStackManager(); + + // every 5 mins attempt to remove specific entities + Bukkit.getScheduler().runTaskTimer(this, () -> { + + List<Entity> toRemove = new ArrayList<>(); + + for (World world : Bukkit.getWorlds()){ + Core.log("[GTM][RemoveTask] Searching world " + world.getName()); + for (LivingEntity le : world.getLivingEntities()){ + if (le.getType() == EntityType.ENDER_DRAGON){ + Core.log("[GTM][RemoveTask] Found enderdragon in " + world.getName()); + toRemove.add(le); + } + } + } + + Core.log("[GTM][RemoveTask] Attempting to remove " + toRemove.size() + " ender dragons..."); + + for (Entity ent : toRemove){ + + // if chunk is not loaded, load it + Chunk chunk = ent.getWorld().getChunkAt(ent.getLocation()); + if (chunk != null && !chunk.isLoaded()){ + chunk.load(); + } + + // get craft world + WorldServer craftWorld = ((CraftWorld) ent.getWorld()).getHandle(); + + // get the craft entity + net.minecraft.server.v1_12_R1.Entity craftEntity = ((CraftEntity) ent).getHandle(); + + // attempt to remove entity from world + craftWorld.removeEntity(craftEntity); + ent.remove(); + } + + }, 0L, 20L * 300); + } + + private void loadDependencies() { + PluginManager plm = Bukkit.getPluginManager(); + Plugin wastedGunsPlugin = plm.getPlugin("WastedGuns"); + if (wastedGunsPlugin == null) { + log("Error while enabling WastedGuns dependency. Is it installed?"); + } else { + wg = (GTMGuns) wastedGunsPlugin; + } + Plugin wastedVehiclesPlugin = plm.getPlugin("WastedVehicles"); + if (wastedVehiclesPlugin == null) { + log("Error while enabling WastedVehicles dependency. Is it installed?"); + } else { + wv = (com.j0ach1mmall3.wastedvehicles.Main) wastedVehiclesPlugin; + } + Plugin wastedCopsPlugin = plm.getPlugin("WastedCops"); + if (wastedCopsPlugin == null) { + log("Error while enabling WastedCops dependency. Is it installed?"); + } else { + wc = (com.j0ach1mmall3.wastedcops.Main) wastedCopsPlugin; + } + pm = ProtocolLibrary.getProtocolManager(); + } + + @Override + public void onDisable() { + + System.out.println("[GTM] Disabling GTM..."); + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + for (Player player : Bukkit.getOnlinePlayers()) { + + // grab user + GTMUser user = GTMUserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + if (user != null){ + + // set as kicked + user.setKicked(true); + + System.out.println("[GTM] Attempting to save player=" + player.getName()); + if (user.isInCombat()) user.setLastTag(-1); + + if (player.getOpenInventory() != null && player.getOpenInventory().getTopInventory() != null) { + String name = ChatColor.stripColor(player.getOpenInventory().getTopInventory().getTitle()); + + // if backpack is open + if (name.equalsIgnoreCase("Backpack")){ + System.out.println("[GTM] Saving backpack contents for player=" + player.getName()); + + ItemStack[] backpackContents = player.getOpenInventory().getTopInventory().getContents(); + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `backpackContents`=? WHERE `uuid`=UNHEX(?);")) { + statement.setString(1, backpackContents == null ? null : GTMUtils.toBase64(backpackContents)); + statement.setString(2, player.getUniqueId().toString().replaceAll("-", "")); + statement.execute(); + } + + player.closeInventory(); + } + } + + if (user.isLocked()){ + user.onSave(connection); + MutexDAO.setGTMUserMutex(connection, user.getUUID(), false); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + + System.out.println("[GTM] Done saving GTMUsers..."); + + this.save(); + + //Casino games. + if (this.coreCasino != null) + this.coreCasino.removeAllGames(); + + } + + private void registerListeners() { + PluginManager pm = Bukkit.getPluginManager(); + pm.registerEvents(new Death(), this); + pm.registerEvents(new Login(), this); + pm.registerEvents(new Leave(), this); + pm.registerEvents(new MenuListener(), this); + pm.registerEvents(new Join(getResourcePackManager()), this); + pm.registerEvents(new Pickup(), this); + pm.registerEvents(new WeaponUse(), this); + pm.registerEvents(new Drop(), this); + pm.registerEvents(new Interact(), this); + pm.registerEvents(new Chat(), this); + pm.registerEvents(new InventoryClick(), this); + pm.registerEvents(new InventoryOpen(), this); + pm.registerEvents(new BackpackManager(), this); + pm.registerEvents(new TrashCanManager(), this); + pm.registerEvents(new UpdateListener(), this); + pm.registerEvents(new Move(), this); + pm.registerEvents(new Damage(), this); + pm.registerEvents(new ChangeWorld(), this); + pm.registerEvents(new FoodChange(), this); + pm.registerEvents(new VehicleUse(), this); + pm.registerEvents(new PetListener(), this); + pm.registerEvents(new BreakBlock(), this); + pm.registerEvents(new WeaponShoot(), this); + pm.registerEvents(new BarrelListener(), this); + pm.registerEvents(new SwapHandItems(), this); + pm.registerEvents(new PrepareItemCraft(), this); + pm.registerEvents(new ChristmasListener(), this); + pm.registerEvents(new MovementCheat(), this); + + if (!Core.getSettings().isSister()) { + pm.registerEvents(new DrugListener(), this); + pm.registerEvents(new DrugPlacementListener(), this); + } + + pm.registerEvents(new FireListener(), this); + pm.registerEvents(new PortalEnter(), this); + pm.registerEvents(new VoteReward(), this); + pm.registerEvents(new ItemBreak(), this); + pm.registerEvents(new ArmorEquip(), this); + pm.registerEvents(new Craft(), this); + pm.registerEvents(new PotionSplash(), this); + pm.registerEvents(new GamemodeChange(), this); + pm.registerEvents(new Dispense(), this); + pm.registerEvents(new CommandPreProcess(), this); + pm.registerEvents(new MobSpawn(), this); +// pm.registerEvents(new PlayerScare(), this);//todo: remove on release + this.getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord"); + } + + private void registerCommands() { + this.getCommand("ammo").setExecutor(new AmmoCommand()); + this.getCommand("feed").setExecutor(new FeedCommand()); + this.getCommand("lootcrate").setExecutor(new LootCrateCommand()); + this.getCommand("spawn").setExecutor(new SpawnCommand()); + this.getCommand("warp").setExecutor(new WarpCommand()); + this.getCommand("gtmadmin").setExecutor(new GTMAdminCommand()); + this.getCommand("gameitem").setExecutor(new GameItemCommand()); + this.getCommand("kit").setExecutor(new KitCommand()); + this.getCommand("shop").setExecutor(new ShopCommand()); + this.getCommand("gtmrank").setExecutor(new GTMRankCommand()); + this.getCommand("money").setExecutor(new MoneyCommand()); + this.getCommand("pay").setExecutor(new PayCommand()); + this.getCommand("rankup").setExecutor(new RankupCommand()); + this.getCommand("tpa").setExecutor(new TpaCommand()); + this.getCommand("tpahere").setExecutor(new TpaCommand()); + this.getCommand("tpaccept").setExecutor(new TpaCommand()); + this.getCommand("tpdeny").setExecutor(new TpaCommand()); + this.getCommand("permits").setExecutor(new PermitsCommand()); + this.getCommand("kill").setExecutor(new KillCommand()); + this.getCommand("suicide").setExecutor(new KillCommand()); + this.getCommand("gangadmin").setExecutor(new GangAdminCommand()); + this.getCommand("picker").setExecutor(new PickerCommand()); + this.getCommand("vehicle").setExecutor(new VehicleCommand()); + this.getCommand("backpack").setExecutor(new BackpackCommand()); + this.getCommand("bribe").setExecutor(new BribeCommand()); + this.getCommand("reset").setExecutor(new ResetCommand()); + this.getCommand("tokenshop").setExecutor(new TokenShopCommand()); + this.getCommand("antiaura").setExecutor(new AntiAuraCommand()); + this.getCommand("clear").setExecutor(new ClearCommand()); + this.getCommand("fix").setExecutor(new FixCommand()); + this.getCommand("near").setExecutor(new NearCommand()); + this.getCommand("teleport").setExecutor(new TeleportCommand()); + this.getCommand("spectator").setExecutor(new SpectatorCommand()); + this.getCommand("backup").setExecutor(new BackupCommand()); + this.getCommand("lottery").setExecutor(new LotteryCommand()); + this.getCommand("speed").setExecutor(new SpeedCommand()); + this.getCommand("chunkunload").setExecutor(new ChunkUnloadCommand()); + this.getCommand("topkillers").setExecutor(new TopKillersCommand()); + this.getCommand("stats").setExecutor(new StatsCommand()); + this.getCommand("resourcepack").setExecutor(new ResourcePackCommand()); + + if (!Core.getSettings().isSister()) { + this.getCommand("drugs").setExecutor(new DrugCommand()); + this.getCommand("drugdealer").setExecutor(new DrugDealerCommand()); + this.getCommand("drugcheck").setExecutor(new DrugCheckCommand()); + } + + this.getCommand("gtmranks").setExecutor(new GTMRanksCommand()); +// this.getCommand("stack").setExecutor(new StackCommand()); Major DUPE glitch, FIX BEFORE ENABLING! + this.getCommand("event").setExecutor(new EventCommand(this)); + new CheatCodeCommand(); + new HalloweenCommand(); + new ChristmasCommand(); + new ChestCheckCommand(); + new CoreNPCCommand(); + new SellCommand(); + + if(WEAPON_SKINS_FEATURE_FLAG) { + new SkinCommand(); + new SkinsCommand(); + } + + new SetRarityCommand(); + new SettingsCommand(); + new TransferCommand(); + } + + private void load() { + settings.setChristmasDropsConfig(Utils.loadConfig("christmasdrops")); + settings.setGtmConfig(Utils.loadConfig("gtm")); + settings.setWarpsConfig(Utils.loadConfig("warps")); + settings.setBountiesConfig(Utils.loadConfig("bounties")); + settings.setItemsConfig(Utils.loadConfig("items")); + settings.setKitsConfig(Utils.loadConfig("kits")); + settings.setLootConfig(Utils.loadConfig("loot")); + settings.setLootCratesConfig(Utils.loadConfig("lootcrates")); + settings.setBarrelsConfig(Utils.loadConfig("barrels")); + settings.setLotteryConfig(Utils.loadConfig("lottery")); + + if (!Core.getSettings().isSister()) { + settings.setDrugBlocksConfig(Utils.loadConfig("drugblocks")); + } + + settings.setGtmShopMenuConfig(Utils.loadConfig("salemenus")); + YamlConfiguration c = settings.getGtmConfig(); + settings.setMap(c.getString("map")); + // can players pvp eachother + settings.setPvp(c.getBoolean("pvp", true)); + // can players transfer data to other servers + settings.setServerTransfer(c.getBoolean("server-transfer", false)); + // can players use cheatcodes + settings.setGlobalCheatcodes(c.getBoolean("cheatcodes", false)); + // can players use /pay + settings.setPayCommand(c.getBoolean("pay", true)); + // can players transfer bank money to other players bank + settings.setBankToBankTransfer(c.getBoolean("bank-to-bank-transfer", true)); + // can players buy items at shops + settings.setBuy(c.getBoolean("buy", true)); + // can players trade eachother + settings.setTrade(c.getBoolean("player-trade", true)); + // can players use the bounty system + settings.setBountySystem(c.getBoolean("bounty-system", true)); + // server take money when new bounties are placed + settings.setBountyTax(c.getBoolean("bounty-system-tax", true)); + // base percent of money taken from new bounties placed + settings.setBountyTaxPercent(c.getDouble("bounty-tax-percent", 20.0)); + // can players use kits + settings.setKitSystem(c.getBoolean("kit-system", true)); + // server take money from players that the players drop on death + settings.setServerDeathTax(c.getBoolean("server-death-tax", true)); + // does the tax scale with GTMRank + settings.setServerDeathTaxScaled(c.getBoolean("server-death-tax-scaled", true)); + // the base percent of money taken from the dropped money + settings.setServerDeathBasePercent(c.getDouble("server-death-tax-percent", 20.0)); + // the min cash that must be taken by the server + settings.setServerDeathTaxMin(c.getInt("server-death-tax-min", 1000)); + // the max cash that must be taken by the server + settings.setServerDeathTaxMax(c.getInt("server-death-tax-max", 50000)); + + // this.setupTables(); todo: throwing errors with new core DAO set up, lukas / stephen might need a look. + this.loadMenus(); + this.loadSettings(); + settings.setOneElevenRespack(RES_PACKS[1][0]); + settings.setOneElevenHash(RES_PACKS[1][1]); + settings.setOneTenRespack(RES_PACKS[0][0]); + settings.setOneTenHash(RES_PACKS[0][1]); + } + + public void reload() { + this.load(); + wm.loadWarps(); + bm.loadBounties(); + im.loadItems(); + im.loadKits(); + cm.loadCrates(); + lottery.loadConfig(); + } + + public void save() { + wm.saveWarps(); + bm.saveBounties(); + cm.saveCrates(); + im.saveItems(); + im.saveKits(); + wbm.unloadBarrels(); + lottery.saveConfig(); + + if (!Core.getSettings().isSister()) { + drugManager.stop(); + } + + FireListener.clearFire(); + } + + public void setupTables() { + + ServerUtil.runTaskAsync(() -> { + BaseDatabase.runCustomQuery("CREATE TABLE IF NOT EXISTS " + Core.name() + "(" + + "`uuid` varchar(40) NOT NULL," + + "`name` varchar(17) NOT NULL," + + "`rank` varchar(255) DEFAULT 'HOBO'," + + "`kills` int(11) default 0," + + "`deaths` int(11) default 0," + + "`money` double default 0," + + "`bank` double default 0," + + "`killCounter` int(11) default 0," + + "`killStreak` int(11) default 0," + + "`permits` int(11) default 0," + + "`jobMode` varchar(255) default NULL," + + "`lastJobMode` bigint(20) default 0," + + "`backpackContents` longtext," + + "`kitExpiries` varchar(255)," + + "`houses` varchar(255)," + + "`gang` varchar(255)," + + "`gangRank` varchar(255) NOT NULL DEFAULT 'member'," + + "`jailTimer` int(11) DEFAULT -1," + + "`jailCop` varchar(255) default NULL," + + "`jailCopName` varchar(255) default NULL," + + "`personalVehicle` varchar(255)," + + "`cheatcodes` BLOB," + + "PRIMARY KEY (`uuid`));"); + + BaseDatabase.runCustomQuery("CREATE TABLE IF NOT EXISTS " + Core.name() + "_gangs (" + + "`name` varchar(255) NOT NULL," + + "`leader` varchar(255) NOT NULL," + + "`leaderName` varchar(255) NOT NULL," + + "`description` varchar(255) NOT NULL DEFAULT 'Your default gang description'," + + "`maxMembers` int(11) NOT NULL," + + "PRIMARY KEY (`name`));"); + + BaseDatabase.runCustomQuery("CREATE TABLE IF NOT EXISTS " + Core.name() + "_gangs_relations (" + + "`gang1` varchar(255) NOT NULL," + + "`gang2` varchar(255) NOT NULL," + + "`relation` varchar(255) NOT NULL);"); + + BaseDatabase.runCustomQuery("CREATE TABLE IF NOT EXISTS " + Core.name() + "_heads (" + + "`sellerUUID` varchar(40) NOT NULL," + + "`sellerName` varchar(17) NOT NULL," + + "`head` varchar(255) NOT NULL," + + "`expiry` bigint(20)," + + "`done` boolean default '0'," + + "`paid` boolean default '0'," + + "`gaveHead` boolean default '0'," + + "`bidderUUID` varchar(40)," + + "`bidderName` varchar(17)," + + "`bid` double default '0');"); + +// try (Connection connection = BaseDatabase.getInstance().getConnection()) { +// try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM " + Core.name() + " LIMIT 1")) { +// try (ResultSet result = statement.executeQuery()) { +// ResultSetMetaData resultMetaData = result.getMetaData(); +// List<String> columns = Lists.newArrayList(); +// for (int i = 1; i <= resultMetaData.getColumnCount(); i++) { +// columns.add(resultMetaData.getCatalogName(i).toLowerCase()); +// System.out.println(resultMetaData.getCatalogName(i).toLowerCase()); +// } +// +// if (!columns.contains("playtime")) +// BaseDatabase.runCustomQuery("ALTER TABLE " + Core.name() + " ADD COLUMN playtime BIGINT(20) NOT NULL DEFAULT 0;"); +// +// for (AmmoType type : AmmoType.values()) +// if (!type.isInInventory() && !columns.contains(type.toString().toLowerCase())) +// BaseDatabase.runCustomQuery("ALTER TABLE " + Core.name() + " ADD COLUMN " + type.toString().toLowerCase() + " INT(11) DEFAULT 0;"); +// +// if (GTM.getWastedVehicles() != null && GTM.getWastedVehicles().getBabies() != null && GTM.getWastedVehicles().getBabies().getVehicleProperties() != null) { +// for (VehicleProperties vehicle : GTM.getWastedVehicles().getBabies().getVehicleProperties()) { +// if (!columns.contains(vehicle.getIdentifier().toLowerCase())) +// BaseDatabase.runCustomQuery("ALTER TABLE " + Core.name() + " ADD COLUMN " + vehicle.getIdentifier().toLowerCase() + " BOOLEAN NOT NULL DEFAULT 0;"); +// +// if (!columns.contains(vehicle.getIdentifier().toLowerCase() + ":info")) +// BaseDatabase.runCustomQuery("ALTER TABLE " + Core.name() + " ADD COLUMN `" + vehicle.getIdentifier().toLowerCase() + ":info` VARCHAR(255);"); +// } +// } +// } +// } +// } catch (SQLException e) { +// e.printStackTrace(); +// } + }); + +// Core.sql.updateAsyncLater("create table if not exists " + Core.name() +// + "(uuid varchar(40) NOT NULL, name varchar(17) NOT NULL, rank varchar(255) DEFAULT 'HOBO', kills int(11) default 0, deaths int(11) default 0," + +// " money double default 0, bank double default 0, killCounter int(11) default 0, killStreak int(11) default 0, permits int(11) default 0, jobMode varchar(255) default NULL, lastJobMode bigint(20) default 0," + +// " backpackContents longtext, kitExpiries varchar(255), houses varchar(255), gang varchar(255), gangRank varchar(255) NOT NULL DEFAULT 'member'," + +// " jailTimer int(11) DEFAULT -1, jailCop varchar(255) default NULL, jailCopName varchar(255) default NULL, personalVehicle varchar(255), cheatcodes BLOB, PRIMARY KEY (uuid))"); +// Core.sql.updateAsyncLater("create table if not exists " + Core.name() +// + "_gangs (name varchar(255) NOT NULL, leader varchar(255) NOT NULL, leaderName varchar(255) NOT NULL," + +// " description varchar(255) NOT NULL DEFAULT 'Your default gang description', maxMembers int(11) NOT NULL, PRIMARY KEY (name));"); +// Core.sql.updateAsyncLater("create table if not exists " + Core.name() +// + "_gangs_relations (gang1 varchar(255) NOT NULL, gang2 varchar(255) NOT NULL, relation varchar(255) NOT NULL);"); +// Core.sql.updateAsyncLater("create table if not exists " + Core.name() + "_heads (sellerUUID varchar(40) NOT NULL, sellerName varchar(17) NOT NULL, head varchar(255) NOT NULL, expiry bigint(20), done boolean default '0', paid boolean default '0', gaveHead boolean default '0', bidderUUID varchar(40), bidderName varchar(17), bid double default '0');"); + +// new BukkitRunnable() { +// @Override +// public void run() { +// try { +// ResultSet rs = Core.sql.query("select * from " + Core.name() + " LIMIT 1;"); +// ResultSetMetaData metaData = rs.getMetaData(); +// List<String> columns = new ArrayList<>(); +// for (int i = 1; i <= metaData.getColumnCount(); i++) +// columns.add(metaData.getColumnName(i).toLowerCase()); +// if (!columns.contains("playtime")) +// Core.sql.updateAsyncLater("ALTER TABLE " + Core.name() + " ADD COLUMN playtime BIGINT(20) NOT NULL DEFAULT 0;"); +// for (AmmoType type : AmmoType.values()) +// if (!type.isInInventory() && !columns.contains(type.toString().toLowerCase())) +// Core.sql.update("alter table " + Core.name() + " add column " + type.toString().toLowerCase() + " int(11) default 0;"); +// +// if(GTM.getWastedVehicles()!=null && GTM.getWastedVehicles().getBabies()!=null && GTM.getWastedVehicles().getBabies().getVehicleProperties()!=null) { +// for (VehicleProperties vehicle : GTM.getWastedVehicles().getBabies().getVehicleProperties()) { +// if (!columns.contains(vehicle.getIdentifier().toLowerCase())) +// Core.sql.update("alter table " + Core.name() + " add column " + vehicle.getIdentifier().toLowerCase() + " BOOLEAN not null default 0;"); +// if (!columns.contains(vehicle.getIdentifier().toLowerCase() + ":info")) +// Core.sql.update("alter table " + Core.name() + " add column `" + vehicle.getIdentifier().toLowerCase() + ":info` VARCHAR(255);"); +// } +// } +// rs.close(); +// } catch (SQLException e) { +// Core.error("Error while altering " + Core.name() + " table: "); +// e.printStackTrace(); +// } +// } +// }.runTaskAsynchronously(this); + } + + private void loadMenus() { + MenuManager.addMenu("phone", 54, "&7&lPhone"); + + MenuManager.addMenu("account", 54, "&d&lMy Account"); + MenuManager.addMenu("ranks", 54, "&a&lRanks"); + MenuManager.addMenu("gtmstats", 54, "&d&lStats"); + MenuManager.addMenu("prefs", 54, "&5&lPreferences"); + MenuManager.addMenu("contacts", 54, "&6&lContacts"); + + MenuManager.addMenu("bounties", 54, "&5&lBounties"); + MenuManager.addMenu("bountieslist", 54, "&5&lBounties List"); + MenuManager.addMenu("bountieshelp", 54, "&5&lBounties Help"); + MenuManager.addMenu("bountiesplace", 54, "&5&lPlace Bounties"); + + MenuManager.addMenu("kits", 54, "&b&lKits"); + + MenuManager.addMenu("taxi", 54, "&e&lTaxi Service"); + MenuManager.addMenu("taxiplayers", 54, "&e&lTaxi Service: Players"); + MenuManager.addMenu("taxihouses", 54, "&e&lTaxi Service: &3&lHouses"); + MenuManager.addMenu("taxiotherplayers", 54, "&e&lPick up a player!"); + MenuManager.addMenu("taxiwarps", 54, "&e&lTaxi Service: Warps"); + + MenuManager.addMenu("bank", 54, "&3&lBanking"); + MenuManager.addMenu("bankwithdraw", 54, "&3&lBanking: Withdraw Money"); + MenuManager.addMenu("bankdeposit", 54, "&3&lBanking: Deposit Money"); + MenuManager.addMenu("banktransfer", 54, "&3&lBanking: Transfer Money"); + + MenuManager.addMenu("gps", 54, "&8&lGPS Tracker"); + MenuManager.addMenu("gpsgangs", 54, "&8&lGPS Tracker: &a&lGangs"); + MenuManager.addMenu("gpshouses", 54, "&8&lGPS Tracker: &3&lHouses"); + MenuManager.addMenu("gpscops", 54, "&8&lGPS Tracker: &b&lCops"); + MenuManager.addMenu("gpscriminals", 54, "&8&lGPS Tracker: &e&lCriminals"); + MenuManager.addMenu("gpsbounties", 54, "&8&lGPS Tracker: &5&lBounties"); + + MenuManager.addMenu("mygang", 54, "&a&lMy Gang"); + MenuManager.addMenu("gang", 54, "&a&lGang"); + MenuManager.addMenu("disbandgang", 54, "&c&lDisband Gang"); + MenuManager.addMenu("leavegang", 54, "&c&lLeave Gang"); + MenuManager.addMenu("mygangmembers", 54, "&a&lMy Gang Members"); + MenuManager.addMenu("mygangrelations", 54, "&a&lMy Gang Relations"); + MenuManager.addMenu("gangmembers", 54, "&a&lGang Members"); + MenuManager.addMenu("gangmember", 54, "&a&lGang Member"); + MenuManager.addMenu("gangrelations", 54, "&a&lGang Relations"); + MenuManager.addMenu("gangs", 54, "&a&lGang List"); + + MenuManager.addMenu("ammopouch", 36, "&c&lAmmo Pouch"); + + MenuManager.addMenu("jail", 54, "&c&lJail"); + + MenuManager.addMenu("property", 54, "&2&lProperty"); + MenuManager.addMenu("vehicles", 54, "&4&lVehicles"); + MenuManager.addMenu("vehicleshop", 54, "&4&lVehicle Shop"); + MenuManager.addMenu("buyvehicle", 54, "&4&lBuy Vehicle Shop"); + MenuManager.addMenu("sellvehicle", 54, "&4&lSell Vehicle"); + MenuManager.addMenu("repairvehicle", 54, "&4&lRepair Vehicle"); + MenuManager.addMenu("personalvehicle", 54, "&4&lPersonal Vehicle"); + MenuManager.addMenu("mechanic", 54, "&4&lMechanic"); + + MenuManager.addMenu("heads", 54, "&e&lHead Auction"); + MenuManager.addMenu("auctionhead", 54, "&e&lAuction Head"); + + MenuManager.addMenu("armorupgrade", 54, "&b&lArmor Upgrade"); + MenuManager.addMenu("christmasshop", 54, "&cC&2h&cr&2i&cs&2t&cm&2a&cs &2S&ch&2o&cp"); + + MenuManager.addMenu("transferconfirm", 54, "&c&lTransfer Confirmation"); + + MenuManager.addMenu("lottery", 54, "&e&lLottery"); + MenuManager.addMenu("sellinvconfirm", 54, "&a&lConfirm Inventory Sell"); + + if (!Core.getSettings().isSister()) { + MenuManager.addMenu("drugdealer", 54, "&3&lDrug Dealer"); + MenuManager.addMenu("drugseller", 54, "&3&lDrug Seller"); + } + + MenuManager.addMenu("cheatcodes", 54, "&2&lCheat Codes"); + + MenuManager.addMenu("realestateagent", 27, "&3&lDynasty 8 Real Estate"); + MenuManager.addMenu("realestate-premium", 54, "&3&lDynasty 8 &a&lPremium Houses"); + MenuManager.addMenu("realestate-nonpremium", 54, "&3&lDynasty 8 &b&lNon-Premium Houses"); + } + + private void loadSettings() { + Settings settings = Core.getSettings(); + settings.setDefaultGameMode(GameMode.ADVENTURE); + settings.setPetsVulnerable(true); + settings.setServerWarperEnabled(false); + settings.setUseEditMode(true); + settings.setTokenShopEnabled(true); + settings.setCanOpenChests(true); + settings.setCanInteractInventory(true); + settings.setLoadCosmetics(true); + settings.setCanCraft(false); + if (GTM.getSettings().getMap() != null) { + World map = Bukkit.getWorld(GTM.getSettings().getMap()); + settings.setStopChunkLoad(map.getName()); + map.setPVP(true); + } + World spawn = Bukkit.getWorlds().get(0); + settings.setStopChunkLoad(spawn.getName()); + settings.setStopHungerChange(spawn.getName()); + settings.setStopWeatherChange(spawn.getName()); + spawn.setPVP(false); + spawn.setSpawnFlags(false, false); + } + + /* public void loadShopMenus(){ + YamlConfiguration menuConfig = settings.getGtmShopMenuConfig(); + Core.log("started loading shop menus"); + for(String saleMenuName : menuConfig.getConfigurationSection("").getKeys(false)) { + Core.log("Current salemenu is " + saleMenuName); + String saleMenuTitle = menuConfig.getString(saleMenuName + ".menu-title"); + ShopMenu saleMenu = new ShopMenu(saleMenuName, 54, saleMenuTitle); + for (String subCategoryName : menuConfig.getConfigurationSection(saleMenuName + ".subcategories").getKeys(false)) { + Core.log("Current subCategory is " + subCategoryName); + String currentPath = saleMenuName + ".subcategories." + subCategoryName; + SubCategoryMenu subCategoryMenu = parseMenuDisplayItemString(saleMenu, null, currentPath, subCategoryName, menuConfig.getString(currentPath + ".display-item")); + saleMenu.addCategory(subCategoryName, subCategoryMenu); + + if (!menuConfig.contains(currentPath + ".subcategories")) { + for (String gameItemString : menuConfig.getStringList(currentPath + ".sale-items")) { + GameItem gameItem = getItemManager().getItem(gameItemString); + ShopMenuItem saleMenuItem = new ShopMenuItem(gameItem.getItem(), gameItem.getSellPrice()); + subCategoryMenu.addSellingItem(saleMenuItem); + } + } + else{ + loopThroughSubCategories(saleMenu, subCategoryMenu, menuConfig, currentPath + ".subcategories"); + } + } + MenuManager.addMenu(saleMenu); + } + } + + private void loopThroughSubCategories(ShopMenu shopMenu, SubCategoryMenu categoryMenu, YamlConfiguration menuConfig, String path){//path should end in .categories + for (String subCategoryName : menuConfig.getConfigurationSection(path).getKeys(false)) { + Core.log("current subcategory is " + subCategoryName); + String currentPath = path + "." + subCategoryName; + SubCategoryMenu subCategoryMenu = parseMenuDisplayItemString(shopMenu, categoryMenu, currentPath, subCategoryName, menuConfig.getString(currentPath + ".display-item")); + categoryMenu.addSubCategory(subCategoryName, subCategoryMenu); + + if (!menuConfig.contains(currentPath + ".subcategories")) { + for (String gameItemString : menuConfig.getStringList(currentPath + ".sale-items")) { + GameItem gameItem = getItemManager().getItem(gameItemString); + ShopMenuItem saleMenuItem = new ShopMenuItem(gameItem.getItem(), gameItem.getSellPrice()); + subCategoryMenu.addSellingItem(saleMenuItem); + } + } + else{ + loopThroughSubCategories(shopMenu, subCategoryMenu, menuConfig, currentPath + ".subcategories"); + } + } + } + + private SubCategoryMenu parseMenuDisplayItemString(ShopMenu saleMenu, SubCategoryMenu previousSubCategory, String currentPath, String subCategoryName, String displayItemString){ + int materialID = 0; + short dataID = 0; + if(displayItemString.contains(":")){ + if(!Utils.isInteger(displayItemString.split(":")[0]) || !Utils.isInteger(displayItemString.split(":")[1])){ + Core.error("Unable to load item located in menu config at path: " + currentPath + ".display-item"); + return null; + } + materialID = Integer.parseInt(displayItemString.split(":")[0]); + dataID = Short.parseShort(displayItemString.split(":")[1]); + } + else{ + if(!Utils.isInteger(displayItemString)){ + Core.error("Unable to load item located in menu config at path: " + currentPath + ".display-item"); + return null; + } + materialID = Integer.parseInt(displayItemString); + } + return new SubCategoryMenu(saleMenu, previousSubCategory, subCategoryName, ServerType.GTM, Material.getMaterial(materialID), dataID); + }*/ +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/GTMSettings.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/GTMSettings.java new file mode 100644 index 0000000..482334f --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/GTMSettings.java @@ -0,0 +1,590 @@ +package net.grandtheftmc.gtm; + +import org.bukkit.configuration.file.YamlConfiguration; + +import net.grandtheftmc.core.Core; + +public class GTMSettings { + private YamlConfiguration gtmConfig; + private YamlConfiguration warpsConfig; + private YamlConfiguration bountiesConfig; + private YamlConfiguration itemsConfig; + private YamlConfiguration kitsConfig; + private YamlConfiguration lootConfig; + private YamlConfiguration lootCratesConfig; + private YamlConfiguration barrelsConfig; + private YamlConfiguration lotteryConfig; + private YamlConfiguration drugDealerConfig; + private YamlConfiguration drugBlocksConfig; + private YamlConfiguration gtmShopMenuConfig; + private YamlConfiguration christmasDropsConfig; + + private String oneTenRespack; + private String oneTenHash; + + private String oneElevenRespack; + private String oneElevenHash; + + /** The name of the main map */ + private String map; + /** Are transfers to other servers allowed */ + private boolean serverTransfer; + /** Are players allowed to pvp eachother */ + private boolean pvp; + /** Are all global cheatcodes enabled */ + private boolean globalCheatcodes; + /** Is /pay enabled */ + private boolean payCommand; + /** Can players transfer between bank accounts */ + private boolean bankToBankTransfer; + /** Can players buy items/weapons/etc. */ + private boolean buy; + /** Can players trade eachother */ + private boolean trade; + /** Can players use the bounty system */ + private boolean bountySystem; + /** Can we tax the bounties placed */ + private boolean bountySystemTax; + /** The percent of tax applied to new bounties placed */ + private double bountySystemTaxPercent; + /** Can players use the kit system */ + private boolean kitSystem; + /** Players money lost upon death to server */ + private boolean serverDeathTax; + /** Base percent of money lost to the death tax */ + private double serverDeathBasePercent; + /** Minimum amount of money lost per death */ + private int serverDeathTaxMin; + /** Maximum amount of money lost per death */ + private int serverDeathTaxMax; + /** Does the death tax scale per GTMRank */ + private boolean serverDeathTaxScaled; + + public void setGtmShopMenuConfig(YamlConfiguration gtmShopMenuConfig) { + this.gtmShopMenuConfig = gtmShopMenuConfig; + } + + public void setChristmasDropsConfig(YamlConfiguration christmasDropsConfig) { + this.christmasDropsConfig = christmasDropsConfig; + } + + public YamlConfiguration getChristmasDropsConfig() { + return this.christmasDropsConfig; + } + + public YamlConfiguration getGtmShopMenuConfig() { + return gtmShopMenuConfig; + } + + public YamlConfiguration getDrugBlocksConfig() { + return drugBlocksConfig; + } + + public void setDrugBlocksConfig(YamlConfiguration drugBlocksConfig) { + this.drugBlocksConfig = drugBlocksConfig; + } + + public YamlConfiguration getDrugDealerConfig() { + return drugDealerConfig; + } + + public void setDrugDealerConfig(YamlConfiguration drugDealerConfig) { + this.drugDealerConfig = drugDealerConfig; + } + + public YamlConfiguration getGtmConfig() { + return this.gtmConfig; + } + + public void setGtmConfig(YamlConfiguration gtmConfig) { + this.gtmConfig = gtmConfig; + } + + public YamlConfiguration getWarpsConfig() { + return this.warpsConfig; + } + + public void setWarpsConfig(YamlConfiguration warpsConfig) { + this.warpsConfig = warpsConfig; + } + + public YamlConfiguration getBountiesConfig() { + return this.bountiesConfig; + } + + public void setBountiesConfig(YamlConfiguration bountiesConfig) { + this.bountiesConfig = bountiesConfig; + } + + public YamlConfiguration getItemsConfig() { + return this.itemsConfig; + } + + public void setItemsConfig(YamlConfiguration itemsConfig) { + this.itemsConfig = itemsConfig; + } + + public YamlConfiguration getKitsConfig() { + return this.kitsConfig; + } + + public void setKitsConfig(YamlConfiguration kitsConfig) { + this.kitsConfig = kitsConfig; + } + + public YamlConfiguration getBarrelsConfig() { + return this.barrelsConfig; + } + + public void setBarrelsConfig(YamlConfiguration barrelsConfig) { + this.barrelsConfig = barrelsConfig; + } + + public String getMap() { + return this.map; + } + + public void setMap(String map) { + this.map = map; + } + + public YamlConfiguration getLootCratesConfig() { + return this.lootCratesConfig; + } + + public void setLootCratesConfig(YamlConfiguration lootCratesConfig) { + this.lootCratesConfig = lootCratesConfig; + } + + public YamlConfiguration getLootConfig() { + return this.lootConfig; + } + + public void setLootConfig(YamlConfiguration lootConfig) { + this.lootConfig = lootConfig; + } + + public YamlConfiguration getLotteryConfig() { + return this.lotteryConfig; + } + + public void setLotteryConfig(YamlConfiguration lotteryConfig) { + this.lotteryConfig = lotteryConfig; + } + + public String getOneElevenRespack() { + return oneElevenRespack; + } + + public String getOneElevenHash() { + return oneElevenHash; + } + + public String getOneTenRespack() { + return oneTenRespack; + } + + public String getOneTenHash() { + return oneTenHash; + } + + public void setOneElevenRespack(String oneElevenRespack) { + this.oneElevenRespack = oneElevenRespack; + } + + public void setOneElevenHash(String oneElevenHash) { + this.oneElevenHash = oneElevenHash; + } + + public void setOneTenRespack(String oneTenRespack) { + this.oneTenRespack = oneTenRespack; + } + + public void setOneTenHash(String oneTenHash) { + this.oneTenHash = oneTenHash; + } + + /** + * Whether or not server transferring is allowed. + * + * @return {@code true} if server transferring is allowed, {@code false} + * otherwise. + */ + public boolean isServerTransfer() { + return serverTransfer; + } + + /** + * Set whether or not server transferring is allowed. + * + * @param serverTransfer - {@code true} if players can transfer server data, + * {@code false} otherwise. + */ + public void setServerTransfer(boolean serverTransfer) { + this.serverTransfer = serverTransfer; + } + + /** + * Get whether or not players are allowed to pvp. + * <p> + * This is used to cancel damage events of any source. + * </p> + * + * @return {@code true} if pvp damage events are allowed, {@code false} + * otherwise. + */ + public boolean isPvp() { + return pvp; + } + + /** + * Set whether players are allowed to pvp. + * <p> + * This is used to cancel damage events of any source. + * </p> + * + * @param pvp - {@code true} if players can take damage, {@code false} + * otherwise. + */ + public void setPvp(boolean pvp) { + this.pvp = pvp; + } + + /** + * Get whether or not cheatcodes are enabled. + * + * @return {@code true} if cheatcodes are enabled, {@code false} otherwise. + */ + public boolean isGlobalCheatcodes() { + return globalCheatcodes; + } + + /** + * Set whether cheatcodes are enabled or not. + * + * @param globalCheatcodes - {@code true} if cheatcodes are enabled, + * {@code false} otherwise. + */ + public void setGlobalCheatcodes(boolean globalCheatcodes) { + this.globalCheatcodes = globalCheatcodes; + } + + /** + * Get whether or not the pay command is enabled. + * + * @return {@code true} if players can use the pay command, {@code false} + * otherwise. + */ + public boolean isPayCommand() { + return payCommand; + } + + /** + * Set whether or not the pay command is enabled. + * + * @param payCommand - {@code true} if the pay command is enabled, + * {@code false} otherwise. + */ + public void setPayCommand(boolean payCommand) { + this.payCommand = payCommand; + } + + /** + * Get whether or not players can transfer between bank accounts. + * + * @return {@code true} if they can transfer between bank accounts, + * {@code false} otherwise. + */ + public boolean isBankToBankTransfer() { + return bankToBankTransfer; + } + + /** + * Set whether or not players can transfer between bank accounts. + * + * @param bankToBankTransfer - {@code true} if players can transfer between + * bank accounts + */ + public void setBankToBankTransfer(boolean bankToBankTransfer) { + this.bankToBankTransfer = bankToBankTransfer; + } + + /** + * Get whether or not players can buy items/weapons/armor/etc. + * + * @return {@code true} if players can buy things, {@code false} otherwise. + */ + public boolean canBuy() { + return buy; + } + + /** + * Set whether or not players can buy items/weapons/armor/etc. + * + * @param buy - {@code true} if players can buy things, {@code false} + * otherwise. + */ + public void setBuy(boolean buy) { + this.buy = buy; + } + + /** + * Get whether or not players can trade eachother. + * + * @return {@code true} if players can trade eachother, {@code false} + * otherwise. + */ + public boolean canTrade() { + return trade; + } + + /** + * Set whether or not players can trade eachother. + * + * @param trade - {@code true} if players can trade eachother + */ + public void setTrade(boolean trade) { + this.trade = trade; + + if (Core.getInstance().getTradeManager() != null) + Core.getInstance().getTradeManager().setEnabled(trade); + } + + /** + * Get whether or not players can use the bounty system. + * + * @return {@code true} if players can use the bounty system. + */ + public boolean isBountySystem() { + return bountySystem; + } + + /** + * Set whether or not players can use the bounty system. + * + * @param bountySystem - {@code true} if the bounty system can be used. + */ + public void setBountySystem(boolean bountySystem) { + this.bountySystem = bountySystem; + } + + /** + * Get whether or not there is a tax on placing new bounties. + * <p> + * Note: When players place new bounties on players, some of the money + * will be taken by the server. + * </p> + * + * @return {@code true} if there is a bounty tax, {@code false} + * otherwise. + */ + public boolean isBountyTax() { + return bountySystemTax; + } + + /** + * Set whether or not there is a bounty tax. + * <p> + * Note: When players place new bounties on players, some of the money + * will be taken by the server. + * </p> + * + * @param bountySystemTax - {@code true} if there is a bounty tax, + * {@code false} otherwise. + */ + public void setBountyTax(boolean bountySystemTax) { + this.bountySystemTax = bountySystemTax; + } + + /** + * Get the base amount of tax percent that is taken from the player's + * bounty when they create a new bounty. + * <p> + * Note: If this balance is set to 22.5, 22.5% of the money that would've + * been added to the bounty is removed from the server. + * </p> + * + * @return The base amount of tax, as a percent, to be removed from the bounty when it is placed. + */ + public double getBountyTaxPercent() { + return bountySystemTaxPercent; + } + + /** + * Set the base amount of tax percent that is taken from the player's + * bounty when they create a new bounty. + * <p> + * Note: If this balance is set to 22.5, 22.5% of the money that would've + * been added to the bounty is removed from the server. + * </p> + * + * @param bountySystemTaxPercent - the new base percent + */ + public void setBountyTaxPercent(double bountySystemTaxPercent) { + this.bountySystemTaxPercent = bountySystemTaxPercent; + } + + /** + * Get whether or not the kit system is enabled for players. + * + * @return {@code true} if the kit system is enabled, {@code false} + * otherwise. + */ + public boolean isKitSystem() { + return kitSystem; + } + + /** + * Set whether or not the kit system is enabled for players. + * + * @param kitSystem - {@code true} if players can use kits + */ + public void setKitSystem(boolean kitSystem) { + this.kitSystem = kitSystem; + } + + /** + * Get whether or not there is a server death tax. + * <p> + * Note: If a player dies, they have money to drop to other players, if this + * is set to {@code true}, some of the money will be taken by the server. + * </p> + * + * @return {@code true} if there is a server death tax, {@code false} + * otherwise. + */ + public boolean isServerDeathTax() { + return serverDeathTax; + } + + /** + * Set whether or not there is a server death tax. + * <p> + * Note: If a player dies, they have money to drop to other players, if this + * is set to {@code true}, some of the money will be taken by the server. + * </p> + * + * @param serverDeathTax - {@code true} if there is a server death tax, + * {@code false} otherwise. + */ + public void setServerDeathTax(boolean serverDeathTax) { + this.serverDeathTax = serverDeathTax; + } + + /** + * Get the base amount of tax percent that is taken from the player's + * available balance. + * <p> + * Note: If this balance is set to 22.5, 22.5% of the money that would've + * been dropped is lost forever to the server. + * </p> + * + * @return The base amount of tax, as a percent, to be stolen from the + * player's available balance. + */ + public double getServerDeathBasePercent() { + return serverDeathBasePercent; + } + + /** + * Set the base amount of tax percent that is taken from the player's + * available balance. + * <p> + * Note: If this balance is set to 22.5, 22.5% of the money that would've + * been dropped is lost forever to the server. + * </p> + * + * @param serverDeathBasePercent - the new base percent + */ + public void setServerDeathBasePercent(double serverDeathBasePercent) { + this.serverDeathBasePercent = serverDeathBasePercent; + } + + /** + * Get the minimum amount of money a player must lose to the server. + * <p> + * Note: If a player would drop $500, and 50% is available to the serverTax, + * which is $250, and this value is set to $400, $400 would be taken and + * only $100 would be dropped. + * </p> + * + * @return The amount, as an integer, that a player will lose to the server + * upon death. + */ + public int getServerDeathTaxMin() { + return serverDeathTaxMin; + } + + /** + * Set the minimum amount of money that a player must lose to the server. + * <p> + * Note: If a player would drop $500, and 50% is available to the serverTax, + * which is $250, and this value is set to $400, $400 would be taken and + * only $100 would be dropped. + * </p> + * + * @param serverDeathTaxMin - the minimum amount of money, as an integer + */ + public void setServerDeathTaxMin(int serverDeathTaxMin) { + this.serverDeathTaxMin = serverDeathTaxMin; + } + + /** + * Get the max amount of money a player must lose to the server. + * <p> + * Note: If a player would drop $500, and 50% is available to the serverTax, + * which is $250, and this value is set to $200, $200 would be taken and + * only $300 would be dropped. + * </p> + * + * @return The amount, as an integer, that a player will lose to the server + * upon death. + */ + public int getServerDeathTaxMax() { + return serverDeathTaxMax; + } + + /** + * Set the max amount of money that a player must lose to the server. + * <p> + * Note: If a player would drop $500, and 50% is available to the serverTax, + * which is $250, and this value is set to $200, $200 would be taken and + * only $300 would be dropped. + * </p> + * + * @param serverDeathTaxMax - the max amount of money, as an integer + */ + public void setServerDeathTaxMax(int serverDeathTaxMax) { + this.serverDeathTaxMax = serverDeathTaxMax; + } + + /** + * Get whether or not the server death tax scales with the GTMRank. + * <p> + * Note: GTMRank would increase the base tax rate, so if a GTMRank had an + * additional 5% tax, it would be the base tax rate, say 20%, plus + * additional 5%. + * </p> + * + * @return {@code true} if the server death tax scales with GTMRank, + * {@code false} otherwise. + */ + public boolean isServerDeathTaxScaled() { + return serverDeathTaxScaled; + } + + /** + * Sets whether or not the server death tax scales with the GTMRank. + * <p> + * Note: GTMRank would increase the base tax rate, so if a GTMRank had an + * additional 5% tax, it would be the base tax rate, say 20%, plus + * additional 5%. + * </p> + * + * @param serverDeathTaxScaled - {@code true} if the death tax scales with + * GTMRank, {@code false} otherwise. + */ + public void setServerDeathTaxScaled(boolean serverDeathTaxScaled) { + this.serverDeathTaxScaled = serverDeathTaxScaled; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/GTMUtils.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/GTMUtils.java new file mode 100644 index 0000000..d4101d4 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/GTMUtils.java @@ -0,0 +1,949 @@ +package net.grandtheftmc.gtm; + +import java.io.BufferedWriter; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.text.NumberFormat; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.Month; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; +import java.util.logging.Level; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.io.BukkitObjectInputStream; +import org.bukkit.util.io.BukkitObjectOutputStream; +import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.WrappedDataWatcher; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.boards.Board; +import net.grandtheftmc.core.boards.BoardType; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.nametags.NametagManager; +import net.grandtheftmc.core.users.Pref; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.items.GameItem; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.users.GTMUserManager; +import net.grandtheftmc.gtm.users.JobMode; +import net.grandtheftmc.gtm.utils.ReflectionUtil; +import net.grandtheftmc.gtm.warps.Warp; +import net.grandtheftmc.guns.weapon.Weapon; + +public final class GTMUtils { + + public static final String HEADER = Utils.f( + " &7&l▀&a&l▄&7&l▀&a&l▄&7&l▀&a&l▄&7&l▀&a&l▄&7&l▀&a&l▄&7&l▀&a&l▄&7&l▀&a&l▄&7&l▀&a&l▄&7&l▀&a&l▄&7&l▀&a&l▄&7&l▀&a&l▄&7&l▀&a&l▄&7&l▀&a&l▄&7&l▀&a&l▄&7&l▀&a&l▄&7&l▀"); + public static final String FOOTER = Utils.f( + " &7&l▄&a&l▀&7&l▄&a&l▀&7&l▄&a&l▀&7&l▄&a&l▀&7&l▄&a&l▀&7&l▄&a&l▀&7&l▄&a&l▀&7&l▄&a&l▀&7&l▄&a&l▀&7&l▄&a&l▀&7&l▄&a&l▀&7&l▄&a&l▀&7&l▄&a&l▀&7&l▄&a&l▀&7&l▄&a&l▀&7&l▄"); + + private GTMUtils() { + } + + public static GTMUser getGTMUser(Player player) { + return GTM.getUserManager().getLoadedUser(player.getUniqueId()); + } + + public static User getUser(Player player) { + return Core.getUserManager().getLoadedUser(player.getUniqueId()); + } + + public static UserRank getRank(Player player) { + return Core.getUserManager().getLoadedUser(player.getUniqueId()).getUserRank(); + } + + public static void updateBoard(Player player, GTMUser gtmUser) { + updateBoard(player, Core.getUserManager().getLoadedUser(player.getUniqueId()), gtmUser); + } + + public static void arrestPlayer(Cancellable e, Weapon weapon, Player player, Player victim) { + UUID victimUUID = victim.getUniqueId(); + GTMUser victimGtmUser = GTM.getUserManager().getLoadedUser(victimUUID); + GTMUser gtmUser = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + User victimUser = Core.getUserManager().getLoadedUser(victimUUID); + if (gtmUser.getJobMode() != JobMode.COP){ + player.sendMessage(Lang.COP.f("&cYou cannot use this as you are not a cop!")); + e.setCancelled(true); + return; + } + if (victimGtmUser.getJobMode() == JobMode.COP) { + e.setCancelled(true); + player.sendMessage(Utils.f(Lang.HEY + "&cYou can't hit cops!")); + return; + } + if (victimGtmUser.getJobMode() == JobMode.CRIMINAL && victimGtmUser.getWantedLevel() == 0) { + player.sendMessage(Lang.HEY.f("&7You can't use this on citizens that are not wanted!")); + e.setCancelled(true); + return; + } + if (gtmUser.getJobMode() == JobMode.COP) { + if (weapon.getCompactName().equalsIgnoreCase("nightstick")) { + victim.addPotionEffect(new PotionEffect(PotionEffectType.CONFUSION, 80, 1)); + victim.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 50, 1)); + } + } + if (!"stungun".equalsIgnoreCase(weapon.getCompactName()) || + victimGtmUser.getJobMode() != JobMode.CRIMINAL || victimGtmUser.getWantedLevel() == 0) return; + if (victim.getLastDamageCause() == null || victim.getLastDamageCause().getCause() != EntityDamageEvent.DamageCause.DRAGON_BREATH) + return; + ItemStack chestPlate = player.getInventory().getChestplate(); + if (chestPlate != null && chestPlate.getType() == Material.GOLD_CHESTPLATE && player.getLocation().getBlock().getRelative(BlockFace.DOWN).getType() == Material.AIR) { + player.sendMessage(Lang.COP_MODE.f("&fYou may not arrest criminals during flight!")); + return; + } + if(player.getVehicle() != null) { + player.sendMessage(Lang.COP_MODE.f("&fYou may not arrest criminals while in a Vehicle!")); + return; + } + int wantedLevel = victimGtmUser.getWantedLevel(); + int timeInJail = GTMUtils.getTimeInJail(wantedLevel); + victimGtmUser.jail(timeInJail, player); + player.sendMessage(Lang.COP_MODE.f("&7You arrested &a" + victimUser.getColoredName(victim) + + "&7! He will go to jail for &a" + Utils.timeInSecondsToText(timeInJail) + "&7!")); + Utils.broadcastExcept(player, Lang.COP_MODE.f("&a" + victimUser.getColoredName(victim) + "&7 was arrested by &a" + + user.getColoredName(player) + "&7!")); + victimGtmUser.addDeaths(1); + victimGtmUser.setLastTag(-1); + victimGtmUser.setKillCounter(0); + victimGtmUser.setKillStreak(0); + victimGtmUser.unsetCompassTarget(victim, victimUser); + if (GTM.getWarpManager().cancelTaxi(victim, victimGtmUser)) + victim.sendMessage(Utils.f(Lang.TAXI + "&eThe taxi was cancelled!")); + victim.setHealth(victim.getMaxHealth()); + victim.spigot().respawn(); + victim.setFireTicks(0); + victim.setGameMode(GameMode.SPECTATOR); + victim.setFlying(true); + victim.getActivePotionEffects().clear(); + victim.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 180, 0), false); + victim.setFoodLevel(20); + victim.playSound(victim.getLocation(), Sound.ENTITY_WITHER_SPAWN, 1, 0.5F); + victim.setFlySpeed(0); + GTMUtils.removeBoard(victim); + double lostMoney = Utils.round(victimGtmUser.getMoney() / 2); + new BukkitRunnable() { + @Override + public void run() { + Player victim = Bukkit.getPlayer(victimUUID); + if (victim == null) + return; + User victimUser = Core.getUserManager().getLoadedUser(victim.getUniqueId()); + GTMUser victimGameUser = GTM.getUserManager().getLoadedUser(victim.getUniqueId()); + victim.sendMessage(Lang.JAIL.f("&7You were arrested and have to stay in jail for &a" + + Utils.timeInSecondsToText(timeInJail) + "&7!")); + if (lostMoney > 0) + victim.sendMessage(Lang.MONEY_TAKE.f(String.valueOf(lostMoney))); + victim.teleport(GTM.getWarpManager().getJail().getLocation()); + victim.setGameMode(GameMode.ADVENTURE); + victim.getActivePotionEffects().clear(); + victim.setFoodLevel(20); + victim.setFlying(false); + victim.setFlySpeed(0.1F); + GTMUtils.giveGameItems(victim); + GTMUtils.updateBoard(victim, victimGameUser); + } + }.runTaskLater(GTM.getInstance(), 150); + ItemStack[] contents = victim.getInventory().getContents(); + victim.getInventory().clear(); + Location loc = victim.getLocation(); + for (ItemStack item : contents) + if (item != null && item.getType() != Material.WATCH && item.getType() != Material.COMPASS + && item.getType() != Material.CHEST) + loc.getWorld().dropItemNaturally(loc, item); + if (lostMoney > 0) { + victimGtmUser.takeMoney(lostMoney); + gtmUser.addMoney(lostMoney); + player.sendMessage(Lang.MONEY.f("&7You confiscated &a$&l" + lostMoney + "&7 of &a" + + victimUser.getColoredName(victim) + "&7's money!")); + } + int copMoney = GTMUtils.getCopMoney(wantedLevel); + gtmUser.addMoney(copMoney); + player.sendMessage(Lang.COP_MODE.f("&7You were rewarded &a$&l" + copMoney + "&7 for arresting a player with &e" + + GTMUtils.getWantedLevelStars(wantedLevel) + " (" + wantedLevel + ")&7!")); + Utils.sendTitle(victim, "&c&lBUSTED", "&7Arrested by " + player.getName(), 80, 50, 20); + GTMUtils.updateBoard(player, user, gtmUser); + } + + public static void updateBoard(Player player, User user, GTMUser gtmUser) { + if(!player.isOnline()) { + return; + } + if (user == null || !user.getPref(Pref.USE_SCOREBOARD) || user.isInTutorial()) { + player.setScoreboard(Bukkit.getScoreboardManager().getNewScoreboard()); + return; + } + Board board = new Board("gtm", "&7&l" + Core.getSettings().getServer_GTM_name(), BoardType.KEY_VALUE); + board.addValue("a", "Money", Utils.formatMoney(gtmUser.getMoney())); + board.addValue("a", "Bank", Utils.formatMoney(gtmUser.getBank())); + board.addValue("e", Core.getSettings().getServer_GTM_shortName() + " Rank", gtmUser.getRank().getName()); + if (gtmUser.getJobMode() == JobMode.CRIMINAL) { + int wantedLevel = gtmUser.getWantedLevel(); + board.addValue("c", "Wanted Level", getWantedLevelStars(wantedLevel) + " (" + wantedLevel + ')'); + } else + board.addValue(gtmUser.getJobMode().getColorChar(), "Job Mode", gtmUser.getJobMode().getName()); + board.addValue("6", "Server IP", user.getServerJoinAddress() != null ? user.getServerJoinAddress() : Core.getSettings().getNetworkIP()); + board.updateFor(player, Core.getUserManager().getLoadedUser(player.getUniqueId())); + } + + public static void removeBoard(Player player) { + player.setScoreboard(Bukkit.getScoreboardManager().getNewScoreboard()); + } + + public static String getWantedLevelStars(int i) { + String[] wantedLevels = new String[]{"✩✩✩✩✩", "✮✩✩✩✩", "✮✮✩✩✩", "✮✮✮✩✩", "✮✮✮✮✩", "✮✮✮✮✮"}; + return wantedLevels[i]; + } + + public static void giveGameItems(Player player) { + ItemStack phone = Utils.createItem(Material.WATCH, "&7&lPhone"); + ItemStack compass = Utils.createItem(Material.COMPASS, "&7&lGPS"); + ItemStack bp = Utils.createItem(Material.CHEST, "&6&lBackpack"); + ItemStack ammoPouch = Utils.createItem(Material.CHEST, "&c&lAmmo Pouch"); + Inventory inv = player.getInventory(); + if (!inv.contains(Material.WATCH)) + if (inv.getItem(8) == null) + inv.setItem(8, phone); + else + inv.addItem(phone); + if (!inv.contains(Material.COMPASS)) + if(inv.getItem(7)==null) + inv.setItem(7, compass); + else + inv.addItem(compass); + inv.setItem(17, bp); + inv.setItem(16, ammoPouch); + + } + + public static boolean isPhoneOrGPS(ItemStack item) { + if (item == null) + return false; + ItemStack gps = Utils.createItem(Material.COMPASS, "&7&lGPS"); + ItemStack phone = Utils.createItem(Material.WATCH, "&7&lPhone"); + return item.equals(gps) || item.equals(phone); + } + + public static String getMessageKilledBy(String name) { + String[] msges = new String[]{"Shanked by " + name, "Rekt by " + name, "Killed by " + name, + name + " killed you", name + " clapped yo ass", name + " killed you"}; + return msges[Utils.getRandom().nextInt(msges.length)]; + } + + public static void sendJoinMessage(Player p, User u) { + p.sendMessage(new String[]{"", "", "", "", "", "", "", "", "", "", Utils.f(HEADER), "", + Utils.fc("Welcome, " + u.getColoredName(p) + "&r to &7&l" + Core.getSettings().getServer_GTM_name() + "&r!"), + Utils.fc("&e&l&oGTA in Minecraft!"), "", Utils.fc("&e&lSTORE &r&n" + Core.getSettings().getStoreLink()), + Utils.fc("&a&lSITE &r&n" + Core.getSettings().getWebsiteLink()), "", Utils.fc("&7Use &a/tutorial&7 to get started!"), + "", Utils.f(FOOTER), ""}); + + } + + public static List<GTMUser> getCops() { + return GTMUserManager.getInstance().getUsers().stream().filter(user -> user.getJobMode() == JobMode.COP).collect(Collectors.toList()); + } + + public static Set<GTMUser> getCriminalsByWantedLevel(int minimumWantedLevel) { + HashMap<GTMUser, Integer> unsortMap = new HashMap<>(); + GTMUserManager.getInstance().getUsers().stream().filter(u -> u.getJobMode() == JobMode.CRIMINAL && u.getWantedLevel() >= minimumWantedLevel + && Objects.equals(Bukkit.getPlayer(u.getUUID()).getWorld().getName(), GTM.getSettings().getMap())).forEach(u -> unsortMap.put(u, u.getWantedLevel())); + return sort(unsortMap).keySet(); + } + + public static Map<GTMUser, Integer> sort(Map<GTMUser, Integer> unsortMap) { + List<Map.Entry<GTMUser, Integer>> list = new LinkedList<>(unsortMap.entrySet()); + list.sort(Comparator.comparing(Map.Entry::getValue)); + Map<GTMUser, Integer> sortedMap = new LinkedHashMap<>(); + for (Map.Entry<GTMUser, Integer> entry : list) { + sortedMap.put(entry.getKey(), entry.getValue()); + } + return sortedMap; + } + + public static List<Player> getJailedPlayers() { + List<Player> players = new ArrayList<>(); + for (Player p : Bukkit.getOnlinePlayers()) { + GTMUser gtmUser = GTM.getUserManager().getLoadedUser(p.getUniqueId()); + if (gtmUser.isArrested()) { + players.add(p); + } + } + return players; + } + + public static String toBase64(ItemStack[] array) { + if (array == null) + return null; + try { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + try (BukkitObjectOutputStream dataOutput = new BukkitObjectOutputStream(outputStream)) { + + dataOutput.writeInt(array.length); + for (ItemStack stack : array) + dataOutput.writeObject(stack); + dataOutput.close(); + } + return Base64Coder.encodeLines(outputStream.toByteArray()); + } catch (Exception e) { + GTM.getInstance().getLogger().log(Level.ALL, "Error while serializing items!"); + e.printStackTrace(); + return null; + } + } + + public static ItemStack[] fromBase64(String data) { + if (data == null) + return new ItemStack[0]; + try { + ByteArrayInputStream inputStream = new ByteArrayInputStream(Base64Coder.decodeLines(data)); + ItemStack[] array; + try (BukkitObjectInputStream dataInput = new BukkitObjectInputStream(inputStream)) { + array = new ItemStack[dataInput.readInt()]; + // Read the serialized inventory + for (int i = 0; i < array.length; i++) + array[i] = (ItemStack) dataInput.readObject(); + + dataInput.close(); + } + return array; + } catch (Exception e) { + GTM.getInstance().getLogger().log(Level.ALL, "Error while deserializing items: " + data); + e.printStackTrace(); + return new ItemStack[0]; + } + } + + public static int getGangMembers(UserRank userRank) { + switch (userRank) { + case DEFAULT: + return 0; + case VIP: + return 2; + case PREMIUM: + return 5; + case ELITE: + return 10; + case SPONSOR: + return 15; + default: + return 20; + } + } + + public static String upperCaseFirst(String s) { + return s.substring(0, 1).toUpperCase() + s.substring(1, s.length()).toLowerCase(); + } + + public static void chooseJobMode(Player player, User user, GTMUser gtmUser, JobMode mode) { + if (mode == JobMode.CRIMINAL) { + if (gtmUser.getJobMode() == JobMode.CRIMINAL) { + player.sendMessage(Utils.f(Lang.JOBS + "&7You are already on the " + + JobMode.CRIMINAL.getColoredNameBold() + " Job&7!")); + return; + } + player.sendMessage(Lang.JOBS.f("&7You have quit the " + gtmUser.getJobMode().getColoredNameBold() + "&7 Job!")); + gtmUser.setJobMode(JobMode.CRIMINAL); + gtmUser.unsetCompassTarget(player, user); + updateBoard(player, user, gtmUser); + NametagManager.updateNametag(player); + GTMUtils.giveGameItems(player); + return; + } + if (gtmUser.getJobMode() == JobMode.COP || gtmUser.getJobMode() == JobMode.HITMAN) { + player.sendMessage(Utils.f(Lang.JOBS + "&7You are already on the " + + gtmUser.getJobMode().getColoredNameBold() + " Job&7!")); + return; + } + if (!gtmUser.canSwitchJobMode(user.getUserRank())) { + player.sendMessage(Utils.f(Lang.JOBS + + "&7Sorry, but you need to wait &a" + Utils.timeInMillisToText(gtmUser.getTimeUntilJobModeSwitch(user.getUserRank())) + + "&7 before switching Job Mode again!" + (user.getUserRank().isHigherThan(UserRank.SPONSOR) ? "" : " Buy a rank a &a&l" + Core.getSettings().getStoreLink() + "&7 to be able to switch faster!"))); + return; + } + if (!mode.canUse(gtmUser.getRank(), user.getUserRank())) { + player.sendMessage(Lang.JOBS.f("&7You don't have access to " + mode.getColoredNameBold() + " Mode&7! Rank up to " + mode.getRank().getColoredNameBold() + "&7 or buy the " + mode.getUserRank().getColoredNameBold() + "&7 rank!")); + return; + } + gtmUser.setJobMode(mode); + if (mode == JobMode.COP) + player.sendMessage(Utils.f(Lang.COP_MODE + "&7You are now in " + mode.getColoredNameBold() + + " Mode&7! You can earn money by killing wanted criminals.")); + else if (mode == JobMode.HITMAN) { + player.sendMessage(Utils.f(Lang.HITMAN_MODE + "&7You are now in " + mode.getColoredNameBold() + " Mode&7! You can earn money by killing players that have a bounty on their head.")); + } + GTM.getItemManager().giveKit(player, user, gtmUser, mode.getName()); + gtmUser.unsetCompassTarget(player, user); + gtmUser.setKillCounter(0); + updateBoard(player, user, gtmUser); + NametagManager.updateNametag(player); + GTMUtils.giveGameItems(player); + } + + public static int getTimeInJail(int wl) { // IN SECONDS + return new int[]{0, 60, 120, 180, 300, 400}[wl]; + } + + public static int getCopMoney(int wl) { + return new int[]{0, 2000, 5000, 10000, 20000, 50000}[wl]; + } + + public static int getJobModeDelay(UserRank rank) { // IN SECONDS + switch (rank) { + case DEFAULT: + return 9000; + case VIP: + return 7200; + case PREMIUM: + return 5400; + case ELITE: + return 3600; + case SPONSOR: + return 2700; + default: + return 1800; + } + } + + public static boolean isArmor(Material material) { + String s = material.toString(); + return s.contains("BOOTS") || s.contains("LEGGINGS") || s.contains("CHESTPLATE") || s.contains("HELMET"); + } + + public static int getFeedDelay(UserRank rank) {// IN SECONDS + switch (rank) { + case DEFAULT: + return 1800; + case VIP: + return 900; + case PREMIUM: + return 600; + case ELITE: + return 300; + case SPONSOR: + return 180; + default: + return 120; + } + + }//testrtasdfadfasdfes + private final static List<String> DEFAULT_ITEMS = new ArrayList<>(Arrays.asList("Phone", "Backpack", "Ammo Pouch")); + public static boolean isDefaultPlayerItem(ItemStack is) { + return is!=null && is.hasItemMeta() && is.getItemMeta().hasDisplayName() && DEFAULT_ITEMS.contains(ChatColor.stripColor(is.getItemMeta().getDisplayName())); + } + + public static int getFixHandDelay(UserRank rank) {// IN SECONDS + switch (rank) { + case DEFAULT: + return 60*60; + case VIP: + return 60*30; + case PREMIUM: + return 60*20; + case ELITE: + return 60*15; + case SPONSOR: + return 60*10; + case SUPREME: + return 60*5; + default: + return 60*5; + } + + } + public static int getFixAllDelay(UserRank rank) {// IN SECONDS + switch (rank) { + default: + return 60*60*3; + } + + } + + public static int getBackpackRows(UserRank rank) { + switch (rank) { + case DEFAULT: + return 2; + case VIP: + return 3; + case PREMIUM: + return 5; + case ELITE: + return 7; + case SPONSOR: + return 9; + default: + return 11; + } + } + + public static int getCompassRadius(UserRank rank) { + switch (rank) { + case DEFAULT: + case VIP: + return 30; + case PREMIUM: + return 50; + case ELITE: + return 75; + case SPONSOR: + return 100; + default: + return 10; + } + } + + public static int getExtraCompassAccuracy(UserRank rank) { + switch (rank) { + case DEFAULT: + case VIP: + return 0; + case PREMIUM: + return 15; + case ELITE: + return 33; + case SPONSOR: + return 50; + default: + return 67; + } + } + + public static int getStartingMoney(UserRank rank) { + switch (rank) { + case DEFAULT: + return 5000; + case VIP: + return 100000; + case PREMIUM: + return 250000; + case ELITE: + return 500000; + case SPONSOR: + return 1000000; + default: + return 2000000; + } + } + + public static int getStartingPermits(UserRank rank) { + switch (rank) { + case DEFAULT: + case VIP: + case PREMIUM: + case ELITE: + return 0; + case SPONSOR: + return 5; + default: + return 10; + } + } + + + public static int getHouses(UserRank userRank) { + switch (userRank) { + case DEFAULT: + return 0; + case VIP: + return 1; + case PREMIUM: + return 2; + case ELITE: + return 3; + case SPONSOR: + return 5; + default: + return 10; + } + } + + public static int getFreeLotteryTickets(UserRank userRank) { + switch (userRank) { + case DEFAULT: + return 0; + case VIP: + return 1; + case PREMIUM: + return 2; + case ELITE: + return 3; + case SPONSOR: + return 5; + default: + return 10; + } + } + + public static int getWarpDelay(UserRank userRank) { + switch (userRank) { + case DEFAULT: + return 15; + case VIP: + return 12; + case PREMIUM: + return 10; + case ELITE: + return 8; + case SPONSOR: + return 6; + default: + return 5; + } + } + + public static int getNearRange(UserRank rank) { + switch (rank) { + case VIP: + return 50; + case PREMIUM: + return 75; + case ELITE: + return 100; + case SPONSOR: + return 125; + case SUPREME: + return 150; + default: + return 100; + } + } + + public static int getStackDelay(UserRank rank) { + switch (rank) { + case SUPREME: + return 3600; + case HELPOP: + case MOD: + case SRMOD: + case ADMIN: + return 300; + case DEV: + case MANAGER: + case OWNER: + return 1; + default: + return 3600; + } + } + + /* + * public static String serialize(ItemStack[] a) { StringBuilder b = new + * StringBuilder(); for (int i = 0; i < a.length; i++) { if (i > 0) + * b.append(","); ItemStack item = a[i]; try { + * b.append(StreamSerializer.getDefault().serializeItemStack(item)); } catch + * (Exception e) { b.append("null"); System.out.println( + * "Error while serializing an item (" + i + "): " + + * e.getCause().getMessage()); } } return b.toString(); } + * + * public static ItemStack[] deserialize(String s) { if (s == null || + * s.length() == 0) return new ItemStack[0]; String[] a = s.split(","); + * ItemStack[] array = new ItemStack[a.length]; for (int i = 0; i < + * a.length; i++) { try { array[i] = + * StreamSerializer.getDefault().deserializeItemStack(a[i]); } catch + * (Exception e) { array[i] = null; System.out.println( + * "Error while deserializing an item (" + i + "): " + e.getMessage()); } } + * return array; } + */ + + public static boolean isValidURL(String string) { + String urlRegex = "^((https?|ftp)://|(www|ftp)\\.)?[a-z0-9-]+(\\.[a-z0-9-]+)+([/?].*)?$"; + Pattern p = Pattern.compile(urlRegex); + Matcher m = p.matcher(string); + return m.find(); + } + + public static double getCrossProduct(LivingEntity livingEntity, Location target) { + if (livingEntity.getWorld() != target.getWorld()) return 10000; + Location head = livingEntity.getLocation(); + org.bukkit.util.Vector look = livingEntity.getLocation().getDirection().normalize(); + org.bukkit.util.Vector direction = head.subtract(target).toVector().normalize(); + org.bukkit.util.Vector cp = direction.crossProduct(look); + return cp.length(); + } + + public static String serializeLocation(Location location) { + String world = location.getWorld().getName(); + String x = String.valueOf(location.getX()); + String y = String.valueOf(location.getY()); + String z = String.valueOf(location.getZ()); + String yaw = String.valueOf(location.getYaw()); + String pitch = String.valueOf(location.getPitch()); + return world + '@' + x + '@' + y + '@' + z + '@' + yaw + '@' + pitch; + } + + public static Optional<Location> deserializeLocation(String loc) { + String[] args = loc.split("@"); + World world = Bukkit.getWorld(args[0]); + double x = Double.valueOf(args[1]); + double y = Double.valueOf(args[2]); + double z = Double.valueOf(args[3]); + float yaw = Float.valueOf(args[4]); + float pitch = Float.valueOf(args[5]); + Location location = new Location(world, x, y, z, yaw, pitch); + return Optional.ofNullable(location); + } + + public static String convertItemStackToJson(ItemStack itemStack) { + Class<?> craftItemStackClazz = ReflectionUtil.getOBCClass("inventory.CraftItemStack"); + Method asNMSCopyMethod = ReflectionUtil.getMethod(craftItemStackClazz, "asNMSCopy", ItemStack.class); + Class<?> nmsItemStackClazz = ReflectionUtil.getNMSClass("ItemStack"); + Class<?> nbtTagCompoundClazz = ReflectionUtil.getNMSClass("NBTTagCompound"); + Method saveNmsItemStackMethod = ReflectionUtil.getMethod(nmsItemStackClazz, "save", nbtTagCompoundClazz); + + Object nmsNbtTagCompoundObj; + Object nmsItemStackObj; + Object itemAsJsonObject; + + try { + nmsNbtTagCompoundObj = nbtTagCompoundClazz.newInstance(); + nmsItemStackObj = asNMSCopyMethod.invoke(null, itemStack); + itemAsJsonObject = saveNmsItemStackMethod.invoke(nmsItemStackObj, nmsNbtTagCompoundObj); + } catch (Throwable t) { + return null; + } + + return itemAsJsonObject.toString(); + } + + + public static void moneylog(Player sender, Player target, double amount) { + if (Core.getSettings().isSister()) return; //Throwing errors.. + + NumberFormat formatter = NumberFormat.getCurrencyInstance(); + String fileName = new SimpleDateFormat("MM-dd-yy").format(new Date()); + File file = new File("gtmlogs/moneylog_" + fileName + ".txt"); + try { + if (!file.isFile() || !file.exists()) + file.createNewFile(); + } catch (IOException exception) { + exception.printStackTrace(); + } + String date = new SimpleDateFormat("MM/dd/yy - h:mm a").format(new Date()); + try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file, true))) { + bufferedWriter.write(date + " - " + sender.getName() + " sent " + formatter.format(amount) + " to " + target.getName() + '\n'); + bufferedWriter.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static void log(String logName, String msg) { + if (Core.getSettings().isSister()) return; //Throwing errors.. + + String fileName = new SimpleDateFormat("MM-dd-yy").format(new Date()); + File file = new File("gtmlogs/" + logName + '_' + fileName + ".txt"); + try { + if (!file.isFile() || !file.exists()) { + file.createNewFile(); + } + String date = new SimpleDateFormat("MM/dd/yy - h:mm a").format(new Date()); + FileWriter fileWriter = new FileWriter(file, true); + try (BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)) { + bufferedWriter.write(date + " - " + msg + '\n'); + } + } catch (IOException exception) { + exception.printStackTrace(); + } + } + + public static GameItem getRandomGameItem() { + List<GameItem> gameItems = GTM.getItemManager().getItems().stream().filter(gameItem -> gameItem.getType() == GameItem.ItemType.ITEMSTACK || gameItem.getType() == GameItem.ItemType.WEAPON).collect(Collectors.toList()); + return gameItems.get(ThreadLocalRandom.current().nextInt(gameItems.size())); + } + + public static Warp getNearestWarp(Location location) { + Warp nearestWarp = null; + for (Warp warp : GTM.getWarpManager().getWarps()) { + if (warp.getLocation().getWorld() != location.getWorld()) continue; + if (nearestWarp == null || + warp.getLocation().distance(location) < nearestWarp.getLocation().distance(location)) { + nearestWarp = warp; + } + } + return nearestWarp; + } + + public static Map<String, Integer> getTopKillers(int count) { + Map<String, Integer> topKillers = new HashMap<>(); + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM " + Core.name() + " WHERE name != 'ERROR' ORDER BY kills DESC LIMIT " + count + ';')) { + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + topKillers.put(result.getString("name"), result.getInt("kills")); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + return topKillers; + } + + public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) { + return map.entrySet() + .stream() + .sorted(Map.Entry.comparingByValue(Collections.reverseOrder())) + .collect(Collectors.toMap( + Map.Entry::getKey, + Map.Entry::getValue, + (e1, e2) -> e1, + LinkedHashMap::new + )); + } + + public static boolean isInteger(String s) { + try { + Integer.parseInt(s); + } catch (NumberFormatException e) { + return false; + } + return true; + } + + public static void spawnTinyArmorStand(Location location, String username, String title) { + ArmorStand armorStand = (ArmorStand) location.getWorld().spawnEntity(location, EntityType.ARMOR_STAND); + armorStand.setSmall(true); + armorStand.setBasePlate(false); + ItemStack skull = Utils.createItem(Material.SKULL_ITEM, 3, Utils.f(username)); + SkullMeta meta = (SkullMeta) skull.getItemMeta(); + meta.setOwner(username); + skull.setItemMeta(meta); + armorStand.setHelmet(skull); + armorStand.setCustomNameVisible(true); + armorStand.setCustomName(Utils.f(title)); + } + + public static void sendGlow(Player player, Player target, long time) { + PacketContainer packet = GTM.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_METADATA); + packet.getIntegers().write(0, target.getEntityId()); + WrappedDataWatcher watcher = new WrappedDataWatcher(); + WrappedDataWatcher.Serializer serializer = WrappedDataWatcher.Registry.get(Byte.class); + watcher.setEntity(target); + watcher.setObject(0, serializer, (byte) 0x40); + packet.getWatchableCollectionModifier().write(0, watcher.getWatchableObjects()); + try { + GTM.getProtocolManager().sendServerPacket(player, packet); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + new BukkitRunnable() { + @Override + public void run() { + removeGlow(player, target); + } + }.runTaskLaterAsynchronously(GTM.getInstance(), time); + } + + public static void removeGlow(Player player, Player target) { + PacketContainer packet = GTM.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_METADATA); + packet.getIntegers().write(0, target.getEntityId()); + WrappedDataWatcher watcher = new WrappedDataWatcher(); + WrappedDataWatcher.Serializer serializer = WrappedDataWatcher.Registry.get(Byte.class); + watcher.setEntity(target); + watcher.setObject(0, serializer, (byte) 0x0); + packet.getWatchableCollectionModifier().write(0, watcher.getWatchableObjects()); + try { + GTM.getProtocolManager().sendServerPacket(player, packet); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + } + + public static Month getMonth() { + return LocalDate.now(ZoneId.systemDefault()).getMonth(); + + } + + public static int getDay() { + return LocalDate.now(ZoneId.systemDefault()).getDayOfMonth(); + } + + public static ChatColor randomColor() { + int a = ThreadLocalRandom.current().nextInt(16); + switch (a) { + case 1: + return ChatColor.GREEN; + case 2: + return ChatColor.DARK_GREEN; + case 3: + return ChatColor.BLUE; + case 4: + return ChatColor.DARK_RED; + case 5: + return ChatColor.DARK_PURPLE; + case 6: + return ChatColor.GOLD; + case 7: + return ChatColor.GRAY; + case 8: + return ChatColor.DARK_GRAY; + case 9: + return ChatColor.DARK_BLUE; + case 10: + return ChatColor.GREEN; + case 11: + return ChatColor.AQUA; + case 12: + return ChatColor.RED; + case 13: + return ChatColor.LIGHT_PURPLE; + case 14: + return ChatColor.YELLOW; + default: + return ChatColor.AQUA; + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/armor/ArmorShopManager.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/armor/ArmorShopManager.java new file mode 100644 index 0000000..f8cd78f --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/armor/ArmorShopManager.java @@ -0,0 +1,510 @@ +package net.grandtheftmc.gtm.armor; + +import java.util.Arrays; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerInteractAtEntityEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.util.EulerAngle; + +import com.google.common.collect.Lists; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.Component; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.items.GameItem; +import net.grandtheftmc.gtm.items.ItemManager; +import net.grandtheftmc.gtm.users.GTMUser; + +public class ArmorShopManager implements Component<ArmorShopManager, GTM> { + + private final ItemManager itemManager; + + public ArmorShopManager(JavaPlugin plugin, ItemManager itemManager) { + this.itemManager = itemManager; + Bukkit.getPluginManager().registerEvents(this, plugin); + + ServerUtil.runTaskLater(() -> { + List<ShopStatue> list = Lists.newArrayList(); + final World spawn = Bukkit.getWorld("spawn"); + list.addAll(Arrays.asList( + new ShopStatue() { + @Override + public Location spawnVisual(World world) { + GameItem gameItem = itemManager.getItem(this.getGameItem()); + if (gameItem == null) return null; + + Location origin = this.getOrigin(world); + + ArmorStand clickable = spawnEntity(origin.clone().add(0, 0.3, 0), VisualType.NAME); + clickable.setCustomName(C.GREEN + "$" + gameItem.getBuyPrice()); + clickable.setCustomNameVisible(true); + + ArmorStand armor = spawnEntity(origin.clone().add(-0.1, 0.1, 0), VisualType.NONE); + armor.setHelmet(gameItem.getItem().clone()); + armor.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(42.0f), 0f, 0f)); + armor.setMarker(true); + return null; + } + + @Override + public Location getOrigin(World world) { + return new Location(spawn, -371.5, 25.5, 268.5, -90.0f, 0.0f); + } + + @Override + public String getGameItem() { + return "baseballcap"; + } + }, //Leather Helmet + new ShopStatue() { + @Override + public Location spawnVisual(World world) { + GameItem gameItem = itemManager.getItem(this.getGameItem()); + if (gameItem == null) return null; + + Location origin = this.getOrigin(world); + + ArmorStand clickable = spawnEntity(origin.clone().add(0, 0.4, 0), VisualType.NAME); + clickable.setCustomName(C.GREEN + "$" + gameItem.getBuyPrice()); + clickable.setCustomNameVisible(true); + + ArmorStand armor = spawnEntity(origin.clone().add(-0.1, 0.5, 0), VisualType.NONE); + armor.setChestplate(gameItem.getItem().clone()); + armor.setMarker(true); + return null; + } + + @Override + public Location getOrigin(World world) { + return new Location(spawn, -371.5, 25.5, 267.5, -90.0f, 0.0f); + } + + @Override + public String getGameItem() { + return "shirt"; + } + }, //Leather Chestplate + new ShopStatue() { + @Override + public Location spawnVisual(World world) { + GameItem gameItem = itemManager.getItem(this.getGameItem()); + if (gameItem == null) return null; + + Location origin = this.getOrigin(world); + + ArmorStand clickable = spawnEntity(origin.clone().add(0, 0.1, 0), VisualType.NAME); + clickable.setCustomName(C.GREEN + "$" + gameItem.getBuyPrice()); + clickable.setCustomNameVisible(true); + + ArmorStand armor = spawnEntity(origin.clone().add(0, 1, 0), VisualType.NONE); + armor.setLeggings(gameItem.getItem().clone()); + armor.setLeftLegPose(new EulerAngle(AngleUtil.getRadianFromDegree(343.0), 0f, AngleUtil.getRadianFromDegree(350.0))); + armor.setRightLegPose(new EulerAngle(AngleUtil.getRadianFromDegree(3.0), 0f, AngleUtil.getRadianFromDegree(7.0))); + armor.setMarker(true); + return null; + } + + @Override + public Location getOrigin(World world) { + return new Location(spawn, -371.5, 25.5, 266.5, -90.0f, 0.0f); + } + + @Override + public String getGameItem() { + return "pants"; + } + }, //Leather Leggings + new ShopStatue() { + @Override + public Location spawnVisual(World world) { + GameItem gameItem = itemManager.getItem(this.getGameItem()); + if (gameItem == null) return null; + + Location origin = this.getOrigin(world); + + ArmorStand name = spawnEntity(origin.clone().add(0, 2.1, 0), VisualType.NAME); + name.setCustomName(C.GREEN + "$" + gameItem.getBuyPrice()); + name.setCustomNameVisible(true); + name.setMarker(true); + + ArmorStand clickable = spawnEntity(origin.clone().add(0, 1.6, 0), VisualType.NAME); + + ArmorStand armor = spawnEntity(origin.clone().add(0, 1.5, 0), VisualType.NONE); + armor.setBoots(gameItem.getItem().clone()); + armor.setLeftLegPose(new EulerAngle(AngleUtil.getRadianFromDegree(343.0), 0f, AngleUtil.getRadianFromDegree(350.0))); + armor.setRightLegPose(new EulerAngle(AngleUtil.getRadianFromDegree(3.0), 0f, AngleUtil.getRadianFromDegree(7.0))); + armor.setMarker(true); + return null; + } + + @Override + public Location getOrigin(World world) { + return new Location(spawn, -371.5, 25.5, 265.5, -75.0f, 0.0f); + } + + @Override + public String getGameItem() { + return "nikes"; + } + }, //Leather Boots + new ShopStatue() { + @Override + public Location spawnVisual(World world) { + GameItem gameItem = itemManager.getItem(this.getGameItem()); + if (gameItem == null) return null; + + Location origin = this.getOrigin(world); + + ArmorStand name = spawnEntity(origin.clone().add(0, 0.6, 0), VisualType.NAME); + name.setCustomName(C.GREEN + "$" + gameItem.getBuyPrice()); + name.setCustomNameVisible(true); + name.setMarker(true); + + ArmorStand clickable = spawnEntity(origin.clone().add(0, 0.15, 0), VisualType.NAME); + + ArmorStand armor = spawnEntity(origin.clone().add(0, 0.15, 0), VisualType.NONE); + armor.setHelmet(gameItem.getItem().clone()); + armor.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(42.0), 0f, 0f)); + armor.setMarker(true); + return null; + } + + @Override + public Location getOrigin(World world) { + return new Location(spawn, -362.5, 25.5, 263.5, 0.0f, 0.0f); + } + + @Override + public String getGameItem() { + return "tacticalmask"; + } + }, //Iron Helmet + new ShopStatue() { + @Override + public Location spawnVisual(World world) { + GameItem gameItem = itemManager.getItem(this.getGameItem()); + if (gameItem == null) return null; + + Location origin = this.getOrigin(world); + + ArmorStand name = spawnEntity(origin.clone().add(0, 0.6, 0), VisualType.NAME); + name.setCustomName(C.GREEN + "$" + gameItem.getBuyPrice()); + name.setCustomNameVisible(true); + name.setMarker(true); + + ArmorStand clickable = spawnEntity(origin.clone().add(0, 0.15, 0), VisualType.NAME); + + ArmorStand armor = spawnEntity(origin.clone().add(0, 0.15, 0), VisualType.NONE); + armor.setHelmet(gameItem.getItem().clone()); + armor.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(42.0), 0f, 0f)); + armor.setMarker(true); + return null; + } + + @Override + public Location getOrigin(World world) { + return new Location(spawn, -360.5, 25.5, 263.5, 0.0f, 0.0f); + } + + @Override + public String getGameItem() { + return "titaniumhelmet"; + } + }, //Diamond Helmet + new ShopStatue() { + @Override + public Location spawnVisual(World world) { + GameItem gameItem = itemManager.getItem(this.getGameItem()); + if (gameItem == null) return null; + + Location origin = this.getOrigin(world); + + ArmorStand name = spawnEntity(origin.clone().add(0, 0.6, 0), VisualType.NAME); + name.setCustomName(C.GREEN + "$" + gameItem.getBuyPrice()); + name.setCustomNameVisible(true); + name.setMarker(true); + + ArmorStand clickable = spawnEntity(origin.clone().add(0, 0.15, 0), VisualType.NAME); + + ArmorStand armor = spawnEntity(origin.clone().add(0, 0.15, 0), VisualType.NONE); + armor.setHelmet(gameItem.getItem().clone()); + armor.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(42.0), 0f, 0f)); + armor.setMarker(true); + return null; + } + + @Override + public Location getOrigin(World world) { + return new Location(spawn, -358.5, 25.5, 263.5, 0.0f, 0.0f); + } + + @Override + public String getGameItem() { + return "pimpcrown"; + } + }, //Golden Helmet + new ShopStatue() { + @Override + public Location spawnVisual(World world) { + GameItem gameItem = itemManager.getItem(this.getGameItem()); + if (gameItem == null) return null; + + Location origin = this.getOrigin(world); + + ArmorStand name = spawnEntity(origin.clone().add(0, 1.6, 0), VisualType.NAME); + name.setCustomName(C.GREEN + "$" + gameItem.getBuyPrice()); + name.setCustomNameVisible(true); + name.setMarker(true); + + ArmorStand clickable = spawnEntity(origin.clone().add(0, 1.5, 0), VisualType.NAME); + + ArmorStand armor = spawnEntity(origin.clone().add(0, 1.5, 0.05), VisualType.NONE); + armor.setChestplate(gameItem.getItem().clone()); + armor.setMarker(true); + return null; + } + + @Override + public Location getOrigin(World world) { + return new Location(spawn, -361.5, 25.5, 263.5, 0.0f, 0.0f); + } + + @Override + public String getGameItem() { + return "ceramicvest"; + } + }, //Iron Chestplate + new ShopStatue() { + @Override + public Location spawnVisual(World world) { + GameItem gameItem = itemManager.getItem(this.getGameItem()); + if (gameItem == null) return null; + + Location origin = this.getOrigin(world); + + ArmorStand name = spawnEntity(origin.clone().add(0, 1.6, 0), VisualType.NAME); + name.setCustomName(C.GREEN + "$" + gameItem.getBuyPrice()); + name.setCustomNameVisible(true); + name.setMarker(true); + + ArmorStand clickable = spawnEntity(origin.clone().add(0, 1.5, 0), VisualType.NAME); + + ArmorStand armor = spawnEntity(origin.clone().add(0, 1.5, 0.05), VisualType.NONE); + armor.setChestplate(gameItem.getItem().clone()); + armor.setMarker(true); + return null; + } + + @Override + public Location getOrigin(World world) { + return new Location(spawn, -359.5, 25.5, 263.5, 0.0f, 0.0f); + } + + @Override + public String getGameItem() { + return "titaniumvest"; + } + }, //Diamond Chestplate + new ShopStatue() { + @Override + public Location spawnVisual(World world) { + GameItem gameItem = itemManager.getItem(this.getGameItem()); + if (gameItem == null) return null; + + Location origin = this.getOrigin(world); + + ArmorStand name = spawnEntity(origin.clone().add(0, 1.6, 0), VisualType.NAME); + name.setCustomName(C.GREEN + "$" + gameItem.getBuyPrice()); + name.setCustomNameVisible(true); + name.setMarker(true); + + ArmorStand clickable = spawnEntity(origin.clone().add(0, 1.5, 0), VisualType.NAME); + + ArmorStand armor = spawnEntity(origin.clone().add(0, 1.5, 0.1), VisualType.NONE); + armor.setChestplate(gameItem.getItem().clone()); + armor.setMarker(true); + return null; + } + + @Override + public Location getOrigin(World world) { + return new Location(spawn, -357.5, 25.5, 263.5, 0.0f, 0.0f); + } + + @Override + public String getGameItem() { + return "jetpack"; + } + }, //Jetpack + new ShopStatue() { + @Override + public Location spawnVisual(World world) { + GameItem gameItem = itemManager.getItem(this.getGameItem()); + if (gameItem == null) return null; + + Location origin = this.getOrigin(world); + + ArmorStand name = spawnEntity(origin.clone().add(0, 2.2, 0), VisualType.NAME); + name.setCustomName(C.WHITE + "x" + C.BOLD + this.getAmount() + C.RESET + " " + C.GREEN + "$" + (gameItem.getBuyPrice() * this.getAmount())); + name.setCustomNameVisible(true); + name.setMarker(true); + + ArmorStand clickable = spawnEntity(origin.clone().add(0, 0.6, 0), VisualType.NAME); + + ArmorStand armor = spawnEntity(origin.clone().add(0, -0.3, 0.1), VisualType.NONE); + armor.setHelmet(gameItem.getItem().clone()); + armor.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(10.0), 0f, 0f)); + armor.setMarker(true); + return null; + } + + @Override + public Location getOrigin(World world) { + return new Location(spawn, -356.5, 25.5, 270.5, 0.0f, 0.0f); + } + + @Override + public String getGameItem() { + return "jetpackfuel"; + } + + @Override + public int getAmount() { + return 10; + } + }, //Jetpack Fuel x10 + new ShopStatue() { + @Override + public Location spawnVisual(World world) { + GameItem gameItem = itemManager.getItem(this.getGameItem()); + if (gameItem == null) return null; + + Location origin = this.getOrigin(world); + + ArmorStand name = spawnEntity(origin.clone().add(0, 2.2, 0), VisualType.NAME); + name.setCustomName(C.WHITE + "x" + C.BOLD + this.getAmount() + C.RESET + " " + C.GREEN + "$" + (gameItem.getBuyPrice() * this.getAmount())); + name.setCustomNameVisible(true); + name.setMarker(true); + + ArmorStand clickable = spawnEntity(origin.clone().add(0, 0.6, 0), VisualType.NAME); + + ArmorStand armor = spawnEntity(origin.clone().add(0, -0.3, -0.1), VisualType.NONE); + armor.setHelmet(gameItem.getItem().clone()); + armor.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(10.0), 0f, 0f)); + armor.setMarker(true); + + ArmorStand armor2 = spawnEntity(origin.clone().add(0.2, -0.28, 0.1), VisualType.NONE); + armor2.setHelmet(gameItem.getItem().clone()); + armor2.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(10.0), 0f, 0f)); + armor2.setMarker(true); + + ArmorStand armor3 = spawnEntity(origin.clone().add(-0.2, -0.25, 0), VisualType.NONE); + armor3.setHelmet(gameItem.getItem().clone()); + armor3.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(10.0), 0f, 0f)); + armor3.setMarker(true); + return null; + } + + @Override + public Location getOrigin(World world) { + return new Location(spawn, -358.5, 25.5, 270.5, 0.0f, 0.0f); + } + + @Override + public String getGameItem() { + return "jetpackfuel"; + } + + @Override + public int getAmount() { + return 64; + } + } //Jetpack Fuel x64 + )); + + for (ShopStatue statue : list) { + Location origin = statue.getOrigin(spawn); + if (!origin.getChunk().isLoaded()) origin.getChunk().load(); + for (Entity entity : origin.getWorld().getNearbyEntities(origin, 2, 10, 2)) { + if (entity.getType() != EntityType.ARMOR_STAND) continue; + entity.remove(); + } + } + + ServerUtil.runTaskLater(() -> { + for (ShopStatue statue : list) { + statue.spawnVisual(spawn); + } + }, 20 * 15); + }, 40L); + } + + @EventHandler + protected final void onArmorstandInteract(PlayerInteractAtEntityEvent event) { + if (event.getRightClicked() == null) return; + if (!event.getRightClicked().hasMetadata("armor-statue")) return; + event.setCancelled(true); + + ShopStatue statue = (ShopStatue) event.getRightClicked().getMetadata("armor-statue").get(0).value(); + if (statue == null) return; + + Player player = event.getPlayer(); + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + + if (!GTM.getSettings().canBuy()){ + player.sendMessage(ChatColor.RED + "Buying things is currently disabled."); + return; + } + + GameItem gi = itemManager.getItem(statue.getGameItem()); + double price = gi.getBuyPrice() * statue.getAmount(); + if (user.hasMoney(price)) { + user.takeMoney(price); + player.sendMessage(Lang.MONEY_TAKE.f(String.valueOf(price))); + } else { + if (user.hasBank(price)) { + user.takeBank(price); + player.sendMessage(Lang.BANK_TAKE.f(String.valueOf(price))); + } else { + player.sendMessage(Lang.MONEY.f("&7You do not have enough money!")); + return; + } + } + GTMUtils.updateBoard(player, Core.getUserManager().getLoadedUser(player.getUniqueId()), user); + switch (gi.getType()) { +// case AMMO: +// int amount = statue.getAmount(); +// AmmoType type = statue.getGameItem().getAmmoType(); +// if (type != null) +// user.addAmmo(type, amount); +// player.sendMessage(Lang.SHOP.f("&7You bought " + (amount > 1 ? "&a&l" + amount + "&7x " : "") +// + statue.getGameItem().getDisplayName() + "&7 for &a$&l" + price + "&7!")); +// return; + case ITEMSTACK: + ItemStack stack = gi.getItem(); + stack.setAmount(statue.getAmount()); + Utils.giveItems(player, stack); + player.sendMessage(Lang.SHOP.f("&7You bought " + (statue.getAmount() > 1 ? "&a&l" + statue.getAmount() + "&7x " : "") + + gi.getDisplayName() + "&7 for &a$&l" + price + "&7!")); + default: + break; + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/armor/ShopStatue.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/armor/ShopStatue.java new file mode 100644 index 0000000..3a80c3b --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/armor/ShopStatue.java @@ -0,0 +1,47 @@ +package net.grandtheftmc.gtm.armor; + +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.items.GameItem; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.metadata.FixedMetadataValue; + +public abstract class ShopStatue { + + public abstract Location spawnVisual(World world); + + public abstract Location getOrigin(World world); + + public abstract String getGameItem(); + + public ArmorStand spawnEntity(Location location, VisualType visualType) { + ArmorStand entity = location.getWorld().spawn(location, ArmorStand.class); + + entity.setGravity(false); + entity.setRemoveWhenFarAway(false); + entity.setAI(false); +// entity.setInvulnerable(true); + entity.setBasePlate(true); + entity.setVisible(false); + entity.setInvulnerable(true); +// entity.setCollidable(false); + entity.setMetadata("armor-statue", new FixedMetadataValue(GTM.getInstance(), this)); + extras(entity); + + return entity; + } + + public void extras(ArmorStand entity) {} + + public int getAmount() { + return 1; + } + + public static enum VisualType { + NAME, + PRICE, + NONE, + ; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/bounties/Bounty.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/bounties/Bounty.java new file mode 100644 index 0000000..7fd0610 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/bounties/Bounty.java @@ -0,0 +1,92 @@ +package net.grandtheftmc.gtm.bounties; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +public class Bounty { + + private UUID uuid; + private String name; + private List<BountyPlacer> placers = new ArrayList<>(); + private long lastUpdate; + + public Bounty(UUID uuid, String name, List<BountyPlacer> placers) { + this.uuid = uuid; + this.name = name; + this.placers = placers; + this.lastUpdate = System.currentTimeMillis(); + } + + public Bounty(UUID uuid, String name, List<BountyPlacer> placers, long lastUpdate) { + this.uuid = uuid; + this.name = name; + this.placers = placers; + this.lastUpdate = lastUpdate; + } + + public Bounty(UUID uuid, String name, BountyPlacer bountyPlacer) { + this.uuid = uuid; + this.name = name; + this.placers.add(bountyPlacer); + this.lastUpdate = System.currentTimeMillis(); + } + + public UUID getUuid() { + return this.uuid; + } + + public void setUuid(UUID u) { + this.uuid = u; + } + + public String getName() { + return this.name; + } + + public void setName(String s) { + this.name = s; + } + + public List<BountyPlacer> getPlacers() { + return this.placers; + } + + public void setPlacers(List<BountyPlacer> l) { + this.placers = l; + } + + public double getAmount() { + return this.placers.stream().mapToDouble(BountyPlacer::getAmount).sum(); + } + + public BountyPlacer getConsolePlacer() { + return this.placers.stream().filter(BountyPlacer::isConsole).findFirst().orElse(null); + } + + public BountyPlacer getPlacer(UUID uniqueId) { + return this.placers.stream().filter(placer -> Objects.equals(uniqueId, placer.getUUID())).findFirst().orElse(null); + } + + public void addPlacer(BountyPlacer bountyPlacer) { + this.placers.add(bountyPlacer); + } + + public long getLastUpdate() { + return this.lastUpdate; + } + + public void setLastUpdate() { + this.lastUpdate = System.currentTimeMillis(); + } + + public boolean hasExpired() { + return this.lastUpdate + 86400000 < System.currentTimeMillis(); + } + + public long getTimeUntilExpiryInMillis() { + return this.lastUpdate + 86400000 - System.currentTimeMillis(); + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/bounties/BountyManager.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/bounties/BountyManager.java new file mode 100644 index 0000000..4e32d17 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/bounties/BountyManager.java @@ -0,0 +1,158 @@ +package net.grandtheftmc.gtm.bounties; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import org.bukkit.Bukkit; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.*; +import java.util.stream.Collectors; + +public class BountyManager { + private List<Bounty> bounties = new ArrayList<>(); + + public BountyManager() { + this.loadBounties(); + this.startSchedule(); + } + + private void startSchedule() { + new BukkitRunnable() { + @Override + public void run() { + Collection<? extends Player> players = Bukkit.getOnlinePlayers(); + if (GTM.getBountyManager().getBounties().size() >= 5 || players.isEmpty()) return; + Random rand = Utils.getRandom(); + int amount = 10000 + (rand.nextInt(91) * 1000); + Player player = (Player) players.toArray()[rand.nextInt(players.size())]; + Bounty bounty = BountyManager.this.getBounty(player.getUniqueId()); + if (bounty == null) { + GTM.getBountyManager().addBounty(new Bounty(player.getUniqueId(), player.getName(), new BountyPlacer(true, amount))); + Utils.broadcast(Lang.BOUNTIES.f("&7An anonymous player put a bounty of &a$&l" + + amount + "&7 on &a" + player.getName() + "&7.")); + } + } + + }.runTaskTimer(GTM.getInstance(), 36000, 36000); + + + } + + + public List<Bounty> getBounties() { + this.bounties = this.bounties.stream().filter(b -> !b.hasExpired()).collect(Collectors.toList()); + return this.bounties; + } + + public Set<Bounty> getBountiesByAmount() { + Map<Bounty, Double> unsortMap = new HashMap<>(); + for (Bounty b : this.getBounties()) + unsortMap.put(b, b.getAmount()); + return this.sort(unsortMap).keySet(); + } + + public Map<Bounty, Double> sort(Map<Bounty, Double> unsortMap) { + List<Map.Entry<Bounty, Double>> list = new LinkedList<>(unsortMap.entrySet()); + list.sort(Comparator.comparing(Map.Entry::getValue)); + + Map<Bounty, Double> sortedMap = new LinkedHashMap<>(); + for (Map.Entry<Bounty, Double> entry : list) { + sortedMap.put(entry.getKey(), entry.getValue()); + } + return sortedMap; + } + + public Bounty getBounty(UUID uuid) { + return this.bounties.stream().filter(b -> Objects.equals(b.getUuid(), uuid)).findFirst().orElse(null); + } + + public void loadBounties() { + YamlConfiguration c = GTM.getSettings().getBountiesConfig(); + this.bounties.clear(); + for (String s : c.getKeys(false)) { + try { + UUID uuid = UUID.fromString(s); + if (uuid == null) + continue; + String name = c.getString(s + ".name"); + long lastUpdate = c.getLong(s + ".lastUpdate"); + List<BountyPlacer> placers = new ArrayList<>(); + for (String p : c.getConfigurationSection(s + ".placers").getKeys(false)) { + if ("console".equalsIgnoreCase(p)) { + placers.add(new BountyPlacer(true, c.getInt(s + ".placers." + p + ".amount"))); + continue; + } + UUID uuidp = UUID.fromString(p); + if (uuidp == null) + continue; + String namep = c.getString(s + ".placers." + p + ".name"); + int amount = c.getInt(s + ".placers." + p + ".amount"); + boolean anonymous = c.getBoolean(s + ".placers." + p + ".anonymous"); + placers.add(new BountyPlacer(uuidp, namep, amount, anonymous)); + } + Bounty b = new Bounty(uuid, name, placers, lastUpdate); + if (!b.hasExpired()) + this.bounties.add(b); + } catch (Exception e) { + Core.error("Error occured while loading bounty: " + s); + e.printStackTrace(); + } + } + } + + public void saveBounties() { + YamlConfiguration c = GTM.getSettings().getBountiesConfig(); + for (String s : c.getKeys(false)) + c.set(s, null); + for (Bounty b : this.bounties) { + try { + if (b.hasExpired()) + continue; + c.set(b.getUuid() + ".name", b.getName()); + c.set(b.getUuid() + ".lastUpdate", b.getLastUpdate()); + for (BountyPlacer p : b.getPlacers()) { + String path = b.getUuid() + ".placers." + (p.isConsole() ? "CONSOLE" : p.getUUID()); + c.set(path + ".name", p.getName()); + c.set(path + ".amount", p.getAmount()); + c.set(path + ".anonymous", p.isAnonymous()); + } + } catch (Exception e) { + Core.error("Error occured while saving bounty: " + b.getName()); + e.printStackTrace(); + } + } + Utils.saveConfig(c, "bounties"); + } + + public void removeBounty(Bounty bounty) { + this.bounties.remove(bounty); + } + + private void addBounty(Bounty bounty) { + this.bounties.add(bounty); + } + + public boolean placeBounty(Player target, int amnt, Player placer, boolean anonymous) { + Bounty bounty = this.getBounty(target.getUniqueId()); + if (bounty == null) { + this.bounties.add(new Bounty(target.getUniqueId(), target.getName(), new BountyPlacer(placer.getUniqueId(), placer.getName(), amnt, anonymous))); + return false; + } else { + BountyPlacer bPlacer = bounty.getPlacer(placer.getUniqueId()); + if (bPlacer == null) + bounty.addPlacer(new BountyPlacer(placer.getUniqueId(), placer.getName(), amnt, anonymous)); + else { + bPlacer.setAmount(bPlacer.getAmount() + amnt); + bPlacer.setAnonymous(anonymous); + } + bounty.setLastUpdate(); + return true; + } + + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/bounties/BountyPlacer.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/bounties/BountyPlacer.java new file mode 100644 index 0000000..692d9dc --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/bounties/BountyPlacer.java @@ -0,0 +1,66 @@ +package net.grandtheftmc.gtm.bounties; + +import java.util.UUID; + +public class BountyPlacer { + + private UUID uuid; + private String name; + private double amount; + private boolean anonymous; + private boolean console; + + public BountyPlacer(UUID uuid, String name, double amount, boolean anonymous) { + this.uuid = uuid; + this.name = name; + this.amount = amount; + this.anonymous = anonymous; + } + + public BountyPlacer(boolean console, double amount) { + this.console = console; + this.amount = amount; + this.anonymous = true; + } + + public BountyPlacer(int amount, boolean b) { + this.amount = amount; + this.anonymous = b; + } + + public UUID getUUID() { + return this.uuid; + } + + public void setUUID(UUID u) { + this.uuid = u; + } + + public String getName() { + return this.name; + } + + public void setName(String s) { + this.name = s; + } + + public double getAmount() { + return this.amount; + } + + public void setAmount(double i) { + this.amount = i; + } + + public boolean isAnonymous() { + return this.anonymous; + } + + public void setAnonymous(boolean b) { + this.anonymous = b; + } + + public boolean isConsole() { + return this.console; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/AmmoCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/AmmoCommand.java new file mode 100644 index 0000000..b64cc24 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/AmmoCommand.java @@ -0,0 +1,152 @@ +package net.grandtheftmc.gtm.commands; + +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.items.AmmoType; +import net.grandtheftmc.gtm.users.GTMUser; + +public class AmmoCommand implements CommandExecutor { + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!s.hasPermission("command.ammo")) { + s.sendMessage(Lang.NOPERM.toString()); + return true; + } + if (args.length == 0) { + s.sendMessage(Utils.f("&c/ammo types")); + s.sendMessage(Utils.f("&c/ammo balance <player> <type>")); + s.sendMessage(Utils.f("&c/ammo give <player> <type> <amount>")); + s.sendMessage(Utils.f("&c/ammo take <player> <type> <amount>")); + return true; + } + switch (args[0].toLowerCase()) { + case "types": { + sendAmmoTypes(s); + return true; + } + case "balance": { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/ammo balance <player> <type>")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player == null) { + s.sendMessage(Lang.AMMO.f("&7That player is not online!")); + return true; + } + AmmoType type = AmmoType.getAmmoType(args[2]); + if (type == null) { + s.sendMessage(Lang.AMMO.f("&7That AmmoType does not exist!")); + sendAmmoTypes(s); + return true; + } + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + s.sendMessage(Lang.AMMO.f("&a" + player.getName() + "&7 has &a&l" + user.getAmmo(type) + ' ' + + type.getGameItem().getDisplayName() + "&7!")); + return true; + } + case "give": { + if (args.length != 4) { + s.sendMessage(Utils.f("&c/ammo give <player> <type> <amount>")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player == null) { + s.sendMessage(Lang.AMMO.f("&7That player is not online!")); + return true; + } + AmmoType type = AmmoType.getAmmoType(args[2]); + if (type == null) { + s.sendMessage(Lang.AMMO.f("&7That AmmoType does not exist!")); + sendAmmoTypes(s); + return true; + } + int amnt; + try { + amnt = Integer.parseInt(args[3]); + } catch (NumberFormatException e) { + s.sendMessage(Lang.AMMO.f("&7The amount must be a number!")); + return true; + } + if (amnt <= 0) { + s.sendMessage(Lang.AMMO.f("&7The amount must be positive!")); + return true; + } + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + user.addAmmo(type, amnt); + s.sendMessage(Lang.AMMO.f("&7You gave &a&l" + amnt + ' ' + type.getGameItem().getDisplayName() + "&7 to &a" + + player.getName() + "&7!")); + player.sendMessage(Lang.AMMO.f("&7You were given &a&l" + amnt + ' ' + type.getGameItem().getDisplayName() + + "&7 by &a" + s.getName() + "&7!")); + return true; + } + case "take": + if (args.length != 4) { + s.sendMessage(Utils.f("&c/ammo take <player> <type> <amount>")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player == null) { + s.sendMessage(Lang.AMMO.f("&7That player is not online!")); + return true; + } + AmmoType type = AmmoType.getAmmoType(args[2]); + if (type == null) { + s.sendMessage(Lang.AMMO.f("&7That AmmoType does not exist!")); + sendAmmoTypes(s); + return true; + } + int amnt; + try { + amnt = Integer.parseInt(args[3]); + } catch (NumberFormatException e) { + s.sendMessage(Lang.AMMO.f("&7The amount must be a number!")); + return true; + } + if (amnt <= 0) { + s.sendMessage(Lang.AMMO.f("&7The amount must be positive!")); + return true; + } + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + if (!user.hasAmmo(type, amnt)) + amnt = user.getAmmo(type); + user.removeAmmo(type, amnt); + s.sendMessage(Lang.AMMO.f("&7You took &c&l" + amnt + ' ' + type.getGameItem().getDisplayName() + + "&7 from &a" + player.getName() + "&7!")); + player.sendMessage(Lang.AMMO.f("&c&l" + amnt + ' ' + type.getGameItem().getDisplayName() + + "&7 was taken from you by &a" + s.getName() + "&7!")); + return true; + default: + s.sendMessage(Utils.f("&c/ammo types")); + s.sendMessage(Utils.f("&c/ammo balance <player> <type>")); + s.sendMessage(Utils.f("&c/ammo give <player> <type> <amount>")); + s.sendMessage(Utils.f("&c/ammo take <player> <type> <amount>")); + return true; + } + } + + private String ammoTypes = null; + + private void sendAmmoTypes(CommandSender sender) { + if (ammoTypes == null) { + StringBuilder b = new StringBuilder("&7"); + for (AmmoType type : AmmoType.getTypes()) { + b.append(type).append("(").append(type.getGameItemName()).append("),"); + } + if (b.toString().endsWith(",")) { + b.setLength(b.length() - 1); + } + ammoTypes = b.toString(); + } + + sender.sendMessage(ammoTypes); + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/AntiAuraCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/AntiAuraCommand.java new file mode 100644 index 0000000..4563a6a --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/AntiAuraCommand.java @@ -0,0 +1,75 @@ +package net.grandtheftmc.gtm.commands; + +import net.grandtheftmc.core.Lang; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.TextComponent; +import org.apache.commons.lang.StringUtils; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.*; + +public class AntiAuraCommand implements CommandExecutor { + + //Checking for existance, hashsets are faster + public static final Set<String> TOGGLED_PLAYERS = new HashSet<>(); + + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (!s.hasPermission("antiaura.admin")) return false; + if (args.length == 0) { + s.sendMessage(Lang.ANTIAURA.f("&7/antiaura toggle")); + return false; + } + if (!(s instanceof Player)) { + if (args.length >= 1 && Objects.equals("notify", args[0])) { + this.notify(StringUtils.join(new ArrayList<>(Arrays.asList(args).subList(1, args.length)), " ")); + } else { + s.sendMessage(Lang.NOTPLAYER.s()); + } + return true; + } + Player player = (Player) s; + if (args.length >= 1) { + if ("toggle".equalsIgnoreCase(args[0])) { + if (TOGGLED_PLAYERS.contains(player.getName())) { + player.sendMessage(Lang.ANTIAURA.f("&7AntiAura notifications disabled.")); + TOGGLED_PLAYERS.remove(player.getName()); + } else { + player.sendMessage(Lang.ANTIAURA.f("&7AntiAura notifications enabled.")); + TOGGLED_PLAYERS.add(player.getName()); + } + } + } + return true; + } + + public void notify(String msg) { + for (String string : TOGGLED_PLAYERS) { + Player player; + if ((player = Bukkit.getPlayer(string)) != null) { + Player target = Bukkit.getPlayer(msg.split(" ")[0]); + if (target.isSprinting() && target.getInventory().getItemInMainHand().getType() == Material.DIAMOND_HOE + || "spawn".equals(target.getWorld().getName())) { + return; + } + + TextComponent component = new TextComponent(Lang.ANTIAURA.f("&7 " + msg)); + component.setColor(ChatColor.GRAY); + if (target != null) { + component.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/tp " + target.getName())); + component.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, + new ComponentBuilder("Click to teleport to " + target.getDisplayName()).create())); + } + player.spigot().sendMessage(component); + } + } + } +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/BackpackCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/BackpackCommand.java new file mode 100644 index 0000000..e185edd --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/BackpackCommand.java @@ -0,0 +1,65 @@ +package net.grandtheftmc.gtm.commands; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.users.GTMUser; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryView; + +import java.util.Objects; + +public class BackpackCommand implements CommandExecutor { + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (args.length == 0 || !s.hasPermission("backpack.admin")) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + Player player = (Player) s; + GTM.getBackpackManager().openBackpack(player); + return true; + } + Player player = (Player) s; + if (Bukkit.getPlayer(args[0]) != null) { + Player target = Bukkit.getPlayer(args[0]); + if (target.getOpenInventory() != null && Objects.equals("Backpack", ChatColor.stripColor(target.getOpenInventory().getTitle()))) { + target.getOpenInventory().close(); + } + Inventory backpack = GTM.getBackpackManager().getBackpack(target, true); + player.openInventory(backpack); + GTM.getUserManager().getLoadedUser(target.getUniqueId()).setBackpackOpen(true); + return true; + } + switch (args[0]) { + case "reset": + if (args.length != 2) { + s.sendMessage(Utils.f("&c/backpack reset <player>")); + return true; + } + Player target = Bukkit.getPlayer(args[1]); + if (target == null) { + return true; + } + InventoryView inv = target.getOpenInventory(); + if (inv != null + && Objects.equals("Backpack", ChatColor.stripColor(inv.getTitle()))) + target.closeInventory(); + GTMUser targetGtmUser = GTM.getUserManager().getLoadedUser(target.getUniqueId()); + targetGtmUser.setBackpackContents(null); + s.sendMessage(Utils.f("&7You cleared the backpack of player &a" + target.getName() + "&7!")); + target.sendMessage(Utils.f("&a" + player.getName() + "&7 cleared your backpack.")); + return true; + default: + s.sendMessage(Utils.f("&c/backpack reset <player>")); + return true; + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/BackupCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/BackupCommand.java new file mode 100644 index 0000000..30066ca --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/BackupCommand.java @@ -0,0 +1,76 @@ +package net.grandtheftmc.gtm.commands; + +import java.util.Objects; + +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.users.GTMUserManager; +import net.grandtheftmc.gtm.users.JobMode; +import net.grandtheftmc.gtm.users.TaxiTarget; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; + +/** + * Created by Liam on 9/12/2016. + */ +public class BackupCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command cmd, String lbl, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + Player player = (Player) s; + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + if (args.length == 0) { + if(user.getWantedLevel()!=0) { + player.sendMessage(Lang.COP_MODE.f("&cSorry, only player's without a wanted level can do this command.")); + return true; + } + if (user.hasRequestedBackup()) { + s.sendMessage(Lang.COP_MODE.f("&7You have already called " + (user.getJobMode() == JobMode.COP ? "for backup" : "the police") + "! Please wait &c&l" + Utils.timeInSecondsToText(Math.round(user.getTimeUntilBackupRequestExpires()/1000.0), "&3", "&7", "&7")+ "&7 to request backup again!")); + return true; + } + player.sendMessage(Lang.COP_MODE.f("&7You have called " + (user.getJobMode() == JobMode.COP ? "for backup" : "the police") + "! A message has been sent to all officers, and they can teleport to you for 1 minute!")); + user.setLastBackupRequest(System.currentTimeMillis()); + for (GTMUser u : GTMUserManager.getInstance().getUsers()) { + if (u.getJobMode() == JobMode.COP) { + Player p = Bukkit.getPlayer(u.getUUID()); + if (!Objects.equals(player, p)) + p.spigot().sendMessage(new ComponentBuilder(Lang.COP_MODE.f((user.getJobMode() == JobMode.COP ? "&3&lCop " : "&7Citizen ") + Core.getUserManager().getLoadedUser(player.getUniqueId()).getColoredName(player))).append(" is requesting " + (user.getJobMode() == JobMode.COP ? "backup" : "police assistance") + "! Teleport: ").color(net.md_5.bungee.api.ChatColor.GRAY). + append(" [ACCEPT] ").color(net.md_5.bungee.api.ChatColor.GREEN).bold(true).event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/backup " + player.getName())).create()); + } + } + return true; + } + if (user.getJobMode() != JobMode.COP) { + s.sendMessage(Lang.COP_MODE.f("&7You must be in &3&lCOP Mode&7 to provide backup!")); + return true; + } + Player target = Bukkit.getPlayer(args[0]); + if (target == null) { + player.sendMessage(Lang.COP_MODE.f("&7That player is not online!")); + return true; + } + GTMUser targetUser = GTM.getUserManager().getLoadedUser(target.getUniqueId()); + if (target.getGameMode() == GameMode.SPECTATOR || !targetUser.hasRequestedBackup()) { + player.sendMessage(Lang.COP_MODE.f("&7That player has not requested backup!")); + return true; + } + GTM.getWarpManager().warp(player, Core.getUserManager().getLoadedUser(player.getUniqueId()), user, new TaxiTarget(target), 0, -1); + target.sendMessage(Lang.COP_MODE.f("&7" + Core.getUserManager().getLoadedUser(player.getUniqueId()).getColoredName(player) + "&7 has accepted your " + (user.getJobMode() == JobMode.COP ? "backup" : "police assistance") + " request.")); + return true; + } + +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/BribeCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/BribeCommand.java new file mode 100644 index 0000000..4eefa91 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/BribeCommand.java @@ -0,0 +1,144 @@ +package net.grandtheftmc.gtm.commands; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.users.JobMode; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +/** + * Created by Liam on 11/10/2016. + */ +public class BribeCommand implements CommandExecutor { + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + Player player = (Player) s; + if (args.length == 0) { + s.sendMessage(Lang.BRIBE.f("&7Help Command")); + s.sendMessage(Utils.f("&3/bribe &a<amount>&7 - Send a bribe offer to the cop who arrested you!")); + s.sendMessage(Utils.f("&3/bribe accept &a<prisoner>&7 - Accept the bribe of a prisoner you arrested!")); + s.sendMessage(Utils.f("&3/bribe deny &a<prisoner>&7 - Deny the bribe of a prisoner you arrested!")); + return true; + } + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + switch (args[0]) { + case "accept": { + if (user.getJobMode() != JobMode.COP) { + player.sendMessage(Lang.BRIBE.f("&7You need to be in &3&lCOP Mode&7 to accept bribes!")); + return true; + } + if (args.length != 2) { + player.sendMessage(Lang.BRIBE.f("&7Please specify the prisoner of whom you would like to accept the bribe!")); + return true; + } + Player prisoner = Bukkit.getPlayer(args[1]); + GTMUser prisonerUser = prisoner == null ? null : GTM.getUserManager().getLoadedUser(prisoner.getUniqueId()); + if (prisoner == null || !prisonerUser.isArrested()) { + player.sendMessage(Lang.BRIBE.f("&7That player is not in jail!")); + return true; + } + if (prisonerUser.getJailTimer() <= 5) { + player.sendMessage(Lang.BRIBE.f("&7That prisoner is already being released!")); + return true; + } + if (prisonerUser.getBribe() <= 0) { + player.sendMessage(Lang.BRIBE.f("&7That prisoner has not sent a bribe offer to you! You can negotiate with them using &a\"/msg " + prisoner.getName() + "\"&7!")); + return true; + } + if (!prisonerUser.hasMoney(prisonerUser.getBribe())) { + player.sendMessage(Lang.BRIBE.f("&7That prisoner does not have enough money to pay for his bribe!")); + return true; + } + double bribe = prisonerUser.getBribe(); + prisonerUser.takeMoney(bribe); + user.addMoney(bribe); + prisonerUser.setBribe(0); + prisonerUser.setJailTimer(5); + GTMUtils.updateBoard(prisoner, prisonerUser); + GTMUtils.updateBoard(player, user); + player.sendMessage(Lang.BRIBE.f("&7You accepted a bribe of &a$&l" + bribe + "&7 from &e&l" + prisoner.getName() + "&7!")); + prisoner.sendMessage(Lang.BRIBE.f("&3&l" + player.getName() + "&7 accepted your bribe of &a$&l" + bribe + "&7!")); + return true; + } + case "deny": + if (user.getJobMode() != JobMode.COP) { + player.sendMessage(Lang.BRIBE.f("&7You need to be in &3&lCOP Mode&7 to accept bribes!")); + return true; + } + if (args.length != 2) { + player.sendMessage(Lang.BRIBE.f("&7Please specify the prisoner of whom you would like to accept the bribe!")); + return true; + } + Player prisoner = Bukkit.getPlayer(args[1]); + GTMUser prisonerUser = prisoner == null ? null : GTM.getUserManager().getLoadedUser(prisoner.getUniqueId()); + if (prisoner == null || !prisonerUser.isArrested()) { + player.sendMessage(Lang.BRIBE.f("&7That player is not in jail!")); + return true; + } + if (prisonerUser.getJailTimer() <= 5) { + player.sendMessage(Lang.BRIBE.f("&7That prisoner is already being released!")); + return true; + } + if (prisonerUser.getBribe() <= 0) { + player.sendMessage(Lang.BRIBE.f("&7That prisoner has not sent a bribe offer to you! You can negotiate with them using &a\"/msg " + prisoner.getName() + "\"&7!")); + return true; + } + double bribe = prisonerUser.getBribe(); + player.sendMessage(Lang.BRIBE.f("&7You denied a bribe of &a$&l" + bribe + "&7 from &e&l" + prisoner.getName() + "&7! You can negotiate with them using &a\"/msg " + prisoner.getName() + "\"&7!")); + player.sendMessage(Lang.BRIBE.f("&3&l" + player.getName() + "&7 denied your bribe of &a$&l" + bribe + "&7! You can negotiate with them using &a\"/msg " + prisoner.getName() + "\"&7!")); + return true; + default: + if (!user.isArrested()) { + player.sendMessage(Lang.BRIBE.f("&7You are not in jail!")); + return true; + } + if (user.getJailTimer() < 5) { + player.sendMessage(Lang.BRIBE.f("&7You are already being released!")); + return true; + } + Player cop = Bukkit.getPlayer(user.getJailCop()); + GTMUser copUser = cop == null ? null : GTM.getUserManager().getLoadedUser(cop.getUniqueId()); + if (cop == null || copUser.getJobMode() != JobMode.COP) { + player.sendMessage(Lang.BRIBE.f("&7The cop who arrested you (&3&l" + user.getJailCopName() + "&7) is off duty!")); + return true; + } + double amnt; + try { + amnt = Double.parseDouble(args[0]); + } catch (NumberFormatException e) { + player.sendMessage(Lang.BRIBE.f("&7The amount must be a number! (double)")); + return true; + } + if (amnt < 5000) { + player.sendMessage(Lang.BRIBE.f("&7Bribes must be at least &a$&l5,000!")); + return true; + } + if (user.getBribe() * 1.05 > amnt) { + player.sendMessage(Lang.BRIBE.f("&7You must raise the bribe by at least &a&l5%&7 of &a$&l" + user.getBribe() + "&7 (&a$&l" + (user.getBribe() * 1.05) + "&7)!")); + return true; + } + if (!user.hasMoney(amnt)) { + player.sendMessage(Lang.BRIBE.f("&7You don't have &c$&l" + amnt + "&7! Please enter a valid number or type &a\"quit\"&7!")); + return true; + } + user.setBribe(amnt); + player.sendMessage(Lang.BRIBE.f("&7You sent a bribe offer of &a$&l" + amnt + "&7 to &3&l" + cop.getName() + "&7. You can negotiate with them using &a\"/msg " + cop.getName() + "\"&7!")); + cop.spigot().sendMessage(new ComponentBuilder(Lang.BRIBE.f("&7A bribe offer of &a$&l" + amnt + "&7 was sent to you by &3&l" + player.getName() + "&7!")).append(" [ACCEPT] ").color(ChatColor.GREEN).bold(true).event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/bribe accept " + player.getName())).append("[DENY]").color(ChatColor.DARK_RED).bold(true).event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/bribe deny " + player.getName())).create()); + return true; + } + + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/CheatCodeCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/CheatCodeCommand.java new file mode 100644 index 0000000..0d07c13 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/CheatCodeCommand.java @@ -0,0 +1,243 @@ +package net.grandtheftmc.gtm.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.commands.CoreCommand; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.State; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.users.CheatCode; +import net.grandtheftmc.gtm.users.CheatCodeState; +import net.grandtheftmc.gtm.users.GTMUser; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import java.sql.*; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +/** + * Created by Timothy Lampen on 8/24/2017. + */ +public class CheatCodeCommand extends CoreCommand<CommandSender> { + + public CheatCodeCommand() { + super("cheatcode", "edit a player's unlocked cheat codes", "cc", "cheatcodes"); + } + + @Override + public void execute(CommandSender sender, String[] args) { + if(args.length==0) { + if(!(sender instanceof Player) || Core.getUserManager().getLoadedUser(((Player)sender).getUniqueId()).getUserRank().isHigherThan(UserRank.ADMIN)) { + sender.sendMessage(Utils.f("&e/cheatcode give <player> <cheatcode> &7- gives a certain player a PERM new cheatcode")); + sender.sendMessage(Utils.f("&e/cheatcode remove <player> <cheatcode> &7- removes a cheatcode from a player")); + sender.sendMessage(Utils.f("&e/cheatcode view <player> &7- view a player's cheatcodes")); + sender.sendMessage(Utils.f("&e/cheatcode list &7- lists all avaliable cheat codes.")); + sender.sendMessage(Utils.f("&e/cheatcode <cheatcode> &7- toggle / activate the specific cheatcode.")); + } + else { + sender.sendMessage(Utils.f("&e/cheatcode <cheatcode> &7- toggle / activate the specific cheatcode.")); + sender.sendMessage(Utils.f("&e/cheatcode list &7- lists all avaliable cheat codes.")); + } + return; + } + if(args.length==1) { + for (CheatCode code : CheatCode.getCodes()) { + if (args[0].equalsIgnoreCase(code.toString())) { + if (!(sender instanceof Player)) { + sender.sendMessage(Lang.NOTPLAYER.f("")); + return; + } + Player player = (Player) sender; + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + if (user.getCheatCodeState(code).getState() == State.LOCKED) { + player.sendMessage(Lang.CHEAT_CODES.f("&7You haven't unlocked this cheat code yet!")); + return; + } + code.activate(Core.getUserManager().getLoadedUser(player.getUniqueId()), user, player, user.getCheatCodeState(code)); + return; + } + } + } + switch (args[0]) { + case "remove": { + if(sender instanceof Player && !Core.getUserManager().getLoadedUser(((Player)sender).getUniqueId()).getUserRank().isHigherThan(UserRank.ADMIN)) { + sender.sendMessage(Lang.NOPERM.f("")); + return; + } + Player target = Bukkit.getPlayer(args[1]); + if(target==null) { + sender.sendMessage(Lang.CHEAT_CODES.f("&7Cannot find the player &a" + args[1])); + return; + } + if (args.length != 3) { + sender.sendMessage(Lang.CHEAT_CODES.f("&c/cheatcode remove <player> <cheatcode>")); + return; + } + Optional<CheatCode> optCode = Arrays.stream(CheatCode.getCodes()).filter(c -> c.toString().equalsIgnoreCase(args[2])).findFirst(); + if (!optCode.isPresent()) { + sender.sendMessage(Lang.CHEAT_CODES.f("&cUnable to find cheatcode with name &e" + args[2])); + return; + } + GTMUser user = GTM.getUserManager().getLoadedUser(target.getUniqueId()); + user.setCheatCodeState(optCode.get(), new CheatCodeState(State.LOCKED, false)); + Core.getUserManager().getLoadedUser(target.getUniqueId()).insertLog(target,"removeCheatCodeCommand","CHEATCODE", optCode.get().toString(),1,0); + target.sendMessage(Lang.CHEAT_CODES.f("&7The cheatcode &e" + optCode.get() + " &7has been removed from your account.")); + sender.sendMessage(Lang.CHEAT_CODES.f("&7You have removed the cheatcode &e" + optCode.get() + " &7from &b" + target.getName() + "&7's account.")); + break; + } + case "give": { + if(sender instanceof Player && !Core.getUserManager().getLoadedUser(((Player)sender).getUniqueId()).getUserRank().isHigherThan(UserRank.ADMIN)) { + sender.sendMessage(Lang.NOPERM.f("")); + return; + } + Player target = Bukkit.getPlayer(args[1]); + if(target==null) { + sender.sendMessage(Lang.CHEAT_CODES.f("&7Cannot find the player &a" + args[1])); + return; + } + if (args.length != 3) { + sender.sendMessage(Lang.CHEAT_CODES.f("&c/cheatcode give <player> <cheatcode>")); + return; + } + Optional<CheatCode> optCode = Arrays.stream(CheatCode.getCodes()).filter(c -> c.toString().equalsIgnoreCase(args[2])).findFirst(); + if (!optCode.isPresent()) { + sender.sendMessage(Lang.CHEAT_CODES.f("&cUnable to find cheatcode with name &e" + args[2])); + return; + } + GTMUser user = GTM.getUserManager().getLoadedUser(target.getUniqueId()); + switch (optCode.get()) { + case STACK: + Core.getPermsManager().addPerm(target.getUniqueId(), "command.stack"); + break; + case FIXALL: + Core.getPermsManager().addPerm(target.getUniqueId(), "command.fix.all"); + break; + case FIXHAND: + Core.getPermsManager().addPerm(target.getUniqueId(), "command.fix.hand"); + break; + + } + + Core.getUserManager().getLoadedUser(target.getUniqueId()).insertLog(target,"giveCheatCodeCommand","CHEATCODE", optCode.get().toString(),1,0); + user.setCheatCodeState(optCode.get(), new CheatCodeState(optCode.get().getDefaultState(), true)); + sender.sendMessage(Lang.CHEAT_CODES.f("&7You have given &b" + target.getName() + " &7the cheatcode &e" + optCode.get().toString() + "&7!")); + target.sendMessage(Lang.CHEAT_CODES.f("&7You have reiceved the cheatcode &e" + optCode.get().toString() + "&7, go into the kit menu located on your phone to toggle the effects.")); + break; + } + case "view": { + if(sender instanceof Player && !Core.getUserManager().getLoadedUser(((Player)sender).getUniqueId()).getUserRank().isHigherThan(UserRank.ADMIN)) { + sender.sendMessage(Lang.NOPERM.f("")); + return; + } + if(args.length !=2) { + sender.sendMessage(Utils.f("&e/cheatcode view <player>")); + return; + } + Player target = Bukkit.getPlayer(args[1]); + if (target == null) { + new BukkitRunnable() { + @Override + public void run() { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("Select * from " + Core.name() + " where name='" + args[1] + "'")) { + try (ResultSet result = statement.executeQuery()) { + int counter = 0; + HashMap<CheatCode, CheatCodeState> cheatCodes = new HashMap<>(); + while (result.next()) { + counter++; + Blob b = result.getBlob("cheatcodes"); + if(b!=null) { + String cheatCodesBlob = new String(b.getBytes(1, (int) b.length())); + for (String serializedCheatCode : cheatCodesBlob.split("-")) { + String[] split = serializedCheatCode.split("#"); + cheatCodes.put(CheatCode.valueOf(split[0]), new CheatCodeState(State.valueOf(split[1]), Boolean.valueOf(split[2]))); + } + } + } + if(counter==0) { + sender.sendMessage(Lang.CHEAT_CODES.f("&cThat player cannot be found!")); + } + else{ + sender.sendMessage(Utils.f("&7Player's Cheat Codes:")); + for(Map.Entry<CheatCode, CheatCodeState> entry : cheatCodes.entrySet()) { + sender.sendMessage(Utils.f("&2&l" + entry.getKey() + "&7: State: " + (entry.getValue().getState()==State.ON ? "&a " : "&c ") + entry.getValue().getState() + "&7, Purchased: " + (entry.getValue().isPurchased() ? "&atrue" : "&cfalse"))); + } + + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + +// ResultSet rs = Core.sql.query("Select * from " + Core.name() + " where name='" + args[1] + "'"); +// try { +// int counter = 0; +// HashMap<CheatCode, CheatCodeState> cheatCodes = new HashMap<>(); +// while (rs.next()) { +// counter++; +// Blob b = rs.getBlob("cheatcodes"); +// if(b!=null) { +// String cheatCodesBlob = new String(b.getBytes(1, (int) b.length())); +// for (String serializedCheatCode : cheatCodesBlob.split("-")) { +// String[] split = serializedCheatCode.split("#"); +// cheatCodes.put(CheatCode.valueOf(split[0]), new CheatCodeState(State.valueOf(split[1]), Boolean.valueOf(split[2]))); +// } +// } +// } +// if(counter==0) { +// sender.sendMessage(Lang.CHEAT_CODES.f("&cThat player cannot be found!")); +// } +// else{ +// sender.sendMessage(Utils.f("&7Player's Cheat Codes:")); +// for(Map.Entry<CheatCode, CheatCodeState> entry : cheatCodes.entrySet()) { +// sender.sendMessage(Utils.f("&2&l" + entry.getKey() + "&7: State: " + (entry.getValue().getState()==State.ON ? "&a " : "&c ") + entry.getValue().getState() + "&7, Purchased: " + (entry.getValue().isPurchased() ? "&atrue" : "&cfalse"))); +// } +// +// } +// } catch (SQLException e) { +// e.printStackTrace(); +// } + } + }.runTaskAsynchronously(GTM.getInstance()); + return; + } + GTMUser user = GTM.getUserManager().getLoadedUser(target.getUniqueId()); + sender.sendMessage(Utils.f("&7Player's Cheat Codes:")); + for(Map.Entry<CheatCode, CheatCodeState> entry : user.getCheatCodes().entrySet()) { + sender.sendMessage(Utils.f("&2&l" + entry.getKey() + "&7: State: " + (entry.getValue().getState()==State.ON ? "&a " : "&c ") + entry.getValue().getState() + "&7, Purchased: " + (entry.getValue().isPurchased() ? "&atrue" : "&cfalse"))); + } + break; + } + + case "list": { + StringBuilder sb = new StringBuilder("&7Cheat Codes:"); + Arrays.stream(CheatCode.getCodes()).forEach(code -> sb.append(" &a" + code.toString() + "&7,")); + sb.deleteCharAt(sb.length()-1); + sender.sendMessage(Utils.f(sb.toString())); + break; + } + default: { + if(!(sender instanceof Player) || Core.getUserManager().getLoadedUser(((Player)sender).getUniqueId()).getUserRank().isHigherThan(UserRank.ADMIN)) { + sender.sendMessage(Utils.f("&e/cheatcode give <player> <cheatcode> &7- gives a certain player a new cheatcode")); + sender.sendMessage(Utils.f("&e/cheatcode remove <player> <cheatcode> &7- removes a cheatcode from a player")); + sender.sendMessage(Utils.f("&e/cheatcode view <player> &7- view a player's cheatcodes")); + sender.sendMessage(Utils.f("&e/cheatcode list &7- lists all avaliable cheat codes.")); + sender.sendMessage(Utils.f("&e/cheatcode <cheatcode> &7- toggle / activate the specific cheatcode.")); + } + else { + sender.sendMessage(Utils.f("&e/cheatcode <cheatcode> &7- toggle / activate the specific cheatcode.")); + sender.sendMessage(Utils.f("&e/cheatcode list &7- lists all avaliable cheat codes.")); + } + break; + } + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/ChestCheckCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/ChestCheckCommand.java new file mode 100644 index 0000000..5f13090 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/ChestCheckCommand.java @@ -0,0 +1,59 @@ +package net.grandtheftmc.gtm.commands; + +import net.grandtheftmc.core.commands.CoreCommand; +import net.grandtheftmc.core.commands.RankedCommand; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.houses.House; +import net.grandtheftmc.houses.houses.HousesManager; +import net.grandtheftmc.houses.houses.PremiumHouse; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.Chest; +import org.bukkit.entity.Player; + +import java.util.Set; + +public class ChestCheckCommand extends CoreCommand<Player> implements RankedCommand { + + public ChestCheckCommand() { + super("chestcheck", "A staff command for recognising house chests."); + } + + @Override + public void execute(Player sender, String[] strings) { + Block targetBlock = sender.getTargetBlock((Set<Material>) null, 5); + if (targetBlock == null || targetBlock.getState() == null || !(targetBlock.getState() instanceof Chest)) { + sender.sendMessage(C.ERROR + "You don't seem to be looking at a chest?.."); + return; + } + + Chest chest = (Chest) targetBlock.getState(); + HousesManager manager = Houses.getHousesManager(); + + House house = manager.getHouseFromChest(chest.getLocation()); + if (house != null) { + sender.sendMessage(C.DARK_GREEN + C.BOLD + "House found"); + sender.sendMessage(C.GREEN + "Premium? " + C.YELLOW + "false"); + sender.sendMessage(C.GREEN + "Identifier " + C.YELLOW + house.getId()); + sender.sendMessage(C.GREEN + "Doors " + C.YELLOW + house.getDoors().size()); + sender.sendMessage(C.GREEN + "Chests " + C.YELLOW + house.getChests().size()); + return; + } + + PremiumHouse premiumHouse = manager.getPremiumHouseFromChest(chest.getLocation()); + if (premiumHouse != null) { + sender.sendMessage(C.DARK_GREEN + C.BOLD + "Premium House found"); + sender.sendMessage(C.GREEN + "Premium? " + C.YELLOW + "true"); + sender.sendMessage(C.GREEN + "Identifier " + C.YELLOW + premiumHouse.getId()); + sender.sendMessage(C.GREEN + "Doors " + C.YELLOW + premiumHouse.getDoors().size()); + sender.sendMessage(C.GREEN + "Chests " + C.YELLOW + premiumHouse.getChests().size()); + } + } + + @Override + public UserRank requiredRank() { + return UserRank.ADMIN; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/ChristmasCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/ChristmasCommand.java new file mode 100644 index 0000000..6b2e480 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/ChristmasCommand.java @@ -0,0 +1,72 @@ +package net.grandtheftmc.gtm.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.commands.CoreCommand; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.event.christmas.SpawnSantaDropTask; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.weapon.ranged.special.Clausinator; +import net.grandtheftmc.guns.GTMGuns; +import net.grandtheftmc.guns.weapon.Weapon; +import net.grandtheftmc.guns.weapon.ranged.RangedWeapon; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import java.util.Optional; + +/** + * Created by Timothy Lampen on 2017-12-16. + */ +public class ChristmasCommand extends CoreCommand<Player> { + public ChristmasCommand() { + super("christmas", "Commands related to the christmas event"); + } + + @Override + public void execute(Player player, String[] args) { + if(args.length==0) { + player.sendMessage("/christmas clausinator - reloads the clausinator weapon"); + return; + } + switch (args[0]) { + case "spawndrop": { + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if(player.isOp() && user.getUserRank().isHigherThan(UserRank.ADMIN)) + new SpawnSantaDropTask(player.getLocation()); + return; + } + case "clausinator": { + GTMUser gtmUser = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + if(gtmUser.isInCombat()) { + player.sendMessage(Lang.GTM.f("&cYou cannot load this weapon in combat!")); + return; + } + if(!gtmUser.hasMoney(100000)){ + player.sendMessage(Lang.GTM.f("&cYou do not have enough money ($100,000) to reload this gun!")); + return; + } + Weapon<?> optClaus = GTMGuns.getInstance().getWeaponManager().getWeaponByItem(player.getInventory().getItemInMainHand()); + if(optClaus==null) { + player.sendMessage(Lang.GTM.f("&cYou are not holding a clausinator in your hand currently")); + return; + } + Clausinator claus = (Clausinator)optClaus; + + if(claus.getAmmo(player.getInventory().getItemInMainHand())!=0) { + player.sendMessage(Lang.CHRISTMAS.f("&cThe clip of the clausinator isn't empty!")); + return; + } + + gtmUser.takeMoney(100000); + ItemStack updated = claus.setAmmo(player.getInventory().getItemInMainHand(), 600,600); + player.getInventory().setItemInMainHand(updated); + player.updateInventory(); + player.sendMessage(Lang.CHRISTMAS.f("&aReloaded your weapon.")); + return; + } + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/ChunkUnloadCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/ChunkUnloadCommand.java new file mode 100644 index 0000000..7e60445 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/ChunkUnloadCommand.java @@ -0,0 +1,47 @@ +package net.grandtheftmc.gtm.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import org.bukkit.Chunk; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; + +import java.util.Arrays; +import java.util.Collection; +import java.util.stream.Collectors; + +public class ChunkUnloadCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.GTM.f("&cYou are not a player!")); + return true; + } + Player player = (Player)s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if(!user.isRank(UserRank.DEV)) { + player.sendMessage(Lang.GTM.f("&7You don't have permission to use this command.")); + return true; + } + Collection<Chunk> chunks = Arrays + .stream(player.getWorld().getLoadedChunks()) + .collect(Collectors.toList()); + for(Chunk chunk : player.getWorld().getLoadedChunks()) { + for(Entity entity : chunk.getEntities()) { + if (entity.getType() == EntityType.PLAYER) { + chunks.remove(chunk); + break; + } + } + } + chunks.forEach(Chunk::unload); + return true; + } +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/ClearCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/ClearCommand.java new file mode 100644 index 0000000..575f4f4 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/ClearCommand.java @@ -0,0 +1,40 @@ +package net.grandtheftmc.gtm.commands; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTMUtils; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class ClearCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!s.hasPermission("command.clear")) { + s.sendMessage(Utils.f("&cYou do not have permission to execute this command!")); + return true; + } + if (!(s instanceof Player)) { + s.sendMessage(Lang.GTM.f("&cYou are not a player!")); + return true; + } + Player player; + if (args.length == 0) { + player = (Player) s; + } else { + if (Bukkit.getPlayer(args[0]) == null) { + s.sendMessage(Lang.GTM.f("&cThat player is not online!")); + return true; + } else { + player = Bukkit.getPlayer(args[0]); + } + } + player.getInventory().iterator().forEachRemaining(itemStack -> player.getInventory().remove(itemStack)); + player.sendMessage(Lang.GTM.f("&7Your inventory has been cleared!")); + GTMUtils.giveGameItems(player); + return true; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/CoreNPCCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/CoreNPCCommand.java new file mode 100644 index 0000000..6394267 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/CoreNPCCommand.java @@ -0,0 +1,92 @@ +package net.grandtheftmc.gtm.commands; + +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.users.npcs.*; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.commands.CoreCommand; + +/** + * Created by Timothy Lampen on 1/14/2018. + */ +public class CoreNPCCommand extends CoreCommand<Player> { + public CoreNPCCommand() { + super("corenpc", "commands dealing with corenpcs"); + } + + @Override + public void execute(Player player, String[] args) { + if(!player.isOp()) { + player.sendMessage(Lang.NOPERM.f("")); + return; + } + + if(args.length==0) { + player.sendMessage(Lang.GTM.f("&7Avaliable NPCs: ")); + player.sendMessage(Utils.f("&aPlay &7- Opens the taxi menu")); + player.sendMessage(Utils.f("&aBank &7- Opens the bank menu")); + player.sendMessage(Utils.f("&aFood &7- Opens a food shop menu")); + player.sendMessage(Utils.f("&aCasino &7- Opens the casino chip dealer menu")); + player.sendMessage(Utils.f("&aCar &7- Opens a car shop menu")); + player.sendMessage(Utils.f("&aRewards &7- Opens the rewards menu")); + player.sendMessage(Utils.f("&aArmor &7- Opens an armor shop menu")); + player.sendMessage(Utils.f("&aShop &7- Opens an inventory where players and buy and sell items.")); + player.sendMessage(Utils.f("&aSkins &7- Opens an inventory where players can manage and view their weapon skins.")); + player.sendMessage(Lang.GTM.f("&c/corenpc delete &7- Removes the nearby entity (please stand within 1 block)")); + player.sendMessage(Lang.GTM.f("&c/corenpc spawn <npc>")); + return; + } + + if(args.length==1){ + switch (args[0].toLowerCase()) { + case "delete": + case "remove": + for(Entity e : player.getNearbyEntities(2,2,2)) + Core.getNPCManager().deleteNPC(e); + player.sendMessage(Lang.GTM.f("&cYou have removed nearby npcs.")); + break; + } + return; + } + + switch (args[1].toLowerCase()) { + case "casino": + new CasinoNPC(player.getLocation()); + break; + case "play": + new TaxiNPC(player.getLocation()); + break; + case "bank": + new BankTellerNPC(player.getLocation()); + break; + case "food": + new FoodNPC(player.getLocation()); + break; + case "car": + new CarNPC(player.getLocation()); + break; + case "rewards": + new RewardsNPC(player.getLocation()); + break; + case "armor": + new ArmorNPC(player.getLocation()); + break; + case "shop": + new ShopNPC(GTM.getWastedGuns().getWeaponManager(), player.getLocation()); + break; + case "skins": + new SkinsNPC(player.getLocation()); + break; + case "heads": + new HeadSellerNPC(player.getLocation()); + break; + case "mechanic": + new MechanicNPC(player.getLocation()); + break; + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/DrugCheckCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/DrugCheckCommand.java new file mode 100644 index 0000000..4bedb69 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/DrugCheckCommand.java @@ -0,0 +1,38 @@ +package net.grandtheftmc.gtm.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; + +/** + * Created by Timothy Lampen on 2017-04-22. + */ +public class DrugCheckCommand implements CommandExecutor { + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if(sender instanceof Player) { + if(!Core.getUserManager().getLoadedUser(((Player) sender).getUniqueId()).isStaff()) + return false; + } + if (args.length != 1) { + sender.sendMessage(Lang.DRUGS.f("&7Syntax Error: /drugcheck <player>")); + return false; + } + Player target = Bukkit.getPlayer(args[0]); + if (target == null) { + sender.sendMessage(Lang.DRUGS.f("&7Error: The specified player is not online.")); + return false; + } + sender.sendMessage(Lang.DRUGS.f("&7Current potion effect portfolio for " + target.getName())); + for (PotionEffect pe : target.getActivePotionEffects()) { + sender.sendMessage(ChatColor.GREEN + pe.getType().getName() + ChatColor.BLUE + " : " + ChatColor.GREEN + pe.getAmplifier() + 1 + ChatColor.BLUE + " : " + ChatColor.GREEN + pe.getDuration() / 20 + "s"); + } + return true; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/DrugDealerCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/DrugDealerCommand.java new file mode 100644 index 0000000..a556661 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/DrugDealerCommand.java @@ -0,0 +1,94 @@ +package net.grandtheftmc.gtm.commands; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.drugs.DrugDealer; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.Optional; + +public class DrugDealerCommand implements CommandExecutor { + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (!sender.hasPermission("drugdealer.command")) { + sender.sendMessage(Lang.DRUGS + "" + ChatColor.RED + "Error: You do not have permission to execute this command."); + return false; + } + if (args.length < 1) { + sender.sendMessage(ChatColor.RED + "/drugdealer add - sets a drugdealer location"); + sender.sendMessage(ChatColor.RED + "/drugdealer tp - teleports you to the drugdealer"); + sender.sendMessage(ChatColor.RED + "/drugdealer next - teleports the drug dealer to a new location"); + sender.sendMessage(ChatColor.RED + "/drugdealer restock - restocks the drug dealer"); + sender.sendMessage(ChatColor.RED + "/drugdealer remove - removes the nearest dealer location from the drug dealer"); + sender.sendMessage(ChatColor.RED + "/drugdealer save - saves the drug dealer locations to config"); + sender.sendMessage(ChatColor.RED + "/drugdealer load - loads the drug dealer locations from config"); + + return false; + } + if (!(sender instanceof Player)) { + sender.sendMessage(Lang.DRUGS + "" + ChatColor.GRAY + "Console cannot execute this command."); + return false; + } + Player player = (Player) sender; + DrugDealer drugDealer = GTM.getDrugManager().getDrugDealer(); + switch (args[0]) { + case "add": { + player.sendMessage(Lang.DRUGS.f("&7You have added a location for the dealer to spawn!")); + drugDealer.addDealerLoc(player.getLocation()); + break; + } + case "tp": { + player.teleport(GTM.getDrugManager().getDrugDealer().dealerStand()); + player.sendMessage(Lang.DRUGS.f("&7You have been teleported to the current drug dealer location.")); + break; + } + case "next": { + Optional<Location> randomLoc = drugDealer.getRandomLoc(); + randomLoc.ifPresent(location -> drugDealer.setLocation(location)); + player.sendMessage(Lang.DRUGS.f("&7You have changed the location of the drug dealer.")); + break; + } + case "restock": { + drugDealer.rerollStock(); + player.sendMessage(Lang.DRUGS.f("&7You have restocked the drug dealer.")); + break; + } + case "remove": { + Location nearestLocation = null; + if (drugDealer.getDealerLocations().isEmpty()) { + player.sendMessage(Lang.DRUGS.f("&7No drug dealer locations exist")); + return true; + } + for (Location location : drugDealer.getDealerLocations()) { + if (player.getWorld() != location.getWorld()) continue; + if (nearestLocation == null || + location.distance(player.getLocation()) < nearestLocation.distance(player.getLocation())) + nearestLocation = location; + } + drugDealer.getDealerLocations().remove(nearestLocation); + player.sendMessage(Lang.DRUGS.f("&7Drug Dealer location nearest to you has been removed.")); + break; + } + case "save": { + drugDealer.saveLocations(); + player.sendMessage(Lang.DRUGS.f("&7You have saved the locations / items for the drug dealer to file")); + break; + } + case "load": { + drugDealer.loadLocations(); + drugDealer.loadDealerItems(); + player.sendMessage(Lang.DRUGS.f("&7You have loaded the locations / items for the drug dealer from file")); + break; + } + default: { + return false; + } + } + return true; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/FeedCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/FeedCommand.java new file mode 100644 index 0000000..a42cf84 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/FeedCommand.java @@ -0,0 +1,59 @@ +package net.grandtheftmc.gtm.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.State; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.users.CheatCode; +import net.grandtheftmc.gtm.users.GTMUser; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + + +public class FeedCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + /* if (args.length > 0 && s.hasPermission("command.feed.others")) { + player = Bukkit.getPlayer(args[0]); + if (player == null) { + s.sendMessage(Lang.GTM.f("&7That player is not online!")); + return true; + } + player.setFoodLevel(20); + player.setSaturation(20); + s.sendMessage(Lang.GTM.f("&7You fed &a" + player.getName() + "&7!")); + return true; + }*/ + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + Player player = (Player) s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + GTMUser GTMUser = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + if (GTMUser.getCheatCodeState(CheatCode.FEED).getState()== State.LOCKED) { + player.sendMessage(Lang.CHEAT_CODES.f(CheatCode.FEED.getLockedLore())); + return true; + } + if(user.isOnCooldown("feed_command")) { + player.sendMessage(Lang.CHEAT_CODES.f("&7You must wait &a" + Utils.timeInSecondsToText(user.getCooldownTimeLeft("feed_command"), C.RED, C.RED, C.GRAY) + " &7before using this cheatcode again!")); + return true; + } + user.addCooldown("feed_command", GTMUtils.getFeedDelay(user.getUserRank()), false, true); + player.setFoodLevel(20); + player.setSaturation(20); + player.sendMessage(Lang.GTM.f("&7You fed yourself!")); + return true; + + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/FixCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/FixCommand.java new file mode 100644 index 0000000..e74dfc9 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/FixCommand.java @@ -0,0 +1,90 @@ +package net.grandtheftmc.gtm.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.State; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.users.CheatCode; +import net.grandtheftmc.gtm.users.GTMUser; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +public class FixCommand implements CommandExecutor { + private final List<Material> repairableItems = Arrays.asList(Material.LEATHER_CHESTPLATE, + Material.CHAINMAIL_CHESTPLATE, Material.IRON_CHESTPLATE, + Material.GOLD_CHESTPLATE, Material.DIAMOND_CHESTPLATE, + Material.LEATHER_BOOTS, Material.LEATHER_LEGGINGS, + Material.LEATHER_CHESTPLATE, Material.LEATHER_HELMET, + Material.DIAMOND_HELMET, Material.ELYTRA, + Material.CHAINMAIL_HELMET, Material.CHAINMAIL_BOOTS); + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + Player player = (Player) s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + GTMUser GTMUser = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + if (args.length == 0 || args.length == 1 && "hand".equalsIgnoreCase(args[0])) { + if(GTMUser.getCheatCodeState(CheatCode.FIXHAND).getState()== State.LOCKED) { + player.sendMessage(Lang.CHEAT_CODES.f(CheatCode.FIXHAND.getLockedLore())); + return false; + } + if(user.isOnCooldown("fix_hand_command")) { + player.sendMessage(Lang.CHEAT_CODES.f("&7You must wait &a" + Utils.timeInSecondsToText(user.getCooldownTimeLeft("fix_hand_command"), C.RED, C.RED, C.GRAY) + " &7before using this cheatcode again!")); + return false; + } + ItemStack item = player.getInventory().getItemInMainHand(); + + if(this.repairableItems.contains(item.getType())) { + + item.setDurability((short)0); + player.sendMessage(Lang.GTM.f("&7You have repaired your " + (item.getItemMeta().getDisplayName() == null ? item.getType().name().toLowerCase().replace("_", "") : item.getItemMeta().getDisplayName()) + "&7!")); + user.addCooldown("fix_hand_command", GTMUtils.getFixHandDelay(user.getUserRank()), true, true); + } else { + player.sendMessage(Lang.GTM.f("&7That item may not be repaired.")); + } + return true; + } else if(args.length == 1 && "all".equalsIgnoreCase(args[0])) { + if(GTMUser.getCheatCodeState(CheatCode.FIXALL).getState()== State.LOCKED) { + player.sendMessage(Lang.CHEAT_CODES.f(CheatCode.FIXALL.getLockedLore())); + return false; + } + if(user.isOnCooldown("fix_all_command")) { + player.sendMessage(Lang.CHEAT_CODES.f("&7You must wait &a" + Utils.timeInSecondsToText(user.getCooldownTimeLeft("fix_all_command"), C.RED, C.RED, C.GRAY) + " &7before using this cheatcode again!")); + return false; + } + for(ItemStack item : player.getInventory().getContents()) { + if(item == null) continue; + if(!this.repairableItems.contains(item.getType())) continue; + item.setDurability((short)0); + } + player.sendMessage(Lang.GTM.f("&7You have repaired all damaged items in your inventory!")); + user.addCooldown("fix_all_command", GTMUtils.getFixAllDelay(user.getUserRank()), true, true); + } else { + player.sendMessage(Lang.GTM.f("&7/fix hand - fixes the item in your hand.")); + player.sendMessage(Lang.GTM.f("&7/fix all - fixes all the items in your inventory.")); + return true; + } + return true; + + } + + +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/GTMAdminCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/GTMAdminCommand.java new file mode 100644 index 0000000..32c7425 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/GTMAdminCommand.java @@ -0,0 +1,260 @@ +package net.grandtheftmc.gtm.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.inventory.CoreMenu; +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import net.grandtheftmc.core.inventory.button.MenuItem; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.items.ArmorUpgrade; +import net.grandtheftmc.gtm.users.CompassTarget; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.wastedbarrels.WastedBarrel; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.houses.House; +import net.grandtheftmc.houses.users.HouseUser; +import net.grandtheftmc.houses.users.UserHouse; +import net.grandtheftmc.houses.users.UserHouseChest; +import org.bukkit.Bukkit; +import org.bukkit.EntityEffect; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import java.util.Map; + +public class GTMAdminCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + if (!s.hasPermission("command.admin")) { + s.sendMessage(Lang.NOPERM.s()); + return true; + } + Player player = (Player) s; + if (args.length == 0) { + s.sendMessage(Utils.f("&c/gtmadmin setkillcounter <player> <amnt>")); + s.sendMessage(Utils.f("&c/gtmadmin release <player>")); + s.sendMessage(Utils.f("&c/gtmadmin target <player>")); + s.sendMessage(Utils.f("&c/gtmadmin resetjobdelay <player>")); + s.sendMessage(Utils.f("&c/gtmadmin kitexpiries <player>")); + s.sendMessage(Utils.f("&c/gtmadmin trashcan")); + s.sendMessage(Utils.f("&c/gtmadmin barrel <add/remove>")); + return true; + } + switch (args[0].toLowerCase()) { + case "barrel": { + if (args.length == 1) { + player.sendMessage(Utils.f("&c/gtmadmin barrel add - &7Add a Flammable Barrel at your location")); + player.sendMessage(Utils.f("&c/gtmadmin barrel remove - &7Remove the Flammable Barrel nearest to you")); + return true; + } + if ("spawn".equalsIgnoreCase(player.getWorld().getName())) { + player.sendMessage(Utils.f("&7Barrels cannot be in Spawn.")); + return true; + } + if ("add".equalsIgnoreCase(args[1])) { + GTM.getBarrelManager().spawnWastedBarrel(player.getLocation()).getArmorStand().playEffect(EntityEffect.WOLF_HEARTS); + } else if ("remove".equalsIgnoreCase(args[1])) { + player.getNearbyEntities(10, 10, 10).stream() + .filter(entity -> entity.getType() == EntityType.ARMOR_STAND) + .forEach(entity -> { + if (((ArmorStand) entity).getHelmet().getType() != Material.TNT) return; + if (!entity.hasMetadata("WastedBarrel")) return; + ArmorStand armorStand = (ArmorStand) entity; + armorStand.setHelmet(null); + armorStand.remove(); + player.sendMessage(armorStand.getLocation().toString()); + WastedBarrel wastedBarrel = (WastedBarrel) armorStand.getMetadata("WastedBarrel").get(0).value(); + GTM.getBarrelManager().getWastedBarrels().remove(wastedBarrel); + }); + player.sendMessage(Utils.f("&7Barrel(s) removed!")); + } else { + player.sendMessage(Utils.f("&c/gtmadmin barrel add - &7Add a Flammable Barrel at your location")); + player.sendMessage(Utils.f("&c/gtmadmin barrel remove - &7Remove the Flammable Barrel nearest to you")); + } + return true; + } + case "trashcan": { + ItemStack item = Utils.createItem(Material.DROPPER, "&7&lTrash Can"); + //Utils.b(ArmorUpgrade.TANK.getEnchantment().getName()); + // item.addUnsafeEnchantment(ArmorUpgrade.TANK.getEnchantment(), 1); + for (Enchantment e : item.getEnchantments().keySet()) + Utils.b(e.getName()); + player.getInventory().addItem(item); + s.sendMessage(Utils.f("&7A Trash Can was added to your inventory. Place it so players can sell items in it.")); + return true; + } + case "kitexpiries": { + if (args.length != 2) { + s.sendMessage(Utils.f("&c/gtmadmin kitexpiries <player>")); + return true; + } + Player p = Bukkit.getPlayer(args[1]); + if (p == null) { + s.sendMessage(Utils.f("&cThat player is not online!")); + return true; + } + GTMUser user = GTM.getUserManager().getLoadedUser(p.getUniqueId()); + s.sendMessage(Utils.f("&7Player &a" + p.getName() + "&7 has the following kit expiries:")); + for (Map.Entry<String, Long> entry : user.getKitExpiries().entrySet()) + s.sendMessage(entry.getKey() + ": expiry " + entry.getValue() + " time left " + (entry.getValue() - System.currentTimeMillis())); + s.sendMessage("KitExpiriesString: " + user.getKitExpiriesString()); + return true; + } + case "resetjobdelay": { + if (args.length != 2) { + s.sendMessage(Utils.f("&c/gtmadmin resetjobdelay <player>")); + return true; + } + Player p = Bukkit.getPlayer(args[1]); + if (p == null) { + s.sendMessage(Utils.f("&cThat player is not online!")); + return true; + } + GTMUser user = GTM.getUserManager().getLoadedUser(p.getUniqueId()); + user.setLastJobMode(-1); + s.sendMessage(Utils.f("&aYou reset &a" + p.getName() + "&7's job mode delay!")); + return true; + } + case "setkillcounter": { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/gtmadmin setkillcounter <player> <amnt>")); + return true; + } + Player p = Bukkit.getPlayer(args[1]); + int amnt; + try { + amnt = Integer.parseInt(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f("&cThe amnt must be a number!")); + return true; + } + GTMUser user = GTM.getUserManager().getLoadedUser(p.getUniqueId()); + user.setKillCounter(amnt); + player.sendMessage(Utils.f("&aYou set " + p.getName() + "'s killcounter to " + amnt + '!')); + return true; + } + case "release": { + if (args.length != 2) { + s.sendMessage(Utils.f("&c/gtmadmin release <player>")); + return true; + } + Player p = Bukkit.getPlayer(args[1]); + if (p == null) { + s.sendMessage(Utils.f("&cThat player is not online!")); + return true; + } + GTMUser user = GTM.getUserManager().getLoadedUser(p.getUniqueId()); + user.setJailTimer(-1); + p.teleport(GTM.getWarpManager().getSpawn().getLocation()); + s.sendMessage(Utils.f("&aYou released " + p.getName() + " from jail!")); + return true; + } + case "target": { + if (args.length != 2) { + s.sendMessage(Utils.f("&c/gtmadmin target <player>")); + return true; + } + Player p = Bukkit.getPlayer(args[1]); + if (p == null) { + s.sendMessage(Utils.f("&cThat player is not online!")); + return true; + } + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + user.setCompassTarget(player, Core.getUserManager().getLoadedUser(player.getUniqueId()), new CompassTarget(p)); + s.sendMessage(Utils.f("&aYou set your compass target to &a" + p.getName() + '!')); + return true; + } + case "hchest": {//gtmadmin hchest playerName houseId chestId + if (args.length < 4) { + s.sendMessage(C.ERROR + "Usage: /gtmadmin [hchest/phchest] playerName houseId chestId"); + return true; + } + + Player target = Bukkit.getPlayer(args[1]); + if (target == null) { + s.sendMessage(C.ERROR + "This player is not online."); + return true; + } + + int houseId = -1, chestId = -1; + try { + houseId = Integer.parseInt(args[2]); + chestId = Integer.parseInt(args[3]); + } catch (NumberFormatException e) { + s.sendMessage(C.ERROR + "The requested Id's couldn't be parsed. Use numerals."); + return true; + } + + if (houseId < 0 || chestId < 0) { + s.sendMessage(C.ERROR + "The requested Id's couldn't be parsed. Use numerals."); + return true; + } + + HouseUser houseUser = Houses.getUserManager().getLoadedUser(target.getUniqueId()); + if (houseUser == null) { + s.sendMessage(C.ERROR + "This player does not own a house."); + return true; + } + + UserHouse userHouse = houseUser.getUserHouse(houseId); + if (userHouse == null) { + s.sendMessage(C.ERROR + "This player does not own this house."); + return true; + } + + UserHouseChest houseChest = userHouse.getChest(chestId); + if (houseChest == null) { + s.sendMessage(C.ERROR + "The house chest with id " + chestId + ", could not be found."); + return true; + } + + if (houseChest.getContents() == null) { + s.sendMessage(C.ERROR + "This chest doesn't contain items."); + return true; + } + + new FakeChestInv(6, houseId, chestId, houseChest.getContents()).openInventory((Player) s); + s.sendMessage(C.GREEN + "Opening fake content inventory."); + } + default: + s.sendMessage(Utils.f("&c/gtmadmin setkillcounter <player> <amnt>")); + s.sendMessage(Utils.f("&c/gtmadmin release <player>")); + s.sendMessage(Utils.f("&c/gtmadmin target <player>")); + s.sendMessage(Utils.f("&c/gtmadmin resetjobdelay <player>")); + s.sendMessage(Utils.f("&c/gtmadmin kitexpiries <player>")); + s.sendMessage(Utils.f("&c/gtmadmin trashcan")); + s.sendMessage(Utils.f("&c/gtmadmin barrel")); + s.sendMessage(Utils.f("&c/gtmadmin gravity <modifier>")); + return true; + } + } + + public class FakeChestInv extends CoreMenu { + + public FakeChestInv(int rows, int houseId, int chestId, ItemStack[] contents) { + super(rows, "Fake contents {" + houseId + "," + chestId + "}", CoreMenuFlag.RESET_CURSOR_ON_OPEN, CoreMenuFlag.CLOSE_ON_NULL_CLICK); + + for (int i = 0; i < contents.length; i++) { + ItemStack item = contents[i]; + if (item == null) continue; + + addItem(new MenuItem(i, item, false)); + } + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/GTMRankCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/GTMRankCommand.java new file mode 100644 index 0000000..63ad54e --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/GTMRankCommand.java @@ -0,0 +1,64 @@ +package net.grandtheftmc.gtm.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.users.GTMRank; +import net.grandtheftmc.gtm.users.GTMUser; + +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class GTMRankCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!s.hasPermission("command.gtmrank")) { + s.sendMessage(Utils.f("&cYou do not have permission to execute this command!")); + return true; + } + if (args.length == 0) { + s.sendMessage(Utils.f("&c/gtmrank set <player> <rank>")); + return true; + } + switch (args[0].toLowerCase()) { + case "set": + if (args.length != 3) { + s.sendMessage(Utils.f("&c/gtmrank set <player> <rank>")); + return true; + } + GTMRank rank = GTMRank.getRankOrNull(args[2]); + if (rank == null) { + String msg = Lang.RANKS + "&7There is no gtmrank with the name &a" + args[2] + "&7! Valid ranks: "; + for (GTMRank r : GTMRank.getGTMRanks()) + msg = msg + "&a" + r.getColoredNameBold() + "&7, "; + if (msg.endsWith("&7, ")) + msg = msg.substring(0, msg.length() - 4); + msg += "&c."; + s.sendMessage(Utils.f(msg)); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player == null) { +// Core.sql.updateAsyncLater("update "+ Core.name()+" set rank='" + rank.getName() + "' where name='" + args[1] + "';"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update "+ Core.name()+" set rank='" + rank.getName() + "' where name='" + args[1] + "';")); + s.sendMessage(Utils.f(Lang.RANKS + "&7That player is not online, so his rank has been forcibly updated in the database.")); + return true; + } + GTMUser u = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + u.setRank(rank, player, Core.getUserManager().getLoadedUser(player.getUniqueId())); + s.sendMessage(Utils.f(Lang.RANKS + "&a" + player.getName() + " &7is now a &a" + u.getRank().getColoredNameBold() + "&7!")); + return true; + + default: + s.sendMessage(Utils.f("&c/gtmrank set <player> <rank>")); + return true; + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/GTMRanksCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/GTMRanksCommand.java new file mode 100644 index 0000000..4718dd8 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/GTMRanksCommand.java @@ -0,0 +1,40 @@ +package net.grandtheftmc.gtm.commands; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.users.GTMRank; +import net.grandtheftmc.gtm.users.LockedWeapon; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.stream.Collectors; + +public class GTMRanksCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + Player player = (Player) s; + player.sendMessage(Lang.RANKS.s()); + List<LockedWeapon> lockedWeapons = new LinkedList<>(Arrays.asList(LockedWeapon.values())); + for (GTMRank gtmRank : GTMRank.values()) { + List<LockedWeapon> unlockedWeapons = lockedWeapons.stream().filter(lockedWeapon -> lockedWeapon.getGTMRank() == gtmRank).collect(Collectors.toList()); + String unlocks = ""; + if (!unlockedWeapons.isEmpty()) { + unlocks = StringUtils.join(unlockedWeapons, "&7, &c&l"); + } + player.sendMessage(Utils.f(gtmRank.getColoredNameBold() + " &7costs &a&l$" + gtmRank.getPrice() + + (unlocks.isEmpty() ? "" : " &7unlocks &c&l" + unlocks))); + } + return true; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/HalloweenCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/HalloweenCommand.java new file mode 100644 index 0000000..43d6419 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/HalloweenCommand.java @@ -0,0 +1,50 @@ +package net.grandtheftmc.gtm.commands; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.commands.CoreCommand; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.gtm.holidays.halloween.PlayerScare; +import net.grandtheftmc.gtm.holidays.halloween.dao.ServerCoupon; +import net.grandtheftmc.gtm.holidays.halloween.dao.ServerCouponDAO; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.sql.Connection; +import java.sql.SQLException; + +/** + * Created by Timothy Lampen on 2017-10-23. + */ +public class HalloweenCommand extends CoreCommand<Player> { + public HalloweenCommand() { + super("halloween", "commands surrounding halloween!"); + } + + @Override + public void execute(Player sender, String[] args) { +// if(!sender.isOp()) { +// sender.sendMessage(Lang.NOPERM.f("")); +// return; +// } +// if(args.length==0) { +// sender.sendMessage(Utils.f("&7/halloween reset")); +// sender.sendMessage(Utils.f("&7/halloween trigger")); +// return; +// } +// switch (args[0].toLowerCase()) { +// case "reset": { +// try(Connection conn = BaseDatabase.getInstance().getConnection()){ +// ServerCouponDAO.deleteServerCoupon(conn, sender.getUniqueId(), true); +// sender.sendMessage(Utils.f("&7deleted your coupon from DB")); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// break; +// } +// case"trigger": { +// PlayerScare.initScare(sender); +// } +// } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/KillCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/KillCommand.java new file mode 100644 index 0000000..9b978ba --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/KillCommand.java @@ -0,0 +1,68 @@ +package net.grandtheftmc.gtm.commands; + +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.Utils; + +public class KillCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.GTM.f("&cYou are not a player!")); + return true; + } + Player player = (Player) s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (lbl.equalsIgnoreCase("suicide")) { + if (player.getWorld().getName().equalsIgnoreCase("spawn")) return true; + player.sendMessage(Lang.GTM.f("&7Have a nice &osuicide!")); + player.getActivePotionEffects().forEach(effect -> player.removePotionEffect(effect.getType())); + + // grab current rank + UserRank rank = user.getUserRank(); + if (rank != null){ + // sr mod or builders and above should always have inventory cleared + if (rank.hasRank(UserRank.SRMOD) || rank.hasRank(UserRank.BUILDER)){ + player.getInventory().clear(); + } + } + + player.damage(player.getHealth() * 10, player); + return true; + } + if (!user.isRank(UserRank.ADMIN)) { + player.sendMessage(Lang.NOPERM.s()); + return true; + } + if (args.length != 1) { + s.sendMessage(Utils.f("&c/kill <player>")); + return true; + } + Player target = Bukkit.getPlayer(args[0]); + if (target == null) { + s.sendMessage(Lang.GTM.f("&7That player is not online!")); + return true; + } + if (target.isOp()) { + s.sendMessage(Lang.GTM.f("&7That player can not be killed")); + return true; + } + target.getActivePotionEffects().forEach(effect -> { + target.removePotionEffect(effect.getType()); + }); + target.damage(target.getHealth()); + s.sendMessage(Lang.GTM.f("&7You killed &a" + + Core.getUserManager().getLoadedUser(target.getUniqueId()).getColoredName(target) + "&7!")); + return true; + } +} + diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/LotteryCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/LotteryCommand.java new file mode 100644 index 0000000..a00b41f --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/LotteryCommand.java @@ -0,0 +1,193 @@ +package net.grandtheftmc.gtm.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.tasks.Lottery; +import net.grandtheftmc.gtm.tasks.LotteryPlayer; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +public class LotteryCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.toString()); + return true; + } + Player player = (Player) s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (!user.isRank(UserRank.SRMOD)) { + player.sendMessage(Lang.NOPERM.toString()); + return true; + } + if (args.length == 0) { + s.sendMessage(Utils.f("&c/lottery sethologram")); + s.sendMessage(Utils.f("&c/lottery start <year> <month> <day> <hour> <minute>")); + s.sendMessage(Utils.f("&c/lottery end")); + s.sendMessage(Utils.f("&c/lottery time")); + s.sendMessage(Utils.f("&c/lottery tickets balance <player>")); + s.sendMessage(Utils.f("&c/lottery tickets give/take <player> <amount>")); + s.sendMessage(Utils.f("&c/lottery tickets top")); + return true; + } + switch (args[0].toLowerCase()) { + case "sethologram": + if (!user.isRank(UserRank.MANAGER)) { + player.sendMessage(Lang.NOPERM.toString()); + return true; + } + GTM.getLottery().setHologramLocation(player.getLocation()); + s.sendMessage(Lang.LOTTERY.f("&7The hologram has been set at your location.")); + return true; + case "start": + if (!user.isRank(UserRank.MANAGER)) { + player.sendMessage(Lang.NOPERM.toString()); + return true; + } + if (args.length != 6) { + s.sendMessage(Lang.LOTTERY.f("&7Please specify when the lottery should end in the following format: /lottery start <year> <month> <day> <hour> <minute>")); + return true; + } + int year = Integer.parseInt(args[1]); + int month = Integer.parseInt(args[2]); + int day = Integer.parseInt(args[3]); + int hour = Integer.parseInt(args[4]); + int minute = Integer.parseInt(args[5]); + LocalDateTime end = LocalDateTime.of(year, month, day, hour, minute); + GTM.getLottery().setEnd(end); + return true; + case "end": { + if (!user.isRank(UserRank.ADMIN)) { + player.sendMessage(Lang.NOPERM.toString()); + return true; + } + GTM.getLottery().end(); + return true; + } + case "test": { + if (!user.isRank(UserRank.MANAGER)) { + player.sendMessage(Lang.NOPERM.toString()); + return true; + } + Lottery.test(); + return true; + } + case "time": { + if (!user.isRank(UserRank.MANAGER)) { + player.sendMessage(Lang.NOPERM.toString()); + return true; + } + s.sendMessage(Lang.LOTTERY.f("&7Current time: " + LocalDateTime.now(ZoneId.of("UTC")))); + s.sendMessage(Lang.LOTTERY.f("&7Time of end: " + GTM.getLottery().getEnd())); + s.sendMessage(Lang.LOTTERY.f("&7Time until end: " + GTM.getLottery().timeToEnd())); + return true; + } + case "tickets": { + if (args.length == 1) { + s.sendMessage(Utils.f("&7/lottery tickets balance &a<player>")); + s.sendMessage(Utils.f("&7/lottery tickets give/take &a<player> <amount>")); + s.sendMessage(Utils.f("&7/lottery tickets top")); + return true; + } + switch (args[1]) { + case "balance": { + if (args.length != 3) { + s.sendMessage(Utils.f("&7/lottery tickets balance &a<player>")); + return true; + } + String targetName = args[2]; + LotteryPlayer lotteryPlayer = GTM.getLottery().getLotteryPlayer(targetName); + if (lotteryPlayer == null) { + s.sendMessage(Lang.LOTTERY.f("&cThat player has not bought any tickets!")); + return true; + } + int tickets = lotteryPlayer.getTickets(); + s.sendMessage(Lang.LOTTERY.f("&7" + targetName)); + s.sendMessage(Utils.f("&7Tickets: " + tickets)); + return true; + } + case "give": { + if (!user.isRank(UserRank.ADMIN)) { + player.sendMessage(Lang.NOPERM.toString()); + return true; + } + if (args.length != 4) { + s.sendMessage(Utils.f("&7/lottery tickets give &a<player> <amount>")); + return true; + } + String targetName = args[2]; + Integer amount = Integer.valueOf(args[3]); + LotteryPlayer lotteryPlayer = GTM.getLottery().getLotteryPlayer(targetName); + if (lotteryPlayer == null) { + s.sendMessage(Lang.LOTTERY.f("&cPlayer not found")); + return true; + } + lotteryPlayer.setTickets(lotteryPlayer.getTickets() + amount); + s.sendMessage(Lang.LOTTERY.f("&7Tickets of &a" + targetName + " &7set to &a" + lotteryPlayer.getTickets())); + return true; + } + case "take": { + if (args.length != 4) { + s.sendMessage(Utils.f("&7/lottery tickets take &a<player> <amount>")); + return true; + } + String targetName = args[2]; + int amount = Integer.valueOf(args[3]); + LotteryPlayer lotteryPlayer = GTM.getLottery().getLotteryPlayer(targetName); + if (lotteryPlayer == null) { + s.sendMessage(Lang.LOTTERY.f("&cPlayer not found")); + return true; + } + int result = lotteryPlayer.getTickets() - amount; + if (result <= 0) result = 1; + lotteryPlayer.setTickets(result); + s.sendMessage(Lang.LOTTERY.f("&7Tickets of &a" + targetName + " &7set to &a" + result)); + return true; + } + case "top": { + Map<String, Integer> ticketCounts = new HashMap<>(); + GTM.getLottery().getLotteryPlayers().forEach(lotteryPlayer -> { + ticketCounts.put(lotteryPlayer.getName(), lotteryPlayer.getTickets()); + }); + Map<String, Integer> topTickets = GTMUtils.sortByValue(ticketCounts); + Iterator iterator = topTickets.entrySet().iterator(); + int loop = 0; + int i = 1; + while (iterator.hasNext()) { + if (loop > 24) break; + Map.Entry pair = (Map.Entry) iterator.next(); + s.sendMessage(Utils.f("&7#" + i++ + " &a" + pair.getKey() + " &7- " + pair.getValue() + " &7tickets")); + iterator.remove(); + loop += 1; + } + } + } + return true; + } + default: + s.sendMessage(Utils.f("&c/lottery sethologram")); + s.sendMessage(Utils.f("&c/lottery start <year> <month> <day> <hour> <minute>")); + s.sendMessage(Utils.f("&c/lottery end")); + s.sendMessage(Utils.f("&c/lottery time")); + s.sendMessage(Utils.f("&c/lottery tickets balance <player>")); + s.sendMessage(Utils.f("&c/lottery tickets give/take <player> <amount>")); + s.sendMessage(Utils.f("&c/lottery tickets top")); + return true; + } + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/MoneyCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/MoneyCommand.java new file mode 100644 index 0000000..335a445 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/MoneyCommand.java @@ -0,0 +1,485 @@ +package net.grandtheftmc.gtm.commands; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.currency.Currency; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.database.dao.CurrencyDAO; +import net.grandtheftmc.core.users.UserDAO; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.TopValue; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.users.GTMUser; + +public class MoneyCommand implements CommandExecutor { + + /** Only display this many highscores, paginated */ + public static final Integer MAX_HIGHSCORES = 80; + /** Number of results to display per page */ + public static final Integer RESULTS_PER_PAGE = 8; + /** Sorted list of top bank values */ + private List<TopValue> topBank; + /** Sorted list of top money values */ + private List<TopValue> topMoney; + + public MoneyCommand(){ + this.topBank = new ArrayList<>(); + this.topMoney = new ArrayList<>(); + + // run update every 60 minutes + new BukkitRunnable() { + @Override + public void run() { + fetchTopBank(); + fetchTopMoney(); + } + }.runTaskTimerAsynchronously(GTM.getInstance(), 0,20L * (60*60)); + } + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!s.hasPermission("command.money")) { + + if (args.length > 0 && args[0].equalsIgnoreCase("top")){ + // ALLOW + } + else{ + s.sendMessage(Lang.NOPERM.toString()); + return true; + } + } + if (args.length == 0) { + s.sendMessage(Utils.f("&c/money balance <player>")); + s.sendMessage(Utils.f("&c/money give <player> <amount>")); + s.sendMessage(Utils.f("&c/money take <player> <amount>")); + s.sendMessage(Utils.f("&c/money bank <player>")); + s.sendMessage(Utils.f("&c/money givebank <player> <amount>")); + s.sendMessage(Utils.f("&c/money takebank <player> <amount>")); + s.sendMessage(Utils.f("&c/money top <money/bank> [page] - Shows the baltop for cash, bank or combined")); + return true; + } + switch (args[0].toLowerCase()) { + case "balance": { + if (args.length != 2) { + s.sendMessage(Utils.f("&c/money balance <player>")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player == null) { + UUID senderUUID = s instanceof Player ? ((Player) s).getUniqueId() : null; + s.sendMessage(Utils.f("&cThat player isn't online, so please wait while the money is pulled from the database.")); + + ServerUtil.runTaskAsync(() -> { + UUID uuid = UserDAO.getUuidByName(args[1]); + + if (uuid == null) { + ServerUtil.runTask(() -> s.sendMessage(Utils.f("&cThis player wasn't found."))); + return; + } + + int money = 0; + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + + money = CurrencyDAO.getCurrency(connection, Currency.MONEY.getServerKey(), uuid, Currency.MONEY); + } catch (Exception e) { + e.printStackTrace(); + } + + int finalMoney = money; + ServerUtil.runTask(() -> (senderUUID == null ? Bukkit.getConsoleSender() : Bukkit.getPlayer(senderUUID)).sendMessage(Lang.MONEY.f("&a " + args[1] + " has $" + finalMoney))); + }); + + return true; + } + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + s.sendMessage(Utils.f(Lang.MONEY + "&a" + player.getName() + "&7 has &a$&l" + user.getMoney() + "&7!")); + return true; + } + case "give": { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/money give <player>")); + return true; + } + double amnt; + try { + amnt = Double.parseDouble(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f(Lang.MONEY + "&7The amount must be a number!")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player == null) { + s.sendMessage(Utils.f("&cThat player isn't online, so hold on a second while the money is forcibly updated in the database.")); + + ServerUtil.runTaskAsync(() -> { + UUID uuid = UserDAO.getUuidByName(args[1]); + + if (uuid == null) { + ServerUtil.runTask(() -> s.sendMessage(Utils.f("&cThis player wasn't found."))); + return; + } + + try (Connection conn = BaseDatabase.getInstance().getConnection()){ + CurrencyDAO.addCurrency(conn, Currency.MONEY.getServerKey(), uuid, Currency.MONEY, (int) amnt); + } + catch(Exception e){ + e.printStackTrace(); + } + + if (uuid == null) Core.log("Error while logging giveMoneyCommand for uuid " + uuid + ", name " + args[1] + ", amnt " + amnt); + else Utils.insertLog(uuid, args[1], "giveMoneyCommand", "MONEY", "$" + amnt + " Money", amnt, 0); + }); + + return true; + } + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + user.addMoney(amnt); + Core.getUserManager().getLoadedUser(player.getUniqueId()).insertLog(player, "giveMoneyCommand", "MONEY", "$" + amnt + " Money", amnt, 0); + GTMUtils.updateBoard(player, Core.getUserManager().getLoadedUser(player.getUniqueId()), user); + s.sendMessage(Utils.f(Lang.MONEY + "&7You gave &a$&l" + amnt + "&7 to &a" + player.getName() + "&7!")); + player.sendMessage( + Utils.f(Lang.MONEY + "&7You were given &a$&l" + amnt + "&7 by &a" + s.getName() + "&7!")); + return true; + } + case "take": { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/money take <player>")); + return true; + } + double amnt; + try { + amnt = Double.parseDouble(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f(Lang.MONEY + "&7The amount must be a number!")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player == null) { + s.sendMessage(Utils.f("&cThat player isn't online, so hold on a second while the money is forcibly updated in the database.")); + + double finalAmnt1 = amnt; + ServerUtil.runTaskAsync(() -> { + UUID uuid = UserDAO.getUuidByName(args[1]); + + if (uuid == null) { + ServerUtil.runTask(() -> s.sendMessage(Utils.f("&cThis player wasn't found."))); + return; + } + + try (Connection conn = BaseDatabase.getInstance().getConnection()){ + CurrencyDAO.addCurrency(conn, Currency.MONEY.getServerKey(), uuid, Currency.MONEY, (int) -finalAmnt1); + } + catch(Exception e){ + e.printStackTrace(); + } + + if (uuid == null) Core.log("Error while logging takeMoneyCommand for uuid " + uuid + ", name " + args[1] + ", amnt " + -finalAmnt1); + else Utils.insertLog(uuid, args[1], "takeMoneyCommand", "MONEY", "-$" + finalAmnt1 + " Money", -finalAmnt1, 0); + }); + return true; + } + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + if (!user.hasMoney(amnt)) + amnt = user.getMoney(); + user.takeMoney(amnt); + Core.getUserManager().getLoadedUser(player.getUniqueId()).insertLog(player, "takeMoneyCommand", "MONEY", "-$" + amnt + " Money", -amnt, 0); + GTMUtils.updateBoard(player, Core.getUserManager().getLoadedUser(player.getUniqueId()), user); + s.sendMessage(Utils.f(Lang.MONEY + "&7You took &c$&l" + amnt + "&7 from &a" + player.getName() + "&7!")); + player.sendMessage( + Utils.f(Lang.MONEY + "&c$&l" + amnt + "&7 was taken from you by &a" + s.getName() + "&7!")); + return true; + } + case "bank": { + if (args.length != 2) { + s.sendMessage(Utils.f("&c/money balance <player>")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player == null) { + UUID senderUUID = s instanceof Player ? ((Player) s).getUniqueId() : null; + s.sendMessage(Utils.f("&cThat player isn't online, so please wait while the money is pulled from the database.")); + + ServerUtil.runTaskAsync(() -> { + UUID uuid = UserDAO.getUuidByName(args[1]); + String name = null; + int money = 0; + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("select name,bank from " + Core.name() + " where uuid=UNHEX('" + uuid.toString().replaceAll("-", "") + "');")) { + try (ResultSet result = statement.executeQuery()) { + if (result.next()) { + name = result.getString("name"); + money = result.getInt("bank"); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + + String finalName = name; + int finalMoney = money; + ServerUtil.runTask(() -> (senderUUID == null ? Bukkit.getConsoleSender() : Bukkit.getPlayer(senderUUID)).sendMessage(Lang.MONEY.f("&a " + finalName + " has $" + finalMoney + " in the bank"))); + }); + + return true; + } + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + s.sendMessage(Utils.f( + Lang.BANK + "&a" + player.getName() + "&7 has &a$&l" + user.getBank() + "&7 in his bank account!")); + return true; + } + case "givebank": { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/money givebank <player>")); + return true; + } + double amnt; + try { + amnt = Double.parseDouble(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f(Lang.MONEY + "&7The amount must be a number!")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player == null) { + s.sendMessage(Utils.f("&cThat player isn't online, so hold on a second while the bank money is forcibly updated in the database.")); + + ServerUtil.runTaskAsync(() -> { + UUID uuid = UserDAO.getUuidByName(args[1]); + BaseDatabase.runCustomQuery("update " + Core.name() + " set bank=bank+" + amnt + " where uuid=UNHEX('" + uuid.toString().replaceAll("-", "") + "');"); + + if(uuid == null) Core.log("Error while logging giveBankCommand for uuid " + uuid + ", name " + args[1] + ", amnt " + amnt); + else Utils.insertLog(uuid, args[1], "giveBankCommand", "MONEY", "$" + amnt + " Money", amnt, 0); + }); + + return true; + } + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + user.addBank(amnt); + Core.getUserManager().getLoadedUser(player.getUniqueId()).insertLog(player, "giveBankCommand", "MONEY", "$" + amnt + " Money", amnt, 0); + GTMUtils.updateBoard(player, Core.getUserManager().getLoadedUser(player.getUniqueId()), user); + s.sendMessage(Utils + .f(Lang.BANK + "&7You put &a$&l" + amnt + "&7 into &a" + player.getName() + "&7's bank account!")); + player.sendMessage( + Utils.f(Lang.BANK + "&a$&l" + amnt + "&7 was put into your account by &a" + s.getName() + "&7!")); + return true; + } + case "takebank": + if (args.length != 3) { + s.sendMessage(Utils.f("&c/money takebank <player>")); + return true; + } + double amnt; + try { + amnt = Double.parseDouble(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f(Lang.MONEY + "&7The amount must be a number!")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player == null) { + s.sendMessage(Utils.f("&cThat player isn't online, so hold on a second while the bank money is forcibly updated in the database.")); + + double finalAmnt = amnt; + ServerUtil.runTaskAsync(() -> { + UUID uuid = UserDAO.getUuidByName(args[1]); + BaseDatabase.runCustomQuery("update " + Core.name() + " set bank=bank-" + finalAmnt + "' where uuid=UNHEX('" + uuid.toString().replaceAll("-", "") + "');"); + + if(uuid == null) Core.log("Error while logging takeBankCommand for uuid " + uuid + ", name " + args[1] + ", amnt " + -finalAmnt); + else Utils.insertLog(uuid, args[1], "takeBankCommand", "MONEY", "-$" + finalAmnt + " Money", -finalAmnt, 0); + }); + + return true; + } + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + if (!user.hasBank(amnt)) + amnt = user.getBank(); + user.takeBank(amnt); + Core.getUserManager().getLoadedUser(player.getUniqueId()).insertLog(player, "takeBankCommand", "MONEY", "-$" + amnt + " Money", -amnt, 0); + GTMUtils.updateBoard(player, Core.getUserManager().getLoadedUser(player.getUniqueId()), user); + s.sendMessage(Utils + .f(Lang.BANK + "&7You took &c$&l" + amnt + "&7 from &a" + player.getName() + "&7's bank account!")); + player.sendMessage( + Utils.f(Lang.BANK + "&c$&l" + amnt + "&7 was taken from your account by &a" + s.getName() + "&7!")); + return true; + case "top": { + + boolean bank = false; + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + if (args.length < 2 || args.length > 3) { + s.sendMessage(Utils.f("&c/money top <money/bank> [page]")); + return true; + } + + if ("money".equalsIgnoreCase(args[1])) { + s.sendMessage(Lang.MONEY.f("&7Looking up Money Top in database...")); + } else if ("bank".equalsIgnoreCase(args[1])) { + bank = true; + s.sendMessage(Lang.MONEY.f("&7Looking up Bank Top in database...")); + } else { + s.sendMessage(Utils.f("&c/money top <money/bank>")); + return true; + } + + int page = 1; + if (args.length > 2) { + try { + page = Integer.parseInt(args[2]); + } + catch (NumberFormatException ignored) { + + } + } + + int maxPages = MAX_HIGHSCORES / RESULTS_PER_PAGE; + if (page > maxPages){ + page = maxPages; + } + + s.sendMessage(bank ? Lang.BANK.f("&7Bank Top Page &a&l" + page + "&7:") : Lang.MONEY.f("&7Money Top Page &a&l" + page + "&7:")); + + // assign a copy + List<TopValue> leaderboard = topMoney; + if (bank){ + leaderboard = topBank; + } + + // iterate from 0 to results per page + for (int i = 0; i < RESULTS_PER_PAGE; i++){ + + // compute the index that we want to retrieve from the top scores + int topIndex = ((page - 1) * RESULTS_PER_PAGE) + i; + + // examples + // page = 1 + // topIndex = (0 * 5) + 0 = 0 + // topIndex = (0 * 5) + 1 = 1 + // page = 2 + // topIndex = (1 * 5) + 0 = 5 + // topIndex = (1 * 5) + 1 = 6 + + if (topIndex < leaderboard.size()){ + TopValue topValue = leaderboard.get(topIndex); + if (topValue != null){ + s.sendMessage(Utils.f("&a#&l" + (topIndex + 1) + "&7: &r" + topValue.getId() + "&7 &a" + Utils.formatMoney(topValue.getAmount()))); + } + } + } + + if (page != maxPages){ + s.sendMessage(Utils.f("&7Type &a/money top " + (bank ? "bank" : "money") + ' ' + (page + 1) + "&7 for more...")); + } + + return true; + } + + default: + s.sendMessage(Utils.f("&c/money balance <player>")); + s.sendMessage(Utils.f("&c/money give <player> <amount>")); + s.sendMessage(Utils.f("&c/money take <player> <amount>")); + s.sendMessage(Utils.f("&c/money bank <player>")); + s.sendMessage(Utils.f("&c/money givebank <player> <amount>")); + s.sendMessage(Utils.f("&c/money takebank <player> <amount>")); + s.sendMessage(Utils.f("&c/money top <money/bank> [page] - Shows the baltop for cash, bank or combined")); + return true; + } + + } + + /** + * Fetch the top banks in the database, and update fields. + */ + protected void fetchTopBank(){ + + try (Connection connection = BaseDatabase.getInstance().getConnection()){ + + try(PreparedStatement ps = connection.prepareStatement("SELECT name, bank FROM "+Core.name()+" WHERE name != 'ERROR' ORDER BY bank DESC LIMIT ?;")) { + ps.setInt(1, MAX_HIGHSCORES); + + try(ResultSet result = ps.executeQuery()) { + + Map<String, Integer> top = new HashMap<>(); + while(result.next()){ + String name = result.getString("name"); + int balance = (int) result.getDouble("bank"); + + top.put(name, balance); + } + ServerUtil.runTask(() -> { + topBank.clear(); + top.forEach((k, v) -> { + topBank.add(new TopValue(k, v)); + }); + Collections.sort(topBank, Collections.reverseOrder()); + }); + } + } + } + catch (SQLException e) { + e.printStackTrace(); + } + } + + /** + * Fetch the top money in the database, and update fields. + */ + protected void fetchTopMoney(){ + + try (Connection connection = BaseDatabase.getInstance().getConnection()){ + + String query = "SELECT U.name as name, UC.amount AS money FROM user U, user_currency UC WHERE U.uuid=UC.uuid AND server_key=? AND currency=? ORDER BY amount DESC LIMIT ?;"; + + try(PreparedStatement ps = connection.prepareStatement(query)) { + ps.setString(1, Core.name().toUpperCase()); + ps.setString(2, "MONEY"); + ps.setInt(3, MAX_HIGHSCORES); + + try(ResultSet result = ps.executeQuery()) { + + Map<String, Integer> top = new HashMap<>(); + while(result.next()){ + String name = result.getString("name"); + int balance = result.getInt("money"); + + top.put(name, balance); + } + ServerUtil.runTask(() -> { + topMoney.clear(); + top.forEach((k, v) -> { + topMoney.add(new TopValue(k, v)); + }); + + Collections.sort(topMoney, Collections.reverseOrder()); + }); + } + } + } + catch (SQLException e) { + e.printStackTrace(); + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/NearCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/NearCommand.java new file mode 100644 index 0000000..b81f539 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/NearCommand.java @@ -0,0 +1,54 @@ +package net.grandtheftmc.gtm.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.gtm.GTMUtils; +import org.apache.commons.lang.StringUtils; +import org.bukkit.GameMode; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class NearCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.GTM.f("&cYou are not a player!")); + return true; + } + Player player = (Player)s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (!user.isRank(UserRank.VIP)) { + player.sendMessage(Lang.GTM.f("&7You must be &6&lVIP+ &7to use this command!")); + return true; + } + Map<String, Integer> nearbySet = new HashMap<>(); + int range = GTMUtils.getNearRange(user.getUserRank()); + for(Entity entity : player.getNearbyEntities(range, range, range)) { + if(entity.getType() != EntityType.PLAYER) continue; + Player target = (Player)entity; + if(target.getGameMode() != GameMode.ADVENTURE) continue; + int distance = (int)player.getLocation().distance(target.getLocation()); + nearbySet.put(target.getDisplayName(), distance); + } + List<String> nearbyFormatted = nearbySet.keySet().stream().map(set -> set + " &f(&c" + nearbySet.get(set) + "b&f)").collect(Collectors.toList()); + if(nearbyFormatted.isEmpty()) { + player.sendMessage(Lang.GTM.f("&7No nearby players found.")); + } else { + String message = StringUtils.join(nearbyFormatted, ", "); + player.sendMessage(Lang.GTM.f("&7Players nearby:" + message)); + } + return true; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/PayCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/PayCommand.java new file mode 100644 index 0000000..7a7eb73 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/PayCommand.java @@ -0,0 +1,75 @@ +package net.grandtheftmc.gtm.commands; + +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.users.GTMUser; + +public class PayCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.toString()); + return true; + } + if (args.length != 2) { + s.sendMessage(Utils.f("&c/pay <player> <amount>")); + return true; + } + + if (!GTM.getSettings().isPayCommand()){ + s.sendMessage(Utils.f("&cPay is currently disabled!")); + return true; + } + + Player player = (Player) s; + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + double amnt; + try { + amnt = Utils.round(Double.parseDouble(args[1])); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f(Lang.MONEY + "&7The amount must be a number!")); + return true; + } + if (amnt <= 0) { + s.sendMessage(Lang.MONEY.f("&7The amount must be greater than 0!")); + return true; + } + if (!user.hasMoney(amnt)) { + s.sendMessage(Utils.f(Lang.MONEY + "&7You don't have &c$&l" + amnt + "&7!")); + return true; + } + if (amnt % 1 != 0) { + s.sendMessage(Utils.f(Lang.MONEY + "&7Whole numbers only! No pennies.")); + return true; + } + Player target = Bukkit.getPlayer(args[0]); + if (target == null) { + s.sendMessage(Utils.f(Lang.MONEY + "&7That player is not online!")); + return true; + } + GTMUser targetUser = GTM.getUserManager().getLoadedUser(target.getUniqueId()); + User u = Core.getUserManager().getLoadedUser(player.getUniqueId()); + User tu = Core.getUserManager().getLoadedUser(target.getUniqueId()); + user.takeMoney(amnt); + targetUser.addMoney(amnt); + GTMUtils.updateBoard(player, u, user); + GTMUtils.updateBoard(target, tu, targetUser); + player.sendMessage(Utils.f(Lang.MONEY + "&7You sent &a$&l" + amnt + "&7 to " + tu.getColoredName(target) + "&7!")); + target.sendMessage(Utils.f(Lang.MONEY + "&7You received &a$&l" + amnt + "&7 from " + u.getColoredName(player) + "&7!")); + if (amnt > 100000) + GTMUtils.moneylog(player, target, amnt); + return true; + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/PermitsCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/PermitsCommand.java new file mode 100644 index 0000000..813764e --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/PermitsCommand.java @@ -0,0 +1,367 @@ +package net.grandtheftmc.gtm.commands; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.currency.Currency; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.database.dao.CurrencyDAO; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserDAO; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.users.GTMUser; + +public class PermitsCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command cmd, String label, String[] args) { + if (s instanceof Player && !s.hasPermission("command.permits")) { + Player player = (Player) s; + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + player.sendMessage(Utils.f("&aYou have &c" + user.getPermits() + " &apermits")); + return true; + } + if (args.length == 0) { + s.sendMessage(Utils.f("&c/permits <balance> name")); + s.sendMessage(Utils.f("&c/permits <set/give/take> <name> <amnt>")); + return true; + } + switch (args[0].toLowerCase()) { + case "balance": { + if (args.length != 2) { + s.sendMessage(Utils.f("&c/houses permits <balance> name")); + return true; + } + Player player = Bukkit.getPlayerExact(args[1]); + if (player == null) { + UUID senderUUID = s instanceof Player ? ((Player) s).getUniqueId() : null; + s.sendMessage(Utils.f("&cThat player isn't online, so please wait while the permits are pulled from the database.")); + + ServerUtil.runTaskAsync(() -> { + int permits = 0; + + UUID uuid = UserDAO.getUuidByName(args[1]); + if (uuid == null) { + ServerUtil.runTask(() -> s.sendMessage(Utils.f("&cThis player wasn't found."))); + return; + } + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + + permits = CurrencyDAO.getCurrency(connection, Currency.PERMIT.getServerKey(), uuid, Currency.PERMIT); + +// try (PreparedStatement statement = connection.prepareStatement("SELECT permits FROM " + Core.name() + " WHERE uuid=?;")) { +// statement.setString(1, uuid.toString()); +// try (ResultSet result = statement.executeQuery()) { +// if (result.next()) { +// permits = result.getInt("permits"); +// } +// } +// } + } catch (SQLException e) { + e.printStackTrace(); + } + + int finalPermits = permits; + ServerUtil.runTask(() -> { + if (senderUUID == null) { + Bukkit.getConsoleSender().sendMessage(args[1] + " has " + finalPermits + " Permits."); + } else { + Bukkit.getPlayer(senderUUID).sendMessage(Utils.f("&a " + args[1] + " has " + finalPermits + " Permits.")); + } + }); + }); + +// new BukkitRunnable() { +// @Override +// public void run() { +// ResultSet rs = Core.getSQL().query("select name,permits from " + Core.name() + " where name='" + args[1] + "';"); +// String name = null; +// int permits = 0; +// try { +// if (rs.next()) { +// name = rs.getString("name"); +// permits = rs.getInt("permits"); +// rs.close(); +// } else { +// rs.close(); +// return; +// } +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// String finalName = name; +// int finalPermits = permits; +// new BukkitRunnable() { +// @Override +// public void run() { +// (senderUUID == null ? Bukkit.getConsoleSender() : Bukkit.getPlayer(senderUUID)).sendMessage(Utils.f("&a " + finalName + " has " + finalPermits + " Permits.")); +// } +// }.runTask(GTM.getInstance()); +// } +// }.runTaskAsynchronously(GTM.getInstance()); + return true; + } + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + s.sendMessage(Utils.f("&a" + player.getName() + " has " + user.getPermits() + " Permits.")); + return true; + } + case "set": { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/permits <set/give/take> <name> <amnt>")); + return true; + } + int amnt; + try { + amnt = Integer.parseInt(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f("&cThe amount must be a number!")); + return true; + } + if (amnt < 0) { + s.sendMessage(Utils.f("&cThe amount must be bigger than 0!")); + return true; + } + Player player = Bukkit.getPlayerExact(args[1]); + if (player == null) { + s.sendMessage(Utils.f("&cThat player isn't online, so hold on a second while the permits are forcibly updated in the database.")); + + ServerUtil.runTaskAsync(() -> { + UUID uuid = UserDAO.getUuidByName(args[1]); + if (uuid == null) { + ServerUtil.runTask(() -> s.sendMessage(Utils.f("&cThis player wasn't found."))); + return; + } + + try (Connection conn = BaseDatabase.getInstance().getConnection()){ + CurrencyDAO.saveCurrency(conn, Currency.PERMIT.getServerKey(), uuid, Currency.PERMIT, amnt); + } + catch(Exception e){ + e.printStackTrace(); + } + + //BaseDatabase.runCustomQuery("update " + Core.name() + " set permits=" + amnt + " where uuid='" + uuid.toString() + "';"); + Utils.insertLog(uuid, args[1], "setPermitsCommand", "PERMITS", amnt + " Permits", amnt, 0); + }); + +// Core.getSQL().updateAsyncLater("update " + Core.name() + " set permits=" + amnt + " where name='" + args[1] + "';"); +// new BukkitRunnable() { +// @Override +// public void run() { +// ResultSet rs = Core.getSQL().query("select uuid,lastname from users where lastname='" + args[1] + "';"); +// UUID uuid = null; +// String name = args[1]; +// try { +// if (rs.next()) { +// uuid = UUID.fromString(rs.getString("uuid")); +// name = rs.getString("lastname"); +// } +// rs.close(); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// if (uuid == null) { +// Core.log("Error while logging setPermitsCommand for uuid " + uuid + ", name " + name + ", amnt " + amnt); +// } else +// Utils.insertLog(uuid, name, "setPermitsCommand", "PERMITS", amnt + " Permits", amnt, 0); +// +// } +// }.runTaskAsynchronously(Core.getInstance()); + return true; + } + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + user.setPermits(amnt); + User u = Core.getUserManager().getLoadedUser(player.getUniqueId()); + u.insertLog(player, "setPermitsCommand", "PERMITS", amnt + " Permits", amnt, 0); + s.sendMessage(Utils.f("&a" + player.getName() + " now has " + user.getPermits() + " permits!")); + return true; + } + case "give": { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/houses permits <set/give/take> <name> <amnt>")); + return true; + } + int amnt; + try { + amnt = Integer.parseInt(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f("&cThe amount must be a number!")); + return true; + } + if (amnt < 0) { + s.sendMessage(Utils.f("&cThe amount must be bigger than 0!")); + return true; + } + Player player = Bukkit.getPlayerExact(args[1]); + if (player == null) { + s.sendMessage(Utils.f("&cThat player isn't online, so hold on a second while the permits are forcibly updated in the database.")); + + ServerUtil.runTaskAsync(() -> { + UUID uuid = UserDAO.getUuidByName(args[1]); + if (uuid == null) { + ServerUtil.runTask(() -> s.sendMessage(Utils.f("&cThis player wasn't found."))); + return; + } + + try (Connection conn = BaseDatabase.getInstance().getConnection()){ + CurrencyDAO.addCurrency(conn, Currency.PERMIT.getServerKey(), uuid, Currency.PERMIT, amnt); + } + catch(Exception e){ + e.printStackTrace(); + } + +// BaseDatabase.runCustomQuery("update " + Core.name() + " set permits=permits+" + amnt + " where uuid='" + uuid.toString() + "';"); + +// UUID uuid = null; +// String name = args[1]; +// +// try (Connection connection = BaseDatabase.getInstance().getConnection()) { +// try (PreparedStatement statement = connection.prepareStatement("select uuid,lastname from users where lastname='" + args[1] + "';")) { +// try (ResultSet result = statement.executeQuery()) { +// if (result.next()) { +// uuid = UUID.fromString(result.getString("uuid")); +// name = result.getString("lastname"); +// } +// } +// } +// } catch (SQLException e) { +// e.printStackTrace(); +// } + + Utils.insertLog(uuid, args[1], "givePermitsCommand", "PERMITS", amnt + " Permits", amnt, 0); + }); + +// Core.getSQL().updateAsyncLater("update " + Core.name() + " set permits=permits+" + amnt + " where name='" + args[1] + "';"); +// new BukkitRunnable() { +// @Override +// public void run() { +// ResultSet rs = Core.getSQL().query("select uuid,lastname from users where lastname='" + args[1] + "';"); +// UUID uuid = null; +// String name = args[1]; +// try { +// if (rs.next()) { +// uuid = UUID.fromString(rs.getString("uuid")); +// name = rs.getString("lastname"); +// } +// rs.close(); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// if (uuid == null) { +// Core.log("Error while logging givePermitsCommand for uuid " + uuid + ", name " + name + ", amnt " + amnt); +// } else +// Utils.insertLog(uuid, name, "givePermitsCommand", "PERMITS", amnt + " Permits", amnt, 0); +// +// } +// }.runTaskAsynchronously(Core.getInstance()); + return true; + } + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + user.addPermits(amnt); + User u = Core.getUserManager().getLoadedUser(player.getUniqueId()); + u.insertLog(player, "givePermitsCommand", "PERMITS", amnt + " Permits", amnt, 0); + s.sendMessage(Utils.f("&a" + player.getName() + " now has " + user.getPermits() + " permits!")); + + return true; + } + case "take": + if (args.length != 3) { + s.sendMessage(Utils.f("&c/houses permits <set/give/take> <name> <amnt>")); + return true; + } + int amnt; + try { + amnt = Integer.parseInt(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f("&cThe amount must be a number!")); + return true; + } + if (amnt < 0) { + s.sendMessage(Utils.f("&cThe amount must be bigger than 0!")); + return true; + } + Player player = Bukkit.getPlayerExact(args[1]); + if (player == null) { + s.sendMessage(Utils.f("&cThat player isn't online, so hold on a second while the permits are forcibly updated in the database.")); + + ServerUtil.runTaskAsync(() -> { + UUID uuid = UserDAO.getUuidByName(args[1]); + if (uuid == null) { + ServerUtil.runTask(() -> s.sendMessage(Utils.f("&cThis player wasn't found."))); + return; + } + + try (Connection conn = BaseDatabase.getInstance().getConnection()){ + CurrencyDAO.addCurrency(conn, Currency.PERMIT.getServerKey(), uuid, Currency.PERMIT, -1 * amnt); + } + catch(Exception e){ + e.printStackTrace(); + } + +// BaseDatabase.runCustomQuery("update " + Core.name() + " set permits=permits-" + amnt + " where uuid='" + uuid.toString() + "';"); + +// UUID uuid = null; +// String name = args[1]; +// +// try (Connection connection = BaseDatabase.getInstance().getConnection()) { +// try (PreparedStatement statement = connection.prepareStatement("select uuid,lastname from users where lastname='" + args[1] + "';")) { +// try (ResultSet result = statement.executeQuery()) { +// if (result.next()) { +// uuid = UUID.fromString(result.getString("uuid")); +// name = result.getString("lastname"); +// } +// } +// } +// } catch (SQLException e) { +// e.printStackTrace(); +// } + + Utils.insertLog(uuid, args[1], "takePermitsCommand", "PERMITS", -amnt + " Permits", -amnt, 0); + }); + +// Core.getSQL().updateAsyncLater("update " + Core.name() + " set permits=permits-" + amnt + " where name='" + args[1] + "';"); +// new BukkitRunnable() { +// @Override +// public void run() { +// ResultSet rs = Core.getSQL().query("select uuid,lastname from users where lastname='" + args[1] + "';"); +// UUID uuid = null; +// String name = args[1]; +// try { +// if (rs.next()) { +// uuid = UUID.fromString(rs.getString("uuid")); +// name = rs.getString("lastname"); +// } +// rs.close(); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// if (uuid == null) { +// Core.log("Error while logging takePermitsCommand for uuid " + uuid + ", name " + name + ", amnt " + -amnt); +// } else +// Utils.insertLog(uuid, name, "takePermitsCommand", "PERMITS", -amnt + " Permits", -amnt, 0); +// +// } +// }.runTaskAsynchronously(Core.getInstance()); + return true; + } + + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + user.takePermits(amnt); + User u = Core.getUserManager().getLoadedUser(player.getUniqueId()); + u.insertLog(player, "takePermitsCommand", "PERMITS", amnt + " Permits", -amnt, 0); + s.sendMessage(Utils.f("&a" + player.getName() + " now has " + user.getPermits() + " permits!")); + return true; + } + return true; + } +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/PickerCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/PickerCommand.java new file mode 100644 index 0000000..5a4b6dc --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/PickerCommand.java @@ -0,0 +1,206 @@ +package net.grandtheftmc.gtm.commands; + +import com.j0ach1mmall3.jlib.inventory.JLibItem; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.items.Kit; +import net.grandtheftmc.gtm.users.JobMode; +import org.bukkit.Color; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; + +public class PickerCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (!s.hasPermission("picker.use")) { + s.sendMessage(Lang.NOPERM.toString()); + return true; + } + if (!(s instanceof Player)) { + s.sendMessage(Utils.f(Lang.GTM + "&cYou are not a player!")); + return true; + } + Player player = (Player) s; + if (args.length == 0) { + s.sendMessage(Utils.f("&c/picker mode <jobMode>")); + s.sendMessage(Utils.f("&c/picker mechanic")); + s.sendMessage(Utils.f("&c/picker cabdriver")); + s.sendMessage(Utils.f("&c/picker warden")); + s.sendMessage(Utils.f("&c/picker heads")); + s.sendMessage(Utils.f("&c/picker dealer")); + s.sendMessage(Utils.f("&c/picker weapondealer")); + s.sendMessage(Utils.f("&c/picker coinvendor")); + + + return true; + } + switch (args[0].toLowerCase()) { + case "coinvendor": { + ArmorStand armorStand = (ArmorStand) player.getWorld().spawnEntity(player.getLocation(), EntityType.ARMOR_STAND); + armorStand.setHelmet(new JLibItem.Builder().withType(Material.LEATHER_HELMET).withColor(Color.YELLOW).build().getItemStack()); + armorStand.setLeggings(GTM.getItemManager().getItem("pants").getItem()); + armorStand.setCustomName(Utils.f("&e&lCoin Vendor")); + armorStand.setCustomNameVisible(true); + armorStand.setAI(false); + armorStand.setCollidable(false); + armorStand.setCanPickupItems(true); + armorStand.setGravity(false); + armorStand.setRemoveWhenFarAway(false); + armorStand.setBasePlate(false); + armorStand.setArms(true); + s.sendMessage(Lang.CASINO.f("&7You created a coin vendor!")); + return true; + } + case "weapondealer": { + ArmorStand armorStand = (ArmorStand) player.getWorld().spawnEntity(player.getLocation(), EntityType.ARMOR_STAND); + armorStand.setHelmet(new JLibItem.Builder().withType(Material.LEATHER_HELMET).withColor(Color.BLACK).build().getItemStack()); + armorStand.setChestplate(GTM.getItemManager().getItem("ceramicvest").getItem()); + armorStand.setLeggings(GTM.getItemManager().getItem("pants").getItem()); + armorStand.setBoots(GTM.getItemManager().getItem("nikes").getItem()); + armorStand.setItemInHand(GTM.getItemManager().getItem("chainsaw").getItem()); + armorStand.setCustomName(Utils.f("&e&lArms Dealer")); + armorStand.setCustomNameVisible(true); + armorStand.setAI(false); + armorStand.setCollidable(false); + armorStand.setCanPickupItems(true); + armorStand.setGravity(false); + armorStand.setRemoveWhenFarAway(false); + armorStand.setBasePlate(false); + armorStand.setArms(true); + s.sendMessage(Lang.HEAD_AUCTION.f("&7You created an Arms Dealer!")); + return true; + } + case "heads": { + ArmorStand armorStand = (ArmorStand) player.getWorld().spawnEntity(player.getLocation(), + EntityType.ARMOR_STAND); + armorStand.setHelmet(new JLibItem.Builder().withType(Material.LEATHER_HELMET).withColor(Color.GREEN).build().getItemStack()); + armorStand.setChestplate(GTM.getItemManager().getItem("kevlarvest").getItem()); + armorStand.setLeggings(GTM.getItemManager().getItem("pants").getItem()); + armorStand.setBoots(GTM.getItemManager().getItem("nikes").getItem()); + armorStand.setItemInHand(new JLibItem.Builder().withType(Material.SKULL_ITEM).withDurability((short) 3).withOwner("Samuri629").build().getItemStack()); + armorStand.setCustomName(Utils.f("&e&lHead Salesman")); + armorStand.setCustomNameVisible(true); + armorStand.setAI(false); + armorStand.setCollidable(false); + armorStand.setCanPickupItems(true); + armorStand.setGravity(false); + armorStand.setRemoveWhenFarAway(false); + armorStand.setBasePlate(false); + armorStand.setArms(true); + s.sendMessage(Lang.HEAD_AUCTION.f("&7You created a Head Salesman!")); + return true; + } + case "mode": { + JobMode mode = JobMode.getModeOrNull(args[1]); + if (mode == null) { + s.sendMessage(Lang.JOBS.f("&7That Job Mode does not exist!")); + return true; + } + Kit kit = GTM.getItemManager().getKit(mode.getName()); + if (kit == null) { + s.sendMessage(Lang.KITS.f("&7That Kit does not exist!")); + return true; + } + ArmorStand armorStand = (ArmorStand) player.getWorld().spawnEntity(player.getLocation(), + EntityType.ARMOR_STAND); + if (kit.getHelmet() != null) + armorStand.setHelmet(kit.getHelmet().getItem().getItem()); + if (kit.getChestPlate() != null) + armorStand.setChestplate(kit.getChestPlate().getItem().getItem()); + if (kit.getLeggings() != null) + armorStand.setLeggings(kit.getLeggings().getItem().getItem()); + if (kit.getBoots() != null) + armorStand.setBoots(kit.getBoots().getItem().getItem()); + if (kit.getOffHand() != null) + armorStand.setItemInHand(kit.getOffHand().getItem().getItem()); + armorStand.setCustomName(mode.getColoredNameBold()); + armorStand.setCustomNameVisible(true); + armorStand.setAI(false); + armorStand.setCollidable(false); + armorStand.setCanPickupItems(true); + armorStand.setGravity(false); + armorStand.setRemoveWhenFarAway(false); + armorStand.setBasePlate(false); + armorStand.setArms(true); + s.sendMessage(Lang.KITS.f("&7You created a Mode Picker for Job Mode " + mode.getColoredNameBold() + + "&7!")); + return true; + } + case "mechanic": { + ArmorStand armorStand = (ArmorStand) player.getWorld().spawnEntity(player.getLocation(), + EntityType.ARMOR_STAND); + armorStand.setHelmet(new JLibItem.Builder().withType(Material.LEATHER_HELMET).withColor(Color.fromRGB(165, 42, 42)).build().getItemStack()); + armorStand.setChestplate(GTM.getItemManager().getItem("shirt").getItem()); + armorStand.setLeggings(GTM.getItemManager().getItem("pants").getItem()); + armorStand.setBoots(GTM.getItemManager().getItem("nikes").getItem()); + armorStand.setItemInHand(new ItemStack(Material.WORKBENCH)); + armorStand.setCustomName(Utils.f("&4&lMechanic")); + armorStand.setCustomNameVisible(true); + armorStand.setAI(false); + armorStand.setCollidable(false); + armorStand.setCanPickupItems(true); + armorStand.setGravity(false); + armorStand.setRemoveWhenFarAway(false); + armorStand.setBasePlate(false); + armorStand.setArms(true); + s.sendMessage(Lang.VEHICLES.f("&7You created a Mechanic!")); + return true; + } + case "cabdriver": { + ArmorStand armorStand = (ArmorStand) player.getWorld().spawnEntity(player.getLocation(), + EntityType.ARMOR_STAND); + armorStand.setHelmet(new JLibItem.Builder().withType(Material.LEATHER_HELMET).withColor(Color.YELLOW).build().getItemStack()); + armorStand.setChestplate(GTM.getItemManager().getItem("shirt").getItem()); + armorStand.setLeggings(GTM.getItemManager().getItem("pants").getItem()); + armorStand.setBoots(GTM.getItemManager().getItem("nikes").getItem()); + armorStand.setItemInHand(new ItemStack(Material.WATCH)); + armorStand.setCustomName(Utils.f("&e&lCab Driver")); + armorStand.setCustomNameVisible(true); + armorStand.setAI(false); + armorStand.setCollidable(false); + armorStand.setCanPickupItems(true); + armorStand.setGravity(false); + armorStand.setRemoveWhenFarAway(false); + armorStand.setBasePlate(false); + armorStand.setArms(true); + s.sendMessage(Lang.VEHICLES.f("&7You created a Cab Driver!")); + return true; + } + case "warden": + ArmorStand armorStand = (ArmorStand) player.getWorld().spawnEntity(player.getLocation(), + EntityType.ARMOR_STAND); + armorStand.setHelmet(new JLibItem.Builder().withType(Material.LEATHER_HELMET).withColor(Color.BLACK).build().getItemStack()); + armorStand.setChestplate(GTM.getItemManager().getItem("kevlarvest").getItem()); + armorStand.setLeggings(GTM.getItemManager().getItem("pants").getItem()); + armorStand.setBoots(GTM.getItemManager().getItem("nikes").getItem()); + armorStand.setItemInHand(GTM.getItemManager().getItem("nightstick").getItem()); + armorStand.setCustomName(Utils.f("&c&lWarden")); + armorStand.setCustomNameVisible(true); + armorStand.setAI(false); + armorStand.setCollidable(false); + armorStand.setCanPickupItems(true); + armorStand.setGravity(false); + armorStand.setRemoveWhenFarAway(false); + armorStand.setBasePlate(false); + armorStand.setArms(true); + s.sendMessage(Lang.VEHICLES.f("&7You created a Warden!")); + return true; + default: + s.sendMessage(Utils.f("&c/picker mode <jobMode>")); + s.sendMessage(Utils.f("&c/picker mechanic")); + s.sendMessage(Utils.f("&c/picker cabdriver")); + s.sendMessage(Utils.f("&c/picker warden")); + s.sendMessage(Utils.f("&c/picker dealer")); + return true; + } + } +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/RankupCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/RankupCommand.java new file mode 100644 index 0000000..43a5217 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/RankupCommand.java @@ -0,0 +1,50 @@ +package net.grandtheftmc.gtm.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.users.GTMRank; +import net.grandtheftmc.gtm.users.GTMUser; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class RankupCommand implements CommandExecutor { + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.toString()); + return true; + } + Player player = (Player) s; + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + User u = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (user.isArrested()) { + player.sendMessage(Lang.JAIL.f("&7You can't rank up in jail!")); + return true; + } + if (args.length == 1 && "confirm".equalsIgnoreCase(args[0])) { + user.rankup(player, u); + return true; + } + GTMRank nextRank = user.getRank().getNext(); + if (nextRank == null) { + player.sendMessage(Utils.f(Lang.RANKUP + "&7You can't rank up any more!")); + return true; + } + int price = nextRank.getPrice(); + + if (!user.hasMoney(price)) { + player.sendMessage(Utils.f(Lang.RANKUP + "&7You don't have the &c$&l" + price + "&7 required to rank up!")); + return true; + } + player.sendMessage(Utils.f(Lang.RANKUP + "&7Ranking up to " + nextRank.getColoredNameBold() + "&7 costs &a$&l" + price + "&7.")); + player.sendMessage(Utils.f(Lang.RANKUP + "&7Type &a/rankup confirm&7 to rank up!")); + return true; + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/ResetCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/ResetCommand.java new file mode 100644 index 0000000..97e7953 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/ResetCommand.java @@ -0,0 +1,280 @@ +package net.grandtheftmc.gtm.commands; + +import java.io.File; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.j0ach1mmall3.wastedvehicles.api.VehicleProperties; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.users.UserDAO; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.gang.Gang; +import net.grandtheftmc.gtm.gang.GangManager; +import net.grandtheftmc.gtm.items.AmmoType; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.houses.PremiumHouse; + +public class ResetCommand implements CommandExecutor { + + + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (!s.isOp()) { + s.sendMessage(Lang.NOPERM.s()); + return true; + } + if (args.length < 2) { + s.sendMessage(Utils.f("&c/reset&7 [player] [category/all] <server>")); + s.sendMessage(Utils.f("&7Categories: tokens, bucks, votes, dailyStreak," + + " lastDonorReward, cosmetics, rank (GTMRank), money, bank, killCounter, permits," + + " jobMode, backpack, kitExpiries, houses, premiumHouses, gang, jail, ammo, vehicles, inventory (includes echest), eventTag")); + return true; + } + if (args.length > 3) { + return true; + } + String name = args[0]; + Player target = Bukkit.getPlayer(name); + UUID uuid = null; + if (target != null) { + name = target.getName(); + uuid = target.getUniqueId(); + target.kickPlayer("You are being reset by an admin."); + } + String server = Core.name(); + if (args.length == 3) { + if (Core.getServerManager().getServer(args[2]) != null) { + server = args[2]; + } + } + + String finalName = name; + UUID finalUniqueId = uuid; + String finalServer = server; + + if ("all".equalsIgnoreCase(args[1])) { + ServerUtil.runTaskAsync(() -> { + UUID value = UserDAO.getUuidByName(finalName); + + try { + File file = new File(Bukkit.getWorldContainer() + "/" + Bukkit.getWorlds().get(0).getName() + "/playerdata/" + value.toString()); + if (file.exists()) file.delete(); + } catch (Exception e) { + e.printStackTrace(); + } + BaseDatabase.runCustomQuery("delete from user_tag where uuid=UNHEX('" + value.toString().replaceAll("-", "") + "');"); + + BaseDatabase.runCustomQuery("update users set tokens=0, bucks=0, votes=0, voteStreak=0, lastVoteStreak=0, dailyStreak=0, lastDailyReward=0, lastDonorReward=0 where uuid='" + value.toString() + "';"); +// BaseDatabase.runCustomQuery("delete from cosmetics where uuid='" + value.toString() + "';"); NOT NEEDED. + BaseDatabase.runCustomQuery("delete from " + finalServer + " where uuid=UNHEX('" + value.toString().replaceAll("-", "") + "');"); +// BaseDatabase.runCustomQuery("delete from " + finalServer + "_gangs where leaderName='" + finalName + "';"); TODO DELETE GANG +// BaseDatabase.runCustomQuery("delete from " + finalServer + "_houses where uuid='" + finalName + "';"); TODO DELETE HOUSE + BaseDatabase.runCustomQuery("update " + finalServer + " set backpackContents=NULL where uuid=UNHEX('" + value.toString().replaceAll("-", "") + "');"); + + ServerUtil.runTask(() -> { + for (PremiumHouse house : Houses.getHousesManager().getPremiumHouses()) { + if (house.getOwner() != null && house.getOwnerName().equalsIgnoreCase(finalName)) { + house.removeOwner(true); + } + } + + for (Gang gang : GangManager.getInstance().getGangs()) { + if (gang.getOwnerName() != null && gang.getOwnerName().equalsIgnoreCase(finalName)) { +// gang.disbandConfirm(); TODO FORCE DELETE. + } + } + + s.sendMessage(Utils.f("&7You fully reset player &a" + finalName + "&7!")); + }); + }); + return true; + } + + switch (args[1].toLowerCase()) { + case "eventtag": { + ServerUtil.runTaskAsync(() -> { + UUID value = UserDAO.getUuidByName(finalName); + BaseDatabase.runCustomQuery("delete from user_tag where uuid=UNHEX('" + value.toString().replaceAll("-", "") + "');"); + }); + s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + } + case "inventory": + ServerUtil.runTaskAsync(() -> { + if (finalUniqueId == null) { + UUID value = UserDAO.getUuidByName(finalName); + if (value != null) { + File file = new File(Bukkit.getWorldContainer() + "/" + Bukkit.getWorlds().get(0).getName() + "/playerdata/" + value.toString()); + if (file.exists()) file.delete(); + } + } + else { + File file = new File(Bukkit.getWorldContainer() + "/" + Bukkit.getWorlds().get(0).getName() + "/playerdata/" + finalUniqueId.toString()); + if (file.exists()) file.delete(); + } + }); + s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + case "tokens": +// Core.sql.updateAsyncLater("update users set tokens=0 where lastname='" + name + "';"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update users set tokens=0 where lastname='" + finalName + "';")); + s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + case "bucks": +// Core.sql.updateAsyncLater("update users set bucks=0 where lastname='" + name + "';"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update users set bucks=0 where lastname='" + finalName + "';")); + s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + case "votes": +// Core.sql.updateAsyncLater("update users set votes=0, voteStreak=0, lastVoteStreak=0 where lastname='" + name + "';"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update users set votes=0, voteStreak=0, lastVoteStreak=0 where lastname='" + finalName + "';")); + s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + case "dailystreak": +// Core.sql.updateAsyncLater("update users set dailyStreak=0, lastDailyReward=0 where lastname='" + name + "';"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update users set dailyStreak=0, lastDailyReward=0 where lastname='" + finalName + "';")); + s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + case "lastdonorreward": +// Core.sql.updateAsyncLater("update users set lastDonorReward=0 where lastname='" + name + "';"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update users set lastDonorReward=0 where lastname='" + finalName + "';")); + s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + case "cosmetics": +// Core.sql.updateAsyncLater("delete from cosmetics where name='" + name + "';"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("delete from cosmetics where name='" + finalName + "';")); + s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + case "rank": +// Core.sql.updateAsyncLater("update " + server + " set rank='HOBO' where name='" + name + "';"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + finalServer + " set rank='HOBO' where name='" + finalName + "';")); + s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + case "money": +// Core.sql.updateAsyncLater("update " + server + " set money=0 where name='" + name + "';"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + finalServer + " set money=0 where name='" + finalName + "';")); + s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + case "bank": +// Core.sql.updateAsyncLater("update " + server + " set bank=0 where name='" + name + "';"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + finalServer + " set bank=0 where name='" + finalName + "';")); + s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + case "killCounter": +// Core.sql.updateAsyncLater("update " + server + " set killCounter=0 where name='" + name + "';"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + finalServer + " set killCounter=0 where name='" + finalName + "';")); + s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + case "permits": +// Core.sql.updateAsyncLater("update " + server + " set permits=0 where name='" + name + "';"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + finalServer + " set permits=0 where name='" + finalName + "';")); + s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + case "jobmode": +// Core.sql.updateAsyncLater("update " + server + " set jobMode='CRIMINAL', lastJobMode=0 where name='" + name + "';"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + finalServer + " set jobMode='CRIMINAL', lastJobMode=0 where name='" + finalName + "';")); + s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + case "backpack": +// Core.sql.updateAsyncLater("update " + server + " set backpackContents=NULL where name='" + name + "';"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + finalServer + " set backpackContents=NULL where name='" + finalName + "';")); + s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + case "kitexpiries": +// Core.sql.updateAsyncLater("update " + server + " set kitExpiries=null where name='" + name + "';"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + finalServer + " set kitExpiries=null where name='" + finalName + "';")); + s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + case "houses": +// Core.sql.updateAsyncLater("delete from " + server + " where name='" + name + "';"); +// Core.sql.updateAsyncLater("delete from " + server + "_houses where name='" + name + "';"); + ServerUtil.runTaskAsync(() -> { + BaseDatabase.runCustomQuery("delete from " + finalServer + " where name='" + finalName + "';"); + BaseDatabase.runCustomQuery("delete from " + finalServer + "_houses where name='" + finalName + "';"); + + UUID id = finalUniqueId == null ? UserDAO.getUuidByName(finalName) : finalUniqueId; + if(id != null) BaseDatabase.runCustomQuery("delete from " + finalServer + "_houses_chests where uuid='" + id + "';"); + }); +// if (uuid == null) { +// String finalName = name; +// new BukkitRunnable() { +// @Override +// public void run() { +// ResultSet rs = Core.sql.query("select uuid from users where lastname='" + finalName + "';"); +// UUID uuid = null; +// try { +// if (rs.next()) { +// uuid = UUID.fromString(rs.getString("uuid")); +// rs.close(); +// return; +// } +// rs.close(); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// } +// }.runTaskAsynchronously(GTM.getInstance()); +// } else { +// Core.sql.updateAsyncLater("delete from " + server + "_houses_chests where uuid='" + uuid + "';"); +// } + s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + case "premiumhouses": + for (PremiumHouse house : Houses.getHousesManager().getPremiumHouses()) + if (house.getOwner() != null && house.getOwnerName().equalsIgnoreCase(name)) + house.removeOwner(true); + return true; + case "gang": +// Core.sql.updateAsyncLater("update " + server + " set gang=null, gangRank='member' where name='" + name + "';"); +// Core.sql.updateAsyncLater("delete from " + server + "_gangs where leaderName='" + name + "';"); + ServerUtil.runTaskAsync(() -> { + BaseDatabase.runCustomQuery("update " + finalServer + " set gang=null, gangRank='member' where name='" + finalName + "';"); + BaseDatabase.runCustomQuery("delete from " + finalServer + "_gangs where leaderName='" + finalName + "';"); + }); + s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + case "jail": +// Core.sql.updateAsyncLater("update " + server + " set jailTimer=-1, jailCop=NULL, jailCopName=NULL where name='" + name + "';"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + finalServer + " set jailTimer=-1, jailCop=NULL, jailCopName=NULL where name='" + finalName + "';")); + s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + case "ammo": { + String st = ""; + for (AmmoType type : AmmoType.values()) + st += type.getGameItemName() + "=0, "; + if (st.endsWith(", ")) + st = st.substring(0, st.length() - 2); +// Core.sql.updateAsyncLater("update " + server + " set " + st + " where name='" + name + "';"); + String finalSt = st; + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + finalServer + " set " + finalSt + " where name='" + finalName + "';")); + s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + } + case "vehicles": + String st = "personalVehicle=NULL, "; + for (VehicleProperties v : GTM.getWastedVehicles().getBabies().getVehicleProperties()) + st += '`' + v.getIdentifier().toLowerCase() + "`=0, `" + v.getIdentifier().toLowerCase() + ":info`=NULL, "; +// Core.sql.updateAsyncLater("update " + server + " set " + st + " where name='" + name + "';"); + String finalSt = st; + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + finalServer + " set " + finalSt + " where name='" + finalName + "';")); + s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + default: + s.sendMessage(Utils.f("&c/reset&7 [player] [category/all] <server>")); + s.sendMessage(Utils.f("&7Categories: tokens, bucks, votes, dailyStreak," + + " lastDonorReward, rank (GTMRank), money, bank, killCounter, permits, jobMode, backpack, kitExpiries, houses, gang, jail, ammo, vehicles")); + return true; + } + + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/ResourcePackCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/ResourcePackCommand.java new file mode 100644 index 0000000..e4dcea6 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/ResourcePackCommand.java @@ -0,0 +1,46 @@ +package net.grandtheftmc.gtm.commands; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.NMSVersion; +import net.grandtheftmc.gtm.GTM; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import us.myles.ViaVersion.api.Via; + +public class ResourcePackCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.GTM.f("&cYou are not a player!")); + return true; + } + Player player = (Player) s; + NMSVersion version = NMSVersion.getVersion(player); + if(version== NMSVersion.MC_1_8) { + player.sendMessage(Lang.GTM.f("&4Your client version is not supported! Please use 1.9+")); + return false; + } + String url; +// if (version==NMSVersion.MC_1_12_1 || version == NMSVersion.MC_1_11_2 || version == NMSVersion.MC_1_12 || version == NMSVersion.MC_1_11) { +// player.setResourcePack(GTM.getSettings().getOneElevenRespack()); +// url = GTM.getSettings().getOneElevenRespack(); +// } else { +// player.setResourcePack(GTM.getSettings().getOneTenRespack()); +// url = GTM.getSettings().getOneTenRespack(); +// } + + if (version.getProtocol() >= NMSVersion.MC_1_11.getProtocol()) { + player.setResourcePack(GTM.getSettings().getOneElevenRespack()); + url = GTM.getSettings().getOneElevenRespack(); + } else { + player.setResourcePack(GTM.getSettings().getOneTenRespack()); + url = GTM.getSettings().getOneTenRespack(); + } + + player.sendMessage(Lang.GTM.f("&cYou can download the server resource pack here: &b" + url)); + return true; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/SellCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/SellCommand.java new file mode 100644 index 0000000..c3f7fa2 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/SellCommand.java @@ -0,0 +1,48 @@ +package net.grandtheftmc.gtm.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.commands.CoreCommand; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.State; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.trashcan.TrashCanManager; +import net.grandtheftmc.gtm.users.CheatCode; +import net.grandtheftmc.gtm.users.CheatCodeState; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.users.HouseUser; +import org.bukkit.entity.Player; + +public class SellCommand extends CoreCommand<Player> { + + public SellCommand() { + super("sell", "Quick sell, open a virtual trashcan", "qsell", "quicksell"); + } + + @Override + public void execute(Player sender, String[] strings) { + sender.closeInventory(); + User user = Core.getUserManager().getLoadedUser(sender.getUniqueId()); + GTMUser gtmUser = GTM.getUserManager().getLoadedUser(sender.getUniqueId()); + if (gtmUser.getCheatCodeState(CheatCode.QUICKSELL).getState() == State.LOCKED && !user.getUserRank().hasRank(UserRank.SUPREME)) { + sender.sendMessage(Utils.f("&cThis command requires the &7QuickSell Cheatcode&c or &lSUPREME&c!")); + return; + } + + if (sender.getWorld().getName().equals("spawn")) { + TrashCanManager.openTrashCan(sender); + return; + } + + HouseUser houseUser = Houses.getUserManager().getLoadedUser(sender.getUniqueId()); + if (houseUser != null && (houseUser.isInsideHouse() || houseUser.isInsidePremiumHouse())) { + TrashCanManager.openTrashCan(sender); + return; + } + + sender.sendMessage(C.RED + "You can only use this cheatcode in your House or at spawn."); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/SetRarityCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/SetRarityCommand.java new file mode 100644 index 0000000..2f0f0e5 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/SetRarityCommand.java @@ -0,0 +1,95 @@ +package net.grandtheftmc.gtm.commands; + +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.commands.CoreCommand; +import net.grandtheftmc.core.commands.RankedCommand; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.items.GameItem; +import net.grandtheftmc.gtm.items.GameItem.ItemType; +import net.grandtheftmc.gtm.items.ItemManager; +import net.grandtheftmc.guns.GTMGuns; +import net.grandtheftmc.guns.weapon.Weapon; + +public class SetRarityCommand extends CoreCommand<CommandSender> implements RankedCommand { + public SetRarityCommand() { + super("setrarity", "Set the rarity of a weapon", "setstars", "setstar"); + } + + @Override + public void execute(CommandSender sender, String[] args) { + if(sender instanceof Player) { + Player player = (Player)sender; + if(!Core.getUserManager().getLoadedUser(player.getUniqueId()).getUserRank().isHigherThan(UserRank.ADMIN)) + return; + + // get item in main hand + ItemStack is = player.getInventory().getItemInMainHand(); + if (is == null){ + sender.sendMessage(ChatColor.RED + "Please put a weapon in hand to set the rarity for."); + return; + } + + if(args.length == 0){ + sender.sendMessage(Utils.f("&c/setrarity <rarity> - &7Sets the rarity level for the item in hand.")); + return; + } + + int rarity = 0; + try { + rarity = Integer.parseInt(args[0]); + } + catch(Exception e){ + sender.sendMessage(ChatColor.RED + "Please use a valid number to set the rarity of the item in hand to."); + e.printStackTrace(); + } + + // clamp bounds of rarity + if (rarity < 0){ + rarity = 0; + } + if (rarity > GTMGuns.MAX_STARS){ + rarity = GTMGuns.MAX_STARS; + } + + ItemManager im = GTM.getItemManager(); + GameItem gi = im.getItem(is); + if (gi == null){ + sender.sendMessage(ChatColor.RED + "Unable to find a game item similar to " + is.toString()); + return; + } + + if (gi.getType() != ItemType.WEAPON){ + sender.sendMessage(ChatColor.RED + "Cannot set rarity of this item, as it's not a weapon."); + return; + } + + Weapon weapon = GTMGuns.getInstance().getWeaponManager().getWeapon(is).orElse(null); + if (weapon == null){ + sender.sendMessage(ChatColor.RED + "Unable to find a weapon similar to " + is.toString()); + return; + } + + if (rarity == 0){ + player.getInventory().setItemInHand(weapon.createItemStack()); + } + else{ + player.getInventory().setItemInMainHand(weapon.createItemStack(rarity, null)); + } + } + else{ + sender.sendMessage(ChatColor.RED + "Player only command."); + } + } + + @Override + public UserRank requiredRank() { + return UserRank.ADMIN; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/SettingsCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/SettingsCommand.java new file mode 100644 index 0000000..a8e7e37 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/SettingsCommand.java @@ -0,0 +1,529 @@ +package net.grandtheftmc.gtm.commands; + +import java.util.Optional; + +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.commands.CoreCommand; +import net.grandtheftmc.core.commands.RankedCommand; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; + +public class SettingsCommand extends CoreCommand<CommandSender> implements RankedCommand { + + // declarations of all handled flags + enum SupportedSetting { + + // TODO add more flags here + PVP, TRANSFER, CHEATCODES, PAY, BANK_TO_BANK, BUY, TRADE, BOUNTY, BOUNTY_TAX, BOUNTY_TAX_PERCENT, KIT, + DEATH_TAX, DEATH_TAX_SCALED, DEATH_TAX_PERCENT, DEATH_TAX_MIN, DEATH_TAX_MAX; + + public static Optional<SupportedSetting> fromID(String id) { + for (SupportedSetting ss : values()) { + if (ss.name().equalsIgnoreCase(id)) { + return Optional.of(ss); + } + } + + return Optional.empty(); + } + } + + /** + * Create a new SettingsCommand. + * <p> + * This handles any types of variable flags that need to be set/read. + */ + public SettingsCommand() { + super("settings", "Change some settings", "conf"); + } + + @Override + public void execute(CommandSender sender, String[] args) { + if (sender instanceof Player) { + Player player = (Player) sender; + if (!Core.getUserManager().getLoadedUser(player.getUniqueId()).getUserRank().isHigherThan(UserRank.ADMIN)) + return; + } + + // must supply 2 args + if (args.length < 2) { + sendHelp(sender); + return; + } + + // parse first two variables + String command = args[0]; + SupportedSetting ss = SupportedSetting.fromID(args[1]).orElse(null); + + if (command == null || ss == null) { + sendHelp(sender); + return; + } + + switch (command.toLowerCase()) { + case "get": + handleGet(sender, command, ss); + break; + case "set": + if (args.length >= 3) { + handleSet(sender, command, ss, args); + } + else { + sender.sendMessage(ChatColor.RED + "Need to specify third argument for command 'set'."); + } + break; + } + } + + /** + * Handles the parsing of the get command. + * + * @param sender - the sender sending the command + * @param command - the command they want + * @param ss - the setting they want + */ + private void handleGet(CommandSender sender, String command, SupportedSetting ss) { + switch (ss) { + case PVP: + sender.sendMessage(ChatColor.RED + ss.name() + ChatColor.WHITE + "=" + ChatColor.GRAY + GTM.getSettings().isPvp()); + break; + case TRANSFER: + sender.sendMessage(ChatColor.RED + ss.name() + ChatColor.WHITE + "=" + ChatColor.GRAY + GTM.getSettings().isServerTransfer()); + break; + case CHEATCODES: + sender.sendMessage(ChatColor.RED + ss.name() + ChatColor.WHITE + "=" + ChatColor.GRAY + GTM.getSettings().isGlobalCheatcodes()); + break; + case PAY: + sender.sendMessage(ChatColor.RED + ss.name() + ChatColor.WHITE + "=" + ChatColor.GRAY + GTM.getSettings().isPayCommand()); + break; + case BANK_TO_BANK: + sender.sendMessage(ChatColor.RED + ss.name() + ChatColor.WHITE + "=" + ChatColor.GRAY + GTM.getSettings().isBankToBankTransfer()); + break; + case BUY: + sender.sendMessage(ChatColor.RED + ss.name() + ChatColor.WHITE + "=" + ChatColor.GRAY + GTM.getSettings().canBuy()); + break; + case TRADE: + sender.sendMessage(ChatColor.RED + ss.name() + ChatColor.WHITE + "=" + ChatColor.GRAY + GTM.getSettings().canTrade()); + break; + case BOUNTY: + sender.sendMessage(ChatColor.RED + ss.name() + ChatColor.WHITE + "=" + ChatColor.GRAY + GTM.getSettings().isBountySystem()); + break; + case BOUNTY_TAX: + sender.sendMessage(ChatColor.RED + ss.name() + ChatColor.WHITE + "=" + ChatColor.GRAY + GTM.getSettings().isBountyTax()); + break; + case BOUNTY_TAX_PERCENT: + sender.sendMessage(ChatColor.RED + ss.name() + ChatColor.WHITE + "=" + ChatColor.GRAY + GTM.getSettings().getBountyTaxPercent()); + break; + case KIT: + sender.sendMessage(ChatColor.RED + ss.name() + ChatColor.WHITE + "=" + ChatColor.GRAY + GTM.getSettings().isKitSystem()); + break; + case DEATH_TAX: + sender.sendMessage(ChatColor.RED + ss.name() + ChatColor.WHITE + "=" + ChatColor.GRAY + GTM.getSettings().isServerDeathTax()); + break; + case DEATH_TAX_SCALED: + sender.sendMessage(ChatColor.RED + ss.name() + ChatColor.WHITE + "=" + ChatColor.GRAY + GTM.getSettings().isServerDeathTaxScaled()); + break; + case DEATH_TAX_PERCENT: + sender.sendMessage(ChatColor.RED + ss.name() + ChatColor.WHITE + "=" + ChatColor.GRAY + GTM.getSettings().getServerDeathBasePercent()); + break; + case DEATH_TAX_MIN: + sender.sendMessage(ChatColor.RED + ss.name() + ChatColor.WHITE + "=" + ChatColor.GRAY + GTM.getSettings().getServerDeathTaxMin()); + break; + case DEATH_TAX_MAX: + sender.sendMessage(ChatColor.RED + ss.name() + ChatColor.WHITE + "=" + ChatColor.GRAY + GTM.getSettings().getServerDeathTaxMax()); + break; + + // TODO add more flags here + default: + break; + } + } + + /** + * Handles the parsing of the set command. + * + * @param sender - the sender sending the command + * @param command - the command they want + * @param ss - the setting they want to set + * @param args - command arguments + */ + private void handleSet(CommandSender sender, String command, SupportedSetting ss, String[] args) { + + // Note: Disregard args[0] and args[1] + + switch (ss) { + case PVP: + + boolean value = false; + try { + value = Boolean.parseBoolean(args[2]); + } + catch (Exception e) { + sender.sendMessage(ChatColor.RED + "Unable to parse '" + args[2] + "' to a boolean!"); + e.printStackTrace(); + return; + } + + sender.sendMessage(ChatColor.GRAY + "Attempting to set " + ChatColor.RED + ss + ChatColor.GRAY + " to " + ChatColor.WHITE + value); + + GTM.getSettings().setPvp(value); + GTM.getSettings().getGtmConfig().set("pvp", value); + Utils.saveConfig(GTM.getSettings().getGtmConfig(), "gtm"); + + sender.sendMessage(ChatColor.GREEN + "SUCCESS!"); + + break; + case TRANSFER: + + value = false; + try { + value = Boolean.parseBoolean(args[2]); + } + catch (Exception e) { + sender.sendMessage(ChatColor.RED + "Unable to parse '" + args[2] + "' to a boolean!"); + e.printStackTrace(); + return; + } + + sender.sendMessage(ChatColor.GRAY + "Attempting to set " + ChatColor.RED + ss + ChatColor.GRAY + " to " + ChatColor.WHITE + value); + + GTM.getSettings().setServerTransfer(value); + GTM.getSettings().getGtmConfig().set("server-transfer", value); + Utils.saveConfig(GTM.getSettings().getGtmConfig(), "gtm"); + + sender.sendMessage(ChatColor.GREEN + "SUCCESS!"); + + break; + case CHEATCODES: + + value = false; + try { + value = Boolean.parseBoolean(args[2]); + } + catch (Exception e) { + sender.sendMessage(ChatColor.RED + "Unable to parse '" + args[2] + "' to a boolean!"); + e.printStackTrace(); + return; + } + + sender.sendMessage(ChatColor.GRAY + "Attempting to set " + ChatColor.RED + ss + ChatColor.GRAY + " to " + ChatColor.WHITE + value); + + GTM.getSettings().setGlobalCheatcodes(value); + GTM.getSettings().getGtmConfig().set("cheatcodes", value); + Utils.saveConfig(GTM.getSettings().getGtmConfig(), "gtm"); + + sender.sendMessage(ChatColor.GREEN + "SUCCESS!"); + + break; + case PAY: + + value = false; + try { + value = Boolean.parseBoolean(args[2]); + } + catch (Exception e) { + sender.sendMessage(ChatColor.RED + "Unable to parse '" + args[2] + "' to a boolean!"); + e.printStackTrace(); + return; + } + + sender.sendMessage(ChatColor.GRAY + "Attempting to set " + ChatColor.RED + ss + ChatColor.GRAY + " to " + ChatColor.WHITE + value); + + GTM.getSettings().setPayCommand(value); + GTM.getSettings().getGtmConfig().set("pay", value); + Utils.saveConfig(GTM.getSettings().getGtmConfig(), "gtm"); + + sender.sendMessage(ChatColor.GREEN + "SUCCESS!"); + + break; + case BANK_TO_BANK: + + value = false; + try { + value = Boolean.parseBoolean(args[2]); + } + catch (Exception e) { + sender.sendMessage(ChatColor.RED + "Unable to parse '" + args[2] + "' to a boolean!"); + e.printStackTrace(); + return; + } + + sender.sendMessage(ChatColor.GRAY + "Attempting to set " + ChatColor.RED + ss + ChatColor.GRAY + " to " + ChatColor.WHITE + value); + + GTM.getSettings().setBankToBankTransfer(value); + GTM.getSettings().getGtmConfig().set("bank-to-bank-transfer", value); + Utils.saveConfig(GTM.getSettings().getGtmConfig(), "gtm"); + + sender.sendMessage(ChatColor.GREEN + "SUCCESS!"); + + break; + case BUY: + + value = false; + try { + value = Boolean.parseBoolean(args[2]); + } + catch (Exception e) { + sender.sendMessage(ChatColor.RED + "Unable to parse '" + args[2] + "' to a boolean!"); + e.printStackTrace(); + return; + } + + sender.sendMessage(ChatColor.GRAY + "Attempting to set " + ChatColor.RED + ss + ChatColor.GRAY + " to " + ChatColor.WHITE + value); + + GTM.getSettings().setBuy(value); + GTM.getSettings().getGtmConfig().set("buy", value); + Utils.saveConfig(GTM.getSettings().getGtmConfig(), "gtm"); + + sender.sendMessage(ChatColor.GREEN + "SUCCESS!"); + + break; + case TRADE: + + value = false; + try { + value = Boolean.parseBoolean(args[2]); + } + catch (Exception e) { + sender.sendMessage(ChatColor.RED + "Unable to parse '" + args[2] + "' to a boolean!"); + e.printStackTrace(); + return; + } + + sender.sendMessage(ChatColor.GRAY + "Attempting to set " + ChatColor.RED + ss + ChatColor.GRAY + " to " + ChatColor.WHITE + value); + + GTM.getSettings().setTrade(value); + GTM.getSettings().getGtmConfig().set("player-trade", value); + Utils.saveConfig(GTM.getSettings().getGtmConfig(), "gtm"); + + sender.sendMessage(ChatColor.GREEN + "SUCCESS!"); + + break; + case BOUNTY: + + value = false; + try { + value = Boolean.parseBoolean(args[2]); + } + catch (Exception e) { + sender.sendMessage(ChatColor.RED + "Unable to parse '" + args[2] + "' to a boolean!"); + e.printStackTrace(); + return; + } + + sender.sendMessage(ChatColor.GRAY + "Attempting to set " + ChatColor.RED + ss + ChatColor.GRAY + " to " + ChatColor.WHITE + value); + + GTM.getSettings().setBountySystem(value); + GTM.getSettings().getGtmConfig().set("bounty-system", value); + Utils.saveConfig(GTM.getSettings().getGtmConfig(), "gtm"); + + sender.sendMessage(ChatColor.GREEN + "SUCCESS!"); + + break; + case BOUNTY_TAX: + + value = false; + try { + value = Boolean.parseBoolean(args[2]); + } + catch (Exception e) { + sender.sendMessage(ChatColor.RED + "Unable to parse '" + args[2] + "' to a boolean!"); + e.printStackTrace(); + return; + } + + sender.sendMessage(ChatColor.GRAY + "Attempting to set " + ChatColor.RED + ss + ChatColor.GRAY + " to " + ChatColor.WHITE + value); + + GTM.getSettings().setBountyTax(value); + GTM.getSettings().getGtmConfig().set("bounty-system-tax", value); + Utils.saveConfig(GTM.getSettings().getGtmConfig(), "gtm"); + + sender.sendMessage(ChatColor.GREEN + "SUCCESS!"); + + break; + case BOUNTY_TAX_PERCENT: + + double percent = 0; + try { + percent = Double.parseDouble(args[2]); + } + catch (Exception e) { + sender.sendMessage(ChatColor.RED + "Unable to parse '" + args[2] + "' to a double!"); + e.printStackTrace(); + return; + } + + sender.sendMessage(ChatColor.GRAY + "Attempting to set " + ChatColor.RED + ss + ChatColor.GRAY + " to " + ChatColor.WHITE + percent); + + GTM.getSettings().setBountyTaxPercent(percent); + GTM.getSettings().getGtmConfig().set("bounty-tax-percent", percent); + Utils.saveConfig(GTM.getSettings().getGtmConfig(), "gtm"); + + sender.sendMessage(ChatColor.GREEN + "SUCCESS!"); + + break; + case KIT: + + value = false; + try { + value = Boolean.parseBoolean(args[2]); + } + catch (Exception e) { + sender.sendMessage(ChatColor.RED + "Unable to parse '" + args[2] + "' to a boolean!"); + e.printStackTrace(); + return; + } + + sender.sendMessage(ChatColor.GRAY + "Attempting to set " + ChatColor.RED + ss + ChatColor.GRAY + " to " + ChatColor.WHITE + value); + + GTM.getSettings().setKitSystem(value); + GTM.getSettings().getGtmConfig().set("kit-system", value); + Utils.saveConfig(GTM.getSettings().getGtmConfig(), "gtm"); + + sender.sendMessage(ChatColor.GREEN + "SUCCESS!"); + + break; + case DEATH_TAX: + + value = false; + try { + value = Boolean.parseBoolean(args[2]); + } + catch (Exception e) { + sender.sendMessage(ChatColor.RED + "Unable to parse '" + args[2] + "' to a boolean!"); + e.printStackTrace(); + return; + } + + sender.sendMessage(ChatColor.GRAY + "Attempting to set " + ChatColor.RED + ss + ChatColor.GRAY + " to " + ChatColor.WHITE + value); + + GTM.getSettings().setServerDeathTax(value); + GTM.getSettings().getGtmConfig().set("server-death-tax", value); + Utils.saveConfig(GTM.getSettings().getGtmConfig(), "gtm"); + + sender.sendMessage(ChatColor.GREEN + "SUCCESS!"); + + break; + case DEATH_TAX_SCALED: + + value = false; + try { + value = Boolean.parseBoolean(args[2]); + } + catch (Exception e) { + sender.sendMessage(ChatColor.RED + "Unable to parse '" + args[2] + "' to a boolean!"); + e.printStackTrace(); + return; + } + + sender.sendMessage(ChatColor.GRAY + "Attempting to set " + ChatColor.RED + ss + ChatColor.GRAY + " to " + ChatColor.WHITE + value); + + GTM.getSettings().setServerDeathTaxScaled(value); + GTM.getSettings().getGtmConfig().set("server-death-tax-scaled", value); + Utils.saveConfig(GTM.getSettings().getGtmConfig(), "gtm"); + + sender.sendMessage(ChatColor.GREEN + "SUCCESS!"); + + break; + case DEATH_TAX_PERCENT: + + percent = 0; + try { + percent = Double.parseDouble(args[2]); + } + catch (Exception e) { + sender.sendMessage(ChatColor.RED + "Unable to parse '" + args[2] + "' to a double!"); + e.printStackTrace(); + return; + } + + sender.sendMessage(ChatColor.GRAY + "Attempting to set " + ChatColor.RED + ss + ChatColor.GRAY + " to " + ChatColor.WHITE + percent); + + GTM.getSettings().setServerDeathBasePercent(percent); + GTM.getSettings().getGtmConfig().set("server-death-tax-percent", percent); + Utils.saveConfig(GTM.getSettings().getGtmConfig(), "gtm"); + + sender.sendMessage(ChatColor.GREEN + "SUCCESS!"); + + break; + case DEATH_TAX_MIN: + + int amount = 0; + try { + amount = Integer.parseInt(args[2]); + } + catch (Exception e) { + sender.sendMessage(ChatColor.RED + "Unable to parse '" + args[2] + "' to an integer!"); + e.printStackTrace(); + return; + } + + sender.sendMessage(ChatColor.GRAY + "Attempting to set " + ChatColor.RED + ss + ChatColor.GRAY + " to " + ChatColor.WHITE + amount); + + GTM.getSettings().setServerDeathTaxMin(amount); + GTM.getSettings().getGtmConfig().set("server-death-tax-min", amount); + Utils.saveConfig(GTM.getSettings().getGtmConfig(), "gtm"); + + sender.sendMessage(ChatColor.GREEN + "SUCCESS!"); + + break; + case DEATH_TAX_MAX: + + amount = 0; + try { + amount = Integer.parseInt(args[2]); + } + catch (Exception e) { + sender.sendMessage(ChatColor.RED + "Unable to parse '" + args[2] + "' to an integer!"); + e.printStackTrace(); + return; + } + + sender.sendMessage(ChatColor.GRAY + "Attempting to set " + ChatColor.RED + ss + ChatColor.GRAY + " to " + ChatColor.WHITE + amount); + + GTM.getSettings().setServerDeathTaxMax(amount); + GTM.getSettings().getGtmConfig().set("server-death-tax-max", amount); + Utils.saveConfig(GTM.getSettings().getGtmConfig(), "gtm"); + + sender.sendMessage(ChatColor.GREEN + "SUCCESS!"); + + break; + + // TODO add more flags here + default: + break; + } + } + + /** + * Send help message to the command sender. + * + * @param sender - the sender of the command + */ + private void sendHelp(CommandSender sender) { + sender.sendMessage(ChatColor.RED + "/settings set <conf> <value>" + ChatColor.WHITE + " - " + ChatColor.GRAY + "Set the new value of the setting"); + sender.sendMessage(ChatColor.RED + "/settings get <conf>" + ChatColor.WHITE + " - " + ChatColor.GRAY + "Get the value of the setting."); + + StringBuilder builder = new StringBuilder(); + for (SupportedSetting ss : SupportedSetting.values()) { + builder.append(ss.name()); + builder.append(","); + } + + sender.sendMessage(""); + sender.sendMessage(ChatColor.RED + "Known conf keys: " + ChatColor.WHITE + builder.substring(0, builder.length() - 1).toString()); + } + + /** + * {@inheritDoc} + */ + @Override + public UserRank requiredRank() { + return UserRank.ADMIN; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/SkinCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/SkinCommand.java new file mode 100644 index 0000000..1a6723b --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/SkinCommand.java @@ -0,0 +1,206 @@ +package net.grandtheftmc.gtm.commands; + +import java.util.Optional; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.commands.CoreCommand; +import net.grandtheftmc.core.commands.RankedCommand; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.guns.weapon.Weapon; +import net.grandtheftmc.guns.weapon.WeaponSkin; + +public class SkinCommand extends CoreCommand<Player> implements RankedCommand { + public SkinCommand() { + super("skin", "A command used to manage weapon skins."); + } + + @Override + public void execute(Player sender, String[] args) { + User user = Core.getUserManager().getLoadedUser(sender.getUniqueId()); + GTMUser gtmUser = GTM.getUserManager().getLoadedUser(sender.getUniqueId()); + + if (user.isAdmin()) { + if (args.length == 3) { + if (args[0].equalsIgnoreCase("unlock")) { + Optional<Weapon<?>> weaponOpt = null; + + try { + short weaponID = Short.parseShort(args[1]); + + weaponOpt = GTM.getWastedGuns().getWeaponManager().getWeapon(weaponID); + } catch (NumberFormatException e) { + String weaponName = args[1]; + + weaponOpt = GTM.getWastedGuns().getWeaponManager().getWeapon(weaponName); + } + + if (weaponOpt.isPresent()) { + Weapon<?> weapon = weaponOpt.get(); + + try { + short skinID = Short.parseShort(args[2]); + WeaponSkin skin = weapon.getWeaponSkins().length > skinID ? weapon.getWeaponSkins()[skinID] : null; + + if (skin != null) { + if (gtmUser.getRawUnlockedWeaponSkins().get(weapon.getUniqueIdentifier()) == null + || !gtmUser.getRawUnlockedWeaponSkins().get(weapon.getUniqueIdentifier()).contains((short) (skin.getIdentifier() - weapon.getWeaponIdentifier()))) { + gtmUser.unlockWeaponSkin(weapon, skin); + + sender.sendMessage(Utils.f("&7You unlocked this skin!")); + } else { + sender.sendMessage(Utils.f("&cThis skin has already been unlocked!")); + } + } else { + sender.sendMessage(Utils.f("&cA skin with this ID does not exist!")); + } + } catch (NumberFormatException e) { + sender.sendMessage(Utils.f("&cThe skin ID has to be a number!")); + } + } else { + sender.sendMessage(Utils.f("&cA weapon with this name/ID does not exist!")); + } + } else if (args[0].equalsIgnoreCase("lock")) { + Optional<Weapon<?>> weaponOpt = null; + + try { + short weaponID = Short.parseShort(args[1]); + + weaponOpt = GTM.getWastedGuns().getWeaponManager().getWeapon(weaponID); + } catch (NumberFormatException e) { + String weaponName = args[1]; + + weaponOpt = GTM.getWastedGuns().getWeaponManager().getWeapon(weaponName); + } + + if (weaponOpt.isPresent()) { + Weapon<?> weapon = weaponOpt.get(); + + try { + short skinID = Short.parseShort(args[2]); + WeaponSkin skin = weapon.getWeaponSkins().length > skinID ? weapon.getWeaponSkins()[skinID] : null; + + if (skin != null) { + if (gtmUser.getRawUnlockedWeaponSkins().get(weapon.getUniqueIdentifier()) != null + && gtmUser.getRawUnlockedWeaponSkins().get(weapon.getUniqueIdentifier()).contains((short) (skin.getIdentifier() - weapon.getWeaponIdentifier()))) { + gtmUser.lockWeaponSkin(weapon, skin); + + sender.sendMessage(Utils.f("&7You locked this skin!")); + } else { + sender.sendMessage(Utils.f("&cThis skin has already been locked!")); + } + } else { + sender.sendMessage(Utils.f("&cA skin with this ID does not exist!")); + } + } catch (NumberFormatException e) { + sender.sendMessage(Utils.f("&cThe skin ID has to be a number!")); + } + } else { + sender.sendMessage(Utils.f("&cA weapon with this name/ID does not exist!")); + } + } + } else if (args.length == 4) { + if (args[0].equalsIgnoreCase("unlock")) { + Player otherPlayer = Bukkit.getPlayer(args[1]); + + if (otherPlayer != null && otherPlayer.isOnline()) { + GTMUser otherGTMUser = GTM.getUserManager().getLoadedUser(otherPlayer.getUniqueId()); + Optional<Weapon<?>> weaponOpt = null; + + try { + short weaponID = Short.parseShort(args[2]); + + weaponOpt = GTM.getWastedGuns().getWeaponManager().getWeapon(weaponID); + } catch (NumberFormatException e) { + String weaponName = args[2]; + + weaponOpt = GTM.getWastedGuns().getWeaponManager().getWeapon(weaponName); + } + + if (weaponOpt.isPresent()) { + Weapon<?> weapon = weaponOpt.get(); + + try { + short skinID = Short.parseShort(args[3]); + WeaponSkin skin = weapon.getWeaponSkins().length > skinID ? weapon.getWeaponSkins()[skinID] : null; + + if (skin != null) { + if (otherGTMUser.getRawUnlockedWeaponSkins().get(weapon.getUniqueIdentifier()) == null + || !otherGTMUser.getRawUnlockedWeaponSkins().get(weapon.getUniqueIdentifier()).contains((short) (skin.getIdentifier() - weapon.getWeaponIdentifier()))) { + otherGTMUser.unlockWeaponSkin(weapon, skin); + + sender.sendMessage(Utils.f("&7You unlocked this skin for &a" + otherPlayer.getName() + "!")); + } else { + sender.sendMessage(Utils.f("&a" + otherPlayer.getName() + " already has this skin unlocked!")); + } + } else { + sender.sendMessage(Utils.f("&cA skin with this ID does not exist!")); + } + } catch (NumberFormatException e) { + sender.sendMessage(Utils.f("&cThe skin ID has to be a number!")); + } + } else { + sender.sendMessage(Utils.f("&cA weapon with this name/ID does not exist!")); + } + } + } else if (args[0].equalsIgnoreCase("lock")) { + Player otherPlayer = Bukkit.getPlayer(args[1]); + + if (otherPlayer != null && otherPlayer.isOnline()) { + GTMUser otherGTMUser = GTM.getUserManager().getLoadedUser(otherPlayer.getUniqueId()); + Optional<Weapon<?>> weaponOpt = null; + + try { + short weaponID = Short.parseShort(args[2]); + + weaponOpt = GTM.getWastedGuns().getWeaponManager().getWeapon(weaponID); + } catch (NumberFormatException e) { + String weaponName = args[2]; + + weaponOpt = GTM.getWastedGuns().getWeaponManager().getWeapon(weaponName); + } + + if (weaponOpt.isPresent()) { + Weapon<?> weapon = weaponOpt.get(); + + try { + short skinID = Short.parseShort(args[3]); + WeaponSkin skin = weapon.getWeaponSkins().length > skinID ? weapon.getWeaponSkins()[skinID] : null; + + if (skin != null) { + if (otherGTMUser.getRawUnlockedWeaponSkins().get(weapon.getUniqueIdentifier()) != null + && otherGTMUser.getRawUnlockedWeaponSkins().get(weapon.getUniqueIdentifier()).contains((short) (skin.getIdentifier() - weapon.getWeaponIdentifier()))) { + otherGTMUser.lockWeaponSkin(weapon, skin); + + sender.sendMessage(Utils.f("&7You locked this skin for &a" + otherPlayer.getName() + "!")); + } else { + sender.sendMessage(Utils.f("&a" + otherPlayer.getName() + " already has this skin locked!")); + } + } else { + sender.sendMessage(Utils.f("&cA skin with this ID does not exist!")); + } + } catch (NumberFormatException e) { + sender.sendMessage(Utils.f("&cThe skin ID has to be a number!")); + } + } else { + sender.sendMessage(Utils.f("&cA weapon with this name/ID does not exist!")); + } + } + } + } + } else { + sender.sendMessage(Utils.f("&cYou do not have permission to execute this command!")); + } + } + + @Override + public UserRank requiredRank() { + return UserRank.DEFAULT; + } +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/SkinsCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/SkinsCommand.java new file mode 100644 index 0000000..ab04b55 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/SkinsCommand.java @@ -0,0 +1,26 @@ +package net.grandtheftmc.gtm.commands; + +import org.bukkit.entity.Player; + +import net.grandtheftmc.core.commands.CoreCommand; +import net.grandtheftmc.core.commands.RankedCommand; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.gtm.weapon.skins.menu.MainMenu; + +public class SkinsCommand extends CoreCommand<Player> implements RankedCommand { + public SkinsCommand() { + super("skins", "View or equip your weapon skins."); + } + + @Override + public void execute(Player sender, String[] args) { + if (args.length == 0) { + new MainMenu(sender).open(); + } + } + + @Override + public UserRank requiredRank() { + return UserRank.DEFAULT; + } +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/SpectatorCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/SpectatorCommand.java new file mode 100644 index 0000000..dd3fcd5 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/SpectatorCommand.java @@ -0,0 +1,75 @@ +package net.grandtheftmc.gtm.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.users.GTMUser; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerTeleportEvent; + +import java.util.ArrayList; +import java.util.List; + +public class SpectatorCommand implements CommandExecutor { + private static final List<String> ACTIVE_STAFF = new ArrayList<>(); + + public static List<String> getActiveStaff() { + return ACTIVE_STAFF; + } + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + Player sender = (Player) s; + GTMUser user = GTM.getUserManager().getLoadedUser(sender.getUniqueId()); + if(user.isDead()) { + s.sendMessage(Lang.GTM.f("&7You cannot issue this command while dead!")); + return false; + } + User coreSender = Core.getUserManager().getLoadedUser(sender.getUniqueId()); + if (!coreSender.isRank(UserRank.HELPOP)) { + sender.sendMessage(Lang.GTM.f("&7Permission denied!")); + return true; + } + if(args.length==1 && args[0].equalsIgnoreCase("true") && ACTIVE_STAFF.contains(sender.getName())){ + return true; + } + if (ACTIVE_STAFF.contains(sender.getName())) { + ACTIVE_STAFF.remove(sender.getName()); + sender.sendMessage(Lang.GTM.f("&bSpectator Mode disabled!")); + sender.setGameMode(GameMode.ADVENTURE); + sender.teleport(Bukkit.getWorld("spawn").getSpawnLocation(), PlayerTeleportEvent.TeleportCause.COMMAND); + sender.setFlySpeed(0.1F); + } else { + ACTIVE_STAFF.add(sender.getName()); + sender.sendMessage(Lang.GTM.f("&bSpectator Mode enabled!")); + sender.teleport(this.getMapLocation(), PlayerTeleportEvent.TeleportCause.COMMAND); + sender.setGameMode(GameMode.SPECTATOR); + } + return true; + } + + private Location getMapLocation() { + Location loc = Bukkit.getWorlds().get(0).getSpawnLocation(); + if (Bukkit.getWorld("minesantos") == null) { + return loc; + } + loc.setWorld(Bukkit.getWorld("minesantos")); + loc.setX(-133.59); + loc.setY(96.000000); + loc.setZ(244.431); + return loc; + } +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/SpeedCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/SpeedCommand.java new file mode 100644 index 0000000..ffc221e --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/SpeedCommand.java @@ -0,0 +1,60 @@ +package net.grandtheftmc.gtm.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class SpeedCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.GTM.f("&cYou are not a player!")); + return true; + } + Player player = (Player)s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if(SpectatorCommand.getActiveStaff().contains(player.getName()) || user.isRank(UserRank.ADMIN)) { + if(args.length != 1) { + player.sendMessage(Lang.GTM.f("&7Usage: /speed <1-10>")); + } else { + float speed = Float.valueOf(args[0]); + if(user.isRank(UserRank.ADMIN) && !player.isFlying()) { + speed = getRealMoveSpeed(speed, false); + player.setWalkSpeed(speed); + } else { + speed = getRealMoveSpeed(speed, true); + player.setFlySpeed(speed); + } + player.sendMessage(Lang.GTM.f("&7Your " + (player.isFlying() ? "fly" : "walk") + + " speed has been set to &a" + Integer.min(Integer.valueOf(args[0]), 10))); + } + } else if(user.isRank(UserRank.HELPOP)) { + player.sendMessage(Lang.GTM.f("&7You must be in spectator mode to use this command.")); + } + return true; + } + + private float getRealMoveSpeed(float userSpeed, final boolean isFly) { + final float defaultSpeed = isFly ? 0.1f : 0.2f; + float maxSpeed = 1f; + + if (userSpeed > 10f) { + userSpeed = 10f; + } else if (userSpeed < 0.0001f) { + userSpeed = 0.0001f; + } + + if (userSpeed < 1f) { + return defaultSpeed * userSpeed; + } else { + float ratio = ((userSpeed - 1) / 9) * (maxSpeed - defaultSpeed); + return ratio + defaultSpeed; + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/StackCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/StackCommand.java new file mode 100644 index 0000000..f1ec26e --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/StackCommand.java @@ -0,0 +1,108 @@ +package net.grandtheftmc.gtm.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.State; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.items.ArmorUpgrade; +import net.grandtheftmc.gtm.items.GameItem; +import net.grandtheftmc.gtm.users.CheatCode; +import net.grandtheftmc.gtm.users.GTMUser; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitRunnable; + +import java.lang.reflect.Array; +import java.util.*; + +public class StackCommand implements CommandExecutor { + //private final Map<String, Long> fixCooldown = new HashMap<>(); + private static final List<Material> UNUSUAL_UNSTACKABLE_MATERIALS = new ArrayList<>(Arrays.asList(Material.SAPLING, Material.CHEST, Material.COMPASS, Material.WATCH, Material.SKULL, Material.SKULL_ITEM)); + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.toString()); + return true; + } + Player player = (Player) s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + GTMUser gtmUser = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + + if (gtmUser.getCheatCodeState(CheatCode.STACK).getState()== State.LOCKED) { + player.sendMessage(Lang.CHEAT_CODES.f(CheatCode.STACK.getLockedLore())); + return false; + } + if(user.isOnCooldown("stack_command")) { + player.sendMessage(Lang.CHEAT_CODES.f("&7You must wait &a" + Utils.timeInSecondsToText(user.getCooldownTimeLeft("stack_command"), C.RED, C.RED, C.GRAY) + " &7before using this cheatcode again!")); + return false; + } + int affected = 0; + for(int i = 0; i<player.getInventory().getSize(); i++) { + ItemStack is = player.getInventory().getItem(i); + if(is==null || is.getType()==Material.AIR) + continue; + if(UNUSUAL_UNSTACKABLE_MATERIALS.contains(is.getType()) && is.getAmount()>=1) { + continue; + } + if(isArmorPiece(is.getType()) && (is.getDurability()!=0 || (is.hasItemMeta() && is.getItemMeta().hasLore()))) { + continue; + } + GameItem gameItem = GTM.getItemManager().getItem(is); + int maxStackSize = (isArmorPiece(is.getType()) && is.getDurability()==0) || (gameItem!=null && (gameItem.getType()== GameItem.ItemType.DRUG || gameItem.getType()== GameItem.ItemType.WEAPON)) ? 64 : is.getMaxStackSize(); + if(is.getAmount()>=maxStackSize) + continue; + int amountNeeded = maxStackSize-is.getAmount(); + for(int j = i+1; j<player.getInventory().getSize(); j++) { + ItemStack compare = player.getInventory().getItem(j); + if(compare==null || (isArmorPiece(is.getType()) && compare.getDurability()!=0) || compare.getType()!=is.getType() || (is.getEnchantments().size()!=compare.getEnchantments().size() || !is.getEnchantments().keySet().containsAll(compare.getEnchantments().keySet())) || (ArmorUpgrade.getArmorUpgrades(is).size()!=ArmorUpgrade.getArmorUpgrades(compare).size() || !ArmorUpgrade.getArmorUpgrades(is).containsAll(ArmorUpgrade.getArmorUpgrades(compare)))) + continue; + GameItem compareGameItem = GTM.getItemManager().getItem(is); + if(!((compareGameItem==null && gameItem==null) || (gameItem.getType()==compareGameItem.getType()))) + continue; + if(is.getAmount()>=maxStackSize) + break; + if(compare.getAmount()>amountNeeded) { + is.setAmount(maxStackSize); + compare.setAmount(compare.getAmount()-amountNeeded); + affected++; + break; + } + else { + is.setAmount(is.getAmount()+compare.getAmount()); + amountNeeded -= compare.getAmount(); + player.getInventory().setItem(j, null); + affected++; + } + } + player.getInventory().setItem(i, is); + } + + if (affected > 0) { + user.addCooldown("stack_command", GTMUtils.getStackDelay(user.getUserRank()), false, true); + new BukkitRunnable() { + @Override + public void run() { + player.updateInventory(); + } + }.runTaskLater(Core.getInstance(), 5); + player.sendMessage(Lang.GTM.f("&7Items compacted into stacks!")); + } else { + player.sendMessage(Lang.GTM.f("&7No stackable items found!")); + } + return true; + } + + private boolean isArmorPiece(Material mat) { + String s = mat.toString(); + return s.contains("LEGGINGS") || s.contains("BOOTS") || s.contains("HELMET") || s.contains("CHESTPLATE"); + } + +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/StatsCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/StatsCommand.java new file mode 100644 index 0000000..ed3e02e --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/StatsCommand.java @@ -0,0 +1,39 @@ +package net.grandtheftmc.gtm.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.gtm.utils.Stats; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class StatsCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.GTM.f("&cYou are not a player!")); + return true; + } + Player player = (Player)s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if(args.length == 0) { + player.sendMessage(Core.getAnnouncer().getHeader()); + Stats.getInstance().getStats(player).forEach(message -> player.sendMessage(message)); + player.sendMessage(Core.getAnnouncer().getFooter()); + } else { + if(Bukkit.getPlayer(args[0]) != null) { + Player target = Bukkit.getPlayer(args[0]); + player.sendMessage(Core.getAnnouncer().getHeader()); + Stats.getInstance().getStats(target).forEach(message -> player.sendMessage(message)); + player.sendMessage(Core.getAnnouncer().getFooter()); + } else { + player.sendMessage(Lang.GTM.f("&7Player not found!")); + } + } + return true; + } +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/TeleportCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/TeleportCommand.java new file mode 100644 index 0000000..6724c50 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/TeleportCommand.java @@ -0,0 +1,66 @@ +package net.grandtheftmc.gtm.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class TeleportCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + Player sender = (Player) s; + User coreSender = Core.getUserManager().getLoadedUser(sender.getUniqueId()); + if (!coreSender.isRank(UserRank.HELPOP) || !coreSender.isRank(UserRank.SRMOD) && !SpectatorCommand.getActiveStaff().contains(sender.getName())) { + sender.sendMessage(Lang.GTM.f("&7Permission denied!")); + return true; + } + if (args.length == 1) { + Player target = Bukkit.getPlayer(args[0]); + if (target == null) { + sender.sendMessage(Lang.GTM.f("&7That player is not online!")); + return true; + } + if (Core.getUserManager().getLoadedUser(target.getUniqueId()).isRank(UserRank.ADMIN) && !coreSender.isRank(UserRank.ADMIN)) { + sender.sendMessage(Lang.GTM.f("&7You may not teleport to that player.")); + return true; + } + sender.teleport(target.getLocation()); + sender.sendMessage(Lang.GTM.f("&7You have been teleported to" + target.getDisplayName() + "&7!")); + } else if (args.length == 2) { + if (!coreSender.isRank(UserRank.ADMIN)) { + sender.sendMessage(Lang.GTM.f("&7Permission denied!")); + return true; + } + Player targetFrom = Bukkit.getPlayer(args[0]); + Player targetTo = Bukkit.getPlayer(args[1]); + if (targetFrom == null || targetTo == null) { + sender.sendMessage(Lang.GTM.f("&7Player(s) not found!")); + return true; + } + if (Core.getUserManager().getLoadedUser(targetFrom.getUniqueId()).isRank(UserRank.ADMIN) || + Core.getUserManager().getLoadedUser(targetTo.getUniqueId()).isRank(UserRank.ADMIN)) { + sender.sendMessage(Lang.GTM.f("&7You may not teleport that player.")); + return true; + } + targetFrom.teleport(targetTo.getLocation()); + sender.sendMessage(Lang.GTM.f("&7You teleported " + targetFrom.getDisplayName() + + " to " + targetTo.getDisplayName() + '!')); + } else { + sender.sendMessage(Lang.GTM.f("&7Usage:")); + sender.sendMessage(Utils.f("&a/teleport <player>")); + sender.sendMessage(Utils.f("&a/teleport <playerfrom> <playerto>")); + } + return true; + } +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/TokenShopCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/TokenShopCommand.java new file mode 100644 index 0000000..e9fd74a --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/TokenShopCommand.java @@ -0,0 +1,24 @@ +package net.grandtheftmc.gtm.commands; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.menus.MenuManager; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +/** + * Created by colt on 11/6/16. + */ +public class TokenShopCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + MenuManager.openMenu((Player)s, "tokenshop"); + return true; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/TopKillersCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/TopKillersCommand.java new file mode 100644 index 0000000..7fae27e --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/TopKillersCommand.java @@ -0,0 +1,49 @@ +package net.grandtheftmc.gtm.commands; + +import com.google.common.collect.Maps; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.Iterator; +import java.util.Map; +import java.util.UUID; + +public class TopKillersCommand implements CommandExecutor { + + private Map<String, Integer> topKillers = Maps.newHashMap(); + + public TopKillersCommand() { + Bukkit.getScheduler().runTaskTimerAsynchronously(GTM.getInstance(), () -> this.topKillers = GTMUtils.sortByValue(GTMUtils.getTopKillers(5)), 0, 20*300); + } + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.GTM.f("&cYou are not a player!")); + return true; + } + + UUID uuid = ((Player) s).getUniqueId(); + s.sendMessage(Lang.GTM.f("&7Compiling top killers list...")); + ServerUtil.runTaskAsync(() -> { + Player player = Bukkit.getPlayer(uuid); + if (player == null) return; + int i = 1; + for(Map.Entry<String,Integer> entry : this.topKillers.entrySet()){ + player.sendMessage(Utils.f("&7#" + i++ + " &a" + entry.getKey() + " &7- " + entry.getValue() + " &7kills")); + } + }); + + return true; + } +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/TransferCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/TransferCommand.java new file mode 100644 index 0000000..1621c6f --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/TransferCommand.java @@ -0,0 +1,47 @@ +package net.grandtheftmc.gtm.commands; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import org.bukkit.entity.Player; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.commands.CoreCommand; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.gtm.GTM; + +/** + * Created by Timothy Lampen on 1/12/2018. + */ +public class TransferCommand extends CoreCommand<Player>{ + + /** The allowed transfer servers */ + private static final Set<Integer> TRANSFERABLE_SERVERS = new HashSet<Integer>(Arrays.asList(2,3,5,6,0)); + + /** + * Construct a new TransferCommand. + */ + public TransferCommand() { + super("transfer", "transfer player data from one server to another"); + } + + @Override + public void execute(Player player, String[] args) { + + if (!GTM.getSettings().isServerTransfer()){ + player.sendMessage(Lang.GTM.f("&7Transferring is currently disabled!")); + return; + } + + // stop tranfers + if(!TRANSFERABLE_SERVERS.contains(Core.getSettings().getNumber())) {//you have to be on server 2,3,5,6 to transfer + player.sendMessage(Lang.GTM.f("&cSorry, transfering is currently &4&lLOCKED &cfor your server.")); + return; + } + + // open transferconfirm menu + MenuManager.openMenu(player, "transferconfirm"); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/VehicleCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/VehicleCommand.java new file mode 100644 index 0000000..7d26eb1 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/commands/VehicleCommand.java @@ -0,0 +1,130 @@ +package net.grandtheftmc.gtm.commands; + +import com.j0ach1mmall3.wastedvehicles.api.VehicleProperties; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.users.GTMUser; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.List; +import java.util.Optional; + +/** + * Created by Liam on 24/09/2016. + */ +public class VehicleCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command cmd, String lbl, String[] args) { + if (!s.hasPermission("command.vehicle")) { + s.sendMessage(Lang.NOPERM.s()); + return true; + } + if (args.length == 0) { + s.sendMessage(Lang.VEHICLES.f("&7/vehicle list [player]")); + s.sendMessage(Lang.VEHICLES.f("&7/vehicle give <player> <name>")); + s.sendMessage(Lang.VEHICLES.f("&7/vehicle remove <player> <name>")); + return true; + } + switch (args[0].toLowerCase()) { + case "list": + if (args.length > 2) { + s.sendMessage(Utils.f("&c/vehicle list <type>")); + return true; + } + List<VehicleProperties> vehicles = GTM.getWastedVehicles().getBabies().getVehicleProperties(); + if (args.length == 2) { + Player player = Bukkit.getPlayer(args[1]); + if (player == null) { + s.sendMessage(Lang.VEHICLES.f("&7That player is not online!")); + return true; + } + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + vehicles = user.getVehicleProperties(); + if (vehicles.isEmpty()) { + s.sendMessage(Lang.VEHICLES.f("&7That player has no vehicles!")); + return true; + } + String msg = ""; + for (VehicleProperties v : vehicles) + if (player == null || user.hasVehicle(v.getIdentifier())) + msg += "&c" + v.getIdentifier() + "&7, "; + if (msg.endsWith("&7, ")) + msg.substring(0, msg.length() - 4); + s.sendMessage(Lang.VEHICLES.f("&7List of vehicles of player " + player.getName() + "&7:")); + s.sendMessage(Utils.f(msg)); + return true; + } else if (vehicles.isEmpty()) { + s.sendMessage(Lang.VEHICLES.f("&7There are no vehicles!")); + return true; + } + String msg = ""; + for (VehicleProperties v : vehicles) + msg += "&c" + v.getIdentifier() + "&7, "; + if (msg.endsWith("&7, ")) + msg.substring(0, msg.length() - 4); + s.sendMessage(Lang.VEHICLES.f("&7List of vehicles:")); + s.sendMessage(Utils.f(msg)); + return true; + case "give": { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/vehicle give <player> <name>")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + Optional<VehicleProperties> opt = GTM.getWastedVehicles().getVehicle(args[2]); + if (opt == null || !opt.isPresent() || opt.get() == null) { + s.sendMessage(Lang.VEHICLES.f("&7That vehicle does not exist!")); + return true; + } + VehicleProperties vehicle = opt.get(); + if (player == null) { +// Core.sql.updateAsyncLater("update " + Core.name() + " set `" + vehicle.getIdentifier().toLowerCase() + "`=true where name='" + args[1] + "';"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + Core.name() + " set `" + vehicle.getIdentifier().toLowerCase() + "`=true where name='" + args[1] + "';")); + s.sendMessage(Lang.VEHICLES.f("&7That player is not online, so his vehicles have been updated directly in the database!")); + return true; + } + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + user.giveVehiclePerm(player, vehicle); + s.sendMessage(Lang.VEHICLES.f("&7You gave vehicle &a" + vehicle.getIdentifier() + "&7 to player " + player.getName() + "&7!")); + return true; + } + case "remove": + if (args.length != 3) { + s.sendMessage(Utils.f("&c/vehicle remove <player> <name>")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + Optional<VehicleProperties> opt = GTM.getWastedVehicles().getVehicle(args[2]); + if (opt == null || !opt.isPresent() || opt.get() == null) { + s.sendMessage(Lang.VEHICLES.f("&7That vehicle does not exist!")); + return true; + } + VehicleProperties vehicle = opt.get(); + if (player == null) { +// Core.sql.updateAsyncLater("update " + Core.name() + " set `" + vehicle.getIdentifier().toLowerCase() + "`=false where name='" + args[1] + "';"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + Core.name() + " set `" + vehicle.getIdentifier().toLowerCase() + "`=false where name='" + args[1] + "';")); + s.sendMessage(Lang.VEHICLES.f("&7That player is not online, so his vehicles have been updated directly in the database!")); + return true; + } + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + user.removeVehiclePerm(player, vehicle); + s.sendMessage(Lang.VEHICLES.f("&7You removed vehicle &a" + vehicle.getIdentifier() + "&7 from player " + player.getName() + "&7!")); + return true; + default: + s.sendMessage(Lang.VEHICLES.f("&7/vehicle list [player]")); + s.sendMessage(Lang.VEHICLES.f("&7/vehicle give <player> <name>")); + s.sendMessage(Lang.VEHICLES.f("&7/vehicle remove <player> <name>")); + return true; + } + + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/database/dao/AmmoDAO.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/database/dao/AmmoDAO.java new file mode 100644 index 0000000..15aa864 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/database/dao/AmmoDAO.java @@ -0,0 +1,159 @@ +package net.grandtheftmc.gtm.database.dao; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.gtm.items.AmmoType; + +public class AmmoDAO { + +// CREATE TABLE IF NOT EXISTS user_ammo( +// uuid BINARY(16) NOT NULL, +// server_key VARCHAR(10) NOT NULL, +// ammo VARCHAR(16) NOT NULL, +// amount INT NOT NULL, +// PRIMARY KEY (uuid, server_key, ammo), +// FOREIGN KEY (uuid) REFERENCES user(uuid) ON DELETE CASCADE +// ); + + /** + * Get all the ammo for the given uuid. + * + * @param conn - the database connection thread + * @param uuid - the uuid of the user + * @param serverKey - the serverKey to lookup + * + * @return A mapping of ammo to amount that exists in the serverKey lookup + * for the user. + */ + public static Map<AmmoType, Integer> getAllAmmo(Connection conn, UUID uuid, String serverKey) { + + Map<AmmoType, Integer> ammo = new HashMap<>(); + + String query = "SELECT ammo, amount FROM user_ammo WHERE uuid=UNHEX(?) AND server_key=?;"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setString(1, uuid.toString().replaceAll("-", "")); + ps.setString(2, serverKey); + + try (ResultSet result = ps.executeQuery()) { + while (result.next()) { + String ammoID = result.getString("ammo"); + int amount = result.getInt("amount"); + + AmmoType ammoType = AmmoType.getAmmoTypeByID(ammoID).orElse(null); + if (ammoType != null) { + ammo.put(ammoType, amount); + } + } + } + } + catch (Exception e) { + Core.log("[AmmoDAO] Unable to getAllAmmo() for uuid=" + uuid.toString() + ", serverKey=" + serverKey); + e.printStackTrace(); + } + + return ammo; + } + + /** + * Get the ammo amount for the given uuid and ammo type. + * + * @param conn - the database connection thread + * @param uuid - the uuid of the user + * @param serverKey - the serverKey to lookup + * @param ammoType - the ammo type to lookup + * + * @return The amount of ammo for the given ammo type for the given uuid. + */ + public static Integer getAmmo(Connection conn, UUID uuid, String serverKey, AmmoType ammoType) { + + String query = "SELECT amount FROM user_ammo WHERE uuid=UNHEX(?) AND server_key=? AND ammo=?;"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setString(1, uuid.toString().replaceAll("-", "")); + ps.setString(2, serverKey); + ps.setString(3, ammoType.getId()); + + try (ResultSet result = ps.executeQuery()) { + if (result.next()) { + return result.getInt("amount"); + } + } + } + catch (Exception e) { + Core.log("[AmmoDAO] Unable to getAmmo() for uuid=" + uuid.toString() + ", serverKey=" + serverKey + ", ammo=" + ammoType.getId()); + e.printStackTrace(); + } + + return 0; + } + + /** + * Save the ammo for the given uuid and ammo type. + * + * @param conn - the database connection thread + * @param uuid - the uuid of the user + * @param serverKey - the serverKey to lookup + * @param ammoType - the ammo type to lookup + * @param amount - the amount of the ammo to save + * + * @return {@code true} if the ammo was saved, {@code false} otherwise. + */ + public static boolean saveAmmo(Connection conn, UUID uuid, String serverKey, AmmoType ammoType, int amount) { + + String query = "INSERT IGNORE INTO user_ammo (uuid, server_key, ammo, amount) VALUES (UNHEX(?), ?, ?, ?) ON DUPLICATE KEY UPDATE amount=VALUES(amount);"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setString(1, uuid.toString().replaceAll("-", "")); + ps.setString(2, serverKey); + ps.setString(3, ammoType.getId()); + ps.setInt(4, amount); + + ps.executeUpdate(); + return true; + } + catch (Exception e) { + Core.log("[AmmoDAO] Unable to saveAmmo() for uuid=" + uuid.toString() + ", serverKey=" + serverKey + ", ammo=" + ammoType.getId() + ", amount=" + amount); + e.printStackTrace(); + } + + return false; + } + + /** + * Save all the ammo for the given uuid and ammo map. + * + * @param conn - the database connection thread + * @param uuid - the uuid of the user + * @param serverKey - the serverKey to lookup + * @param ammo - the ammo mapping + * + * @return {@code true} if all ammo was saved, {@code false} if at least one + * had an issue saving. + */ + public static boolean saveAllAmmo(Connection conn, UUID uuid, String serverKey, Map<AmmoType, Integer> ammo) { + + boolean success = true; + + for (AmmoType at : ammo.keySet()) { + Integer amount = ammo.get(at); + + try { + saveAmmo(conn, uuid, serverKey, at, amount); + } + catch (Exception e) { + Core.log("[AmmoDAO] Unable to saveAllAmmo() for uuid=" + uuid.toString() + ", serverKey=" + serverKey); + e.printStackTrace(); + success = false; + } + } + + return success; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/database/dao/MutexDAO.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/database/dao/MutexDAO.java new file mode 100644 index 0000000..feecad8 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/database/dao/MutexDAO.java @@ -0,0 +1,68 @@ +package net.grandtheftmc.gtm.database.dao; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.UUID; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.debug.Log; + +public class MutexDAO { + + /** + * Get the gtm user's mutex. + * <p> + * If this returns true, then the gtm user's mutex is already lent out to + * someone else. If this returns false, then the gtm user's mutex is not yet + * occupied. + * + * @param conn - the database connection thread + * @param uuid - the uuid of the user + * + * @return {@code true} if the gtm user's mutex is already taken, + * {@code false} if the gtm user's mutex is empty. + */ + public static boolean getGTMUserMutex(Connection conn, UUID uuid) { + + boolean mutex = false; + + String query = "SELECT mutex FROM " + Core.name() + " WHERE uuid=UNHEX('" + uuid.toString().replaceAll("-", "") + "')"; + + try (ResultSet result = conn.createStatement().executeQuery(query)) { + if (result.next()) { + mutex = result.getBoolean("mutex"); + } + } + catch (SQLException exc) { + Log.error("Core", "Error executing getUserMutex() for user identified by " + uuid.toString()); + exc.printStackTrace(); + } + + return mutex; + } + + /** + * Updates the gtm user's mutex. + * + * @param conn - the database connection thread + * @param uuid - the uuid of the user + * @param mutex - {@code true} if we still want to occupy the mutex, + * {@code false} otherwise. + */ + public static void setGTMUserMutex(Connection conn, UUID uuid, boolean mutex) { + + String query = "UPDATE " + Core.name() + " SET mutex=? WHERE uuid=UNHEX('" + uuid.toString().replaceAll("-", "") + "')"; + + try (PreparedStatement statement = conn.prepareStatement(query)) { + statement.setBoolean(1, mutex); + + statement.executeUpdate(); + } + catch (SQLException exc) { + Log.error("Core", "Error executing setUserMutex() for user identified by " + uuid.toString()); + exc.printStackTrace(); + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/database/mutex/common/LoadGTMUserTask.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/database/mutex/common/LoadGTMUserTask.java new file mode 100644 index 0000000..bf64671 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/database/mutex/common/LoadGTMUserTask.java @@ -0,0 +1,63 @@ +package net.grandtheftmc.gtm.database.mutex.common; + +import java.sql.Connection; + +import org.bukkit.plugin.Plugin; + +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.database.mutex.task.LoadMutexTask; +import net.grandtheftmc.core.util.debug.Log; +import net.grandtheftmc.gtm.database.dao.MutexDAO; +import net.grandtheftmc.gtm.users.GTMUser; + +public abstract class LoadGTMUserTask extends LoadMutexTask { + + /** The gtm user reference */ + private GTMUser user; + + /** + * Constructs a new LoadGTMUserTask, which attempts to load a gtm user, + * asynchronously. + * + * @param plugin - the owning plugin + * @param user - the gtm user being loaded + */ + public LoadGTMUserTask(Plugin plugin, GTMUser user) { + super(plugin, user); + this.user = user; + + // run async + execute(true); + } + + /** + * {@inheritDoc} + */ + @Override + protected boolean fetchMutex() { + try (Connection conn = BaseDatabase.getInstance().getConnection()) { + return MutexDAO.getGTMUserMutex(conn, user.getUUID()); + } + catch (Exception e) { + e.printStackTrace(); + } + + // else not free + return true; + } + + /** + * {@inheritDoc} + */ + @Override + public void syncMutex() { + // TODO remove + Log.info("TEST-LoadGTMUserTask", "Setting " + user.getUUID() + "'s mutex to " + user.isLocked()); + try (Connection conn = BaseDatabase.getInstance().getConnection()) { + MutexDAO.setGTMUserMutex(conn, user.getUUID(), user.isLocked()); + } + catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/database/mutex/common/SaveGTMUserTask.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/database/mutex/common/SaveGTMUserTask.java new file mode 100644 index 0000000..af45b22 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/database/mutex/common/SaveGTMUserTask.java @@ -0,0 +1,47 @@ +package net.grandtheftmc.gtm.database.mutex.common; + +import java.sql.Connection; + +import org.bukkit.plugin.Plugin; + +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.database.mutex.task.SaveMutexTask; +import net.grandtheftmc.core.util.debug.Log; +import net.grandtheftmc.gtm.database.dao.MutexDAO; +import net.grandtheftmc.gtm.users.GTMUser; + +public abstract class SaveGTMUserTask extends SaveMutexTask { + + /** The gtm user reference */ + private GTMUser user; + + /** + * Constructs a new SaveGTMUserTask, which attempts to save the gtm user, + * asynchronously. + * + * @param plugin - the owning plugin + * @param user - the user being saved + */ + public SaveGTMUserTask(Plugin plugin, GTMUser user) { + super(plugin, user); + this.user = user; + + // run async + execute(true); + } + + /** + * {@inheritDoc} + */ + @Override + public void syncMutex() { + // TODO remove + Log.info("TEST-SaveGTMUserTask", "Setting " + user.getUUID() + "'s mutex to " + user.isLocked()); + try (Connection conn = BaseDatabase.getInstance().getConnection()) { + MutexDAO.setGTMUserMutex(conn, user.getUUID(), user.isLocked()); + } + catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/Drug.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/Drug.java new file mode 100644 index 0000000..04eca1b --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/Drug.java @@ -0,0 +1,56 @@ +package net.grandtheftmc.gtm.drugs; + +import net.grandtheftmc.gtm.drugs.categories.DrugCategory; +import org.bukkit.entity.Player; + +import java.util.Optional; +import java.util.concurrent.TimeUnit; + +/** + * Created by Remco on 25-3-2017. + */ +public abstract class Drug { + + private final String name; + private int duration; + + protected Drug(String name, int duration) { + this.name = name; + this.duration = duration; + } + + /** + * General startpoint for applying drugs. + * + * @param player + * @return + */ + public abstract boolean apply(Player player); + + /** + * Name of the drug + * + * @return + */ + public String getName() { + return name; + } + + + /** + * Duration of the particle effects + * + * @return + */ + public int getDuration() { + return duration; + } + + public Optional<DrugCategory> getCategory() { + return DrugCategory.byDrug(this); + } + + protected Drug getInstance(){ + return this; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/DrugCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/DrugCommand.java new file mode 100644 index 0000000..7e6010d --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/DrugCommand.java @@ -0,0 +1,52 @@ +package net.grandtheftmc.gtm.drugs; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.Collection; + +public class DrugCommand implements CommandExecutor { + public static Collection<String> addingBlocks = new ArrayList<>(); + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!s.hasPermission("gtm.drugs.admin")) { + s.sendMessage(Utils.f("&cYou do not have permission to execute this command!")); + return true; + } + if (!(s instanceof Player)) { + s.sendMessage(Lang.GTM.f("&cYou are not a player!")); + return true; + } + Player player = (Player) s; + if (args.length != 1) { + sendHelp(player); + return true; + } + switch (args[0]) { + case "lb": + case "lockedblock": + if (addingBlocks.contains(player.getName())) { + player.sendMessage(Lang.DRUGS.f("&cYou are no longer adding/removing locked blocks")); + addingBlocks.remove(player.getName()); + } else { + player.sendMessage(Lang.DRUGS.f("&aYou are now adding/removing locked blocks")); + addingBlocks.add(player.getName()); + } + return true; + default: + sendHelp(player); + } + return true; + } + + public void sendHelp(Player player) { + player.sendMessage(Lang.DRUGS.f("&7Usage:")); + player.sendMessage(Utils.f("&a/drugs [lb/lockedblock] &7- Enable/Disable the Adding or Removal of locked blocks")); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/DrugDealer.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/DrugDealer.java new file mode 100644 index 0000000..28e24e4 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/DrugDealer.java @@ -0,0 +1,172 @@ +package net.grandtheftmc.gtm.drugs; + +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.drugs.item.DrugDealerItem; +import net.grandtheftmc.gtm.drugs.item.DrugItem; +import org.bukkit.Location; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; + +import java.util.*; +import java.util.concurrent.ThreadLocalRandom; +import java.util.logging.Level; +import java.util.stream.Collectors; + +public class DrugDealer { + private final Collection<Location> dealerLocations = new ArrayList<>(); + private final Set<DrugDealerItem> drugDealerItems = new HashSet<>(); + private final BukkitTask dealerTask; + private ArmorStand stand = null; + + public DrugDealer() { + loadLocations(); + loadDealerItems(); + dealerTask = new BukkitRunnable() { + @Override + public void run() { + try { + if (stand != null) { + Collection<ArmorStand> dealers = new ArrayList<>(); + for (LivingEntity entity : stand.getWorld().getLivingEntities()) { + if (entity.getType() != EntityType.ARMOR_STAND) continue; + ArmorStand armorStand = (ArmorStand) entity; + if (armorStand.getHelmet().getType() == GTM.getItemManager().getItem("rastahat").getItem().getType() + && armorStand.getItemInHand().getType() == GTM.getItemManager().getItem("joint").getItem().getType()) { + dealers.add(armorStand); + } + } + if (!dealers.isEmpty()) { + for (ArmorStand armorStand : dealers) { + armorStand.setHealth(0); + armorStand.remove(); + } + } + } + Optional<Location> randomLoc = getRandomLoc(); + randomLoc.ifPresent(location -> setLocation(location)); + } catch (Exception e) { + e.printStackTrace(); + cancel(); + } + } + }.runTaskTimer(GTM.getInstance(), 200, 34000); + } + + public void stop() { + saveLocations(); + if (stand != null) stand.remove(); + dealerTask.cancel(); + } + + public boolean isDrugDealer(Entity e) { + return e.equals(stand); + } + + public void addDealerLoc(Location loc) { + dealerLocations.add(loc); + } + + public void loadDealerItems() { + YamlConfiguration c = GTM.getSettings().getDrugDealerConfig(); + DrugService service = (DrugService) GTM.getDrugManager().getService(); + service.getDrugs().stream().forEach(drug -> { + DrugItem item = DrugItem.getByDrug(drug); + if (item != null) { + int stockMin = c.getString("drugs." + drug.getName().toLowerCase() + ".min") != null ? c.getInt("drugs." + drug.getName().toLowerCase() + ".min") : 1; + int stockMax = c.getString("drugs." + drug.getName().toLowerCase() + ".max") != null ? c.getInt("drugs." + drug.getName().toLowerCase() + ".max") : 10; + int chance = c.getString("drugs." + drug.getName().toLowerCase() + ".chance") != null ? c.getInt("drugs." + drug.getName().toLowerCase() + ".chance") : 5; + int minPrice = c.getString("drugs." + drug.getName().toLowerCase() + ".minprice") != null ? c.getInt("drugs." + drug.getName().toLowerCase() + ".minprice") : -1; + int maxPrice = c.getString("drugs." + drug.getName().toLowerCase() + ".maxprice") != null ? c.getInt("drugs." + drug.getName().toLowerCase() + ".maxprice") : -1; + + if (stockMax == -1 || stockMin == -1 || chance == -1 || minPrice == -1 || maxPrice == -1) { + GTM.getInstance().getLogger().log(Level.SEVERE, "Unable to parse number for drug: " + drug.getName().toLowerCase() + " min=" + stockMin + " max=" + stockMax + " chance=" + chance + " minPrice=" + minPrice + " maxPrice=" + maxPrice); + } + drugDealerItems.add(new DrugDealerItem(item, stockMin, stockMax, chance, minPrice, maxPrice)); + } else { + GTM.getInstance().getLogger().log(Level.SEVERE, "Unable to find DrugItem for drug: " + drug); + } + }); + } + + public void rerollStock() { + drugDealerItems.stream().forEach(DrugDealerItem::reroll); + } + + public void loadLocations() { + GTM.getSettings().setDrugDealerConfig(Utils.loadConfig("drugdealer")); + dealerLocations.clear(); + YamlConfiguration c = GTM.getSettings().getDrugDealerConfig(); + if (!c.getStringList("locs").isEmpty()) { + for (String loc : c.getStringList("locs")) { + GTMUtils.deserializeLocation(loc).ifPresent(dealerLocations::add); + } + } + } + + public void saveLocations() { + YamlConfiguration c = GTM.getSettings().getDrugDealerConfig(); + List<String> locs = dealerLocations.stream().map(GTMUtils::serializeLocation).collect(Collectors.toList()); + c.set("locs", locs); + Utils.saveConfig(c, "drugdealer"); + } + + public Set<DrugDealerItem> getItems() { + return drugDealerItems; + } + + public Collection<Location> getDealerLocations() { + return dealerLocations; + } + + private void initStand(Location loc) { + if (stand != null) { + stand.setHealth(0); + stand.remove(); + } + stand = (ArmorStand) loc.getWorld().spawnEntity(loc, EntityType.ARMOR_STAND); + stand.setHealth(stand.getMaxHealth()); + stand.setCustomName(Utils.f("&8&lDrug Dealer")); + stand.setCustomNameVisible(true); + stand.setAI(false); + stand.setCollidable(false); + stand.setInvulnerable(true); + stand.setCanPickupItems(false); + stand.setGravity(false); + stand.setRemoveWhenFarAway(false); + stand.setBasePlate(false); + stand.setArms(true); + stand.setVisible(true); + stand.setHelmet(GTM.getItemManager().getItem("rastahat").getItem()); + stand.setChestplate(GTM.getItemManager().getItem("shirt").getItem()); + stand.setLeggings(GTM.getItemManager().getItem("pants").getItem()); + stand.setBoots(GTM.getItemManager().getItem("nikes").getItem()); + stand.setItemInHand(GTM.getItemManager().getItem("joint").getItem()); + } + + public void setLocation(Location loc) { + if (stand == null || stand.isDead() || !stand.isVisible() || !stand.isValid()) initStand(loc); + stand.teleport(loc); + rerollStock(); + } + + public Optional<Location> getRandomLoc() { + if (stand == null || this.dealerLocations.size() == 1) return this.dealerLocations.stream().findFirst(); + List<Location> locs = this.dealerLocations + .stream() + .filter(location -> !location.equals(stand.getLocation())) + .collect(Collectors.toList()); + return Optional.of(locs.get(ThreadLocalRandom.current().nextInt(locs.size()))); + } + + public LivingEntity dealerStand() { + return this.stand; + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/DrugEffect.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/DrugEffect.java new file mode 100644 index 0000000..7c15a33 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/DrugEffect.java @@ -0,0 +1,15 @@ +package net.grandtheftmc.gtm.drugs; + +import org.bukkit.entity.Player; + +import java.util.concurrent.TimeUnit; + +/** + * Created by Remco on 25-3-2017. + */ +@FunctionalInterface +public interface DrugEffect { + + void apply(Drug drug, int duration, Player player); + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/DrugHelper.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/DrugHelper.java new file mode 100644 index 0000000..1c3e3f2 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/DrugHelper.java @@ -0,0 +1,26 @@ +package net.grandtheftmc.gtm.drugs; + +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.drugs.internal.service.Helper; +import net.grandtheftmc.gtm.drugs.internal.service.Service; + +/** + * Created by Remco on 25-3-2017. + */ +public class DrugHelper implements Helper { + + @Override + public String getHelperName() { + return "Drug Helper"; + } + + @Override + public Class<? extends Service> getServiceClass() { + return DrugService.class; + } + + private DrugService getService() { + return (DrugService) GTM.getInstance().getDrugManager().getService(); + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/DrugManager.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/DrugManager.java new file mode 100644 index 0000000..6d4fd67 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/DrugManager.java @@ -0,0 +1,138 @@ +package net.grandtheftmc.gtm.drugs; + +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.drugs.example.*; +import net.grandtheftmc.gtm.drugs.example.lsd.LSD; +import net.grandtheftmc.gtm.drugs.internal.manager.Manager; +import net.grandtheftmc.gtm.drugs.item.DrugItem; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; + +public class DrugManager extends Manager { + private EffectManager effectManager; + private DrugDealer drugDealer; + private LockedBlocks lockedBlocks; + private final Set<UUID> ods = new HashSet<>(); + private Set<UUID> unmoveable = new HashSet<>(); + + public DrugManager() { + super("Drug Manager", new AtomicInteger(1), new DrugService()); + } + + @Override + public void start() { + DrugService service = (DrugService) getService(); + + ItemStack roofiedChocolate = DrugUtil.setDisplayName(new ItemStack(Material.RAW_FISH, 1), Utils.f("&b&lRoofied Chocolate")); + roofiedChocolate = DrugUtil.addLore(roofiedChocolate, "&7Just an inconspicuous piece of chocolate"); + service.addDrug(new RoofiedChocolate(), new DrugItem(roofiedChocolate, new RoofiedChocolate())); + + ItemStack mdma = DrugUtil.setDisplayName(new ItemStack(Material.RECORD_11, 1), Utils.f("&e&lMDMA")); + mdma = DrugUtil.hideDurability(mdma); + mdma = DrugUtil.addLore(mdma, "&7Take me to a higher place!"); + service.addDrug(new MDMA(), new DrugItem(mdma, new MDMA())); + + ItemStack lsd = DrugUtil.setDisplayName(new ItemStack(Material.GOLD_RECORD, 1), Utils.f("&d&lLSD")); + lsd = DrugUtil.hideDurability(lsd); + service.addDrug(new LSD(), new DrugItem(lsd, new LSD())); + + ItemStack weed = DrugUtil.setDisplayName(new ItemStack(Material.RECORD_5, 1), Utils.f("&2&lWeed Buds")); + weed = DrugUtil.hideDurability(weed); + service.addDrug(new Weed(), new DrugItem(weed, new Weed())); + + ItemStack joint = DrugUtil.setDisplayName(new ItemStack(Material.RECORD_3, 1), Utils.f("&2&lJoint")); + joint = DrugUtil.hideDurability(joint); + service.addDrug(new Joint(), new DrugItem(joint, new Joint())); + + ItemStack steroids = DrugUtil.setDisplayName(new ItemStack(Material.FLINT_AND_STEEL, 1), Utils.f("&c&lBull Shark Testosterone")); + steroids = DrugUtil.hideDurability(steroids); + steroids = DrugUtil.addLore(steroids, "&7Don’t mess with me!"); + steroids.setDurability((short) 3); + service.addDrug(new Steroids(), new DrugItem(steroids, new Steroids())); + + ItemStack alcohol = DrugUtil.setDisplayName(new ItemStack(Material.FLINT_AND_STEEL, 1), Utils.f("&e&lBeer")); + alcohol = DrugUtil.hideDurability(alcohol); + alcohol.setDurability((short) 1); + service.addDrug(new Alcohol(), new DrugItem(alcohol, new Alcohol())); + + ItemStack meth = DrugUtil.setDisplayName(new ItemStack(Material.FLINT_AND_STEEL, 1), Utils.f("&c&lMeth Pipe")); + meth = DrugUtil.hideDurability(meth); + meth.setDurability((short) 4); + service.addDrug(new Meth(), new DrugItem(meth, new Meth())); + + ItemStack cocaine = DrugUtil.setDisplayName(new ItemStack(Material.RECORD_4, 1), Utils.f("&f&lCocaine")); + cocaine = DrugUtil.hideDurability(cocaine); + service.addDrug(new Cocaine(), new DrugItem(cocaine, new Cocaine())); + + ItemStack heroin = DrugUtil.setDisplayName(new ItemStack(Material.FLINT_AND_STEEL, 1), Utils.f("&b&lHeroin Syringe")); + heroin = DrugUtil.hideDurability(heroin); + heroin = DrugUtil.addLore(heroin, "&7Stick this thing in my arm!"); + heroin.setDurability((short) 5); + service.addDrug(new Heroin(), new DrugItem(heroin, new Heroin())); + + this.drugDealer = new DrugDealer(); + this.effectManager = new EffectManager(); + this.lockedBlocks = new LockedBlocks(); + } + + @Override + public void stop() { + this.drugDealer.stop(); + this.lockedBlocks.save(); + } + + @Override + public boolean destroy() { + return false; + } + + public DrugDealer getDrugDealer() {//added 'get' because I dont think it makes sense to do .drugDealer().drugDealer() to get drug dealer entity + return this.drugDealer; + } + + public EffectManager getEffectManager(){ + return this.effectManager; + } + + public LockedBlocks getLockedBlocks() { + return this.lockedBlocks; + } + + /** + * @param uuid the uuid of the player + * + * @return if the player CAN OD again + */ + public boolean inOD(UUID uuid){ + return this.ods.contains(uuid); + } + + + /*** + * @param uuid uuid of the player + * + * Use when a player has OD'd (at the start of the OD sequence) + */ + public void addOD(UUID uuid){ + if(!this.ods.contains(uuid)){ + this.ods.add(uuid); + } + } + + /** + * @param uuid the player + * + * Use after the OD has completed (at the end of the same OD sequence) + */ + public void removeOD(UUID uuid){ + if(this.ods.contains(uuid)){ + this.ods.remove(uuid); + } + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/DrugParam.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/DrugParam.java new file mode 100644 index 0000000..68e75fa --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/DrugParam.java @@ -0,0 +1,17 @@ +package net.grandtheftmc.gtm.drugs; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Created by Remco on 25-3-2017. + */ + +@Documented +@Retention(RetentionPolicy.RUNTIME) +public @interface DrugParam { + + FunctionalInterface value(); + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/DrugService.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/DrugService.java new file mode 100644 index 0000000..86db7ae --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/DrugService.java @@ -0,0 +1,70 @@ +package net.grandtheftmc.gtm.drugs; + +import com.google.common.collect.HashBasedTable; +import com.google.common.collect.Table; +import net.grandtheftmc.gtm.drugs.internal.service.Service; +import net.grandtheftmc.gtm.drugs.item.DrugItem; +import org.bukkit.inventory.ItemStack; + +import java.util.Collection; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +/** + * Created by Remco on 25-3-2017. + */ +public class DrugService extends Service { + + //All items, sorted on: + private final Table<DrugParam[], DrugItem, Drug> items = HashBasedTable.create(); + + public DrugService() { + super("Drug Item Service", new DrugHelper()); + } + + public Drug addDrug(Drug drug, DrugItem item, DrugParam... params) { + if (this.items.columnKeySet().stream().noneMatch((match) -> false)) { + items.put(params, item, drug); + return drug; + } + return null; + } + + public final Collection<Drug> getDrugs() { + return items.values(); + } + + public final Set<DrugItem> getItems() { + return items.columnKeySet(); + } + + public Drug getDrug(ItemStack item) { + return getDrug(DrugItem.getByItemStack(item)); + } + + public Drug getDrug(DrugItem drugItem) { + return items.columnMap().values().stream().map(Map::values).filter(drugs -> drugs.stream().findFirst().isPresent() && drugs.stream().anyMatch(drugItem::isValid)).map((drug) -> drug.stream().findFirst().get()).findFirst().orElse(null); + } + + public Optional<Drug> getDrug(String name) { + Optional<Drug> drug = items.values().stream().filter(targetDrug -> targetDrug.getName().equalsIgnoreCase(name)).findFirst(); + if (!drug.isPresent()) return Optional.empty(); + return drug; + } + + public Optional<DrugItem> getDrugItem(String name) { + Optional<DrugItem> drug = items.columnKeySet().stream().filter(drugItem -> drugItem.getItemStack().getItemMeta().getDisplayName().equals(name)).findFirst(); + if (!drug.isPresent()) return Optional.empty(); + return drug; + } + + public Set<DrugItem> getAllDrugItems(){ + return items.columnKeySet(); + } + + public Table<DrugParam[], DrugItem, Drug> getRawItems(){ + return items; + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/DrugUtil.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/DrugUtil.java new file mode 100644 index 0000000..08b8a22 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/DrugUtil.java @@ -0,0 +1,195 @@ +package net.grandtheftmc.gtm.drugs; + +import net.grandtheftmc.core.util.Utils; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.*; +import java.util.concurrent.ThreadLocalRandom; + +public class DrugUtil { + private static final Collection<Material> IGNORE_BLOCKS = Arrays.asList(Material.AIR, Material.SIGN, Material.SIGN_POST, + Material.WALL_SIGN, Material.IRON_DOOR, Material.IRON_DOOR_BLOCK, Material.CHEST, + Material.WOODEN_DOOR, Material.WOOD_DOOR, Material.WATER, Material.STATIONARY_WATER, Material.LAVA, Material.STATIONARY_LAVA); + + public static Sound getRandomParanoiaSound() { + int roll = ThreadLocalRandom.current().nextInt(0, 5); + switch (roll) { + default: + case 0: + return Sound.ENTITY_GHAST_SCREAM; + case 1: + return Sound.ENTITY_ZOMBIE_AMBIENT; + case 2: + return Sound.ENTITY_GHAST_AMBIENT; + case 3: + return Sound.ENTITY_SPIDER_AMBIENT; + case 4: + return Sound.ENTITY_CREEPER_PRIMED; + } + } + + public static Sound getRandomAmbientSound() { + int roll = ThreadLocalRandom.current().nextInt(0, 9); + switch (roll) { + default: + case 0: + return Sound.AMBIENT_CAVE; + case 1: + return Sound.ENTITY_RABBIT_AMBIENT; + case 2: + return Sound.ENTITY_BAT_AMBIENT; + case 3: + return Sound.ENTITY_CREEPER_PRIMED; + case 4: + return Sound.ENTITY_CAT_AMBIENT; + case 5: + return Sound.ENTITY_ENDERDRAGON_FIREBALL_EXPLODE; + case 6: + return Sound.BLOCK_CLOTH_BREAK; + case 7: + return Sound.ENTITY_ZOMBIE_INFECT; + case 8: + return Sound.ENTITY_ZOMBIE_PIG_ANGRY; + } + } + + public static String getParanoiaMessage(){ + switch(ThreadLocalRandom.current().nextInt( 10)){ + case 0: + return "They are always watching you"; + case 1: + return "I can see you"; + case 2: + return "I know where you live"; + case 3: + return "There is a camera in front of you, say hi :)"; + case 4: + return "Don't go home, it's not safe"; + case 5: + return "Even when you don't see me I am there"; + case 6: + return "The computer never turns off"; + case 7: + return "The police know what you have done"; + case 8: + return "I can see what you do behind closed doors"; + case 9: + return "I am the monster under your bed"; + default: + return ""; + } + } + + + /*ublic static void sendWorldEnvironment(Player player, World.Environment environment) { + CraftPlayer craftPlayer = (CraftPlayer) player; + CraftWorld world = (CraftWorld) player.getWorld(); + Location location = player.getLocation(); + + PacketPlayOutRespawn packet = new PacketPlayOutRespawn(environment.getId(), EnumDifficulty.getById(world.getDifficulty().getValue()), WorldType.NORMAL, EnumGamemode.getById(player.getGameMode().getValue())); + + craftPlayer.getHandle().playerConnection.sendPacket(packet); + + int viewDistance = GTM.getInstance().getServer().getViewDistance(); + + int xMin = location.getChunk().getX() - viewDistance; + int xMax = location.getChunk().getX() + viewDistance; + int zMin = location.getChunk().getZ() - viewDistance; + int zMax = location.getChunk().getZ() + viewDistance; + + for (int x = xMin; x < xMax; ++x){ + for (int z = zMin; z < zMax; ++z){ + world.refreshChunk(x, z); + } + } + + player.updateInventory(); + + player.teleport(player.getLocation()); + }*/ + + + public static Collection<Block> getNearbyBlocks(Location location, int radius) { + Collection<Block> blocks = new ArrayList<>(); + + for (int x = location.getBlockX() - radius ; x <= location.getBlockX() + radius ; x++) { + for (int z = location.getBlockZ() - radius ; z <= location.getBlockZ() + radius ; z++) { + for(int y = location.getBlockY() - radius ; y <= location.getBlockY() + radius; y++) { + Block block = location.getWorld().getBlockAt(x, y, z); + if (!block.isEmpty() && !IGNORE_BLOCKS.contains(block.getType())) { + blocks.add(block); + } + } + } + } + return blocks; + } + + public static ItemStack setDisplayName(ItemStack itemStack, String displayName) { + ItemMeta itemMeta = itemStack.getItemMeta(); + itemMeta.setDisplayName(displayName); + itemStack.setItemMeta(itemMeta); + return itemStack; + } + + public static ItemStack addLore(ItemStack itemStack, String... lore) { + ItemMeta itemMeta = itemStack.getItemMeta(); + List<String> lores = itemMeta.hasLore() ? itemMeta.getLore() : new ArrayList<>(); + for (String a : lore) lores.add(Utils.f(a)); + itemMeta.setLore(lores); + itemStack.setItemMeta(itemMeta); + return itemStack; + } + + public static ItemStack clearLore(ItemStack itemStack) { + ItemMeta itemMeta = itemStack.getItemMeta(); + itemMeta.setLore(new ArrayList<>()); + itemStack.setItemMeta(itemMeta); + return itemStack; + } + + public static ItemStack hideDurability(ItemStack itemStack) { + ItemStack is = itemStack.clone(); + ItemMeta itemMeta = is.getItemMeta(); + itemMeta.spigot().setUnbreakable(true); + itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, + ItemFlag.HIDE_UNBREAKABLE, + ItemFlag.HIDE_PLACED_ON, + ItemFlag.HIDE_ENCHANTS, + ItemFlag.HIDE_POTION_EFFECTS, + ItemFlag.HIDE_DESTROYS); + is.setItemMeta(itemMeta); + return is; + } + + public static Optional<Map<Integer, ItemStack>> findItem(Inventory inventory, ItemStack itemStack) { + Map<Integer, ItemStack> map = new HashMap<>(); + for (int i = 0; i < inventory.getSize(); i++) { + if (inventory.getItem(i) == null) continue; + ItemStack search = inventory.getItem(i); + System.out.print(search.getType().toString() + " :: " + + itemStack.getType().toString()); + System.out.print(search.getData().getData() + " :: " + + itemStack.getData().getData()); + System.out.print(search.getItemMeta().getDisplayName() + " :: " + + itemStack.getItemMeta().getDisplayName()); + if (search.getType() == itemStack.getType() + && search.getData().getData() == itemStack.getData().getData() + && search.getItemMeta().getDisplayName().equals(itemStack.getItemMeta().getDisplayName())) { + map.put(i, search); + System.out.print("found"); + break; + } + } + return map.isEmpty() ? Optional.empty() : Optional.of(map); + } + + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/EffectManager.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/EffectManager.java new file mode 100644 index 0000000..9b8eb2c --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/EffectManager.java @@ -0,0 +1,48 @@ +package net.grandtheftmc.gtm.drugs; + +import net.grandtheftmc.gtm.GTM; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; + +import java.util.HashMap; +import java.util.UUID; + +public class EffectManager { + + private final HashMap<UUID, Long> cancelEffects = new HashMap<>(); + + /** + * @param player the player who will be getting the effect + * @param effect the effect that may be addded / extended + */ + public void addEffect(Player player, PotionEffect effect) { + Bukkit.getScheduler().runTask(GTM.getInstance(), () -> { + player.addPotionEffect(effect); + }); + } + + /** + * @param player the player who is being checked + * @param origTime the time that the player originally used the drug* + * @return true if the player is still able to have the drug effects + */ + public boolean canRecieveOngoingEffect(Player player, long origTime) { + return player.isOnline() && player.isValid() && cancelEffects.getOrDefault(player.getUniqueId(), (long) 0) <= origTime; + } + + + /** + * @param player the player whose effects will be cancelled + */ + public void cancelEffects(Player player) { + Bukkit.getScheduler().runTask(GTM.getInstance(), () -> { + if (!cancelEffects.containsKey(player.getUniqueId())) { + cancelEffects.put(player.getUniqueId(), System.currentTimeMillis()); + } + for (PotionEffect p : player.getActivePotionEffects()) { + player.removePotionEffect(p.getType()); + } + }); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/LockedBlocks.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/LockedBlocks.java new file mode 100644 index 0000000..72f8b29 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/LockedBlocks.java @@ -0,0 +1,46 @@ +package net.grandtheftmc.gtm.drugs; + +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import org.bukkit.Location; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Optional; + +public class LockedBlocks { + private Collection<Location> lockedBlocks; + private YamlConfiguration config; + + public LockedBlocks() { + this.lockedBlocks = new ArrayList<>(); + this.config = GTM.getSettings().getDrugBlocksConfig(); + load(); + } + + public void load() { + if (!config.getStringList("blocks").isEmpty()) { + for (String stringLoc : config.getStringList("blocks")) { + Optional<Location> location = GTMUtils.deserializeLocation(stringLoc); + if (location.isPresent()) this.lockedBlocks.add(location.get()); + } + } + } + + public void save() { + List<String> serializedLocs = new ArrayList<>(); + this.lockedBlocks.forEach(location -> { + serializedLocs.add(GTMUtils.serializeLocation(location)); + }); + config.set("blocks", serializedLocs); + Utils.saveConfig(config, "drugblocks"); + } + + public Collection<Location> getLocations() { + return this.lockedBlocks; + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/DrugCategory.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/DrugCategory.java new file mode 100644 index 0000000..fc83c0a --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/DrugCategory.java @@ -0,0 +1,37 @@ +package net.grandtheftmc.gtm.drugs.categories; + +import net.grandtheftmc.gtm.drugs.Drug; +import net.grandtheftmc.gtm.drugs.categories.examples.*; + +import java.util.Arrays; +import java.util.Optional; + +/** + * Created by Remco on 25-3-2017. + */ +public enum DrugCategory { + + STIMULANTS(Stimulants.class), + INHALANTS(Inhalants.class), + CANNABINOIDS(Cannabinoids.class), + DEPRESSANTS(Depressants.class), + OPIOIDS(Opioids.class), + ANABOLIC_STEROIDS(AnabolicSteroids.class), + HALLUCINOGENS(Hallucinogens.class), + ALCOHOL(AAlcohol.class), + PRESCRIPTION_DRUGS(PrescriptionDrugs.class); + + private final Class<?>[] categories; + + DrugCategory(Class<?>... categories) { + this.categories = categories; + } + + public Class<?>[] getCategories() { + return categories; + } + + public static Optional<DrugCategory> byDrug(Drug drug){ + return Arrays.stream(values()).filter((categorie) -> Arrays.stream(categorie.categories).anyMatch((categoryClass) -> categoryClass.equals(drug.getClass().getSuperclass()))).findFirst(); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/IDrugCategory.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/IDrugCategory.java new file mode 100644 index 0000000..7c19f97 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/IDrugCategory.java @@ -0,0 +1,20 @@ +package net.grandtheftmc.gtm.drugs.categories; + +/** + * Created by Remco on 25-3-2017. + */ +public interface IDrugCategory { + + /** + * The name of the current Category, so we can define it somewhere. + * @return name + */ + String name(); + + /** + * The general description of the category of Drug. + * @return description + */ + String description(); + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/examples/AAlcohol.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/examples/AAlcohol.java new file mode 100644 index 0000000..6ec3291 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/examples/AAlcohol.java @@ -0,0 +1,26 @@ +package net.grandtheftmc.gtm.drugs.categories.examples; + +import net.grandtheftmc.gtm.drugs.Drug; +import net.grandtheftmc.gtm.drugs.categories.IDrugCategory; + +import java.util.concurrent.TimeUnit; + +/** + * Created by Remco on 25-3-2017. + */ +public abstract class AAlcohol extends Drug implements IDrugCategory { + + protected AAlcohol(String name, int duration) { + super(name, duration); + } + + @Override + public String name() { + return "Alcohol"; + } + + @Override + public String description() { + return "Can make you feel very special. You won't be walking straight if you drink too much though."; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/examples/AnabolicSteroids.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/examples/AnabolicSteroids.java new file mode 100644 index 0000000..d19559b --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/examples/AnabolicSteroids.java @@ -0,0 +1,26 @@ +package net.grandtheftmc.gtm.drugs.categories.examples; + +import net.grandtheftmc.gtm.drugs.Drug; +import net.grandtheftmc.gtm.drugs.categories.IDrugCategory; + +import java.util.concurrent.TimeUnit; + +/** + * Created by Remco on 25-3-2017. + */ +public abstract class AnabolicSteroids extends Drug implements IDrugCategory { + + protected AnabolicSteroids(String name, int duration) { + super(name, duration); + } + + @Override + public String name() { + return "Anabolic Steroids"; + } + + @Override + public String description() { + return "Improves physical performance, enlarges muscles and increases strength."; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/examples/Cannabinoids.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/examples/Cannabinoids.java new file mode 100644 index 0000000..ee93ec8 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/examples/Cannabinoids.java @@ -0,0 +1,27 @@ +package net.grandtheftmc.gtm.drugs.categories.examples; + +import net.grandtheftmc.gtm.drugs.Drug; +import net.grandtheftmc.gtm.drugs.categories.IDrugCategory; +import org.bukkit.inventory.ItemStack; + +import java.util.concurrent.TimeUnit; + +/** + * Created by Remco on 25-3-2017. + */ +public abstract class Cannabinoids extends Drug implements IDrugCategory { + + protected Cannabinoids(String name, int duration) { + super(name, duration); + } + + @Override + public String name() { + return "Cannabinoids"; + } + + @Override + public String description() { + return "Give you a feeling of euphoria. May cause confusion, memory problems, anxiety and a higher heart rate."; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/examples/Depressants.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/examples/Depressants.java new file mode 100644 index 0000000..df85ba6 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/examples/Depressants.java @@ -0,0 +1,26 @@ +package net.grandtheftmc.gtm.drugs.categories.examples; + +import net.grandtheftmc.gtm.drugs.Drug; +import net.grandtheftmc.gtm.drugs.categories.IDrugCategory; + +import java.util.concurrent.TimeUnit; + +/** + * Created by Remco on 25-3-2017. + */ +public abstract class Depressants extends Drug implements IDrugCategory { + + protected Depressants(String name, int duration) { + super(name, duration); + } + + @Override + public String name() { + return "Depressants"; + } + + @Override + public String description() { + return "Slows down activity in the central nervous system. They slow down the body and give you the feeling of relaxation."; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/examples/Hallucinogens.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/examples/Hallucinogens.java new file mode 100644 index 0000000..9c5894e --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/examples/Hallucinogens.java @@ -0,0 +1,26 @@ +package net.grandtheftmc.gtm.drugs.categories.examples; + +import net.grandtheftmc.gtm.drugs.Drug; +import net.grandtheftmc.gtm.drugs.categories.IDrugCategory; + +import java.util.concurrent.TimeUnit; + +/** + * Created by Remco on 25-3-2017. + */ +public abstract class Hallucinogens extends Drug implements IDrugCategory { + + protected Hallucinogens(String name, int duration) { + super(name, duration); + } + + @Override + public String name() { + return "Hallucinogens"; + } + + @Override + public String description() { + return "Change the mind and cause the appearance of things that are not really there."; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/examples/Inhalants.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/examples/Inhalants.java new file mode 100644 index 0000000..31edcfe --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/examples/Inhalants.java @@ -0,0 +1,27 @@ +package net.grandtheftmc.gtm.drugs.categories.examples; + +import net.grandtheftmc.gtm.drugs.Drug; +import net.grandtheftmc.gtm.drugs.categories.IDrugCategory; + +import java.util.concurrent.TimeUnit; + +/** + * Created by Remco on 25-3-2017. + */ +public abstract class Inhalants extends Drug implements IDrugCategory{ + + protected Inhalants(String name, int duration) { + super(name, duration); + + } + + @Override + public String name() { + return "Inhalants"; + } + + @Override + public String description() { + return "Give you immediate results. These can have sudden mental damage."; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/examples/Opioids.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/examples/Opioids.java new file mode 100644 index 0000000..750d7cd --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/examples/Opioids.java @@ -0,0 +1,26 @@ +package net.grandtheftmc.gtm.drugs.categories.examples; + +import net.grandtheftmc.gtm.drugs.Drug; +import net.grandtheftmc.gtm.drugs.categories.IDrugCategory; + +import java.util.concurrent.TimeUnit; + +/** + * Created by Remco on 25-3-2017. + */ +public abstract class Opioids extends Drug implements IDrugCategory { + + protected Opioids(String name, int duration) { + super(name, duration); + } + + @Override + public String name() { + return "Opioids"; + } + + @Override + public String description() { + return "Can cause drowsiness, confusion, nausea, feeligns of euphoria, respiratory complications and relieve pain."; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/examples/PrescriptionDrugs.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/examples/PrescriptionDrugs.java new file mode 100644 index 0000000..5921dcf --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/examples/PrescriptionDrugs.java @@ -0,0 +1,27 @@ +package net.grandtheftmc.gtm.drugs.categories.examples; + +import net.grandtheftmc.gtm.drugs.Drug; +import net.grandtheftmc.gtm.drugs.categories.IDrugCategory; + +import java.util.concurrent.TimeUnit; + +/** + * Created by Remco on 25-3-2017. + */ +public abstract class PrescriptionDrugs extends Drug implements IDrugCategory { + + protected PrescriptionDrugs(String name, int duration) { + super(name, duration); + + } + + @Override + public String name() { + return "Prescription Drugs"; + } + + @Override + public String description() { + return "Can be very helpful (if used wisely). Can be very dangerous."; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/examples/Stimulants.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/examples/Stimulants.java new file mode 100644 index 0000000..ffbcea9 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/categories/examples/Stimulants.java @@ -0,0 +1,27 @@ +package net.grandtheftmc.gtm.drugs.categories.examples; + +import net.grandtheftmc.gtm.drugs.Drug; +import net.grandtheftmc.gtm.drugs.categories.IDrugCategory; + +import java.util.concurrent.TimeUnit; + +/** + * Created by Remco on 25-3-2017. + */ +public abstract class Stimulants extends Drug implements IDrugCategory { + + protected Stimulants(String name, int duration) { + super(name, duration); + } + + @Override + public String name() { + return "Stimulants"; + } + + @Override + public String description() { + return "Speeds up your nevous system and make you feel very alive. Also known as \"uppers\" because of their ability to make you feel very awake."; + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/events/DrugUseEvent.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/events/DrugUseEvent.java new file mode 100644 index 0000000..57123a0 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/events/DrugUseEvent.java @@ -0,0 +1,52 @@ +package net.grandtheftmc.gtm.drugs.events; + +import net.grandtheftmc.gtm.drugs.Drug; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * Created by Remco on 25-3-2017. + */ +public class DrugUseEvent extends Event implements Cancellable { + + private final static HandlerList handlers = new HandlerList(); + + private boolean cancelled; + private final Player user; + private final Drug drug; + + public DrugUseEvent(Player user, Drug drug) { + this.user = user; + this.drug = drug; + this.cancelled = false; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean b) { + this.cancelled = b; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandler(){ + return handlers; + } + + public Player getUser() { + return user; + } + + public Drug getDrug() { + return drug; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/events/listener/DrugListener.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/events/listener/DrugListener.java new file mode 100644 index 0000000..0eb901a --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/events/listener/DrugListener.java @@ -0,0 +1,68 @@ +package net.grandtheftmc.gtm.drugs.events.listener; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.drugs.Drug; +import net.grandtheftmc.gtm.drugs.DrugService; +import net.grandtheftmc.gtm.drugs.example.Alcohol; +import net.grandtheftmc.gtm.drugs.example.Cocaine; +import net.grandtheftmc.gtm.drugs.example.Heroin; +import net.grandtheftmc.gtm.drugs.example.Weed; +import net.grandtheftmc.gtm.drugs.item.DrugItem; +import net.grandtheftmc.gtm.users.GTMUser; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; + +import java.util.Optional; + +public class DrugListener implements Listener { + + @EventHandler + public void onEat(PlayerInteractEvent event) { + Player player = event.getPlayer(); + ItemStack is = event.getItem(); + if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) { + if (is != null && is.getItemMeta() != null) { + DrugItem item = DrugItem.getByItemStack(is); + DrugService drugService = (DrugService) GTM.getInstance().getDrugManager().getService(); + if (item != null) { + if (drugService.getDrugs().stream().anyMatch(item::isValid)) { + Drug drug = drugService.getDrug(item); + if (drug != null && !(drug instanceof Weed) && !(drug instanceof Cocaine)) { + if (drug.apply(player)) { + if (event.getItem().getAmount() > 1) { + player.getInventory().getItemInMainHand().setAmount(event.getItem().getAmount() - 1); + } else { + player.getInventory().setItemInMainHand(null); + } + event.setCancelled(true); + } + } + } + } else { + if(GTM.getItemManager().getItem("vodka") != null) { + if (is.isSimilar(GTM.getItemManager().getItem("vodka").getItem())) { + Optional<Drug> alcohol = ((DrugService) GTM.getInstance().getDrugManager().getService()).getDrug("weed"); + if (alcohol.isPresent()) { + ((Alcohol) alcohol.get()).potentApply(player, true); + if (event.getItem().getAmount() > 1) { + player.getInventory().getItemInMainHand().setAmount(event.getItem().getAmount() - 1); + } else { + player.getInventory().setItemInMainHand(null); + } + event.setCancelled(true); + } + } + } + } + } + } + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/events/listener/DrugPlacementListener.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/events/listener/DrugPlacementListener.java new file mode 100644 index 0000000..a175f4a --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/events/listener/DrugPlacementListener.java @@ -0,0 +1,200 @@ +package net.grandtheftmc.gtm.drugs.events.listener; + +import java.util.Optional; +import java.util.logging.Level; + +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.drugs.Drug; +import net.grandtheftmc.gtm.drugs.DrugCommand; +import net.grandtheftmc.gtm.drugs.DrugService; +import net.grandtheftmc.gtm.drugs.LockedBlocks; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.houses.PremiumHouse; +import net.grandtheftmc.houses.users.HouseUser; + +public class DrugPlacementListener implements Listener { + + @EventHandler + public void onInteract(PlayerInteractEvent event) { + if (event.getClickedBlock() == null) return; + Player player = event.getPlayer(); + if (player.getWorld().getName().equals("spawn")) return; + Block block = event.getClickedBlock(); + Location blockLocation = block.getLocation(); + HouseUser houseUser = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + ItemStack hand = player.getInventory().getItemInMainHand(); + + // if right clicking a block + if (event.getAction() == Action.RIGHT_CLICK_BLOCK) { + + // IF BONG + if (block.getType() == Material.BREWING_STAND) { + + // stop vanilla interaction + event.setCancelled(true); + + // if this is a locked block + LockedBlocks lockedBlocks = GTM.getDrugManager().getLockedBlocks(); + if (DrugCommand.addingBlocks.contains(player.getName())) { + if (lockedBlocks.getLocations().contains(block.getLocation())) { + player.sendMessage(Lang.DRUGS.f("&cBlock is no longer locked.")); + lockedBlocks.getLocations().remove(block.getLocation()); + } else { + player.sendMessage(Lang.DRUGS.f("&aBlock is now locked!")); + lockedBlocks.getLocations().add(block.getLocation()); + } + return; + } + + // if sneaking, we want to remove + if (player.isSneaking()) { + if (lockedBlocks.getLocations().contains(block.getLocation())) { + player.sendMessage(Lang.DRUGS.f("&7This Bong cannot be removed.")); + return; + } + if (houseUser.isInsidePremiumHouse()) { + PremiumHouse house = Houses.getHousesManager().getPremiumHouse(houseUser.getInsidePremiumHouse()); + if (!house.getOwner().equals(player.getUniqueId())) { + player.sendMessage(Lang.GTM.f("&7Only the house owner may place a Bong here!")); + return; + } + } + block.getWorld().dropItemNaturally(blockLocation, getBongItem()); + block.setType(Material.AIR); + player.playSound(blockLocation, Sound.BLOCK_GLASS_BREAK, 3.0F, 3.0F); + } + else { + if (hand.getType() == getWeedItem().getType()) { + Optional<Drug> weed = ((DrugService) GTM.getDrugManager().getService()).getDrug("weed"); + if (weed.isPresent()) { + weed.get().apply(player); + if (hand.getAmount() > 1) { + hand.setAmount(hand.getAmount() - 1); + } else { + player.getInventory().remove(hand); + } + } else { + player.sendMessage(Lang.DRUGS + "" + ChatColor.RED + "Something went wrong internally, please tell a staff member."); + GTM.getInstance().getLogger().log(Level.SEVERE, "Unable to find weed drug (DrugPlacementListener)"); + } + } else { + player.sendMessage(Lang.DRUGS.f("&7Put some &2&lWeed &7in here to start smoking!")); + } + } + } + // IF COCAINE + else if (block.getType() == getCocaineBlock().getType() && block.getData() == getCocaineBlock().getData().getData()) { + + // stop vanilla interaction + event.setCancelled(true); + + // if sneaking, we want to remove + if (player.isSneaking()) { + if (houseUser.isInsidePremiumHouse()) { + PremiumHouse house = Houses.getHousesManager().getPremiumHouse(houseUser.getInsidePremiumHouse()); + if (!house.getOwner().equals(player.getUniqueId())) { + player.sendMessage(Lang.GTM.f("&7Only the house owner may do this!")); + return; + } + } + + player.sendMessage(Lang.GTM.f("&7You quickly gather up the cocaine.")); + + block.getWorld().dropItemNaturally(blockLocation, getCocaineItem()); + block.setType(Material.AIR); + player.playSound(blockLocation, Sound.BLOCK_GLASS_BREAK, 3.0F, 3.0F); + } + else { + + // apply the cocaine + block.setType(Material.AIR); + player.playSound(blockLocation, Sound.ENTITY_CAT_HISS, 1, 1); + Optional<Drug> cocaine = ((DrugService) GTM.getDrugManager().getService()).getDrug("cocaine"); + if (cocaine.isPresent()) { + cocaine.get().apply(player); + } else { + player.sendMessage(Lang.DRUGS.f("&7Unable to locate drug cocaine, report this bug to a staff member.")); + } + } + } else { + Block target = block.getWorld().getBlockAt(blockLocation.getBlockX(), + blockLocation.getBlockY() + 1, + blockLocation.getBlockZ()); + if (hand.getType() == getBongItem().getType() + && hand.getData().getData() == getBongItem().getData().getData()) { + if (target.getType() == Material.AIR) { + if (houseUser.isInsidePremiumHouse()) { + PremiumHouse house = Houses.getHousesManager().getPremiumHouse(houseUser.getInsidePremiumHouse()); + if (!house.getOwner().equals(player.getUniqueId())) { + player.sendMessage(Lang.GTM.f("&7Only the house owner may do this!")); + return; + } + } + target.setType(Material.BREWING_STAND); + if (hand.getAmount() > 1) { + hand.setAmount(hand.getAmount() - 1); + } else { + player.getInventory().remove(hand); + } + player.updateInventory(); + player.playSound(target.getLocation(), Sound.BLOCK_GLASS_PLACE, 3.0F, 3.0F); + } else if (target.getType() != Material.BREWING_STAND) { + player.sendMessage(Lang.GTM.f("&7Bong cannot be placed here!")); + } + } else if (hand.getType() == getCocaineItem().getType() + && hand.getData().getData() == getCocaineItem().getData().getData()) { + if (target.getType() == Material.AIR) { + if (houseUser.isInsidePremiumHouse()) { + PremiumHouse house = Houses.getHousesManager().getPremiumHouse(houseUser.getInsidePremiumHouse()); + if (!house.getOwner().equals(player.getUniqueId())) { + player.sendMessage(Lang.GTM.f("&7Only the house owner may do this!")); + return; + } + } + if(block.getType()==Material.JUKEBOX) { + player.sendMessage(Lang.GTM.f("&7That cocaine cannot be placed here!")); + event.setCancelled(true); + return; + } + target.setType(getCocaineBlock().getType()); + target.setData(getCocaineBlock().getData().getData()); + hand.setAmount(hand.getAmount()-1); + player.updateInventory(); + player.playSound(target.getLocation(), Sound.BLOCK_GLASS_PLACE, 3.0F, 3.0F); + } else if (target.getType() != getCocaineBlock().getType()) { + player.sendMessage(Lang.GTM.f("&7That cocaine cannot be placed here!")); + } + } + } + } + } + + public ItemStack getWeedItem() { + return GTM.getItemManager().getItem("weed").getItem(); + } + + public ItemStack getBongItem() { + return GTM.getItemManager().getItem("bong").getItem(); + } + + public ItemStack getCocaineItem() { + return GTM.getItemManager().getItem("cocaine").getItem(); + } + + public ItemStack getCocaineBlock() { + return GTM.getItemManager().getItem("cocaineblock").getItem(); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/example/Alcohol.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/example/Alcohol.java new file mode 100644 index 0000000..483c3bf --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/example/Alcohol.java @@ -0,0 +1,94 @@ +package net.grandtheftmc.gtm.drugs.example; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.drugs.DrugEffect; +import net.grandtheftmc.gtm.drugs.DrugService; +import net.grandtheftmc.gtm.drugs.categories.examples.AAlcohol; +import net.grandtheftmc.gtm.drugs.events.DrugUseEvent; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Item; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.util.Vector; + +import java.util.*; +import java.util.concurrent.ThreadLocalRandom; + +/** + * Created by Remco on 25-3-2017. + */ +public class Alcohol extends AAlcohol { + private final HashMap<UUID, List<Long>> drinkTimes = new HashMap<>(); + private static final int NEEDED_RATE = 3;//per X + private static final int TIMEFRAME = 300;//seconds + + public Alcohol() { + super("alcohol", 60); + } + + public boolean potentApply(Player p, boolean vodka) { + boolean[] failed = {false}; + UUID uuid = p.getUniqueId(); + DrugEffect effect = (drug, duration, player) -> { + final DrugService service = (DrugService) GTM.getInstance().getDrugManager().getService(); + player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_BURP, 1, 1); + int effectDuration = (int) Math.round(duration + (duration * ThreadLocalRandom.current().nextDouble(-.25, .25))) * 20; //to make it +/-5-25% + Bukkit.getPluginManager().callEvent(new DrugUseEvent(player, this)); + if (isPlayerDrunk(uuid)) { + ItemStack item = player.getInventory().getItemInMainHand(); + if (item != null) + if (item.getAmount() > 1) { + player.getInventory().getItemInMainHand().setAmount(item.getAmount() - 1); + } else { + player.getInventory().setItemInMainHand(null); + } + for (ItemStack is : player.getInventory().getStorageContents()) { + if (is != null && is.getType()!= Material.COMPASS && is.getType() != Material.CHEST && is.getType() != Material.WATCH) { + Item drop = player.getWorld().dropItemNaturally(player.getLocation().add(ThreadLocalRandom.current().nextDouble(-1, 1), 1, ThreadLocalRandom.current().nextDouble(-1, 1)), is); + Vector velocity = player.getEyeLocation().getDirection().normalize(); + velocity.multiply(1.01); + drop.setVelocity(velocity); + player.getInventory().remove(is); + } + } + player.sendMessage(Lang.DRUGS.f("&2&oYou dont feel so good...")); + } + + GTM.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SLOW, effectDuration, 1 + (vodka ? 2 : 1)))); + GTM.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.CONFUSION, effectDuration, 0))); + GTM.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, effectDuration, 1))); + GTM.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.INCREASE_DAMAGE, effectDuration, (vodka ? 1 : 0)))); + }; + effect.apply(this, this.getDuration(), p); + return !failed[0]; + } + + @Override + public boolean apply(Player p) { + return potentApply(p, false); + } + + private boolean isPlayerDrunk(UUID uuid) { + if (drinkTimes.containsKey(uuid)) { + List<Long> tempTimes = new ArrayList<>(); + ArrayList<Long> times = new ArrayList<>(drinkTimes.get(uuid)); + times.add(System.currentTimeMillis()); + times.forEach(l -> { + if ((l + (TIMEFRAME * 1000)) <= System.currentTimeMillis()) { + tempTimes.add(l); + } + }); + + times.removeAll(tempTimes); + drinkTimes.put(uuid, times); + return times.size() >= NEEDED_RATE; + } + drinkTimes.put(uuid, Arrays.asList(System.currentTimeMillis())); + return false; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/example/Cocaine.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/example/Cocaine.java new file mode 100644 index 0000000..06e7015 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/example/Cocaine.java @@ -0,0 +1,120 @@ +package net.grandtheftmc.gtm.drugs.example; + +import java.util.HashSet; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; + +import org.bukkit.Bukkit; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import de.slikey.effectlib.effect.TurnEffect; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.drugs.DrugEffect; +import net.grandtheftmc.gtm.drugs.DrugUtil; +import net.grandtheftmc.gtm.drugs.categories.examples.Stimulants; +import net.grandtheftmc.gtm.drugs.events.DrugUseEvent; + +public class Cocaine extends Stimulants { + HashSet<UUID> unmoveable = new HashSet<>(); + + public Cocaine() { + super("cocaine", 120); + } + + @Override + public boolean apply(Player p) { + boolean[] failed = {false}; + UUID uuid = p.getUniqueId(); + DrugEffect effect = (drug, duration, player) -> { + player.playSound(player.getLocation(), Sound.ENTITY_CAT_HISS, 1, 1); + int effectDuration = (int) Math.round(duration + (duration * ThreadLocalRandom.current().nextDouble(-.25, .25))) * 20; //to make it +/-5-25% + + Bukkit.getPluginManager().callEvent(new DrugUseEvent(player, this)); + int roll = ThreadLocalRandom.current().nextInt(100); + + if (roll > 5 || GTM.getDrugManager().inOD(player.getUniqueId())) { + GTM.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SPEED, effectDuration / 2, 1))); + GTM.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.FAST_DIGGING, effectDuration, 0))); + GTM.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.INCREASE_DAMAGE, effectDuration, 1))); + } else { + GTM.getDrugManager().addOD(player.getUniqueId()); + GTM.getUserManager().getLoadedUser(player.getUniqueId()).setLastTag(System.currentTimeMillis()); + stageOne(player, System.currentTimeMillis()); + } + }; + effect.apply(this, this.getDuration(), p); + return !failed[0]; + } + + public boolean cantMove(UUID uuid) { + return unmoveable.contains(uuid); + } + + public void stageOne(Player player, long addTime){ + int speedLength = ThreadLocalRandom.current().nextInt(100, 200); + GTM.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SPEED, speedLength, 20))); + new BukkitRunnable() { + @Override + public void run() { + if (!GTM.getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) + return; + stageTwo(player, addTime); + } + }.runTaskLater(GTM.getInstance(), speedLength); + } + + public void stageTwo(Player player, long addTime){ + player.setPlayerTime(18000, false); + unmoveable.add(player.getUniqueId()); + TurnEffect turnEffect = new TurnEffect(GTM.getEffectLib()); + turnEffect.setEntity(player); + turnEffect.infinite(); + turnEffect.period = 2; + turnEffect.start(); + int stageLength = ThreadLocalRandom.current().nextInt(10, 16); + long endTime = System.currentTimeMillis() + (stageLength*1000); + player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, stageLength*20, 0)); + new BukkitRunnable() { + boolean flip = false; + @Override + public void run() { + if (System.currentTimeMillis() >= endTime || !GTM.getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) { + turnEffect.cancel(); + cancel(); + return; + } + if(flip){ + player.playSound(player.getLocation(), DrugUtil.getRandomParanoiaSound(), 1, 1); + } + flip = !flip; + player.sendTitle(C.RED + C.MAGIC + "asd" + C.RED + DrugUtil.getParanoiaMessage() + C.MAGIC + "asd", "", 0, 10, 0); +// new TitleBuilder().setTitleText(ChatColor.RED + "" + ChatColor.MAGIC + "asd" + ChatColor.RED + DrugUtil.getParanoiaMessage() + "" + ChatColor.MAGIC + "asd").setFadeIn(0).setDuration(10).setFadeOut(0).send(player); + } + }.runTaskTimer(GTM.getInstance(), 0, 15); + + new BukkitRunnable() { + @Override + public void run() { + dispose(player); + if (GTM.getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) { + stageThree(player); + return; + }} + }.runTaskLater(GTM.getInstance(), stageLength*20); + + } + + public void stageThree(Player player){ + GTM.getDrugManager().getEffectManager().addEffect(player, new PotionEffect(PotionEffectType.SLOW, 20 * 5, 2)); + } + + public void dispose(Player player) { + unmoveable.remove(player.getUniqueId()); + player.resetPlayerTime(); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/example/Heroin.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/example/Heroin.java new file mode 100644 index 0000000..60d671c --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/example/Heroin.java @@ -0,0 +1,81 @@ +package net.grandtheftmc.gtm.drugs.example; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.drugs.DrugEffect; +import net.grandtheftmc.gtm.drugs.categories.examples.Opioids; +import net.grandtheftmc.gtm.drugs.events.DrugUseEvent; +import org.bukkit.Bukkit; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; + +/** + * Created by Timothy Lampen on 2017-04-08. + */ +public class Heroin extends Opioids{ + + public Heroin() { + super("heroin", 15); + } + + @Override + public boolean apply(Player p) { + boolean[] failed = {false}; + UUID uuid = p.getUniqueId(); + DrugEffect effect = (drug, duration, player) -> { + int roll = ThreadLocalRandom.current().nextInt(100); + int effectDuration = (int) Math.round(duration + (duration * ThreadLocalRandom.current().nextDouble(-.25, .25))) * 20; //to make it +/-5-25% + + Bukkit.getPluginManager().callEvent(new DrugUseEvent(player, this)); + player.playSound(player.getLocation(), Sound.ENTITY_SILVERFISH_AMBIENT, 1, 1); + final long addTime = System.currentTimeMillis(); + if (roll > 6 || (GTM.getDrugManager().inOD(player.getUniqueId()))) { + GTM.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SPEED, effectDuration, 1))); + GTM.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.INCREASE_DAMAGE, effectDuration, 0))); + GTM.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.FIRE_RESISTANCE, effectDuration, 1))); + + new BukkitRunnable() { + @Override + public void run() { + if (!GTM.getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) { + cancel(); + return; + } + if (ThreadLocalRandom.current().nextInt(4) == 0) { + GTM.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.WEAKNESS, effectDuration * 3, 1))); + player.sendMessage(Lang.DRUGS.f("&7&oWhy does everything feel so heavy all of a sudden?")); + } + } + }.runTaskLater(GTM.getInstance(), effectDuration); + } else { + GTM.getDrugManager().addOD(player.getUniqueId()); + GTM.getUserManager().getLoadedUser(player.getUniqueId()).setLastTag(System.currentTimeMillis()); + player.sendMessage(Lang.DRUGS.f("&7&oThis doesn't feel right...")); + GTM.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.WITHER, 5 * 20, 1))); + GTM.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.BLINDNESS, 5 * 20, 0))); + GTM.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SLOW, 5 * 20, 0))); + new BukkitRunnable() { + @Override + public void run() { + GTM.getDrugManager().removeOD(player.getUniqueId()); + if (ThreadLocalRandom.current().nextBoolean() && GTM.getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) { + player.getActivePotionEffects().forEach(effect -> { + player.removePotionEffect(effect.getType()); + }); + player.damage(player.getHealth()); + player.sendMessage(Lang.DRUGS.f("&7&oIm never doing heroin again...")); + } + } + }.runTaskLater(GTM.getInstance(), 5 * 20); + } + }; + effect.apply(this, this.getDuration(), p); + return !failed[0]; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/example/Joint.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/example/Joint.java new file mode 100644 index 0000000..e3d48cb --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/example/Joint.java @@ -0,0 +1,94 @@ +package net.grandtheftmc.gtm.drugs.example; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.drugs.DrugEffect; +import net.grandtheftmc.gtm.drugs.DrugService; +import net.grandtheftmc.gtm.drugs.DrugUtil; +import net.grandtheftmc.gtm.drugs.categories.examples.Cannabinoids; +import net.grandtheftmc.gtm.drugs.events.DrugUseEvent; +import org.bukkit.Bukkit; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.Collectors; + +public class Joint extends Cannabinoids { + + public Joint() { + super("joint", 120); + } + + @Override + public boolean apply(Player p) { + boolean[] failed = {false}; + UUID uuid = p.getUniqueId(); + DrugEffect effect = (drug, duration, player) -> { + final DrugService service = (DrugService) GTM.getInstance().getDrugManager().getService(); + int effectDuration = (int) Math.round(duration + (duration * ThreadLocalRandom.current().nextDouble(-.25, .25))) * 20; //to make it +/-5-25% + player.playSound(player.getLocation(), Sound.ENTITY_TNT_PRIMED, 1, 1); + Bukkit.getPluginManager().callEvent(new DrugUseEvent(player, this)); + final long addTime = System.currentTimeMillis(); + int roll = ThreadLocalRandom.current().nextInt(100); + + if (roll > 4 || GTM.getInstance().getDrugManager().inOD(player.getUniqueId())) { + GTM.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SLOW, effectDuration, 1))); + GTM.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SLOW_DIGGING, effectDuration, 0))); + new BukkitRunnable() { + @Override + public void run() { + if (!GTM.getInstance().getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) + return; + GTM.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.HUNGER, effectDuration, 1))); + player.sendMessage(Lang.DRUGS.f("&7&oDamn I could go for some McDonalds right now...")); + + } + }.runTaskLaterAsynchronously(GTM.getInstance(), 20 * 60 * 2); + final long startTime = System.currentTimeMillis(); + final Set<Player> nearby = player.getNearbyEntities(10, 10, 10).stream().filter(entity -> entity instanceof Player).map(entity -> (Player) entity).collect(Collectors.toSet()); + + new BukkitRunnable() { + @Override + public void run() { + if (startTime + (1000 * 2) <= System.currentTimeMillis()) cancel(); + for (int i = 0; i < 5; i++) { + double locX = player.getEyeLocation().getX() + (ThreadLocalRandom.current().nextDouble(0, 1) * (ThreadLocalRandom.current().nextBoolean() ? 1 : -1)); + double locZ = player.getEyeLocation().getZ() + (ThreadLocalRandom.current().nextDouble(0, 1) * (ThreadLocalRandom.current().nextBoolean() ? 1 : -1)); + double locY = player.getLocation().getY() + ThreadLocalRandom.current().nextDouble(1, 1.2); + nearby.forEach(p -> { + p.spawnParticle(Particle.FLAME, locX, locY, locZ, 1); + p.spawnParticle(Particle.SMOKE_NORMAL, locX, locY, locZ, 1); + }); + } + } + }.runTaskTimerAsynchronously(GTM.getInstance(), 0, 12); + } else { + GTM.getInstance().getDrugManager().addOD(player.getUniqueId()); + GTM.getUserManager().getLoadedUser(player.getUniqueId()).setLastTag(System.currentTimeMillis()); + GTM.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.BLINDNESS, effectDuration, 0))); + player.playSound(player.getLocation(), Sound.ENTITY_LIGHTNING_THUNDER, 10, 1); + final long endTime = System.currentTimeMillis() + (effectDuration / 20 * 1000); + new BukkitRunnable() { + @Override + public void run() { + if (System.currentTimeMillis() >= endTime || !GTM.getInstance().getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) { + GTM.getInstance().getDrugManager().removeOD(player.getUniqueId()); + cancel(); + } + player.playSound(player.getLocation(), DrugUtil.getRandomParanoiaSound(), 10, ThreadLocalRandom.current().nextFloat() * 2); + } + }.runTaskTimerAsynchronously(GTM.getInstance(), 5, 15); + player.sendMessage(Lang.DRUGS.f("&7&oUghhh... That must've been a bad batch of K2...")); + } + }; + effect.apply(this, this.getDuration(), p); + return !failed[0]; + } +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/example/MDMA.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/example/MDMA.java new file mode 100644 index 0000000..b61001c --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/example/MDMA.java @@ -0,0 +1,95 @@ +package net.grandtheftmc.gtm.drugs.example; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.drugs.DrugEffect; +import net.grandtheftmc.gtm.drugs.categories.examples.Hallucinogens; +import net.grandtheftmc.gtm.drugs.events.DrugUseEvent; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Particle; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.ArrayList; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.Collectors; + +/** + * Created by Timothy Lampen on 3/26/2017. + */ +public class MDMA extends Hallucinogens { + + public MDMA() { + super("mdma", 120); + } + + private ArrayList<UUID> using = new ArrayList<>(); + + @Override + public boolean apply(Player p) { + boolean[] failed = {false}; + UUID uuid = p.getUniqueId(); + DrugEffect effect = (drug, duration, player) -> { + if (this.using.contains(player.getUniqueId())) { + failed[0] = true; + player.sendMessage(Lang.DRUGS + "" + ChatColor.RED + "I don't think its a good idea to do more than one..."); + return; + } + this.using.add(player.getUniqueId()); + int roll = ThreadLocalRandom.current().nextInt(100); + int effectDuration = (int) Math.round(duration + (duration * ThreadLocalRandom.current().nextDouble(-.25, .25))) * 20;//to make it +/-5-25% + Bukkit.getPluginManager().callEvent(new DrugUseEvent(player, this)); + + if (roll > 4 || !GTM.getInstance().getDrugManager().inOD(player.getUniqueId())) { + final long addTime = System.currentTimeMillis(); + GTM.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SLOW, effectDuration, 0))); + //less anxiety? Or I might have to fool around with .setWalkSpeed etc + GTM.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.CONFUSION, effectDuration, 0))); + final Set<Player> nearby = player.getNearbyEntities(10, 10, 10).stream().filter(entity -> entity instanceof Player).map(entity -> (Player) entity).collect(Collectors.toSet()); + nearby.add(player); + + new BukkitRunnable() { + @Override + public void run() { + if (System.currentTimeMillis() >= (addTime + effectDuration / 20 * 1000) || !GTM.getInstance().getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) { + cancel(); + using.remove(player.getUniqueId()); + return; + } + for (int i = 0; i < 5; i++) {//hopefully blinds the player's view with hearts. Haven't tested how many particles it will actually take. Could do a more systematic approach like draw a panel of hearts, but I think this is better. + double locX = player.getEyeLocation().getX() + (ThreadLocalRandom.current().nextDouble(-.5, .5)); + double locZ = player.getEyeLocation().getZ() + (ThreadLocalRandom.current().nextDouble(-.5, .5)); + double locY = player.getLocation().getY() + ThreadLocalRandom.current().nextDouble(2.1, 2.3); + nearby.forEach(p -> p.spawnParticle(Particle.HEART, locX, locY, locZ, 1)); + } + } + }.runTaskTimerAsynchronously(GTM.getInstance(), 0, 5); + + } else { + GTM.getInstance().getDrugManager().addOD(player.getUniqueId()); + GTM.getUserManager().getLoadedUser(player.getUniqueId()).setLastTag(System.currentTimeMillis()); + GTM.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.CONFUSION, 25 * 20, 0))); + GTM.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.HUNGER, 25 * 20, 2))); + GTM.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.POISON, 25 * 20, 2))); + GTM.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.BLINDNESS, 25 * 20, 0))); + GTM.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SPEED, 25 * 20, 2))); + //message + new BukkitRunnable() { + @Override + public void run() { + GTM.getInstance().getDrugManager().removeOD(player.getUniqueId()); + using.remove(player.getUniqueId()); + } + }.runTaskLaterAsynchronously(GTM.getInstance(), 25 * 20); + } + }; + effect.apply(this, this.getDuration(), p); + return !failed[0]; + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/example/Meth.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/example/Meth.java new file mode 100644 index 0000000..995e805 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/example/Meth.java @@ -0,0 +1,73 @@ +package net.grandtheftmc.gtm.drugs.example; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.drugs.DrugEffect; +import net.grandtheftmc.gtm.drugs.categories.examples.Stimulants; +import net.grandtheftmc.gtm.drugs.events.DrugUseEvent; +import org.bukkit.Bukkit; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; + +/** + * Created by Timothy Lampen on 2017-04-06. + */ +public class Meth extends Stimulants{ + private static final int ADDITIONAL_HALF_HEARTS = 10; + public Meth() { + super("meth", 120); + } + + @Override + public boolean apply(Player p) { + boolean[] failed = {false}; + UUID uuid = p.getUniqueId(); + DrugEffect effect = (drug, duration, player) -> { + GTM.getUserManager().getLoadedUser(player.getUniqueId()).setLastTag(System.currentTimeMillis()); + player.playSound(player.getLocation(), Sound.ENTITY_TNT_PRIMED, 1, 1); + int effectDuration = (int) Math.round(duration + (duration * ThreadLocalRandom.current().nextDouble(-.25, .25))) * 20; + GTM.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SPEED, effectDuration, 1))); + GTM.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.INCREASE_DAMAGE, effectDuration, 0))); + GTM.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.HEALTH_BOOST, effectDuration, 1))); + GTM.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, effectDuration, 0))); + long addTime = System.currentTimeMillis(); + new BukkitRunnable() { + @Override + public void run() { + if (!GTM.getInstance().getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) { + cancel(); + return; + } + GTM.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SLOW, effectDuration, 0))); + GTM.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.WEAKNESS, effectDuration, 0))); + GTM.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.WITHER, effectDuration, 0))); + long endTime = System.currentTimeMillis() + ((effectDuration / 20) * 1000); + new BukkitRunnable() { + @Override + public void run() { + if (System.currentTimeMillis() >= endTime || !GTM.getInstance().getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) { + player.setMaxHealth(20); + cancel(); + return; + } + GTM.getInstance().getDrugManager().getEffectManager().addEffect(player, new PotionEffect(PotionEffectType.BLINDNESS, ThreadLocalRandom.current().nextInt(2, 6) * 20, 0)); + } + }.runTaskTimer(GTM.getInstance(), 0, ThreadLocalRandom.current().nextInt(15, 41) * 20); + player.setMaxHealth(20); + player.sendMessage(Lang.DRUGS.f("&7&oUggh, I shouldn't have tried meth...")); + + } + }.runTaskLater(GTM.getInstance(), duration * 20); + + Bukkit.getPluginManager().callEvent(new DrugUseEvent(player, this)); + }; + effect.apply(this, this.getDuration(), p); + return !failed[0]; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/example/RoofiedChocolate.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/example/RoofiedChocolate.java new file mode 100644 index 0000000..bf1f268 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/example/RoofiedChocolate.java @@ -0,0 +1,51 @@ +package net.grandtheftmc.gtm.drugs.example; + +import de.slikey.effectlib.effect.LoveEffect; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.drugs.categories.examples.Stimulants; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import java.util.concurrent.ThreadLocalRandom; + +/** + * Created by Timothy Lampen on 2017-09-28. + */ +public class RoofiedChocolate extends Stimulants { + public RoofiedChocolate() { + super("roofied_chocolate", 60*4); + } + + + private String[] hornyThingsPrezWouldSay = new String[]{"Holy fuck that tree is so hot right now", "I could probably go hump a cow and be okay with myself", "Is it just me, or is Bruce Jenner kinda hot?", "Best five seconds of my life"}; + @Override + public boolean apply(Player player) { + int ran = ThreadLocalRandom.current().nextInt(0, 100); + if(ran<20) { + player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 20*60*4, 0)); + } + else if(ran<40) { + player.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, 20*60*2, 1)); + } + else if(ran<45) { + player.addPotionEffect(new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, 20*60*5, 0)); + + } + else if(ran<75) { + LoveEffect effect = new LoveEffect(GTM.getEffectLib()); + effect.setEntity(player); + effect.iterations = 15 * 20; + effect.start(); + player.sendMessage(Utils.f("&7&o" + hornyThingsPrezWouldSay[ThreadLocalRandom.current().nextInt(0, this.hornyThingsPrezWouldSay.length)])); + } + else if(ran<90) { + player.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 20*60*2, 0)); + } + else if(ran<100) { + player.addPotionEffect(new PotionEffect(PotionEffectType.CONFUSION, 20*15, 0)); + } + return true; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/example/Steroids.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/example/Steroids.java new file mode 100644 index 0000000..8091353 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/example/Steroids.java @@ -0,0 +1,96 @@ +package net.grandtheftmc.gtm.drugs.example; + +import com.j0ach1mmall3.jlib.player.JLibPlayer; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.NMSUtil; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.drugs.DrugEffect; +import net.grandtheftmc.gtm.drugs.categories.examples.AnabolicSteroids; +import net.grandtheftmc.gtm.drugs.events.DrugUseEvent; +import net.grandtheftmc.gtm.users.GTMUser; +import org.bukkit.Bukkit; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.*; +import java.util.concurrent.ThreadLocalRandom; + +/** + * Created by Timothy Lampen on 2017-04-01. + */ +public class Steroids extends AnabolicSteroids{ + + private final HashMap<UUID, List<Long>> injectTimes = new HashMap<>(); + private static final int NEEDED_RATE = 3;//per X + private static final int TIMEFRAME = 10;//seconds + public Steroids() { + super("steroids", 120); + } + + @Override + public boolean apply(Player p) { + boolean[] failed = {false}; + UUID uuid = p.getUniqueId(); + DrugEffect effect = (drug, duration, player) -> { + player.playSound(player.getLocation(), Sound.BLOCK_NOTE_SNARE, 1, 1); + int effectDuration = (int) Math.round(duration + (duration * ThreadLocalRandom.current().nextDouble(-.25, .25))) * 20; + Bukkit.getPluginManager().callEvent(new DrugUseEvent(player, this)); + if (playerCanRage(uuid)) { + for (PotionEffect type : player.getActivePotionEffects()) { + player.removePotionEffect(type.getType()); + } + GTM.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.WEAKNESS, effectDuration / 2, 0))); + GTM.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SPEED, effectDuration / 2, 2))); + GTM.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.WITHER, effectDuration / 2, 1))); + GTM.getUserManager().getLoadedUser(player.getUniqueId()).setLastTag(System.currentTimeMillis()); + } else { + GTM.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SPEED, effectDuration, 0))); + GTM.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, effectDuration, 0))); + GTM.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.INCREASE_DAMAGE, effectDuration, 1))); + final long addTime = System.currentTimeMillis(); + new BukkitRunnable() { + @Override + public void run() { +// TODO: Not compatible, disabled for now. +// new JLibPlayer(player).setWorldborderTint(100); + + new BukkitRunnable() { + @Override + public void run() { + if (!GTM.getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) { + cancel(); + return; + } + GTMUser user = GTM.getUserManager().getLoadedUser(uuid); + user.updateTintHealth(player, Core.getUserManager().getLoadedUser(player.getUniqueId())); + } + }.runTaskLater(GTM.getInstance(), effectDuration / 20); + } + }.runTaskLater(GTM.getInstance(), 1); + } + }; + effect.apply(this, this.getDuration(), p); + return !failed[0]; + } + + private boolean playerCanRage(UUID uuid){ + if(injectTimes.containsKey(uuid)){ + List<Long> tempTimes = new ArrayList<>(); + ArrayList<Long> times = new ArrayList<>(injectTimes.get(uuid)); + times.add(System.currentTimeMillis()); + times.stream().forEach((l) -> { + if((l+(TIMEFRAME*1000))<=System.currentTimeMillis()){ + tempTimes.add(l); + } + }); + times.removeAll(tempTimes); + injectTimes.put(uuid, times); + return times.size()>=NEEDED_RATE; + } + injectTimes.put(uuid, Arrays.asList(System.currentTimeMillis())); + return false; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/example/Weed.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/example/Weed.java new file mode 100644 index 0000000..a2b0440 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/example/Weed.java @@ -0,0 +1,84 @@ +package net.grandtheftmc.gtm.drugs.example; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.drugs.DrugEffect; +import net.grandtheftmc.gtm.drugs.DrugUtil; +import net.grandtheftmc.gtm.drugs.categories.examples.Cannabinoids; +import net.grandtheftmc.gtm.drugs.events.DrugUseEvent; +import org.bukkit.Bukkit; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; + +public class Weed extends Cannabinoids { + + public Weed() { + super("weed", 120); + /*ShapelessRecipe rollingPaperRecipe = new ShapelessRecipe(GTM.getItemManager().getItem("rollingpaper").getItem()); + rollingPaperRecipe.addIngredient(3, Material.PAPER); + Bukkit.getServer().addRecipe(rollingPaperRecipe); + + ShapelessRecipe jointRecipe = new ShapelessRecipe(GTM.getItemManager().getItem("joint").getItem()); + jointRecipe.addIngredient(GTM.getItemManager().getItem("rollingpaper").getItem().getType()); + jointRecipe.addIngredient(GTM.getItemManager().getItem("groundweed").getItem().getType()); + Bukkit.getServer().addRecipe(jointRecipe);*/ + } + + @Override + public boolean apply(Player p) { + boolean[] failed = {false}; + UUID uuid = p.getUniqueId(); + DrugEffect effect = (drug, duration, player) -> { + int roll = ThreadLocalRandom.current().nextInt(100); + int effectDuration = (int) Math.round(duration + (duration * ThreadLocalRandom.current().nextDouble(-.25, .25))) * 20; + player.playSound(player.getLocation(), Sound.BLOCK_LAVA_POP, 1, 1); + Bukkit.getPluginManager().callEvent(new DrugUseEvent(player, this)); + final long addTime = System.currentTimeMillis(); + + if (roll > 4 || GTM.getInstance().getDrugManager().inOD(player.getUniqueId())) { + GTM.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SLOW, effectDuration, 1))); + GTM.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SLOW_DIGGING, effectDuration, 0))); + new BukkitRunnable() { + @Override + public void run() { + if (!GTM.getInstance().getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) + return; + new BukkitRunnable() { + @Override + public void run() { + GTM.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.HUNGER, effectDuration, 1))); + } + }.runTask(GTM.getInstance()); + player.sendMessage(Lang.DRUGS.f("&7&oDamn I could go for some McDonalds right now...")); + + } + }.runTaskLaterAsynchronously(GTM.getInstance(), 20 * 60 * 2); + } else { + GTM.getInstance().getDrugManager().addOD(player.getUniqueId()); + GTM.getUserManager().getLoadedUser(player.getUniqueId()).setLastTag(System.currentTimeMillis()); + GTM.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.BLINDNESS, effectDuration, 0))); + player.playSound(player.getLocation(), Sound.ENTITY_LIGHTNING_THUNDER, 10, 1); + final long endTime = System.currentTimeMillis() + (effectDuration / 20 * 1000); + new BukkitRunnable() { + @Override + public void run() { + if (System.currentTimeMillis() >= endTime || !GTM.getInstance().getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) { + GTM.getInstance().getDrugManager().removeOD(player.getUniqueId()); + cancel(); + } + player.playSound(player.getLocation(), DrugUtil.getRandomParanoiaSound(), 10, ThreadLocalRandom.current().nextFloat() * 2); + } + }.runTaskTimerAsynchronously(GTM.getInstance(), 5, 15); + player.sendMessage(Lang.DRUGS.f("&7&oUghhh... That must've been a bad batch of K2...")); + } + }; + effect.apply(this, this.getDuration(), p); + return !failed[0]; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/example/lsd/LSD.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/example/lsd/LSD.java new file mode 100644 index 0000000..a7392e4 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/example/lsd/LSD.java @@ -0,0 +1,189 @@ +package net.grandtheftmc.gtm.drugs.example.lsd; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.drugs.DrugEffect; +import net.grandtheftmc.gtm.drugs.DrugService; +import net.grandtheftmc.gtm.drugs.DrugUtil; +import net.grandtheftmc.gtm.drugs.categories.examples.Hallucinogens; +import net.grandtheftmc.gtm.drugs.events.DrugUseEvent; +import org.bukkit.*; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitScheduler; + +import java.util.*; +import java.util.concurrent.ThreadLocalRandom; + +public class LSD extends Hallucinogens { + + private final Hashtable<UUID, HashSet<Location>> changedBlocks = new Hashtable<>(); + private final HashMap<UUID, Long> cooldown = new HashMap<>(); + private int task; + + public LSD() { + super("LSD",30); + } + + @Override + public boolean apply(Player p) { + boolean[] failed = {false}; + UUID uuid = p.getUniqueId(); + final long addTime = System.currentTimeMillis(); + final int stageDuration = getDuration() + (int)Math.round(getDuration()*ThreadLocalRandom.current().nextDouble(-.25, .25)); + + DrugEffect effect = (drug, duration, player) -> { + final DrugService service = (DrugService) GTM.getDrugManager().getService(); + if (checkCooldown(uuid)) { + Bukkit.getPluginManager().callEvent(new DrugUseEvent(player, this)); + if (ThreadLocalRandom.current().nextInt(0, 100) <= 4 && !GTM.getDrugManager().inOD(player.getUniqueId())) { + GTM.getUserManager().getLoadedUser(player.getUniqueId()).setLastTag(System.currentTimeMillis()); + GTM.getDrugManager().addOD(player.getUniqueId()); + badTrip(player, addTime, duration); + return; + } + stageOne(player, addTime, stageDuration); + } else { + player.sendMessage(Lang.DRUGS.f("&7Hey man, I don't think that you should use it so soon, wait a while bro.")); + } + }; + effect.apply(this, this.getDuration(), p); + return !failed[0]; + } + + private void stageOne(Player player, long addTime, int length) { + if(player.isValid()) { + player.playSound(player.getLocation(), Sound.ENTITY_GENERIC_EAT, 1, 1); + GTM.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SLOW, length*2*20, 2))); + GTM.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.CONFUSION, length*2*20, 1))); + GTM.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.REGENERATION, length*2*20, 1))); + GTM.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, length*2*20, 1))); + player.setPlayerTime(18000, false); + new BukkitRunnable(){ + @Override + public void run() { + if(!GTM.getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) + return; + stageTwo(player, addTime, length); + } + }.runTaskLater(GTM.getInstance(), length*20); + } + } + + private void stageTwo(Player player, long addTime, int length) { + if(player.isValid()) { + player.removePotionEffect(PotionEffectType.SLOW); + player.removePotionEffect(PotionEffectType.CONFUSION); + GTM.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SLOW_DIGGING, length*2*20, 1))); + final long endTime = System.currentTimeMillis() + (length*1000) + 10000; + BukkitScheduler scheduler = GTM.getInstance().getServer().getScheduler(); + scheduler.scheduleAsyncRepeatingTask(GTM.getInstance(), new Runnable() { + + @Override + public void run() { + if (System.currentTimeMillis()>=endTime || !GTM.getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) { + scheduler.cancelTask(task); + player.resetPlayerTime(); + return; + } + player.playSound(player.getLocation(), DrugUtil.getRandomAmbientSound(), 3.0F, 1.0F); + } + }, 0, 20L); + new BukkitRunnable(){ + @Override + public void run() { + if(!GTM.getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) + return; + stageThree(player, addTime, length); + } + }.runTaskLater(GTM.getInstance(), length*20); + } + } + + private void stageThree(Player player, long addTime, int length) { + final double stopTime = System.currentTimeMillis() + (length*1000); + new BukkitRunnable() { + @Override + public void run() { + if (System.currentTimeMillis()>=stopTime|| !GTM.getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) { + if(player.isOnline() && changedBlocks.containsKey(player.getUniqueId())){ + changedBlocks.get(player.getUniqueId()).forEach(block -> { + player.sendBlockChange(block, block.getWorld().getBlockAt(block).getType(), block.getWorld().getBlockAt(block).getData()); + }); + } + changedBlocks.remove(player.getUniqueId()); + cancel(); + return; + } + + HashSet<Location> blocks = changedBlocks.containsKey(player.getUniqueId()) ? changedBlocks.get(player.getUniqueId()) : new HashSet<>(); + Collection<Block> nearbyBlocks = DrugUtil.getNearbyBlocks(player.getLocation(), 10); + + nearbyBlocks.forEach(block -> { + if(!blocks.contains(block.getLocation())){ + blocks.add(block.getLocation()); + } + player.sendBlockChange(block.getLocation(), Material.WOOL, (byte)ThreadLocalRandom.current().nextInt(0, 15)); + }); + changedBlocks.put(player.getUniqueId(), blocks); + } + }.runTaskTimer(GTM.getInstance(), 0, 20); + new BukkitRunnable(){ + @Override + public void run() { + if(!GTM.getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) + return; + stageFive(player, addTime, length); + } + }.runTaskLater(GTM.getInstance(), length*20); + } + + private void stageFive(Player player, long addTime, int length) { + if(GTM.getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) { + GTM.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.CONFUSION, length*20*2, 2))); + GTM.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.WEAKNESS, length*20*2, 1))); + } + + } + + public void badTrip(Player player, long addTime, int length) { + if(GTM.getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) { + GTM.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.CONFUSION, length*4, 2))); + GTM.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.WEAKNESS, length*4, 1))); + GTM.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SLOW, length*4, 2))); + BukkitScheduler scheduler = GTM.getInstance().getServer().getScheduler(); + task = scheduler.scheduleAsyncRepeatingTask(GTM.getInstance(), new Runnable() { + int count = 0; + + @Override + public void run() { + count += 1; + if (count >= 70 || !GTM.getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) { + scheduler.cancelTask(task); + GTM.getDrugManager().removeOD(player.getUniqueId()); + return; + } + player.playSound(player.getLocation(), DrugUtil.getRandomParanoiaSound(), 3.0F, 1.0F); + player.playSound(player.getLocation(), DrugUtil.getRandomAmbientSound(), 3.0F, 1.0F); + player.playEffect(EntityEffect.WITCH_MAGIC); + player.playEffect(EntityEffect.ZOMBIE_TRANSFORM); + } + }, 10L, 20L); + } + } + + private boolean checkCooldown(UUID uuid){ + if(cooldown.containsKey(uuid)){ + if(System.currentTimeMillis()>=(cooldown.get(uuid)+(60*15*1000))){//cooldown has expired + cooldown.put(uuid, System.currentTimeMillis()); + return true; + } + return false; + } + cooldown.put(uuid, System.currentTimeMillis()); + return true; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/internal/manager/Manager.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/internal/manager/Manager.java new file mode 100644 index 0000000..9499a98 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/internal/manager/Manager.java @@ -0,0 +1,46 @@ +package net.grandtheftmc.gtm.drugs.internal.manager; + +import net.grandtheftmc.gtm.drugs.internal.service.Service; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Created by Remco on 25-3-2017. + */ +public abstract class Manager <S extends Service> { + + private final S service; + private volatile String name; + private AtomicInteger id; + + public Manager(String name, AtomicInteger id, S service) { + this.service = service; + this.name = name; + this.id = id; + } + + public abstract void start(); + public abstract void stop(); + public abstract boolean destroy(); + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public AtomicInteger getId() { + return id; + } + + public void setId(AtomicInteger id) { + this.id = id; + } + + public S getService() { + return service; + } +} + diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/internal/service/Helper.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/internal/service/Helper.java new file mode 100644 index 0000000..83e1007 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/internal/service/Helper.java @@ -0,0 +1,11 @@ +package net.grandtheftmc.gtm.drugs.internal.service; + +/** + * Created by Remco on 25-3-2017. + */ +public interface Helper { + + String getHelperName(); + Class<? extends Service> getServiceClass(); + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/internal/service/Service.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/internal/service/Service.java new file mode 100644 index 0000000..cc2b6db --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/internal/service/Service.java @@ -0,0 +1,42 @@ +package net.grandtheftmc.gtm.drugs.internal.service; + +/** + * Created by Remco on 25-3-2017. + */ +public abstract class Service { + + private volatile Service instance; + private volatile Helper helper; + + private final String name; + + public Service(String name, Helper helper) { + this.name = name; + this.helper = helper; + } + + protected synchronized void setHelper(Helper helper){ + this.helper = helper; + } + + protected Helper getHelper(){ + return helper; + } + + public String getName() { + return name; + } + + protected Service getInstance(){ + if(instance == null){ + synchronized(Service.class) { + try { + instance = Service.class.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + e.printStackTrace(); + } + } + } + return instance; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/item/DrugDealerItem.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/item/DrugDealerItem.java new file mode 100644 index 0000000..22178e3 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/item/DrugDealerItem.java @@ -0,0 +1,77 @@ +package net.grandtheftmc.gtm.drugs.item; + +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.drugs.DrugUtil; +import org.bukkit.ChatColor; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.ThreadLocalRandom; + +/** + * Created by Timothy Lampen on 2017-04-01. + */ +public class DrugDealerItem { + private final DrugItem item; + private final int minAmount, maxAmount, displayChance, minPrice, maxPrice; + private int stockRemaining; + private boolean shouldDisplay; + private ItemStack is; + private int price; + + public DrugDealerItem(DrugItem item, int minAmount, int maxAmount, int displayChance, int minPrice, int maxPrice) { + this.item = item; + this.minAmount = minAmount > maxAmount ? (maxAmount > 0 ? maxAmount - 1 : 0) : minAmount > -1 ? minAmount : 0; + this.maxAmount = maxAmount > 0 ? maxAmount + 1 : 1; + this.displayChance = displayChance <= -1 ? 0 : displayChance; + this.minPrice = minPrice > maxPrice ? (maxPrice > 0 ? maxPrice - 1 : 0) : minPrice > -1 ? minPrice : 0; + this.maxPrice = maxPrice > 0 ? maxPrice : 1; + ItemStack is = item.getItemStack().clone(); + this.is = is; + reroll(); + } + + public static Optional<DrugDealerItem> byDrugItem(DrugItem item) { + return GTM.getDrugManager().getDrugDealer().getItems().stream().filter(drugDealerItem -> drugDealerItem.item.equals(item)).findFirst(); + } + + public int getStockRemaining() { + return stockRemaining; + } + + public void setStockRemaining(int stockRemaining) { + this.stockRemaining = stockRemaining; + ItemMeta im = is.getItemMeta(); + List<String> lore = im.getLore(); + lore.set(0, ChatColor.GOLD + "Amount Left: " + ChatColor.YELLOW + stockRemaining); + im.setLore(lore); + is.setItemMeta(im); + } + + public int getPrice() { + return this.price; + } + + public void reroll() { + stockRemaining = ThreadLocalRandom.current().nextInt(this.minAmount, this.maxAmount); + shouldDisplay = ThreadLocalRandom.current().nextInt(101) <= displayChance; + this.price = ThreadLocalRandom.current().nextInt(this.minPrice, this.maxPrice); + ItemMeta im = is.getItemMeta(); + List<String> lore = new ArrayList<>(); + lore.add(ChatColor.GOLD + "Amount Left: " + ChatColor.YELLOW + stockRemaining); + lore.add(ChatColor.GOLD + "Price: " + ChatColor.YELLOW + "$" + this.price); + im.setLore(lore); + is.setItemMeta(im); + } + + public boolean isShouldDisplay() { + return shouldDisplay; + } + + public ItemStack getItemStack() { + return DrugUtil.hideDurability(this.is); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/item/DrugItem.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/item/DrugItem.java new file mode 100644 index 0000000..22b69a5 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/drugs/item/DrugItem.java @@ -0,0 +1,106 @@ +package net.grandtheftmc.gtm.drugs.item; + +import com.j0ach1mmall3.jlib.inventory.JLibItem; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.drugs.Drug; +import net.grandtheftmc.gtm.drugs.DrugService; +import net.minecraft.server.v1_12_R1.NBTTagCompound; +import net.minecraft.server.v1_12_R1.NBTTagString; +import org.bukkit.Material; +import org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack; +import org.bukkit.inventory.ItemStack; + +import java.util.Map; +import java.util.UUID; + +public class DrugItem { + + private final static DrugService drugService = (DrugService) GTM.getDrugManager().getService(); + + private ItemStack itemStack; + private Drug drug; + + public DrugItem(Material material, int amount, UUID owner, Drug drug) { + this.itemStack = new ItemStack(material, amount); + this.drug = drug; + apply(); + } + + public DrugItem(ItemStack itemStack, UUID owner, Drug drug) { + this.itemStack = itemStack.clone(); + this.drug = drug; + apply(); + } + + + public DrugItem(ItemStack itemStack, Drug drug) { + this.itemStack = itemStack.clone(); + this.drug = drug; + apply(); + } + + public DrugItem(JLibItem item, Drug drug){ + this.itemStack = item.getItemStack(); + this.drug = drug; + apply(); + } + + protected DrugItem(ItemStack itemStack) { + this.itemStack = itemStack.clone(); + } + + public final static DrugItem getByItemStack(ItemStack itemStack) { + ItemStack clone = itemStack.clone(); + clone.setAmount(1); + DrugItem base = new DrugItem(clone); + if (drugService.getDrugs().stream().anyMatch(base::isValid) || drugService.getItems().contains(base)) return base; + return null; + } + + public static DrugItem getByDrug(Drug drug){ + if(drugService.getRawItems().rowMap().values().stream().anyMatch(drugItemDrugMap -> drugItemDrugMap.containsValue(drug))){ + Map<DrugItem, Drug> drugs = drugService.getRawItems().rowMap().values().stream().filter(drugItemDrugMap -> drugItemDrugMap.containsValue(drug)).findFirst().get(); + for(DrugItem item : drugs.keySet()){ + if(drugs.get(item).equals(drug)){ + return item; + } + } + } + return null; + } + + public void apply() { + if (!isValid(drug)) { + net.minecraft.server.v1_12_R1.ItemStack nmsCopy = CraftItemStack.asNMSCopy(itemStack); + NBTTagCompound tag = nmsCopy.hasTag() ? nmsCopy.getTag() : new NBTTagCompound(); + NBTTagString drugName = new NBTTagString(drug.getName()); + assert tag != null; + tag.set("drugName", drugName); + nmsCopy.setTag(tag); + this.itemStack = CraftItemStack.asBukkitCopy(nmsCopy); + + } + } + + public final ItemStack getItemStack() { + return itemStack; + } + + public boolean isValid(Drug drug) { + if(itemStack!=null && drug!=null) { + net.minecraft.server.v1_12_R1.ItemStack nmsCopy = CraftItemStack.asNMSCopy(itemStack); + if(nmsCopy!=null) { + NBTTagCompound tag = nmsCopy.hasTag() ? nmsCopy.getTag() : new NBTTagCompound(); + if ((tag != null ? tag.get("drugName") : null) != null) { + String name = tag.getString("drugName"); + return drugService.getDrugs().stream().map(Drug::getName).anyMatch(item -> item.equalsIgnoreCase(name) && drug.getName().equalsIgnoreCase(item)); + } + } + } + return false; + } + + public Drug drug(){ + return drug; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/EventManager.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/EventManager.java new file mode 100644 index 0000000..adb06cf --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/EventManager.java @@ -0,0 +1,81 @@ +package net.grandtheftmc.gtm.event; + +import java.util.Optional; + +import net.grandtheftmc.gtm.event.christmas.ChristmasEvent; +import net.grandtheftmc.gtm.event.easter.EasterEvent; +import org.bukkit.plugin.Plugin; + +import net.grandtheftmc.core.event.BaseEvent; +import net.grandtheftmc.core.event.EventData; +import net.grandtheftmc.gtm.event.halloween.HalloweenEvent; + +/** + * An event manager class that is a subclass of the EventManager from Core. + * + * @author sbahr + */ +public class EventManager extends net.grandtheftmc.core.event.EventManager { + + + + /** + * Construct a new EventManager. + * + * @param plugin - the owning plugin + * @param serverKey - the server key + */ + protected EventManager(Plugin plugin, String serverKey) { + super(plugin, serverKey); + // TODO Auto-generated constructor stub + } + + /** + * Initialize the manager. + * + * @param plugin - the owning plugin + * @param serverKey - the key of this server instance + */ + public static void init(Plugin plugin, String serverKey) { + + // create singleton instance + instance = new EventManager(plugin, serverKey); + initialized = true; + + // start sync task + instance.getSyncTask(); + } + + /** + * Construct a BaseEvent object based off the event data. + * + * @param plugin - the owning plugin + * @param data - the data bound for the event + * + * @return The BaseEvent object that was constructed, if one exists. + */ + @Override + public Optional<BaseEvent> constructEvent(Plugin plugin, EventData data){ + + BaseEvent event = null; + if(data==null || data.getEventType()==null) + return Optional.empty(); + switch(data.getEventType()){ + case HALLOWEEN: + event = new HalloweenEvent(plugin, data.getStartTime().getTime(), data.getEndTime().getTime()); + break; + case CHRISTMAS: + event = new ChristmasEvent(plugin, data.getStartTime().getTime(), data.getEndTime().getTime()); + break; + // TODO add more events here + case EASTER: + event = new EasterEvent(plugin, data.getStartTime().getTime(), data.getEndTime().getTime()); + break; + default: + break; + } + + return Optional.ofNullable(event); + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/christmas/ChristmasEvent.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/christmas/ChristmasEvent.java new file mode 100644 index 0000000..d3dfc0a --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/christmas/ChristmasEvent.java @@ -0,0 +1,195 @@ +package net.grandtheftmc.gtm.event.christmas; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.event.BaseEvent; +import net.grandtheftmc.core.event.EventType; +import net.grandtheftmc.gtm.GTM; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.boss.BarColor; +import org.bukkit.boss.BarStyle; +import org.bukkit.boss.BossBar; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +/** + * Created by Timothy Lampen on 2017-12-07. + */ +public class ChristmasEvent extends BaseEvent implements Listener{ + + + private List<Location> spawnLocations = new ArrayList<>(); + + private BossBar bossBar = null; + + private BukkitTask updateEventBarTask; + private BukkitTask spawnSantaDropTask; + + public ChristmasEvent(Plugin plugin, long startTime, long endTime) { + super(plugin, EventType.CHRISTMAS.getId(), startTime, endTime); + GTM.getInstance().getServer().getPluginManager().registerEvents(this, GTM.getInstance()); + + } + + @Override + public void onInit() { + + } + + @Override + public void onStart() { + this.bossBar = Bukkit.createBossBar(Utils.f("&c&lC&2&lh&c&lr&2&li&c&ls&2<&c&lm&2&la&c&ls&2&l!"), BarColor.GREEN, BarStyle.SOLID); + + + this.spawnLocations.addAll(Arrays.asList( + new Location(Bukkit.getWorld("minesantos"), -188,69,226), + new Location(Bukkit.getWorld("minesantos"), 401,68,31), + new Location(Bukkit.getWorld("minesantos"), 32,86,-212), + new Location(Bukkit.getWorld("minesantos"), -604,64,-170), + new Location(Bukkit.getWorld("minesantos"), 256,84,430), + new Location(Bukkit.getWorld("minesantos"), -320,74,158), + new Location(Bukkit.getWorld("minesantos"), 7,73,197), + new Location(Bukkit.getWorld("minesantos"), -9,153,-129), + new Location(Bukkit.getWorld("minesantos"), 323,121,303), + new Location(Bukkit.getWorld("minesantos"), -157,74,159), + new Location(Bukkit.getWorld("minesantos"), 95,83,187), + new Location(Bukkit.getWorld("minesantos"), -210,94,422), + new Location(Bukkit.getWorld("minesantos"), -261,74,-16), + new Location(Bukkit.getWorld("minesantos"), -293,74,369), + new Location(Bukkit.getWorld("minesantos"), -116,73,57) + )); + + this.spawnSantaDropTask = new BukkitRunnable() { + @Override + public void run() { + spawnSantaDrop(); + } + }.runTaskTimer(Core.getInstance(), 20*60*8,20*60*ThreadLocalRandom.current().nextInt(60,120)); + + this.updateEventBarTask = new BukkitRunnable() { + @Override + public void run() { + updateBossBar(); + } + }.runTaskTimerAsynchronously(getPlugin(), 0, 20*60); + + + for(Player player : Bukkit.getOnlinePlayers()) + this.bossBar.addPlayer(player); + + + } + + @EventHandler + public void onJoin(PlayerJoinEvent event){ + Player player = event.getPlayer(); + if(this.bossBar!=null) + this.bossBar.addPlayer(player); + } + + @EventHandler + public void onLeave(PlayerQuitEvent event){ + Player player = event.getPlayer(); + if(this.bossBar!=null) + this.bossBar.removePlayer(player); + } + + @Override + public void onEnd() { + this.updateEventBarTask.cancel(); + this.spawnSantaDropTask.cancel(); + + this.bossBar.removeAll(); + this.bossBar = null; + + } + + private void spawnSantaDrop(){ + List<Location> copy = spawnLocations.stream().filter(loc -> loc.getChunk().isLoaded()).collect(Collectors.toList()); + if(copy.size() == 0) { + GTM.error("Could not spawn a christmas drop because no players are currently near the drop locations"); + return; + } + new SpawnSantaDropTask(copy.get(ThreadLocalRandom.current().nextInt(0,copy.size()))); + } + + + + private void updateBossBar() { + + // how many seconds left until over + int secondsLeft = (int) ((getEndTime() - System.currentTimeMillis()) / 1000.0); + + int day = (int) TimeUnit.SECONDS.toDays(secondsLeft); + long hours = TimeUnit.SECONDS.toHours(secondsLeft) - (day * 24); + long minute = TimeUnit.SECONDS.toMinutes(secondsLeft) - (TimeUnit.SECONDS.toHours(secondsLeft) * 60); + + String timeLeft = day + "d " + hours + "h " + minute + "m"; + String title = Utils.f("&c&lC&2&lh&c&lr&2&li&c&ls&2<&c&lm&2&la&c&ls&2&l! ") + ChatColor.GOLD + ChatColor.BOLD + timeLeft; + + double start = System.currentTimeMillis() - getStartTime(); + double end = getEndTime() - getStartTime(); + + // this gives us how through we are + double through = start / end; + double progress = 1 - through; + + this.bossBar.setTitle(title); + this.bossBar.setProgress(progress); + } + + public static void removeCandyCanes(Player player, int amount){ + int deleted = 0; + ItemStack candyCane = GTM.getItemManager().getItem("candycane").getItem(); + for(int i = 0 ; i<player.getInventory().getSize(); i++){ + ItemStack is = player.getInventory().getItem(i); + + if(is==null || is.getType()== Material.AIR) + continue; + if(candyCane.isSimilar(is)) { + if(deleted + is.getAmount() >= amount) { + is.setAmount(is.getAmount()-(amount-deleted)); + player.getInventory().setItem(i, is); + return; + } + else { + deleted += is.getAmount(); + player.getInventory().setItem(i, new ItemStack(Material.AIR)); + } + } + } + player.updateInventory(); + } + + public static boolean hasCandyCanes(Player player, int amount){ + int candyCanes = 0; + ItemStack candyCane = GTM.getItemManager().getItem("candycane").getItem(); + for(ItemStack is : player.getInventory().getContents()) { + if(is==null || is.getType()==Material.AIR) + continue; + if(candyCane.isSimilar(is)) { + if (candyCanes + is.getAmount() >= amount) + return true; + candyCanes += is.getAmount(); + } + } + return false; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/christmas/ChristmasListener.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/christmas/ChristmasListener.java new file mode 100644 index 0000000..93bbc97 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/christmas/ChristmasListener.java @@ -0,0 +1,257 @@ +package net.grandtheftmc.gtm.event.christmas; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.users.eventtag.EventTag; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.items.GameItem; +import net.grandtheftmc.gtm.users.ChatAction; +import net.grandtheftmc.gtm.users.GTMUser; +import org.bukkit.Bukkit; +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Item; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import java.lang.reflect.Field; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; + +/** + * Created by Timothy Lampen on 1/2/2018. + */ +public class ChristmasListener implements Listener { + + private Set<UUID> naughtyPlayers = new HashSet<>(); + + + public ChristmasListener(){ + new BukkitRunnable(){ + @Override + public void run() { + for(UUID uuid : naughtyPlayers){ + Player player = Bukkit.getPlayer(uuid); + if(player==null || !player.getWorld().getName().equals("minesantos")) + continue; + Item item = player.getWorld().dropItem(player.getLocation(), new ItemStack(Material.BLAZE_POWDER)); + + try { + Field itemField = item.getClass().getDeclaredField("item"); + Field ageField; + Object entityItem; + + itemField.setAccessible(true); + entityItem = itemField.get(item); + + ageField = entityItem.getClass().getDeclaredField("age"); + ageField.setAccessible(true); + ageField.set(entityItem, 5700);//last for 15 sec + } + catch (NoSuchFieldException | IllegalAccessException e) { + e.printStackTrace(); + } + + item.setPickupDelay(Integer.MAX_VALUE); + } + } + }.runTaskTimer(GTM.getInstance(), 0, 20*5); + } + + + @EventHandler(priority = EventPriority.LOW) + public void onDeath(PlayerDeathEvent event){ + Player player= event.getEntity(); + if(player.getKiller()==null) + return; + if(player.getKiller().equals(player)) + return; + if(!this.naughtyPlayers.contains(player.getUniqueId())) + return; + player.getWorld().dropItem(player.getLocation(), GTM.getItemManager().getItem("candycane").getItem(2)); + this.naughtyPlayers.remove(player.getUniqueId()); + + Player killer = player.getKiller(); + killer.sendMessage(Lang.CHRISTMAS.f("&aThank you &b" + killer.getName() + "&a! Christmas has been saved! Here are some candy canes for your trouble.")); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onChat(AsyncPlayerChatEvent e){ + Player player = e.getPlayer(); + String msg = e.getMessage(); + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + User coreUser = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if(user.getCurrentChatAction()==null || user.getCurrentChatAction()!= ChatAction.SANTA_NAUGHTY_LIST) + return; + e.setCancelled(true); + ServerUtil.runTask(() -> { + switch (user.getCurrentChatAction()) { + case SANTA_NAUGHTY_LIST: { + if(msg.equalsIgnoreCase("cancel")) { + user.clearCurrentChatAction(); + player.sendMessage(Lang.CHRISTMAS.f("&7&oThe list is unimpressed with your choice.")); + return; + } + Player target = Bukkit.getPlayer(msg); + if (target == null) { + player.sendMessage(Lang.CHRISTMAS.f("&7&oThe list can't find that player online, type 'cancel' to stop the selection.")); + user.resetCurrentChatActionTimer(null); + return; + } + if(target.equals(player)) { + player.sendMessage(Lang.CHRISTMAS.f("&7&oSanta doesn't like masochists... Pick someone other than yourself!")); + user.resetCurrentChatActionTimer(null); + return; + } + if(!coreUser.getUnlockedTags().contains(EventTag.NAUGHTY)) { + coreUser.giveEventTag(EventTag.NAUGHTY); + player.sendMessage(Lang.CHRISTMAS.f("&aYou have been given the " + EventTag.NAUGHTY.getBoldName() + "&a tag. &7Select your active tag by going into Phone -> Account -> Unlocked Tags.\n&7Make sure that the '&6Show Game Rank&7' preference is toggled on.")); + } + coreUser.addCooldown("naughty_list", 60 * 10, true, true); + Bukkit.broadcastMessage(Lang.CHRISTMAS.f("&cOh no! Santa just recieved a report that &b" + target.getName() + " &chas been a &4&lNAUGHTY &cperson! Santa will give anyone who kills him &a2 candy canes &cfor their troubles. The player will be marked with a blaze powder trail.")); + this.naughtyPlayers.add(target.getUniqueId()); + user.clearCurrentChatAction(); + return; + } + } + }); + } + + @EventHandler + public void onInteract(PlayerInteractEvent e){ + Player player = e.getPlayer(); + ItemStack item = e.getItem(); + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + GTMUser gtmUser = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + if (e.getAction() != Action.RIGHT_CLICK_AIR && e.getAction() != Action.RIGHT_CLICK_BLOCK) + return; + + + + //handle the custom items + if (item != null && player.getInventory().getItemInMainHand().equals(item)) { + if(item.getType()== Material.MAGMA_CREAM && item.hasItemMeta() && item.getItemMeta().getDisplayName().contains("Snowball")) { + if(player.getWorld().getName().equalsIgnoreCase("spawn")) { + player.sendMessage(Lang.CHRISTMAS.f("&cYou cannot use this item at spawn!")); + return; + } + if(item.getAmount()==1) + player.getInventory().setItemInMainHand(new ItemStack(Material.AIR)); + else + item.setAmount(item.getAmount()-1); + player.updateInventory(); + + Location loc = player.getEyeLocation().toVector().add(player.getLocation().getDirection().multiply(2)).toLocation(player.getWorld(), player.getLocation().getYaw(), player.getLocation().getPitch()); + Item cube = player.getWorld().dropItem(loc, new ItemStack(Material.MAGMA_CREAM)); + cube.setVelocity(player.getEyeLocation().getDirection().multiply(2)); + cube.setPickupDelay(Integer.MAX_VALUE); + + new BukkitRunnable() { + @Override + public void run() { + if(cube.isOnGround() || !cube.isValid()) { + cube.remove(); + cancel(); + return; + } + for(Entity e : cube.getNearbyEntities(.3,1.2,.3)){ + if(e.getType() == EntityType.PLAYER){ + Player player = (Player)e; + player.getWorld().playEffect(cube.getLocation(), Effect.EXPLOSION_LARGE, 1, 1); + player.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 20*5, 1)); + cube.remove(); + cancel(); + return; + } + } + } + }.runTaskTimer(GTM.getInstance(), 3,1); + } + //game items + GameItem gItem = GTM.getItemManager().getItem(item); + if(gItem==null) + return; + switch (gItem.getName()) { + case "candycane": { + e.setCancelled(true); + MenuManager.openMenu(player, "christmasshop"); + return; + } + case "santanicelist": { + e.setCancelled(true); + if(player.getWorld().getName().equalsIgnoreCase("spawn")) { + player.sendMessage(Lang.CHRISTMAS.f("&cYou cannot use this item at spawn!")); + return; + } + if (player.getLocation().getY()<player.getWorld().getHighestBlockYAt(player.getLocation())) { + player.sendMessage(Lang.CHRISTMAS.f("&cYou must have a clear path to the sky to spawn the present drop!")); + return; + } + if(!user.getUnlockedTags().contains(EventTag.NICE)) { + player.sendMessage(Lang.CHRISTMAS.f("&aYou have been given the " + EventTag.NICE.getBoldName() + " tag. &7Select your active tag by going into Phone -> Account -> Unlocked Tags.\n&7Make sure that the '&6Show Game Rank&7' preference is toggled off.")); + user.giveEventTag(EventTag.NICE); + } + if(item.getAmount()==1) + player.getInventory().setItemInMainHand(new ItemStack(Material.AIR)); + else + item.setAmount(item.getAmount()-1); + Bukkit.broadcastMessage(Lang.CHRISTMAS.f("&6Thank you &a" + player.getName() + " &6for spawning a santa drop for the server!")); + new SpawnSantaDropTask(player.getWorld().getHighestBlockAt(player.getLocation()).getLocation().clone().add(0,1,0)); + player.updateInventory(); + return; + } + case "santanaughtylist": { + e.setCancelled(true); + if(!user.getUserRank().isHigherThan(UserRank.ADMIN)) { + player.sendMessage(Lang.CHRISTMAS.f("&7Players cannot use this item. Have a cookie instead!")); + player.getInventory().setItemInMainHand(Utils.createItem(Material.COOKIE, "&4&lExtremely &cSalty Cookie")); + player.updateInventory(); + return; + } + if (user.isOnCooldown("naughty_list")) { + player.sendMessage(Lang.CHRISTMAS.f("&cYou must wait " + user.getFormattedCooldown("naughty_list") + "&c to use this item.")); + return; + } + player.sendMessage(Lang.CHRISTMAS.f("&7&oThe list in your hand asks you to enter the name of the player who is naughty into chat")); + gtmUser.setCurrentChatAction(ChatAction.SANTA_NAUGHTY_LIST, null); + return; + } + case "christmascake": { + e.setCancelled(true); + + player.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 30*20, 0), true); + player.addPotionEffect(new PotionEffect(PotionEffectType.REGENERATION, 30*20, 0), true); + + boolean destroy = ThreadLocalRandom.current().nextInt(0,10) == 0; + if(destroy) { + player.getInventory().setItemInMainHand(new ItemStack(Material.AIR)); + player.sendMessage(Lang.CHRISTMAS.f("&7Wow you're fat... You just ate the whole cake!")); + player.updateInventory(); + } + return; + } + } + } + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/christmas/SpawnSantaDropTask.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/christmas/SpawnSantaDropTask.java new file mode 100644 index 0000000..da5fd89 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/christmas/SpawnSantaDropTask.java @@ -0,0 +1,183 @@ +package net.grandtheftmc.gtm.event.christmas; + +import de.slikey.effectlib.effect.*; +import de.slikey.effectlib.util.DynamicLocation; +import de.slikey.effectlib.util.ParticleEffect; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.users.targets.TrackedEntity; +import net.grandtheftmc.core.users.targets.TrackedLocation; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.gtm.GTM; +import org.bukkit.*; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Item; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.EulerAngle; +import org.bukkit.util.Vector; + +import java.util.concurrent.ThreadLocalRandom; + +/** + * Created by Timothy Lampen on 2017-12-07. + */ +public class SpawnSantaDropTask{ + + private ArmorStand giftPackage; + private final Location dropPoint; + + public SpawnSantaDropTask(Location loc) { + this.dropPoint = loc; + beingStage1(); + } + + private void constructPackage(Location loc){ + giftPackage = (ArmorStand)this.dropPoint.getWorld().spawnEntity(loc, EntityType.ARMOR_STAND); + giftPackage.setMetadata("CUSTOM", new FixedMetadataValue(GTM.getInstance(), "fuck vehicles")); + giftPackage.setItemInHand(GTM.getItemManager().getItem("bigpresent").getItem()); + giftPackage.setCollidable(false); + giftPackage.setBasePlate(false); + giftPackage.setVisible(false); + giftPackage.setRightArmPose(new EulerAngle(-Math.PI/2,0,0)); + giftPackage.setGravity(false); + giftPackage.setRemoveWhenFarAway(false); + } + + + /** + * @apiNote The beginning of the whole animation. This method handles up to the point of the package reaching the ground. + */ + private void beingStage1(){ + Bukkit.getOnlinePlayers().forEach(player -> player.sendTitle(ChatColor.translateAlternateColorCodes('&', Lang.CHRISTMAS.toString()), ChatColor.AQUA + "A christmas care package has spawned on the map!", 20, 60, 20)); + double rateOfDecline = 50.0/240;//the rate at decline/2ticks so that it takes a minute for the box to reach the bottom. + + constructPackage(this.dropPoint.clone().add(0,50,0)); + for(Player player : Bukkit.getOnlinePlayers()) { + Core.getUserManager().getLoadedUser(player.getUniqueId()).addBossBarTarget(new TrackedLocation(this.dropPoint)); + } + + StarEffect star = new StarEffect(GTM.getEffectLib()); + DynamicLocation dLoc = new DynamicLocation(this.giftPackage); + star.setDynamicOrigin(dLoc); + star.particle = ParticleEffect.FLAME; + star.iterations = Integer.MAX_VALUE; + star.particles = 4; + star.period = 2; + star.visibleRange = 55f; + star.start(); + + new BukkitRunnable() { + @Override + public void run() { + if(!giftPackage.isValid()) { + Location loc = giftPackage.getLocation().clone(); + giftPackage.remove(); + constructPackage(loc); + star.setDynamicOrigin(new DynamicLocation(giftPackage)); + } + if(dropPoint.getY()-1>=giftPackage.getLocation().getY()) { + cancel(); + star.cancel(); + beginStage2(); + return; + } + + + giftPackage.teleport(giftPackage.getLocation().clone().add(0,-rateOfDecline, 0)); + } + }.runTaskTimer(GTM.getInstance(), 0, 5); + } + + private int inverseShotCandyCanes = ThreadLocalRandom.current().nextInt(10,26); + /** + * @apiNote The middle of the whole animation. This method handles up to the point of the package shoots all of the candy canes. + */ + private void beginStage2(){ + + SphereEffect effect = new SphereEffect(GTM.getEffectLib()); + effect.particle = ParticleEffect.FIREWORKS_SPARK; + effect.iterations = Integer.MAX_VALUE; + effect.setLocation(this.giftPackage.getLocation().clone().add(.2,1,.2)); + effect.radius = 5; + effect.particles = 30; + effect.radiusIncrease = 0; + effect.start(); + + + new BukkitRunnable() { + @Override + public void run() { + + if(inverseShotCandyCanes<=0){ + cancel(); + effect.cancel(); + beginStage3(); + return; + } + double ranX = ThreadLocalRandom.current().nextDouble(-1.5,1.5); + double ranY = ThreadLocalRandom.current().nextDouble(1,2); + double ranZ = ThreadLocalRandom.current().nextDouble(-1.5,1.51);//make velocity in random direction + FlameEffect trace = new FlameEffect(GTM.getEffectLib()); + Item item = giftPackage.getWorld().dropItem(giftPackage.getLocation().clone().add(0,1.2,0), GTM.getItemManager().getItem("candycane").getItem()); + + trace.setEntity(item); + trace.iterations = 60; + trace.period = 2; + trace.particleCount = 1; + trace.start(); + + item.setVelocity(new Vector(ranX, ranY, ranZ)); + item.getLocation().getWorld().playSound(item.getLocation(), Sound.ENTITY_BLAZE_SHOOT, 10, 10); + + inverseShotCandyCanes--; + } + }.runTaskTimer(Core.getInstance(), 0, 30*1); + } + /** + * @apiNote The end of the whole animation. This method cleans everything up. + */ + private void beginStage3(){ + final long startTime = System.currentTimeMillis(); + + + new BukkitRunnable() { + boolean flip = true; + float cRadius = 2f; + @Override + public void run() { + if(startTime+8000<System.currentTimeMillis()) { + cancel(); + for(Player player : Bukkit.getOnlinePlayers()) { + Core.getUserManager().getLoadedUser(player.getUniqueId()).removeBossBarTarget(dropPoint); + } + giftPackage.remove(); + return; + } + + giftPackage.getWorld().playSound(giftPackage.getLocation(), Sound.BLOCK_BREWING_STAND_BREW, 10, 10); + + VortexEffect vortex = new VortexEffect(GTM.getEffectLib()); + vortex.setLocation(giftPackage.getLocation().clone()); + vortex.particle = ParticleEffect.SPELL_MOB; + vortex.color = flip ? Color.GREEN : Color.RED; + vortex.iterations = 20; + vortex.period = 2; + vortex.circles = 2; + vortex.radius = cRadius; + vortex.particleCount = 10; + cRadius -= .095f; + flip = !flip; + vortex.start(); + + giftPackage.teleport(giftPackage.getLocation().clone().add(0,-.05, 0)); + } + }.runTaskTimer(GTM.getInstance(), 0, 4); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/easter/EasterDAO.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/easter/EasterDAO.java new file mode 100644 index 0000000..28ab0f0 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/easter/EasterDAO.java @@ -0,0 +1,92 @@ +package net.grandtheftmc.gtm.event.easter; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import net.grandtheftmc.core.Core; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; + +import java.sql.*; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; + +public final class EasterDAO { + + protected static List<EasterEgg> getEasterEggs(Connection connection) { + List<EasterEgg> eggs = Lists.newArrayList(); + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM easter_egg WHERE server_key=?;")) { + statement.setString(1, Core.name()); + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + int uniqueIdentifier = result.getInt("id"); + World world = Bukkit.getWorld(result.getString("world")); + double x = result.getDouble("x"); + double y = result.getDouble("y"); + double z = result.getDouble("z"); + eggs.add(new EasterEgg(uniqueIdentifier, new Location(world, x, y, z))); + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + + return eggs; + } + + protected static EasterEgg addEasterEgg(Connection connection, Location location) { + EasterEgg easterEgg = new EasterEgg(location); + try (PreparedStatement statement = connection.prepareStatement( + "INSERT INTO easter_egg (world, x, y, z, server_key) VALUES (?, ?, ?, ?, ?);", Statement.RETURN_GENERATED_KEYS)) { + statement.setString(1, location.getWorld().getName()); + statement.setDouble(2, location.getX()); + statement.setDouble(3, location.getY()); + statement.setDouble(4, location.getZ()); + statement.setString(5, Core.name()); + + statement.execute(); + try (ResultSet result = statement.getGeneratedKeys()) { + if (result.next()) { + easterEgg.setUniqueIdentifier(result.getInt(1)); + return easterEgg; + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + + return null; + } + + protected static void addUserFind(Connection connection, UUID uuid, int eggId) { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO easter_user (uuid, egg_id, server_key) VALUES (UNHEX(?), ?, ?);")) { + statement.setString(1, uuid.toString().replaceAll("-", "")); + statement.setInt(2, eggId); + statement.setString(3, Core.name()); + + statement.execute(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + protected static Set<Integer> getFoundEggs(Connection connection, UUID uuid) { + Set<Integer> list = Sets.newHashSet(); + try (PreparedStatement statement = connection.prepareStatement("SELECT egg_id FROM easter_user WHERE uuid=UNHEX(?) AND server_key=?;")) { + statement.setString(1, uuid.toString().replaceAll("-", "")); + statement.setString(2, Core.name()); + + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + list.add(result.getInt(1)); + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + + return list; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/easter/EasterEgg.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/easter/EasterEgg.java new file mode 100644 index 0000000..33b7483 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/easter/EasterEgg.java @@ -0,0 +1,53 @@ +package net.grandtheftmc.gtm.event.easter; + +import net.grandtheftmc.core.wrapper.packet.out.WrapperPlayServerEntityDestroy; +import org.bukkit.Location; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; + +public final class EasterEgg { + + /** Unique Identifier of the Egg */ + private int uniqueIdentifier; + /** Location of the Egg block */ + private final Location location; + + private ArmorStand armorStand; + + protected EasterEgg(Location location) { + this.location = location; + } + + protected EasterEgg(int uniqueIdentifier, Location location) { + this.uniqueIdentifier = uniqueIdentifier; + this.location = location; + } + + protected int getUniqueIdentifier() { + return uniqueIdentifier; + } + + protected void setUniqueIdentifier(int uniqueIdentifier) { + this.uniqueIdentifier = uniqueIdentifier; + } + + protected Location getLocation() { + return location; + } + + protected ArmorStand getArmorStand() { + return armorStand; + } + + protected void setArmorStand(ArmorStand armorStand) { + this.armorStand = armorStand; + } + + protected void destroyFor(Player player) { + if (this.armorStand == null) return; + + WrapperPlayServerEntityDestroy destroy = new WrapperPlayServerEntityDestroy(); + destroy.setEntityId(this.armorStand.getEntityId()); + destroy.sendPacket(player); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/easter/EasterEggCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/easter/EasterEggCommand.java new file mode 100644 index 0000000..9d2290f --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/easter/EasterEggCommand.java @@ -0,0 +1,54 @@ +package net.grandtheftmc.gtm.event.easter; + +import net.grandtheftmc.core.commands.CoreCommand; +import net.grandtheftmc.core.commands.RankedCommand; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.Callback; +import net.grandtheftmc.core.util.ServerUtil; +import org.bukkit.entity.Player; + +import java.sql.Connection; +import java.sql.SQLException; + +public final class EasterEggCommand extends CoreCommand<Player> implements RankedCommand { + + private final EasterEvent event; + + public EasterEggCommand(EasterEvent event) { + super("easteregg", "Management command for setting up Easter Eggs."); + this.event = event; + } + + @Override + public void execute(Player sender, String[] strings) { + this.addEgg(sender, aBoolean -> { + sender.sendMessage(aBoolean ? C.GREEN + "An easter egg location has been set." : C.RED + "There was an error adding an easter egg location.."); + }); + } + + @Override + public UserRank requiredRank() { + return UserRank.MANAGER; + } + + private void addEgg(Player player, Callback<Boolean> callback) { + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + EasterEgg easterEgg = EasterDAO.addEasterEgg(connection, player.getLocation()); + if (easterEgg == null) { + callback.call(false); + return; + } + + if (this.event != null) + this.event.eggs.add(easterEgg); + + callback.call(true); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/easter/EasterEvent.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/easter/EasterEvent.java new file mode 100644 index 0000000..ae3a95a --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/easter/EasterEvent.java @@ -0,0 +1,308 @@ +package net.grandtheftmc.gtm.event.easter; + +import com.comphenix.protocol.ProtocolLibrary; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.properties.Property; +import de.slikey.effectlib.util.ParticleEffect; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.event.BaseEvent; +import net.grandtheftmc.core.event.EventType; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.eventtag.EventTag; +import net.grandtheftmc.core.util.Component; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.gtm.GTM; +import org.bukkit.Bukkit; +import org.bukkit.Chunk; +import org.bukkit.Material; +import org.bukkit.boss.BarColor; +import org.bukkit.boss.BarStyle; +import org.bukkit.boss.BossBar; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.player.AsyncPlayerPreLoginEvent; +import org.bukkit.event.player.PlayerInteractAtEntityEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.world.ChunkUnloadEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; + +import java.lang.reflect.Field; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +public final class EasterEvent extends BaseEvent implements Listener { + + final HashMap<UUID, EasterPlayerData> playerCache = Maps.newHashMap(); + final Set<EasterEgg> eggs = Sets.newHashSet(); + private final Set<Chunk> chunks = Sets.newHashSet(); + final HashMap<Integer, EasterEgg> eggEntityIds = Maps.newHashMap(); + + private final String[] eggSkins = { + "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMjEzYTI3OGFlOTkwMmY3YzE1YmYzOTY5OWM2YTE0MjYxNDI1Y2NhZmVkYWIyNGZhNmE4NTljNDE1YTMwNWQ0YSJ9fX0=", + "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMjVlZDNhZmJkNjk2NDk5ZGVkY2NmMmRmZDY2NWZkY2VmMDQyOWE4OTk0MjhiNmZkODczNWNiZGNiMjViYjgifX19", + "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZDYwZjY5NTU1N2YxYzEzZTNlNjJlNWNhMDVmYWY0YTczMGRiNzcyYzhmYWIxZjA3MmE3MzI5N2YyMCJ9fX0=", + "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOWQ1MGZlMTVhMjEyODY0OGM3YmQxYTk4NWMzMjBiYWRiZmRmNmViYjQ2ODJjYWM0OTEyOTA5NjIwY2NmIn19fQ==", + "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvN2MzNTI4NzA0YTI3MjkxODEzZDk4OWRjMDFmYmI2ODg0YzE2OGI0ZDA5YTkxMzQ2OTE4OGU0N2Y0MGMyZDAifX19", + "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYmE4YWU0NGU4ZDUwM2NjYjhlMGJmNTEzYTI1YjllOGI2MTVlYzkwNGM0ZjgyOTNkOTk1ZjE0Y2Q4NjllZTEifX19", + "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYzg2MDg5Y2Q5NjhmYzY1YTkxNmY2OGIyNGU3YzYzMzcwZDA3Y2JmNjMyZDRhOWQxMmUzYzI4YjlkYTM4In19fQ==", + "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNjIyYjMzMTliNTk5MzQ4MTcyMzAzNThjZjMzZDAzOGM5ODNjOWI2NzdhZDE1YjBhM2Y1ZjFmZTNiNWMxNTdiIn19fQ==", + "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMzEyNThmOTg5ZTAzMjNiZmUzODJlOGViMjIzODQ5YjRkY2RiMGRlODg3MjczMTQxNWMxYzliYmI0YTgyOTE4In19fQ==", + "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYWQ5MDlkM2U5ZGFmZGI2OGU1NDdhODNhNzQ5NDg2YmFjNmVjZTA5YjhmNjA0ZThmODY1ODE2ZjVhN2E5MjE3In19fQ==", + "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMTk1ZWJjMGYxMTUyYmFiZjJhNTU1YWFjNjc0ZTk2OGUyZjEyOTU4Nzc3NDFmMmM4ZjhiZWJjYjE5NTI4YyJ9fX0=", + "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNjJlODdmODgzMzg2NmExNjcyZTFmMmFhODk1NjYxODBmYzkxZmZiZTRiYzg2Mzc5M2ViNWU2MTYyNjQ4NSJ9fX0=", + "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYmFlZWNhMzYxNTczNGYyZGRlNjUyYzc1YzhmYjUyMGVmZjNiYTQwNWM2NTVhNWZmM2E4N2FiYzY4Yzk4MWIyIn19fQ==", + "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZWE1ZWFiYjA5NTc3NTljZjYxODRhMjk0MWNmZGEwMWI5MWZkMjFmMGQxNTIxMzM1YmYxNDMyZDczYWViZWFiIn19fQ==", + "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZDA5NTU4N2FhNTY1ODM3N2VmYmU1ZmY3ZGFmNTRmZWZmZTZkNWY2YmRhYmEzZGMxOWVlN2QyZjE4NjI2MjQ3ZCJ9fX0=", + "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYmI4ODRkNjFmMjM1MjM1MDQ3NDgzYWM0YmE0Y2U1Mjg2OTFlNjQyNGJhYzEzODE0MTU5MjcyZDk2NzNhYyJ9fX0=" + }; + + private final Random random; + private BossBar bossBar = null; + private BukkitTask updateEventBarTask, runEggEffectsTask; + + public EasterEvent(Plugin plugin, long startTime, long endTime) { + super(plugin, EventType.EASTER.getId(), startTime, endTime); + this.random = new Random(); + } + + @Override + public void onInit() { + HandlerList.unregisterAll(this); + Bukkit.getPluginManager().registerEvents(this, super.getPlugin()); +// new EasterEggCommand(this); + } + + @Override + public void onStart() { + this.bossBar = Bukkit.createBossBar(Utils.f("&c&lE&6&la&e&ls&c<&6&le&e&lr &c&lE&6&lg&e&lg &c&lE&6&lv&e&le&c&ln&6<&e&l!"), BarColor.YELLOW, BarStyle.SOLID); + + this.updateEventBarTask = new BukkitRunnable() { + @Override + public void run() { + updateBossBar(); + + for (Player player : Bukkit.getOnlinePlayers()) { + if (bossBar == null) continue; + bossBar.addPlayer(player); + } + } + }.runTaskTimerAsynchronously(getPlugin(), 0, 20*60); + + + for(Player player : Bukkit.getOnlinePlayers()) + this.bossBar.addPlayer(player); + + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + this.eggs.addAll(EasterDAO.getEasterEggs(connection)); + + ServerUtil.runTask(() -> { + for (EasterEgg egg : this.eggs) { + if (egg == null) continue; + + if (!egg.getLocation().getChunk().isLoaded()) + egg.getLocation().getChunk().load(); + + for (Entity entity : egg.getLocation().getWorld().getNearbyEntities(egg.getLocation(), 0.2, 2, 0.2)) { + if (entity == null) continue; + if (entity.getType() != EntityType.ARMOR_STAND) continue; + entity.remove(); + } + + ArmorStand armorStand = egg.getLocation().getWorld().spawn(egg.getLocation().clone().subtract(0, 1.4, 0), ArmorStand.class); + armorStand.setRemoveWhenFarAway(false); + armorStand.setGravity(false); + armorStand.setVisible(false); + armorStand.setInvulnerable(true); + armorStand.setHelmet(this.createEggHead()); + armorStand.setCustomName(Utils.f("&e&lClick Me")); + armorStand.setCustomNameVisible(true); + armorStand.setMetadata("easteregg", new FixedMetadataValue(super.getPlugin(), egg)); + + egg.setArmorStand(armorStand); + + eggEntityIds.put(armorStand.getEntityId(), egg); + chunks.add(egg.getLocation().getChunk()); + } + }); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + + this.runEggEffectsTask = new BukkitRunnable() { + @Override + public void run() { + for (EasterEgg egg : EasterEvent.this.eggs) { + if (egg.getArmorStand() == null) continue; +// egg.getLocation().getWorld().spawnParticle(Particle.VILLAGER_HAPPY, egg.getArmorStand().getEyeLocation(), 25, 0.7, 1, 0.7); + List<Player> players = getPlayersHasntUnlocked(egg.getUniqueIdentifier()); + if (players.isEmpty()) break; + ParticleEffect.VILLAGER_HAPPY.display(0.7f, 1f, 0.7f, 1, 25, egg.getArmorStand().getEyeLocation(), players); + //255f/255f,102f/255f,102f/255f + } + } + }.runTaskTimerAsynchronously(getPlugin(), 100, 20*5); + + ProtocolLibrary.getProtocolManager().addPacketListener(new EasterPacketListener(super.getPlugin(), this)); + } + + @Override + public void onEnd() { + this.updateEventBarTask.cancel(); + this.runEggEffectsTask.cancel(); + + this.bossBar.removeAll(); + this.bossBar = null; + + for (EasterEgg egg : EasterEvent.this.eggs) { + if (egg.getArmorStand() == null) continue; + egg.getArmorStand().remove(); + } + } + + private List<Player> getPlayingPlayers() { + return Bukkit.getOnlinePlayers().stream().filter(player -> this.playerCache.containsKey(player.getUniqueId()) && !this.playerCache.get(player.getUniqueId()).hasFoundAllEggs()).collect(Collectors.toList()); + } + + private List<Player> getPlayersHasntUnlocked(int easterEggId) { + return Bukkit.getOnlinePlayers().stream().filter(player -> { + return !player.getWorld().getName().equals("spawn") && this.playerCache.containsKey(player.getUniqueId()) && !this.playerCache.get(player.getUniqueId()).hasFoundEgg(easterEggId); + }).collect(Collectors.toList()); + } + + private void updateBossBar() { + + // how many seconds left until over + int secondsLeft = (int) ((getEndTime() - System.currentTimeMillis()) / 1000.0); + + int day = (int) TimeUnit.SECONDS.toDays(secondsLeft); + long hours = TimeUnit.SECONDS.toHours(secondsLeft) - (day * 24); + long minute = TimeUnit.SECONDS.toMinutes(secondsLeft) - (TimeUnit.SECONDS.toHours(secondsLeft) * 60); + + String timeLeft = day + "d " + hours + "h " + minute + "m"; + String title = Utils.f("&c&lE&6&la&e&ls&c<&6&le&e&lr &c&lE&6&lg&e&lg &c&lE&6&lv&e&le&c&ln&6<&e&l! &6&l") + timeLeft; + + double start = System.currentTimeMillis() - getStartTime(); + double end = getEndTime() - getStartTime(); + + // this gives us how through we are + double through = start / end; + double progress = 1 - through; + + this.bossBar.setTitle(title); + this.bossBar.setProgress(progress); + } + + private ItemStack createEggHead() { + GameProfile profile = new GameProfile(UUID.randomUUID(), null); + profile.getProperties().clear(); + profile.getProperties().put("textures", new Property("texture", this.eggSkins[this.random.nextInt(this.eggSkins.length)], null)); + + ItemStack head = new ItemStack(Material.SKULL_ITEM, 1, (short) 3); + SkullMeta headMeta = (SkullMeta) head.getItemMeta(); + + try { + Field profileField = headMeta.getClass().getDeclaredField("profile"); + profileField.setAccessible(true); + profileField.set(headMeta, profile); + } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { + e.printStackTrace(); + } + head.setItemMeta(headMeta); + return head; + } + + @EventHandler + protected final void onPlayerLogin(AsyncPlayerPreLoginEvent event) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + this.playerCache.putIfAbsent(event.getUniqueId(), new EasterPlayerData(super.getPlugin(), this, EasterDAO.getFoundEggs(connection, event.getUniqueId()))); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @EventHandler + protected final void onPlayerQuit(PlayerQuitEvent event) { + this.playerCache.remove(event.getPlayer().getUniqueId()); + } + + @EventHandler + protected final void onEntityInteract(PlayerInteractAtEntityEvent event) { + if (event.getRightClicked() == null) return; + if (!this.playerCache.containsKey(event.getPlayer().getUniqueId())) return; + if (!event.getRightClicked().hasMetadata("easteregg")) return; + + ArmorStand armorStand = (ArmorStand) event.getRightClicked(); + if (armorStand.getMetadata("easteregg").size() <= 0) return; + if (armorStand.getMetadata("easteregg").get(0) == null) return; + + EasterEgg easterEgg = (EasterEgg) armorStand.getMetadata("easteregg").get(0).value(); + if (easterEgg == null) return; + + EasterPlayerData playerData = this.playerCache.get(event.getPlayer().getUniqueId()); + playerData.find(event.getPlayer(), easterEgg); + } + + @EventHandler + protected final void onEasterEggFind(EasterFoundEggEvent event) { + User user = Core.getUserManager().getLoadedUser(event.getPlayer().getUniqueId()); + if (!this.playerCache.containsKey(event.getPlayer().getUniqueId())) return; + EasterPlayerData playerData = this.playerCache.get(event.getPlayer().getUniqueId()); + + if (event.isFoundAll()) { + user.giveEventTag(EventTag.EGG); + + user.addCrowbars(2); + event.getPlayer().sendMessage(Lang.CROWBARS_ADD.f("2")); + + event.getPlayer().sendTitle(Utils.f("&6&lEaster Event"), Utils.f("&rAll eggs found, You've unlocked '&c&lE&6&lG&e&lG&r' tag!")); + + Bukkit.broadcastMessage(Utils.f("&c&lE&6&la&e&ls&c<&6&le&e&lr &c&lE&6&lg&e&lg &c&lE&6&lv&e&le&c&ln&6<&r")); + Bukkit.broadcastMessage(Utils.f("&e" + event.getPlayer().getName() + "&r has found all Easter Eggs and has been rewarded the '&c&lE&6&lG&e&lG&r' tag!")); + + playerData.startAnimation(event.getPlayer(), event.getEasterEgg()); + return; + } + + user.addCrowbars(2); + event.getPlayer().sendMessage(Lang.CROWBARS_ADD.f("2")); + + event.getPlayer().sendTitle(Utils.f("&6&lEaster Event"), Utils.f("&rYou found an easter egg, &l" + Math.abs(playerData.getEggsFounds() - this.eggs.size()) + "&r left!")); + + playerData.startAnimation(event.getPlayer(), event.getEasterEgg()); + } + + @EventHandler(ignoreCancelled = true) + protected final void onChunkUnload(ChunkUnloadEvent event) { + if (chunks.contains(event.getChunk())) + event.setCancelled(true); + } + + @EventHandler(ignoreCancelled = true) + protected final void onEntityDamage(EntityDamageEvent event) { + if (event.getEntity() == null) return; + + if (event.getEntity().hasMetadata("easteregg")) + event.setCancelled(true); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/easter/EasterFoundEggEvent.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/easter/EasterFoundEggEvent.java new file mode 100644 index 0000000..a6f65ec --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/easter/EasterFoundEggEvent.java @@ -0,0 +1,30 @@ +package net.grandtheftmc.gtm.event.easter; + +import net.grandtheftmc.core.events.CoreEvent; +import org.bukkit.entity.Player; + +public final class EasterFoundEggEvent extends CoreEvent { + + private final Player player; + private final EasterEgg easterEgg; + private final boolean foundAll; + + public EasterFoundEggEvent(Player player, EasterEgg easterEgg, boolean foundAll) { + super(false); + this.player = player; + this.easterEgg = easterEgg; + this.foundAll = foundAll; + } + + public Player getPlayer() { + return player; + } + + public EasterEgg getEasterEgg() { + return easterEgg; + } + + public boolean isFoundAll() { + return foundAll; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/easter/EasterPacketListener.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/easter/EasterPacketListener.java new file mode 100644 index 0000000..8797052 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/easter/EasterPacketListener.java @@ -0,0 +1,97 @@ +package net.grandtheftmc.gtm.event.easter; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.ListeningWhitelist; +import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.events.PacketListener; +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitScheduler; + +public class EasterPacketListener implements PacketListener { + + private final Plugin plugin; + private final EasterEvent event; + + public EasterPacketListener(Plugin plugin, EasterEvent event) { + this.plugin = plugin; + this.event = event; + } + + /** + * Invoked right before a packet is transmitted from the server to the client. + * <p> + * Note that the packet may be replaced, if needed. + * <p> + * This method is executed on the main thread in 1.6.4 and earlier, and thus the Bukkit API is safe to use. + * <p> + * In Minecraft 1.7.2 and later, this method MAY be executed asynchronously, but only if {@link ListenerOptions#ASYNC} + * have been specified in the listener. This is off by default. + * + * @param event - the packet that should be sent. + */ + @Override + public void onPacketSending(PacketEvent event) { + if (event.getPacketType() == PacketType.Play.Server.SPAWN_ENTITY) { + int id = event.getPacket().getIntegers().readSafely(0); + if (!this.event.eggEntityIds.containsKey(id)) return; + + EasterEgg easterEgg = this.event.eggEntityIds.get(id); + if (easterEgg == null) return; + + if (!this.event.playerCache.containsKey(event.getPlayer().getUniqueId())) { + event.setCancelled(true); + return; + } + + EasterPlayerData playerData = this.event.playerCache.get(event.getPlayer().getUniqueId()); + if (playerData.hasFoundEgg(easterEgg.getUniqueIdentifier())) { + event.setCancelled(true); + } + } + } + + /** + * Invoked right before a received packet from a client is being processed. + * <p> + * <b>WARNING</b>: <br> + * This method will be called <i>asynchronously</i>! You should synchronize with the main + * thread using {@link BukkitScheduler#scheduleSyncDelayedTask(Plugin, Runnable, long) scheduleSyncDelayedTask} + * if you need to call the Bukkit API. + * + * @param event - the packet that has been received. + */ + @Override + public void onPacketReceiving(PacketEvent event) { + //404 + } + + /** + * Retrieve which packets sent by the server this listener will observe. + * + * @return List of server packets to observe, along with the priority. + */ + @Override + public ListeningWhitelist getSendingWhitelist() { + return ListeningWhitelist.newBuilder().types(PacketType.Play.Server.SPAWN_ENTITY).build(); + } + + /** + * Retrieve which packets sent by the client this listener will observe. + * + * @return List of server packets to observe, along with the priority. + */ + @Override + public ListeningWhitelist getReceivingWhitelist() { + return ListeningWhitelist.EMPTY_WHITELIST; + } + + /** + * Retrieve the plugin that created list packet listener. + * + * @return The plugin, or NULL if not available. + */ + @Override + public Plugin getPlugin() { + return this.plugin; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/easter/EasterPlayerData.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/easter/EasterPlayerData.java new file mode 100644 index 0000000..bf2e60b --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/easter/EasterPlayerData.java @@ -0,0 +1,89 @@ +package net.grandtheftmc.gtm.event.easter; + +import com.google.common.collect.Lists; +import de.slikey.effectlib.util.ParticleEffect; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.util.ServerUtil; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.List; +import java.util.Set; +import java.util.concurrent.ThreadLocalRandom; + +public final class EasterPlayerData { + + private final Set<Integer> foundEggs; + private final Plugin plugin; + private final EasterEvent event; + + protected EasterPlayerData(Plugin plugin, EasterEvent event, Set<Integer> foundEggs) { + this.event = event; + this.plugin = plugin; + this.foundEggs = foundEggs; + } + + protected int getEggsFounds() { + return this.foundEggs.size(); + } + + protected boolean hasFoundAllEggs() { + return this.foundEggs.size() >= this.event.eggs.size(); + } + + protected boolean hasFoundEgg(int id) { + return this.foundEggs.contains(id); + } + + /** + * This method is ran when a player finds an Easter Egg. + * + * @param easterEgg - The Easter Egg object + */ + protected void find(Player player, EasterEgg easterEgg) { + + //If the 'foundEggs' list contains this egg, do nothing. + if (this.foundEggs.contains(easterEgg.getUniqueIdentifier())) + return; + + this.foundEggs.add(easterEgg.getUniqueIdentifier()); + + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + EasterDAO.addUserFind(connection, player.getUniqueId(), easterEgg.getUniqueIdentifier()); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + + boolean foundAll = this.foundEggs.size() == event.eggs.size(); + EasterFoundEggEvent foundEggEvent = new EasterFoundEggEvent(player, easterEgg, foundAll); + Bukkit.getPluginManager().callEvent(foundEggEvent); + } + + protected void startAnimation(Player player, EasterEgg easterEgg) { + player.playSound(player.getLocation(), Sound.ENTITY_ENDERDRAGON_DEATH, 1f, 1f); + + if (easterEgg.getArmorStand() == null) return; + + player.playSound(easterEgg.getLocation(), Sound.ENTITY_GENERIC_EXPLODE, 1f, 1f); + ParticleEffect.SMOKE_NORMAL.display(0.3f, 0.3f, 0.3f, 1, 15, easterEgg.getArmorStand().getEyeLocation(), player); + ParticleEffect.SMOKE_LARGE.display(0.3f, 0.3f, 0.3f, 1, 15, easterEgg.getArmorStand().getEyeLocation(), player); + + //After animation, + easterEgg.destroyFor(player); + } + + private List<ItemStack> getRandomItems() { + List<ItemStack> items = Lists.newArrayList(); + int a = ThreadLocalRandom.current().nextInt(8); + for (int i = 0; i < a; i++) items.add(new ItemStack(Material.EGG)); + return items; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/halloween/HalloweenDAO.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/halloween/HalloweenDAO.java new file mode 100644 index 0000000..62eb23f --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/halloween/HalloweenDAO.java @@ -0,0 +1,80 @@ +package net.grandtheftmc.gtm.event.halloween; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +import net.grandtheftmc.core.Core; + +/** + * Data access object for halloween event specific data. + * + * @author sbahr + */ +public class HalloweenDAO { + + /** + * Get a set of ids for the specified user where each id is the id of a + * premium house that has already been redeemed by the user. + * + * @param conn - the database connection thread + * @param uuid - the uuid of the user + * + * @return A set of integers where each integer is the id of a premium + * house. + */ + public static Set<Integer> getRedeemedHouses(Connection conn, UUID uuid) { + + Set<Integer> houses = new HashSet<>(); + + String query = "SELECT house_id from event_halloween WHERE uuid=UNHEX(?);"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setString(1, uuid.toString().replaceAll("-", "")); + + try (ResultSet result = ps.executeQuery()) { + while (result.next()) { + houses.add(result.getInt("house_id")); + } + } + } + catch (SQLException exc) { + Core.log("[HalloweenDAO] Error executing getRedeemedHouses() for uuid=" + uuid.toString()); + exc.printStackTrace(); + } + + return houses; + } + + /** + * Create a redeem house transaction. This is so we mark a house as redeemed. + * + * @param conn - the database connection thread + * @param uuid - the uuid of the user to create the redeem for + * @param houseID - the id of the house + * + * @return {@code true} if the transaction was ran, {@code false} otherwise. + */ + public static boolean createRedeemedHouse(Connection conn, UUID uuid, int houseID) { + + String query = "INSERT IGNORE INTO event_halloween (uuid, house_id) VALUES (UNHEX(?), ?);"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setString(1, uuid.toString().replaceAll("-", "")); + ps.setInt(2, houseID); + + ps.executeUpdate(); + return true; + } + catch (SQLException exc) { + Core.log("[HalloweenDAO] Error executing createRedeemedHouse() for uuid=" + uuid.toString() + " and houseID=" + houseID); + exc.printStackTrace(); + + return false; + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/halloween/HalloweenEvent.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/halloween/HalloweenEvent.java new file mode 100644 index 0000000..242f100 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/halloween/HalloweenEvent.java @@ -0,0 +1,736 @@ +package net.grandtheftmc.gtm.event.halloween; + +import java.sql.Connection; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.BlockState; +import org.bukkit.boss.BarColor; +import org.bukkit.boss.BarFlag; +import org.bukkit.boss.BarStyle; +import org.bukkit.boss.BossBar; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Skeleton; +import org.bukkit.event.Event.Result; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.entity.EntityCombustEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.entity.EntitySpawnEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitTask; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.event.BaseEvent; +import net.grandtheftmc.core.event.EventType; +import net.grandtheftmc.core.gui.ConfirmationMenu; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.title.NMSTitle; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.items.GameItem; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.houses.PremiumHouse; + +public class HalloweenEvent extends BaseEvent implements Listener { + + /** Random instance */ + private static final Random RANDOM = new Random(); + /** The cost to play trick or treat, in tokens */ + public static final int TRICK_COST = 5; + + // spawning variables + /** How often to check to spawn monsters */ + private long spawnTick = 20L * 1; + /** The maximum amount of monsters for this event */ + private int maxMonsters = 100; + /** The spawn variance, how far from the player can we spawn monsters */ + private int spawnVariance = 15; + /** Maps UUID to the entity */ + private Map<UUID, Entity> uuidToEntity; + /** Cache of what users had entities spawned near */ + private Set<UUID> playersTargeted; + /** The last timestamp when we cleared the players target */ + private long targetClearTimestamp; + /** The spawn task for the entities */ + private BukkitTask spawnTask; + /** The world for this event */ + private World world; + + /** Maps UUID to redeemed houses */ + private Map<UUID, Set<Integer>> uuidToRedeemed; + + /** The boss bar for when the event is going on */ + private BossBar bossBar; + /** The total amount of tokens the event has earned in a pot */ + private int tokens; + + /** + * Construct a new HalloweenEvent. + * + * @param plugin - the owning plugin + * @param startTime - the time, in millis since epoch, that this event + * starts + * @param endTime - the time, in millis since epoch, that this event ends + */ + public HalloweenEvent(Plugin plugin, long startTime, long endTime) { + super(plugin, EventType.HALLOWEEN.getId(), startTime, endTime); + this.uuidToEntity = new HashMap<>(); + this.playersTargeted = new HashSet<>(); + this.targetClearTimestamp = System.currentTimeMillis(); + this.world = Bukkit.getWorld("minesantos"); + this.uuidToRedeemed = new HashMap<>(); + this.bossBar = Bukkit.createBossBar("Halloween", BarColor.PINK, BarStyle.SOLID); + } + + /** + * {@inheritDoc} + */ + @Override + public void onInit() { + + } + + /** + * {@inheritDoc} + */ + @Override + public void onStart() { + + // register as plugin + getPlugin().getServer().getPluginManager().registerEvents(this, getPlugin()); + + // set the world time to night + if (world != null) { + world.setTime(12000); + } + + for (Player player : Bukkit.getOnlinePlayers()) { + + // play sound and title + player.playSound(player.getLocation(), Sound.ENTITY_ENDERDRAGON_DEATH, 0.3f, 0f); + NMSTitle.sendTitle(player, ChatColor.GOLD + "Halloween!", ChatColor.WHITE + "Spooky...", 10, 20 * 5, 10); + bossBar.addPlayer(player); + } + + // start the spawn task + this.spawnTask = getSpawnTask(); + } + + /** + * {@inheritDoc} + */ + @Override + public void onEnd() { + + // end the spawn task + if (this.spawnTask != null) { + this.spawnTask.cancel(); + } + + // remove all from boss bar + bossBar.removeAll(); + + // remove all spawned skeletons + removeSpawnedEntities(); + + // unregister this listener + HandlerList.unregisterAll(this); + } + + /** + * Listens in on entity spawn events. + * + * @param event - the event + */ + @EventHandler + public void onEntitySpawn(EntitySpawnEvent event) { + + } + + /** + * Listens in on entity death events. + * + * @param event - the event + */ + @EventHandler + public void onEntityDeath(EntityDeathEvent event) { + + LivingEntity le = event.getEntity(); + + // if custom entity + if (uuidToEntity.containsKey(le.getUniqueId())) { + uuidToEntity.remove(le.getUniqueId()); + + // clear drops + event.getDrops().clear(); + event.setDroppedExp(0); + + // always drop roofied chocolate + GameItem rc = GTM.getItemManager().getItem("roofied_chocolate"); + if (rc != null) { + event.getDrops().add(rc.getItem()); + } + + int chance = RANDOM.nextInt(100); + if (chance < 5) { + + // 5% chance to drop candy bag + GameItem cb = GTM.getItemManager().getItem("candy_bag"); + if (cb != null) { + event.getDrops().add(cb.getItem()); + } + } + } + } + + /** + * Listens in on entity combust event. + * <p> + * This stops entities from getting lit on fire. + * + * @param event - the event + */ + @EventHandler + public void onEntityCombust(EntityCombustEvent event) { + + // grab entity + Entity entity = event.getEntity(); + + // stop custom entities from lit on fire + if (uuidToEntity.containsKey(entity.getUniqueId())) { + event.setCancelled(true); + } + } + + /** + * Listens in on entity damage events for fire tick damage. + * <p> + * This stops entities from getting lit on fire. + * + * @param event - the event + */ + @EventHandler + public void onFireTick(EntityDamageEvent event) { + + // grab entity + Entity entity = event.getEntity(); + + // stop custom entities from lit on fire + if (uuidToEntity.containsKey(entity.getUniqueId())) { + if (event.getCause() == DamageCause.FIRE_TICK) { + event.getEntity().setFireTicks(0); + } + } + } + + /** + * Listens in on player join. + * + * @param event - the event + */ + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) { + + // grab the player + Player player = event.getPlayer(); + + // play sound and title + player.playSound(player.getLocation(), Sound.ENTITY_ENDERDRAGON_DEATH, 0.3f, 0f); + NMSTitle.sendTitle(player, ChatColor.GOLD + "Halloween!", ChatColor.WHITE + "Spooky...", 10, 20 * 5, 10); + bossBar.addPlayer(player); + + // async fetch for house information + Bukkit.getScheduler().runTaskAsynchronously(getPlugin(), () -> { + + Set<Integer> houses = new HashSet<>(); + try (Connection conn = BaseDatabase.getInstance().getConnection()) { + houses.addAll(HalloweenDAO.getRedeemedHouses(conn, player.getUniqueId())); + } + catch (Exception e) { + e.printStackTrace(); + } + + // sync to get back on thread + Bukkit.getScheduler().runTask(getPlugin(), () -> { + uuidToRedeemed.put(player.getUniqueId(), houses); + }); + }); + } + + /** + * Listens in on player quits. + * + * @param event - the event + */ + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + + // grab event variables + Player player = event.getPlayer(); + + // remove boss bar from playing + bossBar.removePlayer(player); + + if (uuidToRedeemed.containsKey(player.getUniqueId())) { + uuidToRedeemed.remove(player.getUniqueId()); + } + } + + /** + * Listens in on the player interact events. + * + * @param event - the event + */ + @EventHandler(ignoreCancelled = true, priority = EventPriority.LOW) + public void onPlayerInteract(PlayerInteractEvent event) { + + // grab the event variables + Player p = event.getPlayer(); + Action a = event.getAction(); + ItemStack is = event.getItem(); + + // if right click block + if (a == Action.RIGHT_CLICK_BLOCK && event.getHand() == EquipmentSlot.HAND) { + + // make sure they have a candy bag + GameItem gi = GTM.getItemManager().getItem(is); + if (gi != null && gi.getName().equalsIgnoreCase("candy_bag")) { + + if (isDay()) { + p.sendMessage(ChatColor.RED + "You can only " + ChatColor.GOLD + "Trick or Treat" + ChatColor.RED + " at night."); + return; + } + + Block block = event.getClickedBlock(); + if (block != null) { + + // grab block state + BlockState state = block.getState(); + + // grab the block underneath + Block underneath = block.getRelative(BlockFace.DOWN); + if (underneath.getType() == Material.IRON_DOOR_BLOCK) { + state = underneath.getState(); + } + + // see if this is a premium house + Object[] data = Houses.getHousesManager().getHouseAndDoor(state.getLocation()); + if (data != null && data[0] instanceof PremiumHouse) { + + // deny interact events + event.setCancelled(true); + event.setUseInteractedBlock(Result.DENY); + event.setUseItemInHand(Result.DENY); + + // make sure they have tokens + User user = Core.getUserManager().getLoadedUser(p.getUniqueId()); + if (user != null) { + if (user.getTokens() > TRICK_COST) { + + // grab premium house id + PremiumHouse premHouse = (PremiumHouse) data[0]; + int houseID = premHouse.getId(); + + // get list of redeemed houses for the user + Set<Integer> redeemed = null; + if (uuidToRedeemed.containsKey(p.getUniqueId())) { + redeemed = uuidToRedeemed.get(p.getUniqueId()); + } + else { + redeemed = new HashSet<>(); + } + uuidToRedeemed.put(p.getUniqueId(), redeemed); + + if (!redeemed.contains(houseID)) { + + // confirm menu + ConfirmationMenu confirm = new ConfirmationMenu(getPlugin(), getInfoItemStack()) { + + @Override + public void onConfirm(InventoryClickEvent e, Player p) { + + // do this check again + if (user.getTokens() > TRICK_COST) { + + if (uuidToRedeemed.containsKey(p.getUniqueId())) { + Set<Integer> redeemed = uuidToRedeemed.get(p.getUniqueId()); + + redeemed.add(houseID); + uuidToRedeemed.put(p.getUniqueId(), redeemed); + + p.sendMessage(ChatColor.WHITE + "--- " + ChatColor.GOLD + "Trick or Treat" + ChatColor.WHITE + "---"); + p.sendMessage(ChatColor.WHITE + "Trick or Treating uses " + ChatColor.GOLD + TRICK_COST + " tokens" + ChatColor.WHITE + "."); + p.sendMessage(ChatColor.WHITE + "You'll have a chance to win rewards plus a large jackpot of tokens!"); + p.sendMessage(ChatColor.RED.toString() + ChatColor.BOLD + "-" + TRICK_COST + " Tokens"); + + // subtract user's tokens + // and add to global + // pot + user.setTokens(user.getTokens() - TRICK_COST); + setTokens(getTokens() + TRICK_COST); + + // don't let them hit the + // door again + Bukkit.getScheduler().runTaskAsynchronously(getPlugin(), () -> { + try (Connection conn = BaseDatabase.getInstance().getConnection()) { + HalloweenDAO.createRedeemedHouse(conn, p.getUniqueId(), houseID); + } + catch (Exception exc) { + exc.printStackTrace(); + } + }); + + // execute trick or treat + new TrickOrTreatTask(getPlugin(), p, block.getLocation()); + } + } + } + + @Override + public void onDeny(InventoryClickEvent e, Player p) { + + } + }; + confirm.open(p); + } + else { + p.sendMessage(ChatColor.RED + "You have already played " + ChatColor.GOLD + "Trick or Treat" + ChatColor.RED + " at this house."); + } + } + else { + p.sendMessage(ChatColor.RED + "You do not have enough tokens to Trick or Treat! You need " + ChatColor.WHITE + TRICK_COST + ChatColor.RED + " tokens to play!"); + } + } + } + else { + p.sendMessage(ChatColor.RED + "You can only Trick or Treat at Premium Houses!"); + } + } + } + } + } + + /** + * Get the spawn task that handles spawning entities. + * + * @return The spawn task that handles the entities spawning. + */ + protected BukkitTask getSpawnTask() { + + return Bukkit.getScheduler().runTaskTimer(getPlugin(), () -> { + + // change time cycle + world.setTime(world.getTime() + 20); + + if (isDay()) { + removeSpawnedEntities(); + bossBar.removeAll(); + return; + } + else { + bossBar.addFlag(BarFlag.CREATE_FOG); + bossBar.addFlag(BarFlag.DARKEN_SKY); + + Bukkit.getOnlinePlayers().forEach(p -> { + bossBar.addPlayer(p); + }); + } + + updateBossBar(); + + // clear targets event 30 secs + if (System.currentTimeMillis() - targetClearTimestamp > 30 * 1000) { + targetClearTimestamp = System.currentTimeMillis(); + playersTargeted.clear(); + } + + // clamp size + if (uuidToEntity.size() < maxMonsters) { + + // attempt to spawn around a player + for (Player p : Bukkit.getOnlinePlayers()) { + + // skip targetted players + if (playersTargeted.contains(p.getUniqueId())) { + continue; + } + + // must be in minesantos + if (p.getWorld().getName().equalsIgnoreCase("minesantos")) { + + Location spawnLoc = getRandomSpawnPoint(p.getLocation(), spawnVariance); + if (spawnLoc != null) { + + Skeleton skeleton = (Skeleton) spawnLoc.getWorld().spawnEntity(spawnLoc, EntityType.SKELETON); + skeleton.setMaxHealth(30); + skeleton.setHealth(30); + + GameItem cr = GTM.getItemManager().getItem("baseballbat"); + if (cr != null) { + skeleton.getEquipment().setItemInHand(cr.getItem()); + } + + // add to uuid mapping + uuidToEntity.put(skeleton.getUniqueId(), skeleton); + + // cache as a target, will clear every so interval + playersTargeted.add(p.getUniqueId()); + } + } + } + } + + }, 0L, spawnTick); + } + + /** + * Remove the spawned entities from this event. + */ + protected void removeSpawnedEntities() { + + for (World world : Bukkit.getWorlds()) { + + for (Entity entity : world.getEntities()) { + + // if this is a custom entity + if (uuidToEntity.containsKey(entity.getUniqueId())) { + uuidToEntity.remove(entity.getUniqueId()); + + // set health to 0 + if (entity instanceof LivingEntity) { + LivingEntity le = (LivingEntity) entity; + le.setHealth(0); + } + + // remove the entity + entity.remove(); + } + } + } + + // clean up the entities if still exist + uuidToEntity.clear(); + } + + /** + * Get a random spawn point around a specific location. + * + * @param loc - the location to get a spawn point around + * @param variance - the variance, or the radius from the location + * + * @return The location that is a random spawn point candidate. + */ + protected Location getRandomSpawnPoint(Location loc, int variance) { + + // assume the location is somewhat near the ground + Location initial = loc.clone(); + + // add random variance around location + // we roll between 0 and 1, and then offset by 0.5 + // then we multiple that number (say its -0.3) by 2 times the variance + // so we get a negative x of variance length + initial.setX(initial.getX() + ((RANDOM.nextDouble() - 0.5) * 2 * variance)); + initial.setZ(initial.getZ() + ((RANDOM.nextDouble() - 0.5) * 2 * variance)); + + // add 15 blocks to account for being underground or in a building + initial.add(0, 15, 0); + + // search for at least 25 blocks down + Location spawnLoc = findFloor(initial, 25); + if (spawnLoc != null) { + + // get 1.25 block up from the floor, so they can "drop" a bit + spawnLoc.add(0, 1.25, 0); + + // attempt to find a ceiling at least 10 blocks up + Location ceiling = findCeiling(spawnLoc, 10); + if (ceiling == null) { + + // no ceiling is good, we don't want to spawn in buildings + return spawnLoc; + } + } + + return null; + } + + /** + * Given a location, attempt to find the floor, but only iterate up to x + * blocks down. + * + * @param loc - the location to find the floor for + * @param maxSearch - the max number of blocks we iterate straight down + * + * @return The location of the floor, if one was found, otherwise null. + */ + protected Location findFloor(Location loc, int maxSearch) { + + Location initial = loc.clone(); + + int tries = maxSearch; + // while we're touching air + while (initial.getBlock().getType() == Material.AIR) { + + // if no more attempts to find + if (tries <= 0) { + break; + } + // go down one + initial.add(0, -1, 0); + + tries--; + } + + // if it's still air, return null + if (initial.getBlock().getType() == Material.AIR) { + return null; + } + + return initial; + } + + /** + * Given a location, attempt to find the ceiling, but only iterate up to x + * blocks down. + * + * @param loc - the location to find the ceiling for + * @param maxSearch - the max number of blocks we iterate straight up + * + * @return The location of the ceiling, if one was found, otherwise null. + */ + protected Location findCeiling(Location loc, int maxSearch) { + + Location initial = loc.clone(); + + int tries = maxSearch; + // while we're touching air + while (initial.getBlock().getType() == Material.AIR) { + + // if no more attempts to find + if (tries <= 0) { + break; + } + // go up one + initial.add(0, 1, 0); + + tries--; + } + + // if it's still air, return null + if (initial.getBlock().getType() == Material.AIR) { + return null; + } + + return initial; + } + + /** + * Updates the boss bar. + */ + protected void updateBossBar() { + + // how many seconds left until over + int secondsLeft = (int) ((getEndTime() - System.currentTimeMillis()) / 1000.0); + + int day = (int) TimeUnit.SECONDS.toDays(secondsLeft); + long hours = TimeUnit.SECONDS.toHours(secondsLeft) - (day * 24); + long minute = TimeUnit.SECONDS.toMinutes(secondsLeft) - (TimeUnit.SECONDS.toHours(secondsLeft) * 60); + long second = TimeUnit.SECONDS.toSeconds(secondsLeft) - (TimeUnit.SECONDS.toMinutes(secondsLeft) * 60); + + String timeLeft = day + "d " + hours + "h " + minute + "m"; + String title = "" + ChatColor.LIGHT_PURPLE + ChatColor.BOLD + "Halloween Event! " + ChatColor.GOLD + ChatColor.BOLD + timeLeft; + + double start = System.currentTimeMillis() - getStartTime(); + double end = getEndTime() - getStartTime(); + + // this gives us how through we are + double through = start / end; + double progress = 1 - through; + + bossBar.setTitle(title); + bossBar.setProgress(progress); + } + + /** + * Get the info itemstack for the confirm menu. + * + * @return The generic info item stack. + */ + private static ItemStack getInfoItemStack() { + ItemStack is = new ItemStack(Material.SIGN); + ItemMeta im = is.getItemMeta(); + List<String> lore = new ArrayList<>(); + lore.add(""); + lore.add(ChatColor.GRAY + "Trick or Treat at this house?"); + lore.add(""); + lore.add(ChatColor.GRAY + "Cost: " + ChatColor.GOLD + TRICK_COST + " tokens"); + im.setLore(lore); + is.setItemMeta(im); + return is; + } + + /** + * Get the total amount of tokens that this halloween event currently has. + * <p> + * This pot changes based off of trick or treat. + * + * @return The total amount of tokens that this halloween event currently + * has. + */ + public int getTokens() { + return tokens; + } + + /** + * Set the total amount of tokens that this halloween event currently has. + * + * @param tokens - the new amount tokens + */ + public void setTokens(int tokens) { + this.tokens = tokens; + } + + /** + * Get whether or not it is day in the main halloween world. + * + * @return Whether or not it is day. + */ + public boolean isDay() { + if (world.getTime() > 0 && world.getTime() < 12000) { + return true; + } + + return false; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/halloween/TrickOrTreatTask.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/halloween/TrickOrTreatTask.java new file mode 100644 index 0000000..e8335bb --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/event/halloween/TrickOrTreatTask.java @@ -0,0 +1,241 @@ +package net.grandtheftmc.gtm.event.halloween; + +import java.util.Arrays; +import java.util.List; +import java.util.Random; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Color; +import org.bukkit.FireworkEffect; +import org.bukkit.Location; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +import de.slikey.effectlib.util.ParticleEffect; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.event.Event; +import net.grandtheftmc.core.event.EventManager; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.PluginAssociated; +import net.grandtheftmc.core.util.Title; +import net.grandtheftmc.core.util.factory.FireworkFactory; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.items.GameItem; + +public class TrickOrTreatTask implements PluginAssociated { + + /** Random instance for this class */ + public static final Random RANDOM = new Random(); + /** Collection of no responses */ + public static final List<String> NO_RESPONSES = Arrays.asList("Fuck off!", "I don't have any candy you kid!", "No... I want free candy. You're not getting any here."); + /** Collection of meh responses */ + public static final List<String> MEH_RESPONSES = Arrays.asList("I guess that was a cool trick, for a brat.", "Okay you little ass. I'll give you something.", "Here's some drugs. Enjoy.", "Don't snort all this at once."); + /** Collection of yes responses */ + public static final List<String> YES_RESPONSES = Arrays.asList("Haha that shit was great.", "Probably the best trick i've seen all day.", "That was a really smooth trick.", "Got me. Now fuck off."); + + /** The owning plugin for this task */ + private final Plugin plugin; + /** The player involved in the event */ + private final Player player; + /** The location for the event */ + private final Location location; + + /** + * Construct a new TrickOrTreatTask. + * + * @param plugin - the owning plugin + * @param player - the player involved in the event + * @param location - the location where the player knocked + */ + public TrickOrTreatTask(Plugin plugin, Player player, Location location) { + this.plugin = plugin; + this.player = player; + this.location = location; + + // start the effect task + start(player, location); + } + + /** + * Start the trait or treat task. + * + * @param p - the player knocking on the door + * @param loc - the location of the door + */ + protected void start(Player p, Location loc) { + + // notify player that they are participating + p.sendMessage(ChatColor.GOLD + "You ring the doorbell..."); + p.playSound(p.getLocation(), Sound.BLOCK_NOTE_CHIME, 1f, 0f); + + Bukkit.getScheduler().runTaskLater(getPlugin(), () -> { + p.playSound(p.getLocation(), Sound.BLOCK_STONE_STEP, 0.6f, 0f); + }, 10L); + + Bukkit.getScheduler().runTaskLater(getPlugin(), () -> { + p.playSound(p.getLocation(), Sound.BLOCK_STONE_STEP, 0.7f, 0f); + }, 20L); + + Bukkit.getScheduler().runTaskLater(getPlugin(), () -> { + p.playSound(p.getLocation(), Sound.BLOCK_STONE_STEP, 0.8f, 0f); + }, 30L); + + Bukkit.getScheduler().runTaskLater(getPlugin(), () -> { + p.playSound(p.getLocation(), Sound.BLOCK_STONE_STEP, 0.9f, 0f); + }, 40L); + + Bukkit.getScheduler().runTaskLater(getPlugin(), () -> { + p.playSound(p.getLocation(), Sound.BLOCK_STONE_STEP, 1.0f, 0f); + }, 50L); + + Bukkit.getScheduler().runTaskLater(getPlugin(), () -> { + p.playSound(p.getLocation(), Sound.BLOCK_IRON_DOOR_OPEN, 0.3f, 0f); + p.playSound(p.getLocation(), Sound.ENTITY_VILLAGER_TRADING, 0.6f, 0f); + }, 80L); + + Bukkit.getScheduler().runTaskLater(getPlugin(), () -> { + determineOutcome(p, loc); + }, 100L); + } + + /** + * Determine the outcome for the specified player/location. + * + * @param p - the player + * @param loc - the location to play effects + */ + protected void determineOutcome(Player p, Location loc) { + + // roll from 0 - 999 + int chance = RANDOM.nextInt(1000); + + // 2.5% chance to get LOVE IT + if (chance < 25) { + + User user = Core.getUserManager().getLoadedUser(p.getUniqueId()); + if (user != null) { + + Event event = EventManager.getInstance().getEvent().orElse(null); + if (event != null && event instanceof HalloweenEvent) { + HalloweenEvent hween = (HalloweenEvent) event; + + + // half goes to play, half is wiped + int pot = hween.getTokens(); + int toGive = (int) (pot / 2.0); + + // reset tokens + hween.setTokens(0); + + // give them tokens + user.setTokens(user.getTokens() + toGive); + + Bukkit.broadcastMessage(ChatColor.GOLD.toString() + ChatColor.BOLD + "Halloween Event - " + ChatColor.WHITE + "A villager loved " + ChatColor.GOLD + p.getName() + "'s TRICK" + ChatColor.WHITE + " and gave them " + ChatColor.GOLD + toGive + " tokens!"); + Bukkit.broadcastMessage(ChatColor.GOLD.toString() + ChatColor.BOLD + "Halloween Event - " + ChatColor.WHITE + "You can participate by knocking on any " + ChatColor.YELLOW + "Premium House's door" + ChatColor.WHITE + " with a " + ChatColor.GOLD + "Candy Bag" + ChatColor.WHITE + " item in hand (Costs " + HalloweenEvent.TRICK_COST + " tokens."); + Bukkit.broadcastMessage(ChatColor.GOLD.toString() + ChatColor.BOLD + "Halloween Event - " + ChatColor.WHITE + "Skeleton's drop " + ChatColor.GOLD + "Candy Bags" + ChatColor.WHITE + " at a rare rate."); + } + } + + p.sendMessage(ChatColor.GREEN + YES_RESPONSES.get(RANDOM.nextInt(YES_RESPONSES.size()))); + + // heart particles everywhere + for (int i = 0; i < 5; i++) { + ParticleEffect.HEART.display(loc, 10, RANDOM.nextFloat(), RANDOM.nextFloat(), RANDOM.nextFloat(), 10, 1); + } + + p.playSound(p.getLocation(), Sound.ENTITY_VILLAGER_AMBIENT, 1f, 0f); + p.playSound(p.getLocation(), Sound.ENTITY_VILLAGER_YES, 1f, 0f); + p.playSound(p.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 0.5f, 0f); + + Bukkit.getScheduler().runTaskLater(getPlugin(), () -> { + p.playSound(p.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 0.6f, 0.1f); + }, 10L); + + Bukkit.getScheduler().runTaskLater(getPlugin(), () -> { + p.playSound(p.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 0.8f, 0.2f); + }, 20L); + + Bukkit.getScheduler().runTaskLater(getPlugin(), () -> { + p.playSound(p.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1f, 0.3f); + }, 30L); + + Bukkit.getScheduler().runTaskLater(getPlugin(), () -> { + p.playSound(p.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1f, 0.5f); + p.playSound(p.getLocation(), Sound.ENTITY_LIGHTNING_THUNDER, 0.1f, 0.1f); + + // multi colored fireworks firework + new FireworkFactory(location.clone().add(0, 1, 0)).setPower(0).setColor(Color.ORANGE).setFadeColor(Color.WHITE).setFlicker(true).setTrail(true).setType(FireworkEffect.Type.BALL).build(); + new FireworkFactory(location.clone().add(RANDOM.nextDouble() - 0.5, RANDOM.nextDouble() + 1, RANDOM.nextDouble() - 0.5)).setPower(0).setColor(Color.YELLOW).setFadeColor(Color.WHITE).setFlicker(true).setTrail(true).setType(FireworkEffect.Type.BALL).build(); + new FireworkFactory(location.clone().add(RANDOM.nextDouble() - 0.5, 0, RANDOM.nextDouble() - 0.5)).setPower(0).setColor(Color.YELLOW).setFadeColor(Color.WHITE).setFlicker(true).setTrail(true).setType(FireworkEffect.Type.BURST).build(); + new FireworkFactory(location.clone().add(RANDOM.nextDouble() - 0.5, 0, RANDOM.nextDouble() - 0.5)).setPower(0).setColor(Color.ORANGE).setFadeColor(Color.WHITE).setFlicker(true).setTrail(true).setType(FireworkEffect.Type.BURST).build(); + + // play title to player + Title title = new Title(ChatColor.GOLD + "Nice Trick!", ChatColor.WHITE + "", 10, 20 * 5, 10); + title.play(p); + }, 40L); + } + // 47.5% chacnce to get EH + else if (chance < 500) { + // tell player their trick was cool + p.sendMessage(ChatColor.YELLOW + MEH_RESPONSES.get(RANDOM.nextInt(MEH_RESPONSES.size()))); + + // TODO throw plant particles everywhere + for (int i = 0; i < 5; i++) { + // p.getWorld().playEffect(loc, Effect.TILE_BREAK, + // Material.VINE.getId()); + // ParticleEffect.BLOCK_CRACK.display(new + // ParticleData(Material.WOOL, (byte) 15){}, 1F, 1F, 1F, 1F, 30, + // loc, 32); + } + + // player receives 1-3 roofied chocolate + int numRewards = 1 + RANDOM.nextInt(2); + for (int i = 0; i < numRewards; i++) { + GameItem rc = GTM.getItemManager().getItem("roofied_chocolate"); + if (rc != null) { + p.getInventory().addItem(rc.getItem()); + } + } + } + // 50% chance to get NO + else { + // player gets nothing + p.sendMessage(ChatColor.RED + NO_RESPONSES.get(RANDOM.nextInt(NO_RESPONSES.size()))); + + // play loud villager hurt sound + p.playSound(p.getLocation(), Sound.ENTITY_VILLAGER_HURT, 0.6f, 0f); + // throw green plant particles everywhere + for (int i = 0; i < 5; i++) { + ParticleEffect.VILLAGER_ANGRY.display(loc, 10, RANDOM.nextFloat(), RANDOM.nextFloat(), RANDOM.nextFloat(), 10, 1); + } + + Bukkit.getScheduler().runTaskLater(getPlugin(), () -> { + // slam door sound + p.playSound(p.getLocation(), Sound.BLOCK_IRON_DOOR_CLOSE, 1f, 0f); + }, 10L); + + // follow by fading footsteps + Bukkit.getScheduler().runTaskLater(getPlugin(), () -> { + p.playSound(p.getLocation(), Sound.BLOCK_STONE_STEP, 1f, 0f); + }, 20L); + + Bukkit.getScheduler().runTaskLater(getPlugin(), () -> { + p.playSound(p.getLocation(), Sound.BLOCK_STONE_STEP, 0.8f, 0f); + }, 30L); + + Bukkit.getScheduler().runTaskLater(getPlugin(), () -> { + p.playSound(p.getLocation(), Sound.BLOCK_STONE_STEP, 0.6f, 0f); + }, 40L); + } + } + + /** + * {@inheritDoc} + */ + @Override + public Plugin getPlugin() { + return plugin; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/events/TPEvent.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/events/TPEvent.java new file mode 100644 index 0000000..08dffab --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/events/TPEvent.java @@ -0,0 +1,116 @@ +package net.grandtheftmc.gtm.events; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class TPEvent extends Event { + private static final HandlerList HANDLERS = new HandlerList(); + + @Override + public HandlerList getHandlers() { + return HANDLERS; + } + + public static HandlerList getHandlerList() { + return HANDLERS; + } + + private Player sender; + private Player target; + private TPType type; + private String cancelMessage; + private Location targetLocation; + + public TPEvent(Player sender, TPType type) { + this.sender = sender; + this.type = type; + } + + public TPEvent(Player sender, Player target, TPType type) { + this.sender = sender; + this.target = target; + this.type = type; + } + + + public TPType getType() { + return this.type; + } + + public void setType(TPType type) { + this.type = type; + } + + public boolean isCancelled() { + return this.cancelMessage != null; + } + + public String getCancelMessage() { + return this.cancelMessage; + } + + public void setCancelled(String msg) { + this.cancelMessage = msg; + } + + public TPEvent call() { + Bukkit.getPluginManager().callEvent(this); + return this; + } + + public Location getTargetLocation() { + return this.targetLocation; + } + + public void setTargetLocation(Location targetLocation) { + this.targetLocation = targetLocation; + } + + public boolean targetLocationIsChanged() { + return this.targetLocation != null; + } + + + public Player getSender() { + return this.sender; + } + + public Player getPlayer() { + return this.sender; + } + + public void setSender(Player sender) { + this.sender = sender; + } + + + public Player getTarget() { + return this.target; + } + + public void setTarget(Player target) { + this.target = target; + } + + + public enum TPType { + TPA_REQ, + TPAHERE_REQ, + TPA_ACCEPT, + TPAHERE_ACCEPT, + TP_COMPLETE, + WARP, + VEHICLE_SEND_AWAY, + VEHICLE_CALL, + HOUSE_ENTER, + HOUSE_LEAVE, + PREMIUM_HOUSE_ENTER, + PREMIUM_HOUSE_LEAVE, + BACKUP + + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/events/WantedLevelChangeEvent.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/events/WantedLevelChangeEvent.java new file mode 100644 index 0000000..f626641 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/events/WantedLevelChangeEvent.java @@ -0,0 +1,43 @@ +package net.grandtheftmc.gtm.events; + +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import net.grandtheftmc.gtm.users.GTMUser; + +public class WantedLevelChangeEvent extends Event { + private static final HandlerList HANDLERS = new HandlerList(); + + @Override + public HandlerList getHandlers() { + return HANDLERS; + } + + public static HandlerList getHandlerList() { + return HANDLERS; + } + + private final Player player; + private final GTMUser user; + private final int wantedLevel; + + public WantedLevelChangeEvent(Player player, GTMUser user, int wantedLevel) { + this.player = player; + this.user = user; + this.wantedLevel = wantedLevel; + } + + public Player getPlayer() { + return this.player; + } + + public GTMUser getUser() { + return this.user; + } + + public int getWantedLevel() { + return this.wantedLevel; + } + +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/GTMGang.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/GTMGang.java new file mode 100644 index 0000000..c754469 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/GTMGang.java @@ -0,0 +1,1109 @@ +package net.grandtheftmc.gtm.gang; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.users.Pref; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserManager; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.gang.member.GTMGangMember; +import net.grandtheftmc.gtm.gang.member.GangMember; +import net.grandtheftmc.gtm.gang.member.GangRole; +import net.grandtheftmc.gtm.gang.relation.GTMGangRelation; +import net.grandtheftmc.gtm.gang.relation.GangRelation; +import net.grandtheftmc.gtm.gang.relation.RelationType; +import net.grandtheftmc.gtm.users.GTMRank; +import net.grandtheftmc.gtm.users.GTMUser; + +public class GTMGang implements Gang { + + private Set<GangMember> members; + private Set<GangRelation> relations; + private final Map<Integer, RelationType> relationRequests; + + private final int id; + + private UUID owner; + private String name, description; + private int maxMembers; + + /** Don't ask why this is needed.. */ + private boolean hasUpdated = false; + + public GTMGang(int id) { + this.id = id; + this.members = Sets.newHashSet(); + this.relations = Sets.newHashSet(); + this.relationRequests = Maps.newHashMap(); + } + + public GTMGang(int id, UUID owner, String name, String description, int maxMembers) { + this(id); + this.owner = owner; + this.name = name; + this.description = description; + this.maxMembers = maxMembers; + } + + @Override + public int getUniqueId() { + return id; + } + + @Override + public UUID getOwner() { + return owner; + } + + @Override + public void setOwner(UUID owner) { + this.owner = owner; + + if (!GangManager.ENABLED) return; + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + GangDAO.setOwner(connection, owner, id); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Override + public String getName() { + return name; + } + + @Override + public void setName(String name) { + this.name = name; + + if (!GangManager.ENABLED) return; + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + GangDAO.setName(connection, name, id); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Override + public String getDescription() { + return description; + } + + @Override + public void setDescription(String description) { + this.description = description; + + if (!GangManager.ENABLED) return; + + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + GangDAO.setDescription(connection, description, id); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } + + @Override + public int getMaxMembers() { + return maxMembers; + } + + @Override + public void setMaxMembers(int maxMembers) { + this.maxMembers = maxMembers; + } + + @Override + public String getOwnerName() { + Optional<GangMember> optional = this.members.stream().filter(member -> member.getUniqueId().equals(this.owner)).findFirst(); + return optional.isPresent() ? optional.get().getName() : "Unknown"; + } + + @Override + public void toggleChat(UUID uuid) { + this.members.stream().filter(member -> member.getUniqueId().equals(uuid)).findFirst().ifPresent(GangMember::toggleChat); + } + + @Override + public boolean isGangChat(UUID uuid) { + Optional<GangMember> optional = this.members.stream().filter(member -> member.getUniqueId().equals(uuid)).findFirst(); + return optional.isPresent() && optional.get().getChatToggle(); + } + + @Override + public void setGangChat(UUID uuid, boolean on) { + this.members.stream().filter(member -> member.getUniqueId().equals(uuid)).findFirst().ifPresent(member -> member.setChat(on)); + } + + @Override + public Set<GangMember> getMembers() { + return members; + } + + @Override + public void setMembers(Set<GangMember> members) { + this.members = members; + } + + @Override + public Set<GangMember> getOnlineMembers() { + return this.members.stream().filter(GangMember::isOnline).collect(Collectors.toSet()); + } + + @Override + public Optional<GangMember> getMember(UUID uuid) { + return this.members.stream().filter(member -> member.getUniqueId().equals(uuid)).findFirst(); + } + + @Override + public Optional<GangMember> getMember(String playerName) { + return this.members.stream().filter(member -> member.getName().equalsIgnoreCase(playerName)).findFirst(); + } + + @Override + public void addMember(GangMember member) { + if (this.hasMember(member.getUniqueId())) return; + this.members.add(member); + + if (!GangManager.ENABLED) return; + + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + GangDAO.addMember(connection, member.getUniqueId(), member.getRole(), this.id); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } + + @Override + public void removeMember(UUID uuid) { + if (!this.hasMember(uuid)) return; + this.members.stream().filter(member -> member.getUniqueId().equals(uuid)).findFirst().ifPresent(this.members::remove); + + if (!GangManager.ENABLED) return; + + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + GangDAO.removeMember(connection, uuid, this.id); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } + + @Override + public boolean hasMember(UUID uuid) { + return this.members.stream().anyMatch(member -> member.getUniqueId().equals(uuid)); + } + + @Override + public void setMemberRole(UUID uuid, GangRole role) { + Optional<GangMember> optional = this.getMember(uuid); + if (!optional.isPresent()) return; + optional.get().setRole(this.id, role); + } + + @Override + public Set<GangRelation> getRelations() { + return relations; + } + + @Override + public void setRelation(Set<GangRelation> relations) { + this.relations = relations; + } + + @Override + public void addRelation(GangRelation relation) { + if (hasRelation(relation.getRelativeId())) return; + this.relations.add(relation); + + if (!GangManager.ENABLED) return; + + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + GangDAO.addRelation(connection, this.id, relation.getRelativeId(), relation.getRelationType()); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } + + @Override + public void addRelationRequest(int id, RelationType type) { + this.relationRequests.put(id, type); + } + + @Override + public void removeRelation(int id) { + Optional<GangRelation> rel = this.relations.stream().filter(relation -> relation.getRelativeId() == id).findFirst(); + if (!rel.isPresent()) return; + this.relations.remove(rel.get()); + } + + @Override + public boolean hasRelation(int id) { + return this.relations.stream().anyMatch(relation -> relation.getRelativeId() == id); + } + + @Override + public String list(Gang gang) { + int online = (int) this.members.stream().filter(member -> Bukkit.getPlayer(member.getUniqueId()) != null).count(); + int total = this.members.size(); + return (this.isAllied(gang) || this.equals(gang) ? "&a" : this.isEnemy(gang) ? "&c" : "&7") + "&l" + this.name + ": " + online + "&7/&a" + total + "&7 players online"; + } + + @Override + public void sendToAll(String str) { + this.members.stream().filter(member -> Bukkit.getPlayer(member.getUniqueId()) != null).forEach(member -> Bukkit.getPlayer(member.getUniqueId()).sendMessage(str)); + } + + @Override + public void sendToAllExcept(String str, UUID uuid) { + this.members.stream().filter(member -> !member.getUniqueId().equals(uuid) && Bukkit.getPlayer(member.getUniqueId()) != null).forEach(member -> Bukkit.getPlayer(member.getUniqueId()).sendMessage(str)); + } + + @Override + public RelationType getRelation(int id) { + Optional<GangRelation> relation = this.relations.stream().filter(r -> r.getRelativeId() == id).findFirst(); + return relation.isPresent() ? relation.get().getRelationType() : RelationType.NEUTRAL; + } + + @Override + public boolean isNeutral(Gang gang) { + RelationType rel = this.getRelation(gang.getUniqueId()); + return rel == RelationType.NEUTRAL; + } + + @Override + public boolean isAllied(Gang gang) { + return this.relations.stream().anyMatch(relation -> relation.getRelativeId() == gang.getUniqueId() && relation.getRelationType() == RelationType.ALLY); + } + + @Override + public boolean isEnemy(Gang gang) { + return this.relations.stream().anyMatch(relation -> relation.getRelativeId() == gang.getUniqueId() && relation.getRelationType() == RelationType.ENEMY); + } + + @Override + public boolean isLeader(UUID uuid) { + return this.owner.equals(uuid); + } + + @Override + public boolean isCoLeader(UUID uuid) { + return this.members.stream().anyMatch(member -> member.isCoLeader() && member.getUniqueId().equals(uuid)); + } + + @Override + public boolean isMember(UUID uuid) { + return this.members.stream().anyMatch(member -> member.getUniqueId().equals(uuid)); + } + + @Override + public Optional<Gang> getViewingGang(UUID uuid) { + Optional<GangMember> member = this.getMember(uuid); + return member.isPresent() ? member.get().getViewingGang() : Optional.empty(); + } + + @Override + public void setViewingGang(UUID uuid, Gang gang) { + this.getMember(uuid).ifPresent(member -> member.setViewingGang(gang)); + } + + @Override + public boolean isViewingGang(UUID uuid, Gang gang) { + Optional<GangMember> member = this.getMember(uuid); + if (!member.isPresent()) return false; + + Optional<Gang> g = member.get().getViewingGang(); + return g.isPresent() && g.get().getUniqueId() == gang.getUniqueId(); + } + + @Override + public boolean isViewingGang(UUID uuid) { + Optional<GangMember> member = this.getMember(uuid); + return member.map(gangMember -> gangMember.getViewingGang().isPresent()).orElse(false); + } + + @Override + public Optional<GangMember> getViewingGangMember(UUID uuid) { + Optional<GangMember> member = this.getMember(uuid); + return member.isPresent() ? member.get().getViewingGangMember() : Optional.empty(); + } + + @Override + public void setViewingGangMember(UUID uuid, GangMember member) { + this.getMember(uuid).ifPresent(m -> m.setViewingGangMember(member)); + } + + @Override + public boolean isViewingGangMember(UUID uuid, UUID member) { + Optional<GangMember> m = this.getMember(uuid); + if (!m.isPresent()) return false; + + Optional<GangMember> g = m.get().getViewingGangMember(); + return g.isPresent() && g.get().getUniqueId().equals(member); + } + + public boolean canJoinGang(User user, GTMUser gtmUser) { + return user.isSpecial() || gtmUser.isRank(GTMRank.HOMIE); + } + + public boolean canLeadGang(User user, GTMUser gtmUser) { + return user.getUserRank().isHigherThan(UserRank.VIP) || gtmUser.isRank(GTMRank.GANGSTER); + } + + @Override + public void invite(Player sender, User user, Player target) { + if (!this.isLeader(sender.getUniqueId()) && !this.isCoLeader(sender.getUniqueId())) { + sender.sendMessage(Lang.GANGS.f("&7You are not the leader of this gang!")); + return; + } + + if (target == null) { + sender.sendMessage(Lang.GANGS.f("&7That player is not online!")); + return; + } + + if (Objects.equals(sender, target)) { + sender.sendMessage(Lang.GANGS.f("&7You can't invite yourself!")); + return; + } + + if (this.isMember(target.getUniqueId())) { + sender.sendMessage(Lang.GANGS.f("&7That player is already in your gang!")); + return; + } + + if (this.maxMembers <= this.members.size()) { + sender.sendMessage(Lang.GANGS.f("&7Your gang is full! Rank up or buy a rank at &a" + Core.getSettings().getStoreLink() + "&7 for more gang members!")); + return; + } + + User targetUser = Core.getUserManager().getLoadedUser(target.getUniqueId()); + GTMUser targetGtmUser = GTM.getUserManager().getLoadedUser(target.getUniqueId()); + if (!canJoinGang(targetUser, targetGtmUser)) { + sender.sendMessage(Lang.GANGS.f("&7That player can not join a gang because he is not a &e&lHOMIE&7 yet!")); + target.sendMessage(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 tried to invite you to gang &a" + this.name + "&7, but you need to be &a &e&lHOMIE&7 or &6&lVIP&7 to join a gang!")); + return; + } + +// targetGtmUser.addGangInvite(this.name); + GangManager.getInstance().addGangInvite(target.getUniqueId(), this.id); + + sender.sendMessage(Lang.GANGS.f("&7You invited " + targetUser.getColoredName(target) + "&7 to your gang!")); + target.sendMessage(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 invited you to gang &a" + this.name + "&7! Use &a\"/g join " + this.name + "\"&7 to join the gang!")); + this.sendToAllExcept(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 invited " + targetUser.getColoredName(target) + "&7 to your gang!"), sender.getUniqueId()); + } + + @Override + public void accept(Player sender, User user, GTMUser gtmUser) { + if (!canJoinGang(user, gtmUser)) { + sender.sendMessage(Lang.GANGS.f("You must be " + GTMRank.HOMIE.getColoredNameBold() + "&7 or &6&lVIP&7 to join a gang! Check the &d&lMy Account&7 -> &a&lRanks&7 menu on your phone for more information.")); + return; + } + + if (this.isMember(sender.getUniqueId()) || this.isLeader(sender.getUniqueId())) { + sender.sendMessage(Lang.GANGS.f("&7You are a member of this gang already!")); + return; + } + + if (!GangManager.getInstance().isInvited(user.getUUID(), this.id)) { + sender.sendMessage(Lang.GANGS.f("&7You have not been invited to this gang!")); + return; + } + + if (this.maxMembers <= this.members.size()) { + sender.sendMessage(Lang.GANGS.f("&7This gang is full!")); + return; + } + + Gang current = GangManager.getInstance().getGangByMember(sender.getUniqueId()).orElse(null); + if (current != null) { + sender.sendMessage(Lang.GANGS.f("&7Leave your current gang before joining another.")); + return; + } + + sender.sendMessage(Lang.GANGS.f("&7You joined the gang &a" + this.name + "&7!")); + + if (!GangManager.ENABLED) return; + +// gtmUser.setGang(this.name); +// gtmUser.removeGangInvite(this.name); + GangManager.getInstance().removeGangInvite(user.getUUID()); + + this.addMember(new GTMGangMember(sender.getUniqueId(), sender.getName(), GangRole.MEMBER)); + this.sendToAll(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 joined your gang!")); + } + + @Override + public void leave(Player sender, User user, GTMUser gtmUser) { + if (this.isLeader(sender.getUniqueId())) { + sender.sendMessage(Lang.GANGS.f("&7You are the leader of your gang! Please use &a\"/gang leader <player\"&7 before leaving the gang!")); + return; + } + + if (!this.isMember(sender.getUniqueId())) { + sender.sendMessage(Lang.GANGS.f("&7You are not a member of this gang!")); + return; + } + + if (!GangManager.ENABLED) return; + + this.removeMember(sender.getUniqueId()); +// gtmUser.resetGang(); + + sender.sendMessage(Lang.GANGS.f("&7You left the gang &a" + this.name + "&7!")); + this.sendToAll(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 left the gang!")); + } + + @Override + public void setOwner(Player sender, User user, GTMUser gtmUser, Player target) { + if (!this.isLeader(sender.getUniqueId())) { + sender.sendMessage(Lang.GANGS.f("&7You are not the leader of this gang!")); + return; + } + + if (target == null) { + sender.sendMessage(Lang.GANGS.f("&7That player is not online!")); + return; + } + + if (!this.isMember(target.getUniqueId())) { + sender.sendMessage(Lang.GANGS.f("&7That player is not a member of this gang!")); + return; + } + + User targetUser = Core.getUserManager().getLoadedUser(target.getUniqueId()); + GTMUser targetGtmUser = GTM.getUserManager().getLoadedUser(target.getUniqueId()); + if (!canLeadGang(targetUser, targetGtmUser)) { + sender.sendMessage(Lang.GANGS.f("&7You must be a &e&l" + GTMRank.GANGSTER.getColoredNameBold() + "&7 to create a gang! Check the &d&lMy Account&7 -> &a&lRanks&7 menu on your phone for more information.")); + return; + } + +// targetGtmUser.setGang(this.name, GangRole.LEADER); + this.setOwner(target.getUniqueId()); + this.setMemberRole(target.getUniqueId(), GangRole.LEADER); + +// gtmUser.setGangRole(GangRole.CO_LEADER); + this.setMemberRole(sender.getUniqueId(), GangRole.CO_LEADER); + +// Player player = Bukkit.getPlayer(this.owner); +// if (player != null) +// GTM.getUserManager().getLoadedUser(this.owner).setGangRole(GangRole.LEADER); + +// this.members.stream().filter(member -> Objects.equals(member.getUniqueId(), target.getUniqueId())).findFirst().ifPresent(this.members::remove); +// this.removeMember(target.getUniqueId()); + + sender.sendMessage(Lang.GANGS.f("&7You promoted " + targetUser.getColoredName(target) + "&7 to the leader of your gang! You are now a co-leader!")); + target.sendMessage(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 promoted you to leader of your gang!")); + this.sendToAll(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 promoted " + targetUser.getColoredName(target) + "&7 to the leader of your gang!")); + +// this.members.add(new GTMGangMember(sender.getUniqueId(), sender.getName(), "coleader")); +// this.addMember(new GTMGangMember(sender.getUniqueId(), sender.getName(), GangRole.CO_LEADER)); + + if (!GangManager.ENABLED) return; + + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + GangDAO.setOwner(connection, owner, id); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } + + @Override + public void promote(Player sender, User user, GTMUser gtmUser, String targetName) { + if (!this.isLeader(sender.getUniqueId())) { + sender.sendMessage(Lang.GANGS.f("&7You are not the leader of this gang!")); + return; + } + + Optional<GangMember> optional = this.members.stream().filter(member -> member.getName().equalsIgnoreCase(targetName)).findFirst(); + if (!optional.isPresent()) { + sender.sendMessage(Lang.GANGS.f("&7That player is not a member of this gang!")); + return; + } + + if (optional.get().isCoLeader()) { + sender.sendMessage(Lang.GANGS.f("&7That player is already a coleader of this gang!")); + return; + } + + if (!GangManager.ENABLED) return; + + Player target = Bukkit.getPlayer(optional.get().getUniqueId()); + String n = optional.get().getName(); + + if (target == null) { +// Core.sql.updateAsyncLater("update " + Core.name() + " set gangRank='coleader' where gang='" + this.name + "' and uuid='" + member.getUUID() + "';"); +// ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + Core.name() + " set gangRank='coleader' where gang='" + this.name + "' and uuid='" + member.getUniqueId() + "';")); + +// ServerUtil.runTaskAsync(() -> { +// try (Connection connection = BaseDatabase.getInstance().getConnection()) { +// GangDAO.setMemberRole(connection, optional.get().getUniqueId(), GangRole.CO_LEADER, id); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// }); + this.setMemberRole(optional.get().getUniqueId(), GangRole.CO_LEADER); + } else { + User targetUser = Core.getUserManager().getLoadedUser(target.getUniqueId()); +// GTMUser targetGtmUser = GTM.getUserManager().getLoadedUser(target.getUniqueId()); + n = targetUser.getColoredName(target); + +// targetGtmUser.setGangRole(GangRole.CO_LEADER); + this.setMemberRole(target.getUniqueId(), GangRole.CO_LEADER); + + target.sendMessage(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 promoted you to coleader of your gang!")); + } + + this.setMemberRole(optional.get().getUniqueId(), GangRole.CO_LEADER); +// optional.get().setRole(this.id, GangRole.CO_LEADER); + + for (Player player : Bukkit.getOnlinePlayers()) { + if (this.isMember(player.getUniqueId()) && !Objects.equals(player, target) && !Objects.equals(player, sender)) { + player.sendMessage(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 promoted " + n + "&7 to coleader of your gang!")); + } + } + + sender.sendMessage(Lang.GANGS.f("&7You promoted " + n + "&7 to coleader of your gang!")); + } + + @Override + public void demote(Player sender, User user, GTMUser gtmUser, String targetName) { + if (!this.isLeader(sender.getUniqueId())) { + sender.sendMessage(Lang.GANGS.f("&7You are not the leader of this gang!")); + return; + } + + Optional<GangMember> optional = this.members.stream().filter(member -> member.getName().equalsIgnoreCase(targetName)).findFirst(); + if (!optional.isPresent()) { + sender.sendMessage(Lang.GANGS.f("&7That player is not a member of this gang!")); + return; + } + + if (!optional.get().isCoLeader()) { + sender.sendMessage(Lang.GANGS.f("&7That player is not a coleader of this gang!")); + return; + } + + if (!GangManager.ENABLED) return; + + Player target = Bukkit.getPlayer(optional.get().getUniqueId()); + String n = optional.get().getName(); + if (target == null) { + this.setMemberRole(optional.get().getUniqueId(), GangRole.MEMBER); + } else { + User targetUser = Core.getUserManager().getLoadedUser(target.getUniqueId()); + n = targetUser.getColoredName(target); + + this.setMemberRole(target.getUniqueId(), GangRole.MEMBER); + target.sendMessage(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 demoted you to member of your gang!")); + } + + optional.get().setRole(this.id, GangRole.MEMBER); + for (Player player : Bukkit.getOnlinePlayers()) + if (this.isMember(player.getUniqueId()) && !Objects.equals(player, target) && !Objects.equals(player, sender)) + player.sendMessage(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 demoted " + n + "&7 to member of your gang!")); + + sender.sendMessage(Lang.GANGS.f("&7You demoted " + n + "&7 to member of your gang!")); + } + + @Override + public void kick(Player sender, User user, GTMUser gtmUser, String targetName) { + if (!this.isLeader(sender.getUniqueId()) && !this.isCoLeader(sender.getUniqueId())) { + sender.sendMessage(Lang.GANGS.f("&7You are not the leader of this gang!")); + return; + } + + if (sender.getName().equalsIgnoreCase(targetName)) { + sender.sendMessage(Lang.GANGS.f("&7You can't kick yourself!")); + return; + } + + if (!GangManager.ENABLED) return; + + Optional<GangMember> optional; + Player target = Bukkit.getPlayer(targetName); + if (target != null) optional = this.members.stream().filter(member -> member.getUniqueId().equals(target.getUniqueId())).findFirst(); + else optional = this.members.stream().filter(member -> member.getName().equalsIgnoreCase(targetName)).findFirst(); + + if (!optional.isPresent()) { + sender.sendMessage(Lang.GANGS.f("&7That player is not in your gang!")); + return; + } + +// this.gangMembers.remove(member); + + if (optional.get().getRole() == GangRole.LEADER) { + sender.sendMessage(Lang.GANGS.f("&cYou cannot kick the leader!")); + return; + } + + this.removeMember(optional.get().getUniqueId()); + + String name = targetName; + if (target == null) { +// Core.sql.updateAsyncLater("update " + Core.name() + " set gang=null, gangRank='member' where name='" + name + "';"); +// String finalName = name; +// ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + Core.name() + " set gang=null, gangRank='member' where name='" + finalName + "';")); + +// ServerUtil.runTaskAsync(() -> { +// try (Connection connection = BaseDatabase.getInstance().getConnection()) { +// GangDAO.removeMember(connection, optional.get().getUniqueId(), this.id); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// }); + } else { + name = Core.getUserManager().getLoadedUser(target.getUniqueId()).getColoredName(target); +// GTMUser targetGtmUser = GTM.getUserManager().getLoadedUser(player.getUniqueId()); +// targetGtmUser.resetGang(); + target.sendMessage(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 kicked you from the gang!")); + } + + this.sendToAllExcept(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 kicked &a" + name + "&7 from your gang!"), sender.getUniqueId()); + sender.sendMessage(Lang.GANGS.f("&7You kicked &a" + name + "&7 from the gang!")); + } + + @Override + public void disbandConfirm(Player sender, User user, GTMUser gtmUser) { + if (!this.isLeader(sender.getUniqueId())) { + sender.sendMessage(Lang.GANGS.f("&7You are not the leader of this gang!")); + return; + } + + if (!GangManager.ENABLED) return; + +// Core.sql.updateAsyncLater("delete from " + Core.name() + "_gangs where name='" + this.name + "';"); +// Core.sql.updateAsyncLater("delete from " + Core.name() + "_gangs_relations where gang1='" + this.name + "' or gang2='" + this.name + "';"); +// Core.sql.updateAsyncLater("update " + Core.name() + " set gang=null,gangRank='member' where gang='" + this.name + "';"); + ServerUtil.runTaskAsync(() -> { +// BaseDatabase.runCustomQuery("delete from " + Core.name() + "_gangs where name='" + this.name + "';"); +// BaseDatabase.runCustomQuery("delete from " + Core.name() + "_gangs_relations where gang1='" + this.name + "' or gang2='" + this.name + "';"); +// BaseDatabase.runCustomQuery("update " + Core.name() + " set gang=null,gangRank='member' where gang='" + this.name + "';"); + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + GangDAO.deleteGang(connection, this.id); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + + sender.sendMessage(Lang.GANGS.f("&7You disbanded the gang &a" + this.name + "&7!")); +// gtmUser.setGangName(null); + + for (Player player : Bukkit.getOnlinePlayers()) { + if (this.isMember(player.getUniqueId())) { +// GTMUser u = GTM.getUserManager().getLoadedUser(player.getUniqueId()); +// u.setGangName(null); + player.sendMessage(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 disbanded your gang &a" + this.name + "&7!")); + } + else if (!this.isLeader(player.getUniqueId())) { + player.sendMessage(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 disbanded the gang &a" + this.name + "&7!")); + } + } + + for (GangRelation r : this.relations) { + Gang g = GangManager.getInstance().getGang(r.getRelativeId()).orElse(null); + if (g == null) continue; + g.removeRelation(this.id); + } + + //TODO, Should auto remove in database. +// this.relations.stream().filter(relation -> GangManager.getInstance().getGang(relation.getRelativeId()).isPresent()) +// .forEach(relation -> GangManager.getInstance().getGang(relation.getRelativeId()).get().removeRelation(this.id)); + +// this.relations.keySet().stream().filter(gang -> GTM.getGangManager().isLoaded(gang)).forEach(gang -> GTM.getGangManager().getLoadedGang(gang).removeRelation(this.name)); + +// GTM.getGangManager().unloadGang(this.name); + GangManager.getInstance().removeGang(this); + } + + @Override + public void disband(Player sender) { + if (!this.isLeader(sender.getUniqueId())) { + sender.sendMessage(Lang.GANGS.f("&7You are not the leader of this gang!")); + return; + } + + sender.sendMessage(Lang.GANGS.f("&7Are you sure you want to disband this gang? It will remove all members and delete it forever. Type \"&a/gang disband confirm\"&7 to disband your gang!")); + } + + @Override + public void rename(Player sender, User user, GTMUser gtmUser, String gangName) { + UUID uuid = sender.getUniqueId(); + if (!this.isLeader(sender.getUniqueId())) { + sender.sendMessage(Lang.GANGS.f("&7You are not the leader of this gang!")); + return; + } + + if (!gangName.matches("^[a-zA-Z_0-9]+$")) { + sender.sendMessage(Lang.GANGS.f("&7Only a-z, A-Z, 0-9 and _ are allowed in a gang name!")); + return; + } + + if (gangName.length() > 16 || gangName.length() < 3) { + sender.sendMessage(Lang.GANGS.f("&7The name of your gang needs to be 3-16 characters long!")); + return; + } + + if (GangManager.getInstance().getGang(gangName).isPresent()) { + sender.sendMessage(Lang.GANGS.f("&7A gang with that name already exists!")); + return; + } + + if (!GangManager.ENABLED) return; + + ServerUtil.runTaskAsync(() -> { + boolean[] exists = {false}; + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + exists[0] = GangDAO.isGangExisting(connection, gangName); + } catch (SQLException e) { + e.printStackTrace(); + return; + } + + ServerUtil.runTask(() -> { + Player sender2 = Bukkit.getPlayer(uuid); + if (sender2 == null) return; + if (exists[0]) { + sender2.sendMessage(Lang.GANGS.f("&7A gang with that name already exists!")); + return; + } + + this.setName(gangName); + + sender.sendMessage(Lang.GANGS.f("&7You changed the name of your gang to &a" + gangName + "&7!")); + sendToAllExcept(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 changed the name of your gang to &a" + gangName + "&7!"), sender.getUniqueId()); + }); + }); + +// new BukkitRunnable() { +// @Override +// public void run() { +// String s = null; +// try (Connection connection = BaseDatabase.getInstance().getConnection()) { +// try (PreparedStatement statement = connection.prepareStatement("SELECT name FROM gtm_gang WHERE server_key=? AND name=?;")) { +// statement.setString(1, Core.name().toUpperCase()); +// statement.setString(2, gangName); +// try (ResultSet result = statement.executeQuery()) { +// if (result.next()) s = result.getString("name"); +// } +// } +// } catch (SQLException e) { +// e.printStackTrace(); +// return; +// } +// +// String name = s; +// new BukkitRunnable() { +// @Override +// public void run() { +// Player sender = Bukkit.getPlayer(uuid); +// if (sender == null) return; +// if (name != null) { +// sender.sendMessage(Lang.GANGS.f("&7A gang with that name already exists!")); +// return; +// } +// +// User user = Core.getUserManager().getLoadedUser(uuid); +// GTMUser gtmUser = GTM.getUserManager().getLoadedUser(uuid); +// Gang gang = gtmUser.getGang(); +// gang.setName(gangName); +// +// sender.sendMessage(Lang.GANGS.f("&7You changed the name of your gang to &a" + gangName + "&7!")); +// sendToAllExcept(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 changed the name of your gang to &a" + gangName + "&7!"), sender.getUniqueId()); +// } +// }.runTask(GTM.getInstance()); +// } +// }.runTaskAsynchronously(GTM.getInstance()); + } + + @Override + public void description(Player sender, User user, GTMUser gtmUser, String description) { + if (!this.isLeader(sender.getUniqueId()) && !this.isCoLeader(sender.getUniqueId())) { + sender.sendMessage(Lang.GANGS.f("&7You are not the (co-)leader of this gang!")); + return; + } + + if (description.length() > 64 || description.length() < 3) { + sender.sendMessage(Lang.GANGS.f("&7The description must be between 3-64 characters long!")); + return; + } + + if (!GangManager.ENABLED) return; + + this.setDescription(description); + sender.sendMessage(Lang.GANGS.f("&7You changed the description of your gang to &a" + description + "&7!")); + this.sendToAllExcept(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 changed the description of your gang to &a" + description + "&7!"), sender.getUniqueId()); + } + + @Override + public void ally(Player sender, User user, GTMUser gtmUser, String gang) { + if (!this.isLeader(sender.getUniqueId()) && !this.isCoLeader(sender.getUniqueId())) { + sender.sendMessage(Lang.GANGS.f("&7You are not the (co-)leader of this gang!")); + return; + } + + Optional<Gang> g = GangManager.getInstance().getGang(gang); + if (!g.isPresent()) { + sender.sendMessage(Lang.GANGS.f("&7That gang does not exist or no one in that gang is online!")); + return; + } + + if (this.isAllied(g.get())) { + sender.sendMessage(Lang.GANGS.f("&7That gang is allied to you already!")); + sender.sendMessage(Lang.GANGS.f("&7Want to unally this gang? Use /g neutral")); + return; + } + + if (!GangManager.ENABLED) return; + + if (this.relationRequests.containsKey(g.get().getUniqueId()) && Objects.equals(RelationType.ALLY, this.relationRequests.get(g.get().getUniqueId()))) { + this.addRelation(new GTMGangRelation(g.get().getUniqueId(), g.get().getName(), RelationType.ALLY)); + g.get().addRelation(new GTMGangRelation(this.id, this.name, RelationType.ALLY)); + this.relationRequests.remove(g.get().getUniqueId()); + +// ServerUtil.runTaskAsync(() -> { +// try (Connection connection = BaseDatabase.getInstance().getConnection()) { +// GangDAO.removeRelation(connection, g.get().getUniqueId(), this.id); +// GangDAO.addRelation(connection, this.id, g.get().getUniqueId(), RelationType.ALLY); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// }); + + for (Player player : Bukkit.getOnlinePlayers()) { + if (g.get().isMember(player.getUniqueId()) || g.get().isLeader(player.getUniqueId())) { + player.sendMessage(Lang.GANGS.f("&7Your gang is now allied to &a" + this.name + "&7!")); + } + else if (this.isMember(player.getUniqueId()) || this.isLeader(player.getUniqueId()) && !Objects.equals(player, sender)) { + player.sendMessage(Lang.GANGS.f("&7Your gang is now allied to &a" + g.get().getName() + "&7!")); + } + } + sender.sendMessage(Lang.GANGS.f("&7You accepted the ally request from gang &a" + g.get().getName() + "&7!")); + } + + g.get().addRelationRequest(this.id, RelationType.ALLY); + for (Player player : Bukkit.getOnlinePlayers()) { + if (g.get().isMember(player.getUniqueId()) || g.get().isLeader(player.getUniqueId())) { + player.sendMessage(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 from gang &a" + this.name + "&7 has requested to be allied to your gang!")); + } + else if (this.isMember(player.getUniqueId()) || this.isLeader(player.getUniqueId()) && !Objects.equals(player, sender)) { + player.sendMessage(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 has requested to be allied to &a" + g.get().getName() + "&7!")); + } + } + + sender.sendMessage(Lang.GANGS.f("&7You sent an ally request to gang &a" + g.get().getName() + "&7!")); + } + + @Override + public void neutral(Player sender, User user, GTMUser gtmUser, String gang) { + if (!this.isLeader(sender.getUniqueId()) && !this.isCoLeader(sender.getUniqueId())) { + sender.sendMessage(Lang.GANGS.f("&7You are not the leader of this gang!")); + return; + } + + Optional<Gang> g = GangManager.getInstance().getGang(gang); + if (!g.isPresent()) { + sender.sendMessage(Lang.GANGS.f("&7That gang does not exist or no one in that gang is online!")); + return; + } + + if (this.isNeutral(g.get())) { + sender.sendMessage(Lang.GANGS.f("&7That gang is neutral to you already!")); + return; + } + + if (!GangManager.ENABLED) return; + + if (this.relationRequests.containsKey(g.get().getUniqueId()) && Objects.equals(RelationType.NEUTRAL, this.relationRequests.get(g.get().getUniqueId()))) { +// this.relations.add(new GTMGangRelation(g.get().getUniqueId(), g.get().getName(), RelationType.NEUTRAL)); +// g.get().addRelation(new GTMGangRelation(this.id, this.name, RelationType.NEUTRAL)); + this.relationRequests.remove(g.get().getUniqueId()); + + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + GangDAO.removeRelation(connection, g.get().getUniqueId(), this.id); + GangDAO.removeRelation(connection, this.id, g.get().getUniqueId()); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + + for (Player player : Bukkit.getOnlinePlayers()) { + if (g.get().isMember(player.getUniqueId()) || g.get().isLeader(player.getUniqueId())) { + player.sendMessage(Lang.GANGS.f("&7Your gang is now neutral to &a" + this.name + "&7!")); + } + else if (this.isMember(player.getUniqueId()) || this.isLeader(player.getUniqueId()) && !Objects.equals(player, sender)) { + player.sendMessage(Lang.GANGS.f("&7Your gang is now neutral to &a" + g.get().getName() + "&7!")); + } + } + sender.sendMessage(Lang.GANGS.f("&7You accepted the neutral request from gang &a" + g.get().getName() + "&7!")); + } + + g.get().addRelationRequest(this.id, RelationType.NEUTRAL); + for (Player player : Bukkit.getOnlinePlayers()) { + if (g.get().isMember(player.getUniqueId()) || g.get().isLeader(player.getUniqueId())) { + player.sendMessage(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 from gang &a" + this.name + "&7 has requested to be neutral to your gang!")); + } + else if (this.isMember(player.getUniqueId()) || this.isLeader(player.getUniqueId()) && !Objects.equals(player, sender)) { + player.sendMessage(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 has requested to be neutral to &a" + g.get().getName() + "&7!")); + } + } + + sender.sendMessage(Lang.GANGS.f("&7You sent a neutral request to gang &a" + g.get().getName() + "&7!")); + } + + @Override + public void enemy(Player sender, User user, GTMUser gtmUser, String gang) { + if (!this.isLeader(sender.getUniqueId()) && !this.isCoLeader(sender.getUniqueId())) { + sender.sendMessage(Lang.GANGS.f("&7You are not the leader of this gang!")); + return; + } + + Optional<Gang> g = GangManager.getInstance().getGang(gang); + if (!g.isPresent()) { + sender.sendMessage(Lang.GANGS.f("&7That gang does not exist or no one in that gang is online!")); + return; + } + + if (this.isEnemy(g.get())) { + sender.sendMessage(Lang.GANGS.f("&7That gang is an enemy to you already!")); + sender.sendMessage(Lang.GANGS.f("&7Want to unenemy this gang? Use /g neutral")); + return; + } + + if (!GangManager.ENABLED) return; + + this.relations.add(new GTMGangRelation(g.get().getUniqueId(), g.get().getName(), RelationType.ENEMY)); + this.addRelation(new GTMGangRelation(g.get().getUniqueId(), g.get().getName(), RelationType.ENEMY)); + g.get().addRelation(new GTMGangRelation(this.id, this.name, RelationType.ENEMY)); + this.relationRequests.remove(g.get().getUniqueId()); + +// ServerUtil.runTaskAsync(() -> { +// try (Connection connection = BaseDatabase.getInstance().getConnection()) { +// GangDAO.removeRelation(connection, g.get().getUniqueId(), this.id); +// GangDAO.addRelation(connection, this.id, g.get().getUniqueId(), RelationType.ALLY); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// }); + + for (Player player : Bukkit.getOnlinePlayers()) + if (g.get().isMember(player.getUniqueId()) || g.get().isLeader(player.getUniqueId())) + player.sendMessage(Lang.GANGS.f("&7Your gang is now an enemy to gang &a" + this.name + "&7!")); + else if (this.isMember(player.getUniqueId()) || this.isLeader(player.getUniqueId())) + player.sendMessage(Lang.GANGS.f("&7Your gang is now an enemy to gang &a" + g.get().getName() + "&7!")); + } + + @Override + public void chat(Player player, User user, GTMUser gtmUser, String msg) { + Bukkit.getOnlinePlayers().stream().filter(p -> this.isMember(p.getUniqueId()) || this.isLeader(p.getUniqueId())).forEach(p -> p.sendMessage(Lang.GANGCHAT.f("&7[&a&l" + user.getColoredName(player) + "&7] &r") + Utils.fColor(msg))); + + UserManager.getInstance().getUsers().stream().filter(u -> u.getPref(Pref.SOCIALSPY)).forEach(u -> { + if (u != null && u.getUUID() != null) { + Player p = Bukkit.getPlayer(u.getUUID()); + if (p != null) p.sendMessage(Lang.SS.f("&r" + player.getName() + ": /gc " + msg)); + } + }); + } + + @Override + public boolean updateDataFromDb() { +// if (this.hasUpdated) return true; +// boolean b = true; +// +//// try (Connection connection = BaseDatabase.getInstance().getConnection()) { +//// try (PreparedStatement statement = connection.prepareStatement("select * from " + Core.name() + "_gangs where name=?;")) { +//// statement.setString(1, this.name); +//// try (ResultSet result = statement.executeQuery()) { +//// if (result.next()) { +//// this.description = result.getString("description"); +//// this.leader = UUID.fromString(result.getString("leader")); +//// this.leaderName = result.getString("leaderName"); +//// this.maxMembers = result.getInt("maxMembers"); +//// } +//// else { +//// b = false; +//// } +//// } +//// } +//// } catch (SQLException e) { +//// e.printStackTrace(); +//// } +// +// try (Connection connection = BaseDatabase.getInstance().getConnection()) { +// Gang temp = GangDAO.getGang() +// this.members.addAll(GangDAO.getMembers(connection, this.id)); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// +// try (Connection connection = BaseDatabase.getInstance().getConnection()) { +// try (PreparedStatement statement = connection.prepareStatement("select uuid,name,gangRank from " + Core.name() + " where gang=?;")) { +// statement.setString(1, this.name); +// try (ResultSet result = statement.executeQuery()) { +// while (result.next()) { +// if (!Objects.equals("leader", result.getString("gangRank"))) { +// this.gangMembers.add(new net.grandtheftmc.gtm.gangs.GangMember(UUID.fromString(result.getString("uuid")), +// result.getString("name"), result.getString("gangRank"))); +// } +// } +// } +// } +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// +// this.relations = new HashMap<>(); +// this.relationRequests = new HashMap<>(); +// try (Connection connection = BaseDatabase.getInstance().getConnection()) { +// try (PreparedStatement statement = connection.prepareStatement("select * from " + Core.name() + "_gangs_relations where gang1=? or gang2=?;")) { +// statement.setString(1, this.name); +// statement.setString(2, this.name); +// try (ResultSet result = statement.executeQuery()) { +// while (result.next()) { +// String gang1 = result.getString("gang1"); +// String gang2 = result.getString("gang2"); +// this.relations.put(gang1.equalsIgnoreCase(this.name) ? gang2 : gang1, result.getString("relation")); +// } +// } +// } +// } catch (SQLException e) { +// e.printStackTrace(); +// b = false; +// } +// +// this.hasUpdated = b; +// return b; + return true; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/Gang.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/Gang.java new file mode 100644 index 0000000..295c7d8 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/Gang.java @@ -0,0 +1,95 @@ +package net.grandtheftmc.gtm.gang; + +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.gtm.gang.member.GangMember; +import net.grandtheftmc.gtm.gang.member.GangRole; +import net.grandtheftmc.gtm.gang.relation.GangRelation; +import net.grandtheftmc.gtm.gang.relation.RelationType; +import net.grandtheftmc.gtm.users.GTMUser; +import org.bukkit.entity.Player; + +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; + +public interface Gang { + + int getUniqueId(); + + UUID getOwner(); + void setOwner(UUID owner); + + String getName(); + void setName(String name); + + String getDescription(); + void setDescription(String description); + + int getMaxMembers(); + void setMaxMembers(int maxMembers); + + String getOwnerName(); + + void toggleChat(UUID uuid); + boolean isGangChat(UUID uuid); + void setGangChat(UUID uuid, boolean on); + + Set<GangMember> getMembers(); + void setMembers(Set<GangMember> members); + Set<GangMember> getOnlineMembers(); + Optional<GangMember> getMember(UUID uuid); + Optional<GangMember> getMember(String playerName); + void addMember(GangMember member); + void removeMember(UUID uuid); + boolean hasMember(UUID uuid); + void setMemberRole(UUID uuid, GangRole role); + + Set<GangRelation> getRelations(); + void setRelation(Set<GangRelation> relations); + void addRelation(GangRelation relation); + void removeRelation(int id); + boolean hasRelation(int id); + + RelationType getRelation(int id); + void addRelationRequest(int id, RelationType type); + + String list(Gang gang); + void sendToAll(String str); + void sendToAllExcept(String str, UUID uuid); + + boolean isNeutral(Gang gang); + boolean isAllied(Gang gang); + boolean isEnemy(Gang gang); + boolean isLeader(UUID uuid); + boolean isCoLeader(UUID uuid); + boolean isMember(UUID uuid); + + Optional<Gang> getViewingGang(UUID uuid); + void setViewingGang(UUID uuid, Gang gang); + boolean isViewingGang(UUID uuid, Gang gang); + boolean isViewingGang(UUID uuid); + + Optional<GangMember> getViewingGangMember(UUID uuid); + void setViewingGangMember(UUID uuid, GangMember member); + boolean isViewingGangMember(UUID uuid, UUID member); + + void invite(Player sender, User user, Player target); + void accept(Player sender, User user, GTMUser gtmUser); + void leave(Player sender, User user, GTMUser gtmUser); + void setOwner(Player sender, User user, GTMUser gtmUser, Player target); + void promote(Player sender, User user, GTMUser gtmUser, String targetName); + void demote(Player sender, User user, GTMUser gtmUser, String targetName); + void kick(Player sender, User user, GTMUser gtmUser, String targetName); + void disbandConfirm(Player sender, User user, GTMUser gtmUser); + void disband(Player sender); + void rename(Player sender, User user, GTMUser gtmUser, String gangName); + void description(Player sender, User user, GTMUser gtmUser, String description); + + void ally(Player sender, User user, GTMUser gtmUser, String gang); + void neutral(Player sender, User user, GTMUser gtmUser, String gang); + void enemy(Player sender, User user, GTMUser gtmUser, String gang); + void chat(Player player, User user, GTMUser gtmUser, String msg); + + boolean updateDataFromDb(); +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/GangChatCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/GangChatCommand.java new file mode 100644 index 0000000..021d109 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/GangChatCommand.java @@ -0,0 +1,60 @@ +package net.grandtheftmc.gtm.gang; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.users.GTMUser; + +import org.apache.commons.lang.StringUtils; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.Arrays; +import java.util.Optional; + +public class GangChatCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + Player player = (Player) s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + GTMUser gtmUser = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + + Optional<Gang> gang = GangManager.getInstance().getGangByMember(player.getUniqueId()); + if (!gang.isPresent()) { + s.sendMessage(Lang.GANGCHAT.f("&7You are not in any gang!")); + return true; + } + + if (args.length == 0) { + gang.get().toggleChat(player.getUniqueId()); + s.sendMessage(Lang.GANGCHAT.f("&7You turned " + (gang.get().isGangChat(player.getUniqueId()) ? "&a&lon" : "&c&loff") + "&7 gang chat!")); + return true; + } + + if ("on".equalsIgnoreCase(args[0])) { +// gtmUser.setGangChat(true); + gang.get().setGangChat(player.getUniqueId(), true); + s.sendMessage(Lang.GANGCHAT.f("&7You turned &a&lon&7 gang chat!")); + return true; + } + + if ("off".equalsIgnoreCase(args[0])) { +// gtmUser.setGangChat(false); + gang.get().setGangChat(player.getUniqueId(), false); + s.sendMessage(Lang.GANGCHAT.f("&7You turned &c&loff&7 gang chat!")); + return true; + } + + String msg = StringUtils.join(Arrays.asList(args), " "); + gang.get().chat(player, user, gtmUser, msg); + return true; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/GangDAO.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/GangDAO.java new file mode 100644 index 0000000..15be0c8 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/GangDAO.java @@ -0,0 +1,343 @@ +package net.grandtheftmc.gtm.gang; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; + +import javax.annotation.Nullable; + +import com.google.common.collect.Lists; + +import com.google.common.collect.Sets; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.UUIDUtil; +import net.grandtheftmc.gtm.gang.member.GTMGangMember; +import net.grandtheftmc.gtm.gang.member.GangMember; +import net.grandtheftmc.gtm.gang.member.GangRole; +import net.grandtheftmc.gtm.gang.relation.GTMGangRelation; +import net.grandtheftmc.gtm.gang.relation.GangRelation; +import net.grandtheftmc.gtm.gang.relation.RelationType; + +public class GangDAO { + + public static Gang createGang(Connection connection, UUID owner, String name, int maxMembers) { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO `gtm_gang` (`server_key`,`name`,`owner`,`description`,`max_members`) VALUES (?,?,UNHEX(?),?,?);", Statement.RETURN_GENERATED_KEYS)) { + statement.setString(1, Core.name().toUpperCase()); + statement.setString(2, name); + statement.setString(3, owner.toString().replaceAll("-", "")); + statement.setString(4, "Default gang description."); + statement.setInt(5, maxMembers); + + statement.executeUpdate(); + + try (ResultSet result = statement.getGeneratedKeys()) { + if (result.next()) { + return new GTMGang(result.getInt(1), owner, name, null, maxMembers); + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + return null; + } + + public static Gang deleteGang(Connection connection, int id) { + try (PreparedStatement statement = connection.prepareStatement("DELETE FROM gtm_gang WHERE id=?;")) { + statement.setInt(1, id); + + statement.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + } + return null; + } + + public static boolean setName(Connection connection, String name, int id) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `gtm_gang` SET `name`=? WHERE `id`=?;")) { + statement.setString(1, name); + statement.setInt(2, id); + + statement.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + return true; + } + + public static boolean setDescription(Connection connection, String desc, int id) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `gtm_gang` SET `description`=? WHERE `id`=?;")) { + statement.setString(1, desc); + statement.setInt(2, id); + + statement.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + return true; + } + + public static boolean setOwner(Connection connection, UUID owner, int id) { + + if (owner == null){ + Core.log("[GangDAO] Cannot set owner for id=" + id + " as the owner is null."); + return false; + } + + try (PreparedStatement statement = connection.prepareStatement("UPDATE `gtm_gang` SET `owner`=UNHEX(?) WHERE `id`=?;")) { + statement.setString(1, owner.toString().replaceAll("-", "")); + statement.setInt(2, id); + + statement.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + return true; + } + + public static boolean setMemberRole(Connection connection, UUID uuid, GangRole role, int id) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `gtm_gang_member` SET `role`=? WHERE `gang_id`=? AND uuid=UNHEX(?);")) { + statement.setInt(1, role.getRankId()); + statement.setInt(2, id); + statement.setString(3, uuid.toString().replaceAll("-", "")); + + statement.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + return true; + } + + public static boolean addMember(Connection connection, UUID uuid, @Nullable GangRole role, int id) { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO `gtm_gang_member` (`gang_id`,`uuid`,`role`) VALUES (?,UNHEX(?),?);")) { + statement.setInt(1, id); + statement.setString(2, uuid.toString().replaceAll("-", "")); + statement.setInt(3, role == null ? 1 : role.getRankId()); + + statement.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + return true; + } + + public static boolean removeMember(Connection connection, UUID owner, int id) { + try (PreparedStatement statement = connection.prepareStatement("DELETE FROM `gtm_gang_member` WHERE gang_id=? AND uuid=UNHEX(?);")) { + statement.setInt(1, id); + statement.setString(2, owner.toString().replaceAll("-", "")); + + statement.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + return true; + } + + + public static boolean addRelation(Connection connection, int id, int otherId, RelationType relationType) { + if (relationType == RelationType.NEUTRAL) return false; + + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO `gtm_gang_relation` (`gang_id`,`other_id`,`relation`) VALUES (?,?,?) ON DUPLICATE KEY UPDATE relation=?;")) { + statement.setInt(1, id); + statement.setInt(2, otherId); + statement.setString(3, relationType.getKey()); + statement.setString(4, relationType.getKey()); + + statement.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + return true; + } + + public static boolean removeRelation(Connection connection, int id, int otherId) { + try (PreparedStatement statement = connection.prepareStatement("DELETE FROM `gtm_gang_relation` WHERE (gang_id=? AND other_id=?) OR (other_id=? AND gang_id=?);")) { + statement.setInt(1, id); + statement.setInt(2, otherId); + statement.setInt(3, id); + statement.setInt(4, otherId); + + statement.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + return true; + } + + public static boolean setMaxMembers(Connection connection, int maxMembers, int id) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `gtm_gang` SET `max_members`=? WHERE `gang_id`=?;")) { + statement.setInt(1, maxMembers); + statement.setInt(2, id); + + statement.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + return true; + } + + public static boolean isGangExisting(Connection connection, String name) { + try (PreparedStatement statement = connection.prepareStatement("SELECT `name` FROM `gtm_gang` WHERE `server_key`=? AND (name REGEXP '.*" + name + ".*');")) { + statement.setString(1, Core.name().toUpperCase()); +// statement.setString(2, name); + + try (ResultSet result = statement.executeQuery()) { + return result.next(); + } + } catch (SQLException e) { + e.printStackTrace(); + } + + return true; + } + + public static Gang getGang(Connection connection, int id) { + String query = "SELECT id,HEX(owner) as leader,name,description,max_members FROM gtm_gang WHERE id=?;"; + try (PreparedStatement statement = connection.prepareStatement(query)) { + statement.setInt(1, id); + + try (ResultSet result = statement.executeQuery()) { + if (result.next()) { + Gang gang = new GTMGang(result.getInt("id")); + gang.setName(result.getString("name")); + UUIDUtil.createUUID(result.getString("leader")).ifPresent(gang::setOwner); + gang.setDescription(result.getString("description")); + gang.setMaxMembers(result.getInt("max_members")); + return gang; + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + return null; + } + + public static Set<Gang> getGangs(Connection connection) { + Set<Gang> list = Sets.newHashSet(); + final String query = "SELECT id,HEX(owner) as leader,name,description,max_members FROM gtm_gang WHERE server_key=?;"; + try (PreparedStatement statement = connection.prepareStatement(query)) { + statement.setString(1, Core.name().toUpperCase()); + + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + int gangID = result.getInt("id"); + Gang gang = new GTMGang(gangID); + gang.setName(result.getString("name")); + String leader = result.getString("leader"); + if (leader != null){ + UUID leaderUUID = UUIDUtil.createUUID(leader).orElse(null); + if (leaderUUID != null){ + gang.setOwner(leaderUUID); + } + else{ + Core.log("[GangDAO] Unable to set owner of gang due to leader uuid not being parsed, leader=" + leader + ", gang_id=" + gangID); + } + } + gang.setDescription(result.getString("description")); + gang.setMaxMembers(result.getInt("max_members")); + list.add(gang); + } + return list; + } + } catch (SQLException e) { + e.printStackTrace(); + } + return list; + } + + public static Set<GangMember> getMembers(Connection connection, int id) { + //Pull player name by uuid, no current way of doing this.. + String query = "SELECT HEX(GM.uuid) as uid,GM.role,U.name FROM gtm_gang_member GM, gtm_gang G, user U WHERE GM.gang_id=? AND GM.gang_id=G.id AND GM.uuid=U.uuid;"; + try (PreparedStatement statement = connection.prepareStatement(query)) { + statement.setInt(1, id); + + try (ResultSet result = statement.executeQuery()) { + Set<GangMember> list = Sets.newHashSet(); + + while (result.next()) { + UUID uuid = UUIDUtil.createUUID(result.getString("uid")).orElse(null); + if (uuid == null) continue; + list.add(new GTMGangMember(uuid, result.getString("name"), GangRole.getById(result.getInt("role")))); + } + + return list; + } + } catch (SQLException e) { + e.printStackTrace(); + } + return Sets.newHashSet(); + } + + public static Set<GangRelation> getRelations(Connection connection, int id) { + String query = "SELECT other_id, relation FROM gtm_gang_relation WHERE gang_id=?;"; + try (PreparedStatement statement = connection.prepareStatement(query)) { + statement.setInt(1, id); + + try (ResultSet result = statement.executeQuery()) { + Set<GangRelation> list = Sets.newHashSet(); + + while (result.next()) { + list.add(new GTMGangRelation(result.getInt("other_id"), RelationType.getByKey(result.getString("relation")))); + } + + return list; + } + } catch (SQLException e) { + e.printStackTrace(); + } + return Sets.newHashSet(); + } + + public static Optional<Gang> getGangInfo(Connection connection, int id) { + String query = "SELECT * FROM gtm_gang WHERE id=?;"; + try (PreparedStatement statement = connection.prepareStatement(query)) { + statement.setInt(1, id); + + try (ResultSet result = statement.executeQuery()) { + if (result.next()) { + Optional<UUID> optional = UUIDUtil.createUUID(result.getString("owner")); + if (!optional.isPresent()) return Optional.empty(); + + return Optional.of(new GTMGang(result.getInt("id"), optional.get(), result.getString("name"), result.getString("description"), result.getInt("max_members"))); + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + return Optional.empty(); + } + + public static Optional<Gang> getGangInfo(Connection connection, String name) { + String query = "SELECT id,name,description,max_members FROM gtm_gang WHERE name=? AND server_key=?;"; + try (PreparedStatement statement = connection.prepareStatement(query)) { + statement.setString(1, name); + statement.setString(2, Core.name().toUpperCase()); + + try (ResultSet result = statement.executeQuery()) { + if (result.next()) { + Optional<UUID> optional = UUIDUtil.createUUID(result.getString("owner")); + if (!optional.isPresent()) return Optional.empty(); + + return Optional.of(new GTMGang(result.getInt("id"), optional.get(), result.getString("name"), result.getString("description"), result.getInt("max_members"))); + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + return Optional.empty(); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/GangManager.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/GangManager.java new file mode 100644 index 0000000..6d956ed --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/GangManager.java @@ -0,0 +1,277 @@ +package net.grandtheftmc.gtm.gang; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.gang.command.GangCommand; +import net.grandtheftmc.gtm.gang.command.GangDisableCommand; +import net.grandtheftmc.gtm.gang.member.GTMGangMember; +import net.grandtheftmc.gtm.gang.member.GangMember; +import net.grandtheftmc.gtm.gang.member.GangRole; +import net.grandtheftmc.gtm.gang.relation.GangRelation; +import net.grandtheftmc.gtm.gang.relation.RelationType; +import net.grandtheftmc.gtm.users.GTMRank; +import net.grandtheftmc.gtm.users.GTMUser; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; + +public class GangManager { + + public static boolean ENABLED = true; + private static GangManager instance; + + private Set<Gang> gangs; + private final HashMap<UUID, Integer> gangInvites; + + public GangManager(JavaPlugin plugin) { + instance = this; + this.gangs = Sets.newHashSet(); + this.gangInvites = Maps.newHashMap(); + + new GangCommand(this); + new GangDisableCommand(); + plugin.getCommand("gangchat").setExecutor(new GangChatCommand()); + + ServerUtil.runTaskAsync(() -> { + long start = System.currentTimeMillis(); + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + this.gangs = GangDAO.getGangs(connection); + System.out.println("Loaded gangs(" + gangs.size() + "), took " + (System.currentTimeMillis() - start) + "ms."); + + for (Gang gang : this.getGangs()) { + gang.setMembers(GangDAO.getMembers(connection, gang.getUniqueId())); + gang.setRelation(GangDAO.getRelations(connection, gang.getUniqueId())); + + boolean found = false; + GangMember coOwner = null; + for (GangMember member : gang.getMembers()) { + if (member.getRole() == GangRole.LEADER) + found = true; + if (member.getRole() == GangRole.CO_LEADER && !found) + coOwner = member; + } + + if (!found && coOwner != null) { + gang.setOwner(coOwner.getUniqueId()); + System.out.println("Owner set for gang (" + gang.getUniqueId() + ")"); + } + } + + System.out.println("Loaded gangs(" + gangs.size() + ")"); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } + + public static GangManager getInstance() { + return instance; + } + + public Set<Gang> getGangs() { + return gangs; + } + + public void addGang(Gang gang) { + this.gangs.add(gang); + } + + public void removeGang(Gang gang) { + this.gangs.remove(gang); + } + + public Optional<Gang> getGang(int id) { + return this.gangs.stream().filter(gang -> gang.getUniqueId() == id).findFirst(); + } + + public Optional<Gang> getGang(String name) { + return this.gangs.stream().filter(gang -> gang.getName().equalsIgnoreCase(name)).findFirst(); + } + + public Optional<Gang> getGangByMember(UUID uuid) { + return this.gangs.stream().filter(gang -> gang.getMembers().stream().anyMatch(mem -> mem.getUniqueId().equals(uuid))).findFirst(); + } + + public Integer getGangInvites(UUID uuid) { + return this.gangInvites.getOrDefault(uuid, -1); + } + + public void addGangInvite(UUID uuid, int id) { + this.gangInvites.put(uuid, id); + } + + public void removeGangInvite(UUID uuid) { + this.gangInvites.remove(uuid); + } + + public boolean isInvited(UUID uuid, int id) { + return this.gangInvites.containsKey(uuid) && this.gangInvites.get(uuid) == id; + } + + public void createGang(Player sender, String name) { + UUID uuid = sender.getUniqueId(); + String gangName = name; + + User user = Core.getUserManager().getLoadedUser(uuid); + GTMUser gtmUser = GTM.getUserManager().getLoadedUser(uuid); + + if (!gtmUser.isRank(GTMRank.GANGSTER) && user.getUserRank().isHigherThan(UserRank.VIP)) { + sender.sendMessage(Lang.GANGS.f("&7You must be a &e&l" + GTMRank.GANGSTER.getColoredNameBold() + "&7 or &a&lPREMIUM&7 to create a gang! Check the &d&lMy Account&7 -> &a&lRanks&7 menu on your phone for more information.")); + return; + } + + if (this.getGangByMember(uuid).orElse(null) != null) { + sender.sendMessage(Lang.GANGS.f("&7You are in a gang already!")); + return; + } + + if (!name.matches("^[a-zA-Z_0-9]+$")) { + sender.sendMessage(Lang.GANGS.f("&7Only a-z, A-Z, 0-9 and _ are allowed in a gang name!")); + return; + } + + if (name.length() > 16 || name.length() < 3) { + sender.sendMessage(Lang.GANGS.f("&7The name of your gang needs to be 3-16 characters long!")); + return; + } + + if (this.getGang(gangName).orElse(null) != null) { + sender.sendMessage(Lang.GANGS.f("&7A gang with that name already exists!")); + return; + } + + if (!gtmUser.hasMoney(500000)) { + sender.sendMessage(Lang.GANGS.f("&7You don't have &a$&l500,000&7 to create this gang!")); + return; + } + + ServerUtil.runTaskAsync(() -> { + boolean b = false; + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + b = GangDAO.isGangExisting(connection, gangName); + } catch (SQLException e) { + e.printStackTrace(); + } + + boolean exists = b; + + ServerUtil.runTask(() -> { + Player sender2 = Bukkit.getPlayer(uuid); + if (sender2 == null) return; + if (exists) { + sender.sendMessage(Lang.GANGS.f("&7A gang with that name already exists!")); + return; + } + + if (!gtmUser.hasMoney(500000)) { + sender.sendMessage(Lang.GANGS.f("&7You don't have &a$&l500,000&7 to create this gang!")); + return; + } + + gtmUser.takeMoney(500000); + GTMUtils.updateBoard(sender2, user, gtmUser); + int maxMembers = this.getMaxGangMembers(sender2, user); + + ServerUtil.runTaskAsync(() -> { + Gang gang = null; + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + gang = GangDAO.createGang(connection, sender2.getUniqueId(), gangName, maxMembers); + } catch (SQLException e) { + e.printStackTrace(); + } + + if(gang == null) return; + this.addGang(gang); + gang.addMember(new GTMGangMember(sender2.getUniqueId(), sender2.getName(), GangRole.LEADER)); + + ServerUtil.runTask(() -> { + Player sender3 = Bukkit.getPlayer(uuid); + if (sender3 == null) return; + + sender3.sendMessage(Lang.GANGS.f("&7You created a gang with the name &a" + gangName + "&7!")); + }); + }); + }); + }); + } + + public int getMaxGangMembers(Player player, User user) { + GTMUser gtmUser = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + + int amnt = gtmUser.getRank().getGangMembers() + GTMUtils.getGangMembers(user.getUserRank()); + for (int i = 20; i > 0; i--) + if (player.hasPermission("gangs.members." + i)) { + amnt = i; + break; + } + for (int i = 20; i > 0; i--) + if (player.hasPermission("gangs.extramembers." + i)) { + amnt += i; + break; + } + return amnt; + } + + public void info(Gang gang, Player sender, User user, GTMUser gtmUser) { + sender.sendMessage(Utils.f(" &7&m---------------&7[&a&l " + gang.getName() + " &7]&m---------------")); + sender.sendMessage(Utils.f("&a&lDescription: &7" + gang.getDescription())); + + StringBuilder ally = new StringBuilder(), enemy = new StringBuilder(); + int iAlly = 0, iEnemy = 0; + for (GangRelation relation : gang.getRelations()) { + if (relation.getRelationType() == RelationType.ALLY) { + ally.append(iAlly > 0 ? "&7, " : "").append("&a").append(relation.getRelativeName()); + iAlly++; + } + else if (relation.getRelationType() == RelationType.ENEMY) { + enemy.append(iEnemy > 0 ? "&c, " : "").append("&c").append(relation.getRelativeName()); + iEnemy++; + } + } + + int online = 0, offline = 0; + StringBuilder on = new StringBuilder(), off = new StringBuilder(); + Player leader = Bukkit.getPlayer(gang.getOwner()); + if (leader != null) { + User u = Core.getUserManager().getLoadedUser(leader.getUniqueId()); + on.append(online > 0 ? "&7, " : "").append("&aLeader ").append(u.getColoredName(leader)); +// members[0].append("&aLeader ").append(u.getColoredName(leader)).append("&7, "); + online++; + } + + for (GangMember member : gang.getMembers()) { + if (member.getRole() == GangRole.LEADER) continue; + Player player = Bukkit.getPlayer(member.getUniqueId()); + if (player == null) { + off.append(offline > 0 ? "&7, " : "").append("&a").append(member.isCoLeader() ? "Coleader " : "").append(member.getName()); + offline++; + continue; + } + + User u = Core.getUserManager().getLoadedUser(member.getUniqueId()); + on.append(online > 0 ? "&7, " : "").append("&a").append(member.isCoLeader() ? "Coleader " : "").append(u.isSpecial() ? u.getColoredName(player) : player.getName()); + online++; + } + + if (iAlly > 0) sender.sendMessage(Utils.f("&a&lAllies&7(&a" + iAlly + "&7)&a: &7" + ally.toString())); + if (iEnemy > 0) sender.sendMessage(Utils.f("&c&lEnemies&7(&c" + iEnemy + "&7)&c: &7" + enemy.toString())); + sender.sendMessage(Utils.f("&a&lOnline Members&7(&a" + online + "&7)&a: &7" + on)); + sender.sendMessage(Utils.f("&a&lOffline Members&7(&a" + offline + "&7)&a: &7" + off)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/command/GangAdminCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/command/GangAdminCommand.java new file mode 100644 index 0000000..c975728 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/command/GangAdminCommand.java @@ -0,0 +1,98 @@ +package net.grandtheftmc.gtm.gang.command; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.users.GTMUser; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.UUID; + +public class GangAdminCommand implements CommandExecutor { + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (!s.hasPermission("gangs.admin")) { + s.sendMessage(Lang.NOPERM.s()); + return true; + } + + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + +// Player player = (Player) s; +// UUID uuid = player.getUniqueId(); +// User user = Core.getUserManager().getLoadedUser(uuid); +// GTMUser gtmUser = GTM.getUserManager().getLoadedUser(uuid); +// if (args.length == 0 || "help".equalsIgnoreCase(args[0])) { +// int page = 1; +// if (args.length > 1) +// try { +// page = Integer.parseInt(args[1]); +// } catch (NumberFormatException e) { +// page = 1; +// } +// if (page < 1) { +// s.sendMessage(Lang.GANGS.f("&7The page must be a positive number!")); +// return true; +// } +// s.sendMessage(Utils.f(" &7&m---------------&7[&a GangAdmin Help &7Page &a" + page + "&7/&a2 &7]&m---------------")); +// switch (page) { +// case 1: +// s.sendMessage(Utils.f("&a/ga help [page] &7Show this help page")); +// s.sendMessage(Utils.f("&a/ga set [player] [gang name] &7Forcefully add a player to a gang")); +// s.sendMessage(Utils.f("&a/ga setrank [player] [rank] &7Forcefully set a player's rank in their gang")); +// s.sendMessage(Utils.f("&a/ga kick [player] &7Forcefully kick a player from their gang")); +// s.sendMessage(Utils.f("&a/ga disband [gang] &7Forcefully disband a gang")); +// return true; +// } +// } +// switch (args[0]) { +// case "set": { +// if (args.length != 3) { +// player.sendMessage(Lang.GANGS.f("&cError! &7Usage: &a/ga set [player] [gang name]")); +// return true; +// } +// String gangName = args[2]; +// String gangRank = "member"; +// if (Bukkit.getPlayer(args[1]) == null) { +//// Core.sql.updateAsyncLater("update " + Core.name() + " set gang='" + gangName + "',gangRank='" + gangRank +//// + "' where name='" + args[1] + "';"); +// ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + Core.name() + " set gang='" + gangName + "',gangRank='" + gangRank + "' where name='" + args[1] + "';")); +// } else { +// Player target = Bukkit.getPlayer(args[1]); +// GTMUser targetGTMUser = GTM.getUserManager().getLoadedUser(target.getUniqueId()); +// targetGTMUser.setGang(gangName); +// } +// player.sendMessage(Lang.GANGS.f("&a" + args[1] + " &7is now a member of &a" + gangName)); +// return true; +// } +// case "setrank": { +// return true; +// } +// case "kick": { +// return true; +// } +// case "disband": { +// return true; +// } +// default: +// s.sendMessage(Utils.f("&a/ga help [page] &7Show this help page")); +// s.sendMessage(Utils.f("&a/ga set [player] [gang name] &7Forcefully add a player to a gang")); +// s.sendMessage(Utils.f("&a/ga setrank [player] [rank] &7Forcefully set a player's rank in their gang")); +// s.sendMessage(Utils.f("&a/ga kick [player] &7Forcefully kick a player from their gang")); +// s.sendMessage(Utils.f("&a/ga disband [gang] &7Forcefully disband a gang")); +// return true; +// } + return true; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/command/GangCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/command/GangCommand.java new file mode 100644 index 0000000..35090fa --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/command/GangCommand.java @@ -0,0 +1,353 @@ +package net.grandtheftmc.gtm.gang.command; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.commands.CoreCommand; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.gang.Gang; +import net.grandtheftmc.gtm.gang.GangManager; +import net.grandtheftmc.gtm.users.GTMUser; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import java.util.*; + +public class GangCommand extends CoreCommand<Player> { + + private final GangManager gangManager; + + public GangCommand(GangManager gangManager) { + super("gang", "Gangs base command.", "g"); + this.gangManager = gangManager; + } + + @Override + public void execute(Player sender, String[] args) { + UUID uuid = sender.getUniqueId(); + User user = Core.getUserManager().getLoadedUser(uuid); + GTMUser gtmUser = GTM.getUserManager().getLoadedUser(uuid); + Gang playerGang = gangManager.getGangByMember(uuid).orElse(null); + + if (args.length == 0 || "help".equalsIgnoreCase(args[0])) { + int page = 1; + if (args.length > 1) { + try { + page = Integer.parseInt(args[1]); + } catch (NumberFormatException e) { + page = 1; + } + } + + if (page < 1) { + sender.sendMessage(Lang.GANGS.f("&7The page must be a positive number!")); + return; + } + + sender.sendMessage(Utils.f(" &7&m---------------&7[&a Gangs Help &7Page &a" + page + "&7/&a2 &7]&m---------------")); + this.sendHelp(sender, page); + } + + if(args.length < 1) return; + + switch (args[0]) { + case "create": + if (args.length != 2) { + sender.sendMessage(Utils.f("&c/gangs create <name>")); + return; + } + + gangManager.createGang(sender, args[1]); + return; + + case "i": + case "s": + case "info": + case "show": { +// Gang gang = args.length == 1 ? gtmUser.getGang() : GTM.getGangManager().getAlreadyLoadedGang(args[1]); + Optional<Gang> optional; + if(args.length == 1) optional = gangManager.getGangByMember(uuid); + else optional = this.gangManager.getGang(args[1]); + + if (!optional.isPresent()) { + sender.sendMessage(Lang.GANGS.f(args.length == 1 ? "&7You are not in any gang!" : "&7That gang does not exist or no one in that gang is online!")); + return; + } + + gangManager.info(optional.get(), sender, user, gtmUser); + return; + } + + case "p": + case "player": { + if (args.length != 2) { + sender.sendMessage(Utils.f("&c/gangs " + args[0] + " <name>")); + return; + } + + Player target = Bukkit.getPlayer(args[1]); + if (target == null) { + sender.sendMessage(Lang.GANGS.f("&7That player is not online!")); + return; + } + +// Gang gang = GTM.getUserManager().getLoadedUser(target.getUniqueId()).getGang(); + Gang gang = gangManager.getGangByMember(target.getUniqueId()).orElse(null); + if (gang == null) { + sender.sendMessage(Lang.GANGS.f("&7That player is not in any gang!")); + return; + } + + gangManager.info(gang, sender, user, gtmUser); + return; + } + + case "l": + case "list": { + if (true) { + sender.sendMessage(C.ERROR + "This command is currently disabled."); + return; + } + + Set<Gang> gangs = this.gangManager.getGangs(); + int page = 0; + if (args.length > 1) { + try { + page = Integer.parseInt(args[1]) - 1; + } catch (NumberFormatException e) { + sender.sendMessage(Lang.GANGS.f("&7The page must be a number!")); + return; + } + } + + if (page < 0) { + sender.sendMessage(Lang.GANGS.f("&7The page must be a positive number!")); + return; + } + + int pages = gangs.size() / 6; + sender.sendMessage(Utils.f(" &7&m---------------&7[&a&l Gangs List &7Page &a" + (page + 1) + "&7/&a" + pages + " &7&m]---------------")); + Iterator<Gang> it = gangs.iterator(); + for (int i = 0; i < page * 6; i++) { + if (!it.hasNext()) return; + Gang g = it.next(); + g.list(playerGang); + } + return; + } + + case "invite": { + if (args.length != 2) { + sender.sendMessage(Utils.f("&c/gangs invite <name>")); + return; + } + if (playerGang == null) { + sender.sendMessage(Lang.GANGS.f("&7You are not in any gang!")); + return; + } + Player target = Bukkit.getPlayer(args[1]); + playerGang.invite(sender, user, target); + return; + } + + case "accept": + case "join": + if (args.length != 2) { + sender.sendMessage(Utils.f("&c/gangs " + args[0] + " <name>")); + return; + } + + Optional<Gang> gang = this.gangManager.getGang(args[1]); + if (!gang.isPresent()) { + sender.sendMessage(Lang.GANGS.f("&7That gang does not exist!")); + return; + } + + gang.get().accept(sender, user, gtmUser); + return; + + case "leave": + if (playerGang == null) { + sender.sendMessage(Lang.GANGS.f("&7You are not in any gang!")); + return; + } + + playerGang.leave(sender, user, gtmUser); + return; + + case "leader": { + if (args.length != 2) { + sender.sendMessage(Utils.f("&c/gangs leader <name>")); + return; + } + + if (playerGang == null) { + sender.sendMessage(Lang.GANGS.f("&7You are not in any gang!")); + return; + } + + Player target = Bukkit.getPlayer(args[1]); + playerGang.setOwner(sender, user, gtmUser, target); + return; + } + + case "promote": + if (args.length != 2) { + sender.sendMessage(Utils.f("&c/gangs promote <name>")); + return; + } + + if (playerGang == null) { + sender.sendMessage(Lang.GANGS.f("&7You are not in any gang!")); + return; + } + + playerGang.promote(sender, user, gtmUser, args[1]); + return; + + case "demote": + if (args.length != 2) { + sender.sendMessage(Utils.f("&c/gangs demote <name>")); + return; + } + + if (playerGang == null) { + sender.sendMessage(Lang.GANGS.f("&7You are not in any gang!")); + return; + } + + playerGang.demote(sender, user, gtmUser, args[1]); + return; + + case "kick": + if (args.length != 2) { + sender.sendMessage(Utils.f("&c/gangs kick <name>")); + return; + } + + if (playerGang == null) { + sender.sendMessage(Lang.GANGS.f("&7You are not in any gang!")); + return; + } + + playerGang.kick(sender, user, gtmUser, args[1]); + return; + + case "disband": + if (playerGang == null) { + sender.sendMessage(Lang.GANGS.f("&7You are not in any gang!")); + return; + } + if (args.length == 2 && "confirm".equalsIgnoreCase(args[1])) { + playerGang.disbandConfirm(sender, user, gtmUser); + return; + } + playerGang.disband(sender); + return; + + case "rename": + case "name": + if (args.length != 2) { + sender.sendMessage(Utils.f("&c/gangs name <name>")); + return; + } + + if (playerGang == null) { + sender.sendMessage(Lang.GANGS.f("&7You are not in any gang!")); + return; + } + + playerGang.rename(sender, user, gtmUser, args[1]); + return; + + case "desc": + case "description": + if (args.length < 2) { + sender.sendMessage(Utils.f("&c/gangs " + args[0] + " <description>")); + return; + } + + if (playerGang == null) { + sender.sendMessage(Lang.GANGS.f("&7You are not in any gang!")); + return; + } + + Collection<String> descArgs = new ArrayList<>(); + for (int i = 1; i < args.length; i++) { + descArgs.add(args[i]); + } + + String desc = StringUtils.join(descArgs, " "); + playerGang.description(sender, user, gtmUser, desc); + return; + + case "ally": + if (args.length < 2) { + sender.sendMessage(Utils.f("&c/gangs " + args[0] + " <name>")); + return; + } + if (playerGang == null) { + sender.sendMessage(Lang.GANGS.f("&7You are not in any gang!")); + return; + } + playerGang.ally(sender, user, gtmUser, args[1]); + return; + + case "neutral": + if (args.length < 2) { + sender.sendMessage(Utils.f("&c/gangs " + args[0] + " <name>")); + return; + } + if (playerGang == null) { + sender.sendMessage(Lang.GANGS.f("&7You are not in any gang!")); + return; + } + playerGang.neutral(sender, user, gtmUser, args[1]); + return; + + case "enemy": + if (args.length < 2) { + sender.sendMessage(Utils.f("&c/gangs " + args[0] + " <name>")); + return; + } + if (playerGang == null) { + sender.sendMessage(Lang.GANGS.f("&7You are not in any gang!")); + return; + } + playerGang.enemy(sender, user, gtmUser, args[1]); + return; + + default: + this.sendHelp(sender, 1); + break; + } + } + + private void sendHelp(Player player, int page) { + if(page == 1) { + player.sendMessage(Utils.f("&a/gang help [page] &7Show this help page")); + player.sendMessage(Utils.f("&a/gang list [page] &7List the most powerful online gangs")); + player.sendMessage(Utils.f("&a/gang info <gang> &7Show information about your/a Gang")); + player.sendMessage(Utils.f("&a/gang join <gang> &7Join a Gang you were invited to")); + player.sendMessage(Utils.f("&a/gang invite <name> &7Invite a player to your Gang")); + player.sendMessage(Utils.f("&a/gang create <name> &7Create a new Gang")); + player.sendMessage(Utils.f("&a/gang player <name> &7Show info about the Gang of another player")); + player.sendMessage(Utils.f("&a/gang leader <name> &7Transfer leadership of your Gang")); + player.sendMessage(Utils.f("&a/gang leave &7Leave your Gang")); + return; + } + + player.sendMessage(Utils.f("&a/gang promote <name> &7Promote a player to coleader of your Gang")); + player.sendMessage(Utils.f("&a/gang demote <name> &7Demote a coleader of your Gang")); + player.sendMessage(Utils.f("&a/gang kick <name> &7Kick a player from your Gang")); + player.sendMessage(Utils.f("&a/gang disband &7Kick all members and delete your Gang")); + player.sendMessage(Utils.f("&a/gang rename <name> &7Change the name of your Gang")); + player.sendMessage(Utils.f("&a/gang desc <text> &7Change the description of your Gang")); + player.sendMessage(Utils.f("&a/gang ally <gang> &7Declare a Gang your ally")); + player.sendMessage(Utils.f("&a/gang neutral <gang> &7Designate a Gang as neutral")); + player.sendMessage(Utils.f("&a/gang enemy <gang> &7Declare a Gang your enemy")); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/command/GangDisableCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/command/GangDisableCommand.java new file mode 100644 index 0000000..db8c689 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/command/GangDisableCommand.java @@ -0,0 +1,26 @@ +package net.grandtheftmc.gtm.gang.command; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.commands.CoreCommand; +import net.grandtheftmc.core.commands.RankedCommand; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.gtm.gang.GangManager; +import org.bukkit.entity.Player; + +public class GangDisableCommand extends CoreCommand<Player> implements RankedCommand { + + public GangDisableCommand() { + super("gangdisable", "Temp disable features of gangs."); + } + + @Override + public void execute(Player sender, String[] strings) { + GangManager.ENABLED = !GangManager.ENABLED; + sender.sendMessage(Lang.GANGS.f("&cCreating & Info features have been " + (GangManager.ENABLED ? "Enabled." : "Disabled!"))); + } + + @Override + public UserRank requiredRank() { + return UserRank.ADMIN; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/member/GTMGangMember.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/member/GTMGangMember.java new file mode 100644 index 0000000..d13a1f7 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/member/GTMGangMember.java @@ -0,0 +1,125 @@ +package net.grandtheftmc.gtm.gang.member; + +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.gtm.gang.Gang; +import net.grandtheftmc.gtm.gang.GangDAO; +import net.grandtheftmc.gtm.gang.GangManager; +import net.grandtheftmc.gtm.users.GTMRank; +import net.grandtheftmc.gtm.users.GTMUser; +import org.bukkit.Bukkit; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Optional; +import java.util.UUID; + +public class GTMGangMember implements GangMember { + + private final UUID uuid; + private GangRole role = GangRole.MEMBER; + private String name; + + private boolean chat = false; + private Gang viewingGang; + private GangMember viewingGangMember; + + public GTMGangMember(UUID uuid) { + this.uuid = uuid; + } + + public GTMGangMember(UUID uuid, String name, GangRole role) { + this(uuid); + this.name = name; + this.role = role; + } + + @Override + public UUID getUniqueId() { + return uuid; + } + + @Override + public String getName() { + return name; + } + + @Override + public void setName(String name) { + this.name = name; + } + + @Override + public GangRole getRole() { + return role; + } + + @Override + public void setRole(int id, GangRole role) { + this.role = role; + + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + GangDAO.setMemberRole(connection, uuid, role, id); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } + + @Override + public boolean isCoLeader() { + return this.role == GangRole.CO_LEADER; + } + + @Override + public boolean isOnline() { + return Bukkit.getPlayer(this.uuid) != null; + } + + @Override + public boolean getChatToggle() { + return this.chat; + } + + @Override + public void toggleChat() { + this.chat = !this.chat; + } + + @Override + public void setChat(boolean chat) { + this.chat = chat; + } + + @Override + public Optional<Gang> getViewingGang() { + return this.viewingGang == null ? Optional.empty() : Optional.of(this.viewingGang); + } + + @Override + public boolean isViewingGang(Gang gang) { + return this.viewingGang != null && this.viewingGang.getUniqueId() == gang.getUniqueId(); + } + + @Override + public void setViewingGang(Gang viewingGang) { + this.viewingGang = viewingGang; + } + + @Override + public Optional<GangMember> getViewingGangMember() { + return this.viewingGangMember == null ? Optional.empty() : Optional.of(this.viewingGangMember); + } + + @Override + public void setViewingGangMember(GangMember member) { + this.viewingGangMember = member; + } + + @Override + public boolean isViewingGangMember(UUID uuid) { + return this.viewingGangMember != null && this.viewingGangMember.getUniqueId().equals(uuid); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/member/GangMember.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/member/GangMember.java new file mode 100644 index 0000000..569eb6e --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/member/GangMember.java @@ -0,0 +1,34 @@ +package net.grandtheftmc.gtm.gang.member; + +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.gtm.gang.Gang; +import net.grandtheftmc.gtm.users.GTMUser; + +import java.util.Optional; +import java.util.UUID; + +public interface GangMember { + + UUID getUniqueId(); + + String getName(); + void setName(String name); + + GangRole getRole(); + void setRole(int id, GangRole role); + + boolean isCoLeader(); + boolean isOnline(); + + boolean getChatToggle(); + void toggleChat(); + void setChat(boolean on); + + Optional<Gang> getViewingGang(); + void setViewingGang(Gang gang); + boolean isViewingGang(Gang gang); + + Optional<GangMember> getViewingGangMember(); + void setViewingGangMember(GangMember member); + boolean isViewingGangMember(UUID uuid); +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/member/GangRole.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/member/GangRole.java new file mode 100644 index 0000000..007a8c0 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/member/GangRole.java @@ -0,0 +1,41 @@ +package net.grandtheftmc.gtm.gang.member; + +public enum GangRole { + MEMBER(1, "member", "Member"), + TRUSTED(2, "trusted", "Trusted"), + + //Room for 2 more. + + CO_LEADER(5, "coleader", "Co-Leader"), + LEADER(6, "leader", "Leader"), + ; + + private final int rankId; + private final String tag; + private final String formattedTag; + + GangRole(int rankId, String tag, String formattedTag) { + this.rankId = rankId; + this.tag = tag; + this.formattedTag = formattedTag; + } + + public int getRankId() { + return rankId; + } + + public String getTag() { + return tag; + } + + public String getFormattedTag() { + return formattedTag; + } + + public static GangRole getById(int id) { + for(GangRole role : values()) + if(role.rankId == id) + return role; + return MEMBER; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/relation/GTMGangRelation.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/relation/GTMGangRelation.java new file mode 100644 index 0000000..fa6b667 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/relation/GTMGangRelation.java @@ -0,0 +1,43 @@ +package net.grandtheftmc.gtm.gang.relation; + +public class GTMGangRelation implements GangRelation { + + private final int relativeId; + private String relativeName; + private RelationType relationType; + + public GTMGangRelation(int relativeId, RelationType relationType) { + this.relativeId = relativeId; + this.relationType = relationType; + } + + public GTMGangRelation(int relativeId, String relativeName, RelationType relationType) { + this(relativeId, relationType); + this.relativeName = relativeName; + } + + @Override + public int getRelativeId() { + return relativeId; + } + + @Override + public String getRelativeName() { + return relativeName; + } + + @Override + public void setRelativeName(String relativeName) { + this.relativeName = relativeName; + } + + @Override + public RelationType getRelationType() { + return relationType; + } + + @Override + public void setRelationType(RelationType relationType) { + this.relationType = relationType; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/relation/GangRelation.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/relation/GangRelation.java new file mode 100644 index 0000000..5daf56a --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/relation/GangRelation.java @@ -0,0 +1,12 @@ +package net.grandtheftmc.gtm.gang.relation; + +public interface GangRelation { + + int getRelativeId(); + + String getRelativeName(); + void setRelativeName(String name); + + RelationType getRelationType(); + void setRelationType(RelationType relationType); +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/relation/RelationType.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/relation/RelationType.java new file mode 100644 index 0000000..af37a5d --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/relation/RelationType.java @@ -0,0 +1,35 @@ +package net.grandtheftmc.gtm.gang.relation; + +public enum RelationType { + + NEUTRAL(null, null), + ALLY("ALLY", "Ally"), + ENEMY("ENEMY", "Enemy"), + ; + + private final String key; + private final String name; + + RelationType(String key, String name) { + this.key = key; + this.name = name; + } + + public String getKey() { + return key; + } + + public String getName() { + return name; + } + + public static RelationType getByKey(String str) { + for(RelationType type : values()) { + if (type.key == null) continue; + if (type.key.equalsIgnoreCase(str)) { + return type; + } + } + return NEUTRAL; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/schema.md b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/schema.md new file mode 100644 index 0000000..d8a909e --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gang/schema.md @@ -0,0 +1,65 @@ +/***** +** Table Description: +** Represents GTM gang information. +** +** id is primary auto increment so we can change gang names. +** server_key is the server that this gang is on +** name is the name of the gang +** owner is the uuid of the player that owns this gang +** +** Reasoning for structure: +** PK is the (`id`) field, as every gang needs its own unique key. We +** index the server_key so we can lookup gangs by server_type. +*****/ +CREATE TABLE IF NOT EXISTS gtm_gang( +id INT NOT NULL AUTO_INCREMENT, +server_key VARCHAR(10) NOT NULL, +name VARCHAR(36) NOT NULL, +owner BINARY(16) NOT NULL, +description VARCHAR(255) NOT NULL, +max_members INT(11) NOT NULL, +PRIMARY KEY (id), +INDEX (server_key) +); + + +/***** +** Table Description: +** Represents GTM gang member information, every gang will +** have multiple records, one for each member. +** +** gang_id is foreign key reference to gtm_gang table +** uuid is the uuid of the member +** +** Reasoning for structure: +** PK is the (`gang_id`, `uuid`) pair, as a member can only exist in that gang once. +*****/ +CREATE TABLE IF NOT EXISTS gtm_gang_member( +gang_id INT NOT NULL, +uuid BINARY(16) NOT NULL, +role TINYINT(6) NOT NULL DEFAULT 0, +PRIMARY KEY (gang_id, uuid), +FOREIGN KEY (gang_id) REFERENCES gtm_gang(id) ON DELETE CASCADE +); + + +/***** +** Table Description: +** Represents GTM gang relationships. +** +** gang_id is owner of the relationship +** other_id is the other gang in this relationship +** relation is the relationship they share +** +** Reasoning for structure: +** PK is the (`gang_id`, `other_id`) pair, as a gang can only have +** ONE unique relationship between them. +*****/ +CREATE TABLE IF NOT EXISTS gtm_gang_relation( +gang_id INT NOT NULL, +other_id INT NOT NULL, +relation VARCHAR(10), +PRIMARY KEY (gang_id, other_id), +FOREIGN KEY (gang_id) REFERENCES gtm_gang(id) ON DELETE CASCADE, +FOREIGN KEY (other_id) REFERENCES gtm_gang(id) ON DELETE CASCADE +); \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gangs/Gang.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gangs/Gang.java new file mode 100644 index 0000000..c9da57c --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gangs/Gang.java @@ -0,0 +1,885 @@ +package net.grandtheftmc.gtm.gangs; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.Pref; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.gang.GangDAO; +import net.grandtheftmc.gtm.gang.member.GangRole; +import net.grandtheftmc.gtm.users.GTMRank; +import net.grandtheftmc.gtm.users.GTMUser; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; + +public class Gang { + +// private boolean hasUpdated; +// +// private int id; +// protected String name; +// +// protected String description = "Your default gang description!"; +// protected UUID leader; +// protected String leaderName; +// protected int maxMembers; +// protected List<GangMember> gangMembers = new ArrayList<>(); +// protected Map<Integer, Integer> relations = new HashMap<>(); +// protected Map<Integer, Integer> relationRequests = new HashMap<>(); +// +// public Gang(int id) { +// this.id = id; +// } +// +// public Gang(String name, UUID leader, String leaderName, int maxMembers) { +// this.name = name; +// this.leader = leader; +// this.leaderName = leaderName; +// this.maxMembers = maxMembers; +// } +// +// public String getName() { +// return this.name; +// } +// +// public void setName(String newName) { +//// Core.sql.updateAsyncLater("update " + Core.name() + "_gangs set name='" + name + "' where name='" + this.name + "';"); +//// Core.sql.updateAsyncLater("update " + Core.name() + " set gang='" + name + "' where gang='" + this.name + "';"); +//// Core.sql.updateAsyncLater("update " + Core.name() + "_gangs_relations set gang1='" + name + "' where gang1='" + this.name + "';"); +//// Core.sql.updateAsyncLater("update " + Core.name() + "_gangs_relations set gang2='" + name + "' where gang2='" + this.name + "';"); +// +// ServerUtil.runTaskAsync(() -> { +//// BaseDatabase.runCustomQuery("update " + Core.name() + "_gangs set name='" + name + "' where name='" + this.name + "';"); +//// BaseDatabase.runCustomQuery("update " + Core.name() + " set gang='" + name + "' where gang='" + this.name + "';"); +//// BaseDatabase.runCustomQuery("update " + Core.name() + "_gangs_relations set gang1='" + name + "' where gang1='" + this.name + "';"); +//// BaseDatabase.runCustomQuery("update " + Core.name() + "_gangs_relations set gang2='" + name + "' where gang2='" + this.name + "';"); +// +// // -- NEW -- +// try (Connection connection = BaseDatabase.getInstance().getConnection()) { +// GangDAO.setName(connection, newName, id); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// }); +// +// //Remove from hashmap +//// GTM.getGangManager().unloadGang(newName); +// +// for (Player p : Bukkit.getOnlinePlayers()) { +// if (this.isMember(p.getUniqueId()) || this.isLeader(p.getUniqueId())) { +// GTMUser user = GTM.getUserManager().getLoadedUser(p.getUniqueId()); +// user.setGang(newName); +// } +// } +// this.name = newName; +// +// //Associate new mapping +//// GTM.getGangManager().addLoadedGang(this); +// +// } +// +// public boolean updateDataFromDb() { +// if (this.hasUpdated) return true; +// boolean b = true; +// +// GangDAO +//// try (Connection connection = BaseDatabase.getInstance().getConnection()) { +//// try (PreparedStatement statement = connection.prepareStatement("select * from " + Core.name() + "_gangs where name=?;")) { +//// statement.setString(1, this.name); +//// try (ResultSet result = statement.executeQuery()) { +//// if (result.next()) { +//// this.description = result.getString("description"); +//// this.leader = UUID.fromString(result.getString("leader")); +//// this.leaderName = result.getString("leaderName"); +//// this.maxMembers = result.getInt("maxMembers"); +//// } +//// else { +//// b = false; +//// } +//// } +//// } +//// } catch (SQLException e) { +//// e.printStackTrace(); +//// } +// +// this.gangMembers = new ArrayList<>(); +// try (Connection connection = BaseDatabase.getInstance().getConnection()) { +// try (PreparedStatement statement = connection.prepareStatement("select uuid,name,gangRank from " + Core.name() + " where gang=?;")) { +// statement.setString(1, this.name); +// try (ResultSet result = statement.executeQuery()) { +// while (result.next()) { +// if (!Objects.equals("leader", result.getString("gangRank"))) { +// this.gangMembers.add(new GangMember(UUID.fromString(result.getString("uuid")), +// result.getString("name"), result.getString("gangRank"))); +// } +// } +// } +// } +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// +// this.relations = new HashMap<>(); +// this.relationRequests = new HashMap<>(); +// try (Connection connection = BaseDatabase.getInstance().getConnection()) { +// try (PreparedStatement statement = connection.prepareStatement("select * from " + Core.name() + "_gangs_relations where gang1=? or gang2=?;")) { +// statement.setString(1, this.name); +// statement.setString(2, this.name); +// try (ResultSet result = statement.executeQuery()) { +// while (result.next()) { +// String gang1 = result.getString("gang1"); +// String gang2 = result.getString("gang2"); +// this.relations.put(gang1.equalsIgnoreCase(this.name) ? gang2 : gang1, result.getString("relation")); +// } +// } +// } +// } catch (SQLException e) { +// e.printStackTrace(); +// b = false; +// } +// +// this.hasUpdated = b; +// return b; +// } +// +// public String getDescription() { +// return this.description; +// } +// +// public void setDescription(String s) { +// this.description = s; +//// Core.sql.updateAsyncLater("update " + Core.name() + "_gangs set description='" + s + "' where name='" + this.name + "';"); +// +//// ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + Core.name() + "_gangs set description='" + s + "' where name='" + this.name + "';")); +// ServerUtil.runTaskAsync(() -> { +// try (Connection connection = BaseDatabase.getInstance().getConnection()) { +// GangDAO.setDescription(connection, s, id); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// }); +// } +// +// public UUID getLeader() { +// return this.leader; +// } +// +// public void setLeader(UUID uuid) { +// this.leader = uuid; +// Player player = Bukkit.getPlayer(uuid); +// if (player != null) { +// GTMUser user = GTM.getUserManager().getLoadedUser(uuid); +// user.setGangRole("leader"); +// this.hasMaxMembers(player, Core.getUserManager().getLoadedUser(uuid), user); +// } +// +//// Core.sql.updateAsyncLater("update " + Core.name() + "_gangs set leader='" + uuid + "',maxMembers=" + this.maxMembers + " where name='" + this.name + "';"); +// +//// ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + Core.name() + "_gangs set leader='" + uuid + "',maxMembers=" + this.maxMembers + " where name='" + this.name + "';")); +// ServerUtil.runTaskAsync(() -> { +// try (Connection connection = BaseDatabase.getInstance().getConnection()) { +// GangDAO.setLeader(connection, uuid, id); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// }); +// } +// +// public boolean isLeader(UUID uuid) { +// return Objects.equals(uuid, this.leader); +// } +// +// public void setLeader(UUID uuid, String name) { +// this.leader = uuid; +// this.leaderName = name; +// Player player = Bukkit.getPlayer(uuid); +// if (player != null) { +// GTMUser user = GTM.getUserManager().getLoadedUser(uuid); +// user.setGangRole("leader"); +// this.hasMaxMembers(player, Core.getUserManager().getLoadedUser(uuid), user); +// } +// +//// Core.sql.updateAsyncLater("update " + Core.name() + "_gangs set leader='" + uuid + "',leaderName='" + name + "',maxMembers=" + this.maxMembers + " where name='" + this.name + "';"); +// +//// ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + Core.name() + "_gangs set leader='" + uuid + "',leaderName='" + name + "',maxMembers=" + this.maxMembers + " where name='" + this.name + "';")); +// ServerUtil.runTaskAsync(() -> { +// try (Connection connection = BaseDatabase.getInstance().getConnection()) { +// GangDAO.setLeader(connection, uuid, id); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// }); +// } +// +// public String getLeaderName() { +// return this.leaderName; +// } +// +// public void setLeaderName(String name) { +// this.leaderName = name; +//// Core.sql.updateAsyncLater("update " + Core.name() + "_gangs set leaderName='" + name + "' where name='" + this.name + "';"); +// ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + Core.name() + "_gangs set leaderName='" + name + "' where name='" + this.name + "';")); +// } +// +// public boolean isLeader(String name) { +// return this.leaderName.equalsIgnoreCase(name); +// } +// +// public int getMaxMembers() { +// Player player = Bukkit.getPlayer(this.leader); +// if (player == null) +// return this.maxMembers; +// return GTM.getUserManager().getLoadedUser(this.leader).getMaxGangMembers(player, +// Core.getUserManager().getLoadedUser(this.leader)); +// } +// +// public boolean hasMaxMembers() { +// Player player = Bukkit.getPlayer(this.leader); +// if (player == null) +// return this.maxMembers <= this.gangMembers.size(); +// return this.hasMaxMembers(player, Core.getUserManager().getLoadedUser(this.leader), +// GTM.getUserManager().getLoadedUser(this.leader)); +// } +// +// public boolean hasMaxMembers(Player leader, User user, GTMUser gtmUser) { +// this.maxMembers = gtmUser.getMaxGangMembers(leader, user); +// return this.maxMembers <= this.gangMembers.size(); +// } +// +// public void updateMaxMembers(Player leader, User user, GTMUser gtmUser) { +// this.maxMembers = gtmUser.getMaxGangMembers(leader, user); +//// Core.sql.updateAsyncLater("update " + Core.name() + "_gangs set maxMembers=" + this.maxMembers + " where name='" + this.name + "';"); +// ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + Core.name() + "_gangs set maxMembers=" + this.maxMembers + " where name='" + this.name + "';")); +// } +// +// public List<GangMember> getGangMembers() { +// return this.gangMembers; +// } +// +// public int getOnlineMembers() { +// return (int) Bukkit.getOnlinePlayers().stream().filter(player -> this.isMember(player.getUniqueId()) || this.isLeader(player.getUniqueId())).count(); +// } +// +// public GangMember getMember(UUID uuid) { +// return this.gangMembers.stream().filter(m -> Objects.equals(m.getUUID(), uuid)).findFirst().orElse(null); +// } +// +// public GangMember getMember(String name) { +// return this.gangMembers.stream().filter(m -> Objects.equals(m.getName(), name)).findFirst().orElse(null); +// } +// +// public boolean isMember(UUID uuid) { +// return this.getMember(uuid) != null; +// } +// +// public boolean isMember(String name) { +// return this.getMember(name) != null; +// } +// +// public boolean isColeader(UUID uuid) { +// GangMember m = this.getMember(uuid); +// return m != null && m.isColeader(); +// } +// +// public Map<String, String> getRelations() { +// return this.relations; +// } +// +// public String getRelation(String name) { +// return this.relations.get(name); +// } +// +// public boolean hasRelation(String name) { +// return this.getRelation(name) != null; +// } +// +// public boolean isAllied(String name) { +// String rel = this.getRelation(name); +// return Objects.equals("ally", rel); +// } +// +// public boolean isEnemy(String name) { +// String rel = this.getRelation(name); +// return Objects.equals("enemy", rel); +// } +// +// public boolean isNeutral(String name) { +// String rel = this.getRelation(name); +// return rel == null; +// } +// +// public void addRelation(String name, String relation) { +// this.relations.put(name, relation); +// } +// +// public void removeRelation(String name) { +// this.relations.remove(name); +// } +// +// public void addRelationRequest(String name, String relation) { +// this.relationRequests.put(name, relation); +// } +// +// public void unload(UUID uuid) { +// if (!Objects.equals(this.leader, uuid) && Bukkit.getPlayer(this.leader) != null) return; +// for (GangMember member : this.gangMembers) { +// if (!Objects.equals(member.getUUID(), uuid) && Bukkit.getPlayer(member.getUUID()) != null) +// return; +// } +// GTM.getGangManager().unloadGang(this.name); +// +// } +// +// public void disband(Player sender) { +// if (!this.isLeader(sender.getUniqueId())) { +// sender.sendMessage(Lang.GANGS.f("&7You are not the leader of this gang!")); +// return; +// } +// sender.sendMessage(Lang.GANGS.f( +// "&7Are you sure you want to disband this gang? It will remove all members and delete it forever. Type \"&a/gang disband confirm\"&7 to disband your gang!")); +// } +// +// public void disbandConfirm(Player sender, User user, GTMUser gtmUser) { +// if (!this.isLeader(sender.getUniqueId())) { +// sender.sendMessage(Lang.GANGS.f("&7You are not the leader of this gang!")); +// return; +// } +// +//// Core.sql.updateAsyncLater("delete from " + Core.name() + "_gangs where name='" + this.name + "';"); +//// Core.sql.updateAsyncLater("delete from " + Core.name() + "_gangs_relations where gang1='" + this.name + "' or gang2='" + this.name + "';"); +//// Core.sql.updateAsyncLater("update " + Core.name() + " set gang=null,gangRank='member' where gang='" + this.name + "';"); +// ServerUtil.runTaskAsync(() -> { +// BaseDatabase.runCustomQuery("delete from " + Core.name() + "_gangs where name='" + this.name + "';"); +// BaseDatabase.runCustomQuery("delete from " + Core.name() + "_gangs_relations where gang1='" + this.name + "' or gang2='" + this.name + "';"); +// BaseDatabase.runCustomQuery("update " + Core.name() + " set gang=null,gangRank='member' where gang='" + this.name + "';"); +// }); +// +// sender.sendMessage(Lang.GANGS.f("&7You disbanded the gang &a" + this.name + "&7!")); +// gtmUser.setGangName(null); +// for (Player player : Bukkit.getOnlinePlayers()) +// if (this.isMember(player.getUniqueId())) { +// GTMUser u = GTM.getUserManager().getLoadedUser(player.getUniqueId()); +// u.setGangName(null); +// player.sendMessage( +// Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 disbanded your gang &a" + this.name + "&7!")); +// } else if (!this.isLeader(player.getUniqueId())) +// player.sendMessage( +// Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 disbanded the gang &a" + this.name + "&7!")); +// this.relations.keySet().stream().filter(gang -> GTM.getGangManager().isLoaded(gang)).forEach(gang -> GTM.getGangManager().getLoadedGang(gang).removeRelation(this.name)); +// GTM.getGangManager().unloadGang(this.name); +// } +// +// public void setLeader(Player sender, User user, GTMUser gtmUser, Player target) { +// if (!this.isLeader(sender.getUniqueId())) { +// sender.sendMessage(Lang.GANGS.f("&7You are not the leader of this gang!")); +// return; +// } +// +// if (target == null) { +// sender.sendMessage(Lang.GANGS.f("&7That player is not online!")); +// return; +// } +// +// if (!this.isMember(target.getUniqueId())) { +// sender.sendMessage(Lang.GANGS.f("&7That player is not a member of this gang!")); +// return; +// } +// +// User targetUser = Core.getUserManager().getLoadedUser(target.getUniqueId()); +// GTMUser targetGtmUser = GTM.getUserManager().getLoadedUser(target.getUniqueId()); +// if (!targetGtmUser.canLeadGang(targetUser)) { +// sender.sendMessage(Lang.GANGS.f("&7You must be a &e&l" + GTMRank.GANGSTER.getColoredNameBold() + "&7 to create a gang! Check the &d&lMy Account&7 -> &a&lRanks&7 menu on your phone for more information.")); +// return; +// } +// +// targetGtmUser.setGang(this.name, "leader"); +// gtmUser.setGangRole("coleader"); +// this.setLeader(target.getUniqueId(), target.getName()); +// this.gangMembers.stream().filter(member -> Objects.equals(member.getUUID(), target.getUniqueId())).findFirst().ifPresent(member -> this.gangMembers.remove(member)); +// sender.sendMessage(Lang.GANGS.f("&7You promoted " + targetUser.getColoredName(target) + "&7 to the leader of your gang! You are now a co-leader!")); +// target.sendMessage(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 promoted you to leader of your gang!")); +// Bukkit.getOnlinePlayers().stream().filter(player -> this.isMember(player.getUniqueId())).forEach(player -> player.sendMessage(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 promoted " +// + targetUser.getColoredName(target) + "&7 to the leader of your gang!"))); +// this.gangMembers.add(new GangMember(sender.getUniqueId(), sender.getName(), "coleader")); +// } +// +// public void promote(Player sender, User user, GTMUser gtmUser, String targetName) { +// if (!this.isLeader(sender.getUniqueId())) { +// sender.sendMessage(Lang.GANGS.f("&7You are not the leader of this gang!")); +// return; +// } +// GangMember member = this.getMember(targetName); +// if (member == null) { +// sender.sendMessage(Lang.GANGS.f("&7That player is not a member of this gang!")); +// return; +// } +// if (member.isColeader()) { +// sender.sendMessage(Lang.GANGS.f("&7That player is already a coleader of this gang!")); +// return; +// } +// Player target = Bukkit.getPlayer(member.getUUID()); +// String n = member.getName(); +// if (target == null) { +//// Core.sql.updateAsyncLater("update " + Core.name() + " set gangRank='coleader' where gang='" + this.name + "' and uuid='" + member.getUUID() + "';"); +// ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + Core.name() + " set gangRank='coleader' where gang='" + this.name + "' and uuid='" + member.getUUID() + "';")); +// } +// else { +// User targetUser = Core.getUserManager().getLoadedUser(target.getUniqueId()); +// GTMUser targetGtmUser = GTM.getUserManager().getLoadedUser(target.getUniqueId()); +// n = targetUser.getColoredName(target); +// targetGtmUser.setGangRole("coleader"); +// target.sendMessage(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 promoted you to coleader of your gang!")); +// } +// member.setRank(GangRole.CO_LEADER); +// for (Player player : Bukkit.getOnlinePlayers()) +// if (this.isMember(player.getUniqueId()) && !Objects.equals(player, target) && !Objects.equals(player, sender)) +// player.sendMessage(Lang.GANGS +// .f("&7" + user.getColoredName(sender) + "&7 promoted " + n + "&7 to coleader of your gang!")); +// sender.sendMessage(Lang.GANGS.f("&7You promoted " + n + "&7 to coleader of your gang!")); +// } +// +// public void demote(Player sender, User user, GTMUser gtmUser, String targetName) { +// if (!this.isLeader(sender.getUniqueId())) { +// sender.sendMessage(Lang.GANGS.f("&7You are not the leader of this gang!")); +// return; +// } +// GangMember member = this.getMember(targetName); +// if (member == null) { +// sender.sendMessage(Lang.GANGS.f("&7That player is not a member of this gang!")); +// return; +// } +// if (!member.isColeader()) { +// sender.sendMessage(Lang.GANGS.f("&7That player is not a coleader of this gang!")); +// return; +// } +// Player target = Bukkit.getPlayer(member.getUUID()); +// String n = member.getName(); +// if (target == null) { +//// Core.sql.updateAsyncLater("update " + Core.name() + " set gangRank='member' where gang='" + this.name + "' and uuid='" + member.getUUID() + "';"); +// ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + Core.name() + " set gangRank='member' where gang='" + this.name + "' and uuid='" + member.getUUID() + "';")); +// } +// else { +// User targetUser = Core.getUserManager().getLoadedUser(target.getUniqueId()); +// GTMUser targetGtmUser = GTM.getUserManager().getLoadedUser(target.getUniqueId()); +// n = targetUser.getColoredName(target); +// targetGtmUser.setGangRole("member"); +// target.sendMessage( +// Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 demoted you to member of your gang!")); +// } +// member.setRank(GangRole.MEMBER); +// for (Player player : Bukkit.getOnlinePlayers()) +// if (this.isMember(player.getUniqueId()) && !Objects.equals(player, target) && !Objects.equals(player, sender)) +// player.sendMessage(Lang.GANGS +// .f("&7" + user.getColoredName(sender) + "&7 demoted " + n + "&7 to member of your gang!")); +// sender.sendMessage(Lang.GANGS.f("&7You demoted " + n + "&7 to member of your gang!")); +// +// } +// +// public void ally(Player sender, User user, GTMUser gtmUser, String gang) { +// if (!this.isLeader(sender.getUniqueId()) && !this.isColeader(sender.getUniqueId())) { +// sender.sendMessage(Lang.GANGS.f("&7You are not the (co-)leader of this gang!")); +// return; +// } +// Gang g = GTM.getGangManager().getLoadedGang(gang); +// if (g == null) { +// sender.sendMessage(Lang.GANGS.f("&7That gang does not exist or no one in that gang is online!")); +// return; +// } +// if (this.isAllied(g.name)) { +// sender.sendMessage(Lang.GANGS.f("&7That gang is allied to you already!")); +// sender.sendMessage(Lang.GANGS.f("&7Want to unally this gang? Use /g neutral")); +// return; +// } +// if (this.relationRequests.containsKey(g.name) && Objects.equals("ally", this.relationRequests.get(g.name))) { +// this.relations.put(g.name, "ally"); +// g.addRelation(this.name, "ally"); +// this.relationRequests.remove(g.name); +// +//// Core.sql.updateAsyncLater("delete from " + Core.name() + "_gangs_relations where (gang1='" + this.name + "' and gang2='" + g.name + "') or (gang1='" + g.name + "' and gang2='" + this.name + "');"); +//// Core.sql.updateAsyncLater("insert into " + Core.name() + "_gangs_relations(gang1,gang2,relation) values('" + this.name + "','" + g.name + "','ally');"); +// ServerUtil.runTaskAsync(() -> { +// BaseDatabase.runCustomQuery("delete from " + Core.name() + "_gangs_relations where (gang1='" + this.name + "' and gang2='" + g.name + "') or (gang1='" + g.name + "' and gang2='" + this.name + "');"); +// BaseDatabase.runCustomQuery("insert into " + Core.name() + "_gangs_relations(gang1,gang2,relation) values('" + this.name + "','" + g.name + "','ally');"); +// }); +// +// for (Player player : Bukkit.getOnlinePlayers()) +// if (g.isMember(player.getUniqueId()) || g.isLeader(player.getUniqueId())) +// player.sendMessage(Lang.GANGS.f("&7Your gang is now allied to &a" + this.name + "&7!")); +// else if (this.isMember(player.getUniqueId()) || this.isLeader(player.getUniqueId()) && !Objects.equals(player, sender)) { +// player.sendMessage(Lang.GANGS.f("&7Your gang is now allied to &a" + g.name + "&7!")); +// } +// sender.sendMessage(Lang.GANGS.f("&7You accepted the ally request from gang &a" + g.name + "&7!")); +// } +// g.addRelationRequest(this.name, "ally"); +// for (Player player : Bukkit.getOnlinePlayers()) +// if (g.isMember(player.getUniqueId()) || g.isLeader(player.getUniqueId())) +// player.sendMessage(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 from gang &a" + this.name +// + "&7 has requested to be allied to your gang!")); +// else if (this.isMember(player.getUniqueId()) || this.isLeader(player.getUniqueId()) && !Objects.equals(player, sender)) { +// player.sendMessage(Lang.GANGS.f("&7" + user.getColoredName(sender) +// + "&7 has requested to be allied to &a" + g.name + "&7!")); +// } +// sender.sendMessage(Lang.GANGS.f("&7You sent an ally request to gang &a" + g.name + "&7!")); +// } +// +// public void neutral(Player sender, User user, GTMUser gtmUser, String gang) { +// if (!this.isLeader(sender.getUniqueId()) && !this.isColeader(sender.getUniqueId())) { +// sender.sendMessage(Lang.GANGS.f("&7You are not the leader of this gang!")); +// return; +// } +// Gang g = GTM.getGangManager().getLoadedGang(gang); +// if (g == null) { +// sender.sendMessage(Lang.GANGS.f("&7That gang does not exist or no one in that gang is online!")); +// return; +// } +// if (this.isNeutral(g.name)) { +// sender.sendMessage(Lang.GANGS.f("&7That gang is neutral to you already!")); +// return; +// } +// if (this.relationRequests.containsKey(g.name) && Objects.equals("neutral", this.relationRequests.get(g.name))) { +// this.relations.put(g.name, "neutral"); +// g.addRelation(this.name, "neutral"); +// this.relationRequests.remove(g.name); +// +//// Core.sql.updateAsyncLater("delete from " + Core.name() + "_gangs_relations where (gang1='" + this.name + "' and gang2='" + g.name + "') or (gang1='" + g.name + "' and gang2='" + this.name + "');"); +// ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("delete from " + Core.name() + "_gangs_relations where (gang1='" + this.name + "' and gang2='" + g.name + "') or (gang1='" + g.name + "' and gang2='" + this.name + "');")); +// +// for (Player player : Bukkit.getOnlinePlayers()) +// if (g.isMember(player.getUniqueId()) || g.isLeader(player.getUniqueId())) +// player.sendMessage(Lang.GANGS.f("&7Your gang is now neutral to &a" + this.name + "&7!")); +// else if (this.isMember(player.getUniqueId()) || this.isLeader(player.getUniqueId()) && !Objects.equals(player, sender)) +// player.sendMessage(Lang.GANGS.f("&7Your gang is now neutral to &a" + g.name + "&7!")); +// sender.sendMessage(Lang.GANGS.f("&7You accepted the neutral request from gang &a" + g.name + "&7!")); +// } +// g.addRelationRequest(this.name, "neutral"); +// for (Player player : Bukkit.getOnlinePlayers()) +// if (g.isMember(player.getUniqueId()) || g.isLeader(player.getUniqueId())) +// player.sendMessage(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 from gang &a" + this.name +// + "&7 has requested to be neutral to your gang!")); +// else if (this.isMember(player.getUniqueId()) || this.isLeader(player.getUniqueId()) && !Objects.equals(player, sender)) +// player.sendMessage(Lang.GANGS.f("&7" + user.getColoredName(sender) +// + "&7 has requested to be neutral to &a" + g.name + "&7!")); +// sender.sendMessage(Lang.GANGS.f("&7You sent a neutral request to gang &a" + g.name + "&7!")); +// } +// +// public void enemy(Player sender, User user, GTMUser gtmUser, String gang) { +// if (!this.isLeader(sender.getUniqueId()) && !this.isColeader(sender.getUniqueId())) { +// sender.sendMessage(Lang.GANGS.f("&7You are not the leader of this gang!")); +// return; +// } +// Gang g = GTM.getGangManager().getLoadedGang(gang); +// if (g == null) { +// sender.sendMessage(Lang.GANGS.f("&7That gang does not exist or no one in that gang is online!")); +// return; +// } +// if (this.isEnemy(g.name)) { +// sender.sendMessage(Lang.GANGS.f("&7That gang is an enemy to you already!")); +// sender.sendMessage(Lang.GANGS.f("&7Want to unenemy this gang? Use /g neutral")); +// return; +// } +// this.relations.put(g.name, "enemy"); +// g.addRelation(this.name, "enemy"); +// this.relationRequests.remove(g.name); +// +//// Core.sql.updateAsyncLater("delete from " + Core.name() + "_gangs_relations where (gang1='" + this.name + "' and gang2='" + g.name + "') or (gang1='" + g.name + "' and gang2='" + this.name + "');"); +//// Core.sql.updateAsyncLater("insert into " + Core.name() + "_gangs_relations(gang1,gang2,relation) values('" + this.name + "','" + g.name + "','enemy');"); +// ServerUtil.runTaskAsync(() -> { +// BaseDatabase.runCustomQuery("delete from " + Core.name() + "_gangs_relations where (gang1='" + this.name + "' and gang2='" + g.name + "') or (gang1='" + g.name + "' and gang2='" + this.name + "');"); +// BaseDatabase.runCustomQuery("insert into " + Core.name() + "_gangs_relations(gang1,gang2,relation) values('" + this.name + "','" + g.name + "','enemy');"); +// }); +// +// for (Player player : Bukkit.getOnlinePlayers()) +// if (g.isMember(player.getUniqueId()) || g.isLeader(player.getUniqueId())) +// player.sendMessage(Lang.GANGS.f("&7Your gang is now an enemy to gang &a" + this.name + "&7!")); +// else if (this.isMember(player.getUniqueId()) || this.isLeader(player.getUniqueId())) +// player.sendMessage(Lang.GANGS.f("&7Your gang is now an enemy to gang &a" + g.name + "&7!")); +// } +// +// public void invite(Player sender, User user, GTMUser gtmUser, Player target) { +// if (!this.isLeader(sender.getUniqueId()) && !this.isColeader(sender.getUniqueId())) { +// sender.sendMessage(Lang.GANGS.f("&7You are not the leader of this gang!")); +// return; +// } +// if (target == null) { +// sender.sendMessage(Lang.GANGS.f("&7That player is not online!")); +// return; +// } +// if (Objects.equals(sender, target)) { +// sender.sendMessage(Lang.GANGS.f("&7You can't invite yourself!")); +// return; +// } +// if (this.isMember(target.getUniqueId())) { +// sender.sendMessage(Lang.GANGS.f("&7That player is already in your gang!")); +// return; +// } +// if (this.hasMaxMembers()) { +// sender.sendMessage(Lang.GANGS.f( +// "&7Your gang is full! Rank up or buy a rank at &astore.grandtheftmc.net&7 for more gang members!")); +// return; +// } +// User targetUser = Core.getUserManager().getLoadedUser(target.getUniqueId()); +// GTMUser targetGtmUser = GTM.getUserManager().getLoadedUser(target.getUniqueId()); +// if (!targetGtmUser.canJoinGang(targetUser)) { +// sender.sendMessage(Lang.GANGS.f("&7That player can not join a gang because he is not a &e&lHOMIE&7 yet!")); +// target.sendMessage(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 tried to invite you to gang &a" + this.name + "&7, but you need to be &a &e&lHOMIE&7 or &6&lVIP&7 to join a gang!")); +// return; +// } +// targetGtmUser.addGangInvite(this.name); +// sender.sendMessage(Lang.GANGS.f("&7You invited " + targetUser.getColoredName(target) + "&7 to your gang!")); +// target.sendMessage(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 invited you to gang &a" + this.name +// + "&7! Use &a\"/g join " + this.name + "\"&7 to join the gang!")); +// this.sendToAllExcept(sender, Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 invited " +// + targetUser.getColoredName(target) + "&7 to your gang!")); +// } +// +// public void accept(Player sender, User user, GTMUser gtmUser) { +// if (!gtmUser.canJoinGang(user)) { +// sender.sendMessage(Lang.GANGS.f("You must be " + GTMRank.HOMIE.getColoredNameBold() + "&7 or &6&lVIP&7 to join a gang! Check the &d&lMy Account&7 -> &a&lRanks&7 menu on your phone for more information.")); +// return; +// } +// if (this.isMember(sender.getUniqueId()) || this.isLeader(sender.getUniqueId())) { +// sender.sendMessage(Lang.GANGS.f("&7You are a member of this gang already!")); +// return; +// } +// if (!gtmUser.isInvited(this.name)) { +// sender.sendMessage(Lang.GANGS.f("&7You have not been invited to this gang!")); +// return; +// } +// if (this.hasMaxMembers()) { +// sender.sendMessage(Lang.GANGS.f("&7This gang is full!")); +// return; +// } +// sender.sendMessage(Lang.GANGS.f("&7You joined the gang &a" + this.name + "&7!")); +// gtmUser.setGang(this.name); +// gtmUser.removeGangInvite(this.name); +// this.sendToAll(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 joined your gang!")); +// this.gangMembers.add(new GangMember(sender.getUniqueId(), sender.getName(), "member")); +// } +// +// public void kick(Player sender, User user, GTMUser gtmUser, String target) { +// if (!this.isLeader(sender.getUniqueId()) && !this.isColeader(sender.getUniqueId())) { +// sender.sendMessage(Lang.GANGS.f("&7You are not the leader of this gang!")); +// return; +// } +// if (sender.getName().equalsIgnoreCase(target)) { +// sender.sendMessage(Lang.GANGS.f("&7You can't kick yourself!")); +// return; +// } +// if (!this.isMember(target)) { +// sender.sendMessage(Lang.GANGS.f("&7That player is not in your gang!")); +// return; +// } +// GangMember member = this.getMember(target); +// this.gangMembers.remove(member); +// Player player = Bukkit.getPlayer(target); +// String name = target; +// if (player == null) { +//// Core.sql.updateAsyncLater("update " + Core.name() + " set gang=null, gangRank='member' where name='" + name + "';"); +// String finalName = name; +// ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + Core.name() + " set gang=null, gangRank='member' where name='" + finalName + "';")); +// } +// else { +// name = Core.getUserManager().getLoadedUser(player.getUniqueId()).getColoredName(player); +// GTMUser targetGtmUser = GTM.getUserManager().getLoadedUser(player.getUniqueId()); +// targetGtmUser.resetGang(); +// player.sendMessage(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 kicked you from the gang!")); +// } +// this.sendToAllExcept(sender, Lang.GANGS +// .f("&7" + user.getColoredName(sender) + "&7 kicked &a" + name + "&7 from your gang!")); +// sender.sendMessage(Lang.GANGS.f("&7You kicked &a" + name + "&7 from the gang!")); +// } +// +// public void leave(Player sender, User user, GTMUser gtmUser) { +// if (this.isLeader(sender.getUniqueId())) { +// sender.sendMessage(Lang.GANGS.f( +// "&7You are the leader of your gang! Please use &a\"/f leader <player\"&7 before leaving the gang!")); +// return; +// } +// if (!this.isMember(sender.getUniqueId())) { +// sender.sendMessage(Lang.GANGS.f("&7You are not a member of this gang!")); +// return; +// } +// GangMember member = this.getMember(sender.getUniqueId()); +// this.gangMembers.remove(member); +// gtmUser.resetGang(); +// sender.sendMessage(Lang.GANGS.f("&7You left the gang &a" + this.name + "&7!")); +// this.sendToAll(Lang.GANGS.f("&7" + user.getColoredName(sender) + "&7 left the gang!")); +// } +// +// public void info(Player sender, User user, GTMUser gtmUser) { +// sender.sendMessage(Utils.f(" &7&m---------------&7[&a&l " + this.name + " &7]&m---------------")); +// sender.sendMessage(Utils.f("&a&lDescription: &7" + this.description)); +// int allies = 0; +// int enemies = 0; +// String a = ""; +// String e = ""; +// for (Map.Entry<String, String> entry : this.relations.entrySet()) { +// String r = entry.getValue(); +// if (Objects.equals("ally", r)) { +// a = a + (allies > 0 ? "&7, " : "") + "&a" + entry.getKey(); +// allies++; +// } else if (Objects.equals("enemy", r)) { +// e = e + (enemies > 0 ? "&c, " : "") + "&c" + entry.getKey(); +// enemies++; +// } +// } +// int online = 0; +// int offline = 0; +// String on = ""; +// String off = ""; +// Player leader = Bukkit.getPlayer(this.leader); +// if (leader != null) { +// User u = Core.getUserManager().getLoadedUser(leader.getUniqueId()); +// on = on + (online > 0 ? "&7, " : "") + "&aLeader " + u.getColoredName(leader); +// online++; +// } +// for (GangMember member : this.gangMembers) { +// Player player = Bukkit.getPlayer(member.getUUID()); +// if (player == null) { +// off = off + (offline > 0 ? "&7, " : "") + "&a" + (member.isColeader() ? "Coleader" : "") + +// member.getName(); +// offline++; +// } else { +// User u = Core.getUserManager().getLoadedUser(member.getUUID()); +// on = on + (online > 0 ? "&7, " : "") + "&a" + (member.isColeader() ? "Coleader" : "") + +// (u.isSpecial() ? u.getColoredName(player) : player.getName()); +// online++; +// } +// } +// if (allies > 0) +// sender.sendMessage(Utils.f("&a&lAllies&7(&a" + allies + "&7)&a: &7" + a)); +// if (enemies > 0) +// sender.sendMessage(Utils.f("&c&lEnemies&7(&c" + enemies + "&7)&c: &7" + e)); +// sender.sendMessage(Utils.f("&a&lOnline Members&7(&a" + online + "&7)&a: &7" + on)); +// sender.sendMessage(Utils.f("&a&lOffline Members&7(&a" + offline + "&7)&a: &7" + off)); +// } +// +// public String list(Player sender, Gang gang) { +// int online = (int) this.gangMembers.stream().filter(member -> Bukkit.getPlayer(member.getUUID()) != null).count(); +// int total = this.gangMembers.size(); +// return (this.isAllied(gang.name) || this.equals(gang) ? "&a" : this.isEnemy(gang.name) ? "&c" : "&7") + "&l" + this.name + ": " + online + "&7/&a" + total + "&7 players online"; +// } +// +// public boolean hasUpdated() { +// return this.hasUpdated; +// } +// +// public void name(Player sender, User user, GTMUser gtmUser, String gangName) { +// UUID uuid = sender.getUniqueId(); +// if (!this.isLeader(sender.getUniqueId())) { +// sender.sendMessage(Lang.GANGS.f("&7You are not the leader of this gang!")); +// return; +// } +// if (!gangName.matches("^[a-zA-Z_0-9]+$")) { +// sender.sendMessage(Lang.GANGS.f("&7Only a-z, A-Z, 0-9 and _ are allowed in a gang name!")); +// return; +// } +// if (gangName.length() > 16 || gangName.length() < 3) { +// sender.sendMessage(Lang.GANGS.f("&7The name of your gang needs to be 3-16 characters long!")); +// return; +// } +// if (GTM.getGangManager().isLoaded(gangName)) { +// sender.sendMessage(Lang.GANGS.f("&7A gang with that name already exists!")); +// return; +// } +// new BukkitRunnable() { +// @Override +// public void run() { +// String s = null; +//// try { +//// ResultSet rs = Core.sql +//// .query("select name from " + Core.name() + "_gangs where name='" + gangName + "';"); +//// if (rs.next()) +//// s = rs.getString("name"); +//// rs.close(); +//// } catch (SQLException e) { +//// e.printStackTrace(); +//// return; +//// } +// try (Connection connection = BaseDatabase.getInstance().getConnection()) { +// try (PreparedStatement statement = connection.prepareStatement("select name from " + Core.name() + "_gangs where name='" + gangName + "';")) { +// try (ResultSet result = statement.executeQuery()) { +// if (result.next()) s = result.getString("name"); +// } +// } +// } catch (SQLException e) { +// e.printStackTrace(); +// return; +// } +// +// String name = s; +// new BukkitRunnable() { +// @Override +// public void run() { +// Player sender = Bukkit.getPlayer(uuid); +// if (sender == null) +// return; +// if (name != null) { +// sender.sendMessage(Lang.GANGS.f("&7A gang with that name already exists!")); +// return; +// } +// User user = Core.getUserManager().getLoadedUser(uuid); +// GTMUser gtmUser = GTM.getUserManager().getLoadedUser(uuid); +// Gang gang = gtmUser.getGang(); +// gang.setName(gangName); +// sender.sendMessage( +// Lang.GANGS.f("&7You changed the name of your gang to &a" + gangName + "&7!")); +// Gang.this.sendToAllExcept(sender, Lang.GANGS.f("&7" + user.getColoredName(sender) +// + "&7 changed the name of your gang to &a" + gangName + "&7!")); +// } +// }.runTask(GTM.getInstance()); +// } +// }.runTaskAsynchronously(GTM.getInstance()); +// } +// +// public void description(Player sender, User user, GTMUser gtmUser, String description) { +// if (!this.isLeader(sender.getUniqueId()) && !this.isColeader(sender.getUniqueId())) { +// sender.sendMessage(Lang.GANGS.f("&7You are not the (co-)leader of this gang!")); +// return; +// } +// if (description.length() > 64 || description.length() < 3) { +// sender.sendMessage(Lang.GANGS.f("&7The description must be between 3-64 characters long!")); +// return; +// } +// this.setDescription(description); +// sender.sendMessage(Lang.GANGS.f("&7You changed the description of your gang to &a" + description + "&7!")); +// this.sendToAllExcept(sender, Lang.GANGS.f("&7" + user.getColoredName(sender) +// + "&7 changed the description of your gang to &a" + description + "&7!")); +// } +// +// public void chat(Player player, User user, GTMUser gtmUser, String msg) { +// Bukkit.getOnlinePlayers().stream().filter(p -> this.isMember(p.getUniqueId()) || this.isLeader(p.getUniqueId())).forEach(p -> p.sendMessage(Lang.GANGCHAT.f("&7[&a&l" + user.getColoredName(player) + "&7] &r") + Utils.fColor(msg))); +// Core.getUserManager().getLoadedUsers().stream().filter(u -> (Boolean)u.getPref(Pref.SOCIALSPY)).forEach(u -> { +// if(u != null && u.getUUID() != null) { +// Player p = Bukkit.getPlayer(u.getUUID()); +// if(p != null) p.sendMessage(Lang.SS.f("&r" + player.getName() + ": /gc " + msg)); +// } +// }); +// } +// +// public void sendToAll(String msg) { +// Bukkit.getOnlinePlayers().stream().filter(p -> this.isMember(p.getUniqueId()) || this.isLeader(p.getUniqueId())).forEach(p -> p.sendMessage(Utils.f(msg))); +// } +// +// public void sendToAllExcept(Player player, String msg) { +// Bukkit.getOnlinePlayers().stream().filter(p -> (this.isMember(p.getUniqueId()) || this.isLeader(p.getUniqueId())) && !Objects.equals(p, player)).forEach(p -> p.sendMessage(Utils.f(msg))); +// } +// +// public int getUniqueId() { +// return this.id; +// } +// +// protected void setUniqueId(int identifier) { +// this.id = identifier; +// } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gangs/GangManager.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gangs/GangManager.java new file mode 100644 index 0000000..7fc4a92 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gangs/GangManager.java @@ -0,0 +1,71 @@ +package net.grandtheftmc.gtm.gangs; + +public class GangManager { +// private final Map<Integer, Gang> mappedGangs = new HashMap<>(); +// +// public static Map<Gang, Integer> sort(Map<Gang, Integer> unsortMap) { +// List<Map.Entry<Gang, Integer>> list = new LinkedList<>(unsortMap.entrySet()); +// list.sort(Comparator.comparing(Map.Entry::getValue)); +// Map<Gang, Integer> sortedMap = new LinkedHashMap<>(); +// for (Map.Entry<Gang, Integer> entry : list) { +// sortedMap.put(entry.getKey(), entry.getValue()); +// } +// return sortedMap; +// } +// +// public Collection<Gang> getLoadedGangs() { +// return mappedGangs.values(); +// } +// +// public boolean unloadGang(int id) { +// return mappedGangs.remove(id) != null; +// } +// +// public boolean isLoaded(int id) { +// return mappedGangs.containsKey(id); +// } +// +// public Gang getAlreadyLoadedGang(int id) { +// return mappedGangs.get(id); +// } +// +// public Gang getLoadedGang(int id) { +// Gang gang = mappedGangs.get(id); +// +// if (gang == null) { +// gang = new Gang(id); +// mappedGangs.put(id, gang); +// } +// +// return gang; +// } +// +// public void addLoadedGang(Gang gang) { +// mappedGangs.put(gang.getUniqueId(), gang); +// } +// +// public Set<Gang> getGangsByOnlineMembers() { +// Map<Gang, Integer> unsortMap = new HashMap<>(); +// for (Gang g : this.getLoadedGangs()) { +// unsortMap.put(g, g.getOnlineMembers()); +// } +// return sort(unsortMap).keySet(); +// } +// +// public boolean isValid(String gangName) { +// boolean b = false; +// +// try (Connection connection = BaseDatabase.getInstance().getConnection()) { +// try (PreparedStatement statement = connection.prepareStatement("select * from " + Core.name() + "_gangs where name='" + gangName + "';")) { +// try (ResultSet result = statement.executeQuery()) { +// b = result.next(); +// } +// } +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// +// return b; +// } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gangs/GangMember.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gangs/GangMember.java new file mode 100644 index 0000000..72c4679 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/gangs/GangMember.java @@ -0,0 +1,53 @@ +package net.grandtheftmc.gtm.gangs; + +import net.grandtheftmc.gtm.gang.member.GangRole; +import org.bukkit.Bukkit; + +import java.util.UUID; + +public class GangMember { + + private final UUID uuid; + private final String name; + private GangRole rank; + + public GangMember(UUID uuid, String name, GangRole rank) { + this.uuid = uuid; + this.name = name; + this.rank = rank; + } + + public UUID getUUID() { + return this.uuid; + } + + public String getName() { + return this.name; + } + + public GangRole getRank() { + return this.rank; + } + + public void setRank(GangRole rank) { + this.rank = rank; + } + + public boolean isColeader() { +// return Objects.equals("coleader", this.rank); + return this.rank == GangRole.CO_LEADER; + } + + public boolean isMember() { +// return Objects.equals("member", this.rank); + return this.rank == GangRole.MEMBER; + } + + public String getFormattedRank() { + return rank.getFormattedTag(); + } + + public boolean isOnline() { + return Bukkit.getPlayer(this.uuid) != null; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/Holiday.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/Holiday.java new file mode 100644 index 0000000..28ae51d --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/Holiday.java @@ -0,0 +1,6 @@ +package net.grandtheftmc.gtm.holidays; + +public abstract class Holiday { + + public abstract boolean isActive(); +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/HolidayManager.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/HolidayManager.java new file mode 100644 index 0000000..4e23f9e --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/HolidayManager.java @@ -0,0 +1,24 @@ +package net.grandtheftmc.gtm.holidays; + +import net.grandtheftmc.gtm.holidays.easter.Easter; +import net.grandtheftmc.gtm.holidays.independenceday.IndependenceDay; + +public class HolidayManager { + private Easter easter; + private IndependenceDay independenceDay; + + public HolidayManager() { + this.easter = new Easter(); + this.independenceDay = new IndependenceDay(); + } + + public Easter getEaster() { + if (this.easter == null) this.easter = new Easter(); + return this.easter; + } + + public IndependenceDay getIndependenceDay() { + if (this.independenceDay == null) this.independenceDay = new IndependenceDay(); + return this.independenceDay; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/easter/Easter.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/easter/Easter.java new file mode 100644 index 0000000..16540d4 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/easter/Easter.java @@ -0,0 +1,82 @@ +package net.grandtheftmc.gtm.holidays.easter; + +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.holidays.Holiday; +import org.bukkit.Chunk; +import org.bukkit.Material; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Item; +import org.bukkit.entity.Rabbit; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.time.Month; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Optional; + +public class Easter extends Holiday { + private EasterTask easterTask; + + public Easter() { + new EasterListener(this); + if (this.isActive()) { + if (this.easterTask == null) this.easterTask = new EasterTask(this); + } + } + + public boolean isActive() { +// return GTMUtils.getMonth() == Month.APRIL && GTMUtils.getDay() == 15 +// || GTMUtils.getDay() == 16 || GTMUtils.getDay() == 17; + return false; + } + + public Optional<EasterTask> getEasterTask() { + return Optional.ofNullable(this.easterTask); + } + + public ItemStack getEasterEgg() { + ItemStack easterEgg = new ItemStack(Material.EGG); + ItemMeta meta = easterEgg.getItemMeta(); + meta.setDisplayName(Utils.f(GTMUtils.randomColor() + "&lEaster Egg")); + easterEgg.setItemMeta(meta); + return easterEgg; + } + + public ItemStack getChocolateBunny() { + ItemStack chocolateBunny = new ItemStack(Material.COOKED_RABBIT); + ItemMeta meta = chocolateBunny.getItemMeta(); + meta.setDisplayName(Utils.f(GTMUtils.randomColor() + "&lChocolate")); + chocolateBunny.setItemMeta(meta); + return chocolateBunny; + } + + public Rabbit.Type[] getAllowedTypes() { + Rabbit.Type[] allowed = {Rabbit.Type.BLACK, Rabbit.Type.BLACK_AND_WHITE, + Rabbit.Type.GOLD, Rabbit.Type.WHITE}; + return allowed; + } + + public Collection<Rabbit> getRabbitsByChunk(Chunk chunk) { + Collection<Rabbit> rabbits = new ArrayList<>(); + if (chunk == null || !chunk.isLoaded()) return rabbits; + for (Entity entity : chunk.getEntities()) { + if (entity.getType() != EntityType.RABBIT) continue; + rabbits.add((Rabbit) entity); + } + return rabbits; + } + + public Collection<Item> getItemsByChunk(Chunk chunk) { + Collection<Item> items = new ArrayList<>(); + if (chunk == null || !chunk.isLoaded()) return items; + for (Entity entity : chunk.getEntities()) { + if (entity.getType() != EntityType.DROPPED_ITEM) continue; + items.add((Item) entity); + } + return items; + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/easter/EasterListener.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/easter/EasterListener.java new file mode 100644 index 0000000..de24623 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/easter/EasterListener.java @@ -0,0 +1,79 @@ +package net.grandtheftmc.gtm.holidays.easter; + +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import org.bukkit.Bukkit; +import org.bukkit.Effect; +import org.bukkit.Sound; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.entity.Rabbit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.entity.EntitySpawnEvent; +import org.bukkit.event.player.PlayerEggThrowEvent; +import org.bukkit.event.player.PlayerItemConsumeEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import java.util.concurrent.ThreadLocalRandom; + +public class EasterListener implements Listener { + private Easter easter; + + public EasterListener(Easter easter) { + this.easter = easter; + + if (!easter.isActive()) return; + Bukkit.getPluginManager().registerEvents(this, GTM.getInstance()); + } + + @EventHandler + public void playerEggThrow(PlayerEggThrowEvent event) { + Player player = event.getPlayer(); + if (event.isHatching()) { + if (easter.isActive()) event.setHatchingType(EntityType.RABBIT); + if (player.getWorld().getName().equalsIgnoreCase("spawn") || !easter.isActive()) event.setHatching(false); + if (easter.getRabbitsByChunk(player.getLocation().getChunk()).size() > 50) event.setHatching(false); + player.playSound(event.getEgg().getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 5.0F, 5.0F); + player.playSound(event.getEgg().getLocation(), Sound.ENTITY_FIREWORK_BLAST, 5.0F, 5.0F); + player.getWorld().spigot().playEffect(event.getEgg().getLocation(), Effect.FIREWORKS_SPARK); + player.getWorld().dropItemNaturally(event.getEgg().getLocation(), GTMUtils.getRandomGameItem().getItem()); + } + } + + @EventHandler + public void playerItemConsume(PlayerItemConsumeEvent event) { + Player player = event.getPlayer(); + ItemStack item = event.getItem(); + if (item.getType() == easter.getChocolateBunny().getType()) { + GTM.getDrugManager().getEffectManager().cancelEffects(player); + player.addPotionEffect(new PotionEffect(PotionEffectType.ABSORPTION, 600, 1)); + player.setFoodLevel(20); + player.setSaturation(20); + player.setExhaustion(0); + } + } + + @EventHandler + public void entityDeath(EntityDeathEvent event) { + if (!easter.isActive()) return; + if (event.getEntity().getType() != EntityType.RABBIT) return; + if (event.getEntity().getKiller() == null) return; + event.getDrops().clear(); + event.getDrops().add(GTM.getHolidayManager().getEaster().getChocolateBunny()); + } + + @EventHandler + public void entitySpawn(EntitySpawnEvent event) { + if (event.getEntityType() != EntityType.RABBIT) return; + Rabbit rabbit = (Rabbit) event.getEntity(); + rabbit.setAdult(); + rabbit.setCustomName(""); + rabbit.setCustomNameVisible(false); + Rabbit.Type targetType = easter.getAllowedTypes()[ThreadLocalRandom.current().nextInt(easter.getAllowedTypes().length)]; + rabbit.setRabbitType(targetType); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/easter/EasterTask.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/easter/EasterTask.java new file mode 100644 index 0000000..ffb5b1c --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/easter/EasterTask.java @@ -0,0 +1,43 @@ +package net.grandtheftmc.gtm.holidays.easter; + +import net.grandtheftmc.gtm.GTM; +import org.bukkit.Location; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Rabbit; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.concurrent.ThreadLocalRandom; + +public class EasterTask extends BukkitRunnable { + private Easter easter; + + public EasterTask(Easter easter) { + this.easter = easter; + if (this.easter.getEasterTask().isPresent()) return; + this.runTaskTimer(GTM.getInstance(), 0, 4800); + } + + @Override + public void run() { + Location location = GTM.getWarpManager().getRandomWarp().getLocation(); + if (easter.getRabbitsByChunk(location.getChunk()).size() > 10) return; + Rabbit rabbit = (Rabbit) location.getWorld().spawnEntity(location, EntityType.RABBIT); + Rabbit.Type type = easter.getAllowedTypes()[ThreadLocalRandom.current().nextInt(easter.getAllowedTypes().length)]; + rabbit.setRabbitType(type); + rabbit.setCustomName(""); + rabbit.setCustomNameVisible(false); + rabbit.setAdult(); + rabbit.setBreed(true); + rabbit.setRemoveWhenFarAway(true); + location.getWorld().getLivingEntities() + .stream() + .filter(livingEntity -> livingEntity.getType() == EntityType.RABBIT) + .forEach(livingEntity -> { + livingEntity.setRemoveWhenFarAway(true); + if (easter.getItemsByChunk(livingEntity.getLocation().getChunk()).size() > 50) return; + if (ThreadLocalRandom.current().nextInt(3) == 1) { + livingEntity.getWorld().dropItemNaturally(livingEntity.getLocation(), easter.getEasterEgg()); + } + }); + } +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/halloween/PlayerScare.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/halloween/PlayerScare.java new file mode 100644 index 0000000..9175fcf --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/halloween/PlayerScare.java @@ -0,0 +1,186 @@ +package net.grandtheftmc.gtm.holidays.halloween; + +import net.buycraft.plugin.client.ApiException; +import net.buycraft.plugin.data.Coupon; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.util.title.NMSTitle; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.holidays.halloween.dao.ServerCoupon; +import net.grandtheftmc.gtm.holidays.halloween.dao.ServerCouponDAO; +import net.grandtheftmc.gtm.users.GTMUser; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.scheduler.BukkitRunnable; + +import java.io.IOException; +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.ThreadLocalRandom; + +/** + * Created by Timothy Lampen on 2017-09-28. + */ +public class PlayerScare implements Listener{ + + public PlayerScare(){ +// new BukkitRunnable() { +// @Override +// public void run() { +// List<ServerCoupon> coupons = ServerCouponDAO.getAllServerCoupons(); +// coupons.forEach(coupon -> { +// final long timeRemaining = coupon.getCreationTime() + 1000 * 60 * 60 * 24 - System.currentTimeMillis(); +// if(timeRemaining <= 0) { +// ServerCouponDAO.deleteServerCoupon(coupon.getCouponID()); +// try { +// GTM.getBuycraftX().getApiClient().deleteCoupon(coupon.getCouponID()); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// }); +// } +// }.runTaskTimerAsynchronously(GTM.getInstance(), 0, 20*60*60); + } + +// @EventHandler +// public void onJoin(PlayerJoinEvent event) { +// Player player = event.getPlayer(); +// +// int rand = ThreadLocalRandom.current().nextInt(10, 300); +// new BukkitRunnable() { +// @Override +// public void run() { +// final Optional<ServerCoupon> optCoupon = ServerCouponDAO.getServerCoupon(player.getUniqueId()); +// +// if (!optCoupon.isPresent()) {//player not in there +// initScare(player); +// } else { +// if (optCoupon.get().getCreationTime() == 0) return; +// final long timeRemaining = optCoupon.get().getCreationTime() + 1000 * 60 * 60 * 24 - System.currentTimeMillis(); +// if (timeRemaining <= 0) { +// try { +// GTM.getBuycraftX().getApiClient().deleteCoupon(optCoupon.get().getCouponID()); +// } catch (IOException | ApiException e) { +// e.printStackTrace(); +// } +// ServerCouponDAO.deleteServerCoupon(player.getUniqueId()); +// return; +// } +// +// Coupon coupon = null; +// try { +// coupon = GTM.getBuycraftX().getApiClient().getCoupon(optCoupon.get().getCouponID()); +// } catch (IOException | ApiException e) { +// e.printStackTrace(); +// } +// +// if (coupon != null && coupon.getExpire().getLimit() <= 0) {//coupon has already been used +// if (optCoupon.get().getCreationTime() != 0) { +// ServerCouponDAO.deleteServerCoupon(player.getUniqueId()); +// } +// return; +// } +// +// if(coupon == null) return; +// Coupon finalCoupon = coupon; +// +// new BukkitRunnable() { +// @Override +// public void run() { +// NMSTitle.sendTitle(player, Utils.f("&6&lHAPPY HALLOWEEN"), Utils.f("&eRead chat for more information & exciting offers!"), 20, 60, 20); +// +// for(int i = 0; i < 4; i++) +// player.sendMessage(""); +// +// player.sendMessage(Utils.f("&6▀&8▔&6▀&8▔&6▀&8▔&6▀&8▔&6▀&8▔&6▀&8▔&6▀&8▔&6▀&8▔&6▀&8▔&6▀&8▔&6▀&8▔&6▀&8▔&6▀&8▔&6▀&8▔&6▀&8▔&6▀&8▔&6▀&8▔&6▀"));//▔▀ +// player.sendMessage(""); +// player.sendMessage(Utils.f(" &6&lHappy Halloween!&r")); +// player.sendMessage(Utils.f(" Your &c&l30&c% off coupon&r hasn't yet been used, hurry before it ends! Expires in " + Utils.timeInSecondsToText(timeRemaining / 1000L, C.DARK_RED + C.BOLD, C.DARK_RED, C.WHITE))); +// player.sendMessage(""); +// player.sendMessage(Utils.f(" &e&lCOUPON&r: &6" + finalCoupon.getCode())); +// player.sendMessage(Utils.f(" &e&lSTORE&r: &6https://store.grandtheftmc.net/halloweenremind")); +// player.sendMessage(""); +// player.sendMessage(Utils.f("&6▄&8▁&6▄&8▁&6▄&8▁&6▄&8▁&6▄&8▁&6▄&8▁&6▄&8▁&6▄&8▁&6▄&8▁&6▄&8▁&6▄&8▁&6▄&8▁&6▄&8▁&6▄&8▁&6▄&8▁&6▄&8▁&6▄&8▁&6▄"));//▄▁ +// } +// }.runTask(GTM.getInstance()); +// } +// } +// }.runTaskLaterAsynchronously(GTM.getInstance(), rand*20);//todo:change back to 15-20min +// } + +// private void initScare(Player player) { +// GTMUser gtmUser = GTM.getUserManager().getLoadedUser(player.getUniqueId()); +// long delay = gtmUser.isInCombat() ? 20*15 : 0; +// new BukkitRunnable() { +// @Override +// public void run() { +// if(!player.isOnline()) return; +// if(gtmUser.isInCombat()) { +// initScare(player); +// return; +// } +// +// String couponName = "SPOOK" + player.getName() + ThreadLocalRandom.current().nextInt(100, 1000); +// try { +// Coupon coupon = Coupon.builder() +// .code(couponName) +// .effective(new Coupon.Effective("cart", null, null)) +// .basketType("both").startDate(new Date()) +// .discount(new Coupon.Discount("percentage", new BigDecimal(30), new BigDecimal(0))) +// .expire(new Coupon.Expire("limit", 1, new Date())) +// .userLimit(1) +// .minimum(new BigDecimal(0)) +// .build(); +// Coupon generatedCoupon = GTM.getBuycraftX().getApiClient().createCoupon(coupon); +// +// if(generatedCoupon == null) { +// player.sendMessage(Lang.GTM.f("&cError: Couldn't generate your coupon: " + couponName + " contact an admin immediately.")); +// return; +// } +// +// new BukkitRunnable() { +// @Override +// public void run() { +// player.spawnParticle(Particle.MOB_APPEARANCE, player.getLocation(), 1); +// player.playSound(player.getLocation(), Sound.ENTITY_GHAST_SCREAM, 10, 10); +// player.playSound(player.getLocation(), "custome.halloween", 10, 10); +// NMSTitle.sendTitle(player, Utils.f("&6&lHAPPY HALLOWEEN"), Utils.f("&eRead chat for more information & exciting offers!"), 20, 60, 20); +// +// for(int i = 0; i < 4; i++) +// player.sendMessage(""); +// +// player.sendMessage(Utils.f("&6▀&8▔&6▀&8▔&6▀&8▔&6▀&8▔&6▀&8▔&6▀&8▔&6▀&8▔&6▀&8▔&6▀&8▔&6▀&8▔&6▀&8▔&6▀&8▔&6▀&8▔&6▀&8▔&6▀&8▔&6▀&8▔&6▀&8▔&6▀"));//▔▀ +// player.sendMessage(""); +// player.sendMessage(Utils.f(" &6&lHappy Halloween!&r As a celebration, and a ðank you &rfor playing, here is a &a&l30&r&a% off&r, private, exclusive coupon for our store. It runs out in &c&l24&r &chours&f, and only you have it!")); +// player.sendMessage(""); +// player.sendMessage(Utils.f(" &e&lCOUPON&r: &6" + couponName)); +// player.sendMessage(Utils.f(" &e&lSTORE&r: &6https://store.grandtheftmc.net/halloween")); +// player.sendMessage(""); +// player.sendMessage(Utils.f("&6▄&8▁&6▄&8▁&6▄&8▁&6▄&8▁&6▄&8▁&6▄&8▁&6▄&8▁&6▄&8▁&6▄&8▁&6▄&8▁&6▄&8▁&6▄&8▁&6▄&8▁&6▄&8▁&6▄&8▁&6▄&8▁&6▄&8▁&6▄"));//▄▁ +// } +// }.runTask(GTM.getInstance()); +// +// ServerCouponDAO.setServerCoupon(player.getUniqueId(), generatedCoupon.getId(), couponName, System.currentTimeMillis()); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// }.runTaskLaterAsynchronously(GTM.getInstance(), delay); +// } +// +// public void clearEvent(){ +// Core.sql.updateAsyncLater("TRUNCATE server_coupons"); +// Core.log("Successfully cleared the halloween event!"); +// } + + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/halloween/dao/ServerCoupon.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/halloween/dao/ServerCoupon.java new file mode 100644 index 0000000..16e5a1f --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/halloween/dao/ServerCoupon.java @@ -0,0 +1,28 @@ +package net.grandtheftmc.gtm.holidays.halloween.dao; + +/** + * Created by Timothy Lampen on 2017-10-15. + */ +public class ServerCoupon { + private int couponID; + private String couponName; + private long creationTime; + + public ServerCoupon(int couponID, String couponName, long creationTime) { + this.couponID = couponID; + this.couponName = couponName; + this.creationTime = creationTime; + } + + public int getCouponID() { + return couponID; + } + + public String getCouponName() { + return couponName; + } + + public long getCreationTime() { + return creationTime; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/halloween/dao/ServerCouponDAO.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/halloween/dao/ServerCouponDAO.java new file mode 100644 index 0000000..4299ffc --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/halloween/dao/ServerCouponDAO.java @@ -0,0 +1,98 @@ +package net.grandtheftmc.gtm.holidays.halloween.dao; + +import net.grandtheftmc.core.database.BaseDatabase; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; + +/** + * Created by Timothy Lampen on 2017-10-15. + */ +public class ServerCouponDAO { + + public static boolean deleteServerCoupon(UUID uuid) { + String query = "UPDATE server_coupons SET creationTime=0 WHERE uuid=?;"; + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try(PreparedStatement ps = connection.prepareStatement(query)) { + ps.setString(1, uuid.toString()); + ps.executeUpdate(); + return true; + } + } catch (SQLException e) { + e.printStackTrace(); + } + return false; + } + + public static boolean deleteServerCoupon(int couponID) { + String query = "UPDATE server_coupons SET creationTime=0 WHERE couponID=?;"; + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try(PreparedStatement ps = connection.prepareStatement(query)) { + ps.setInt(1, couponID); + ps.executeUpdate(); + return true; + } + } catch (SQLException e) { + e.printStackTrace(); + } + return false; + } + + public static List<ServerCoupon> getAllServerCoupons() { + String query = "SELECT * FROM server_coupons;"; + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try(ResultSet set = connection.prepareStatement(query).executeQuery()) { + List<ServerCoupon> coupons = new ArrayList<>(); + while (set.next()) { + int couponID = set.getInt("couponID"); + long creationTime = set.getLong("creationTime"); + String couponName = set.getString("couponName"); + coupons.add(new ServerCoupon(couponID, couponName, creationTime)); + } + return coupons; + } + } catch (SQLException e) { + e.printStackTrace(); + } + return Collections.emptyList(); + } + + public static Optional<ServerCoupon> getServerCoupon(UUID uuid) { + String query = "SELECT * FROM server_coupons WHERE UUID=?;"; + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try(PreparedStatement ps = connection.prepareStatement(query)) { + ps.setString(1, uuid.toString()); + try (ResultSet set = ps.executeQuery()) { + if (!set.next()) return Optional.empty(); + int couponID = set.getInt("couponID"); + long creationTime = set.getLong("creationTime"); + String couponName = set.getString("couponName"); + return Optional.of(new ServerCoupon(couponID, couponName, creationTime)); + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + return Optional.empty(); + } + + public static boolean setServerCoupon(UUID uuid, int couponID, String couponName, long creationTime) { + String query = "INSERT INTO server_coupons (uuid, couponID, couponName, creationTime) VALUES (?,?,?,?);"; + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try(PreparedStatement ps = connection.prepareStatement(query)) { + ps.setString(1, uuid.toString()); + ps.setInt(2, couponID); + ps.setString(3, couponName); + ps.setLong(4, creationTime); + ps.executeUpdate(); + return true; + } + } catch (SQLException e) { + e.printStackTrace(); + } + return false; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/independenceday/IndependenceDay.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/independenceday/IndependenceDay.java new file mode 100644 index 0000000..db2a1a1 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/independenceday/IndependenceDay.java @@ -0,0 +1,85 @@ +package net.grandtheftmc.gtm.holidays.independenceday; + +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.holidays.Holiday; +import org.bukkit.ChatColor; +import us.myles.ViaVersion.api.Via; +import us.myles.ViaVersion.api.boss.BossBar; +import us.myles.ViaVersion.api.boss.BossColor; +import us.myles.ViaVersion.api.boss.BossStyle; + +import java.time.Month; +import java.util.Optional; + +public class IndependenceDay extends Holiday { + private IndependenceDayTask independenceDayTask; + private BossBar bossBar; + private Integer voteCount = 0; + + public IndependenceDay() { + if (isActive()) { + new IndependenceDayListener(this); + if (this.independenceDayTask == null) this.independenceDayTask = new IndependenceDayTask(this); + if (this.bossBar == null) { + this.bossBar = Via.getAPI().createBossBar( + getNextChatColor() + "HAPPY JULY FOURTH! VOTES UNTIL REWARD DROP: " + String.valueOf(100 - getVoteCount()), + 1F, + BossColor.BLUE, + BossStyle.SEGMENTED_10); + } + } + } + + public boolean isActive() { + return GTMUtils.getMonth() == Month.JULY && GTMUtils.getDay() == 4; + } + + public Optional<IndependenceDayTask> getIndependenceDayTask() { + return Optional.ofNullable(this.independenceDayTask); + } + + public Integer getVoteCount() { + return this.voteCount; + } + + public void addVote(int amount) { + if (this.voteCount == 100) return; + this.voteCount += amount; + } + + public void resetVotes() { + this.voteCount = 0; + this.getBossBar().setHealth(1F); + } + + public BossBar getBossBar() { + return this.bossBar; + } + + public BossColor getNextBossColor() { + BossColor currentColor = bossBar.getColor(); + switch (currentColor) { + case RED: + return BossColor.WHITE; + case BLUE: + return BossColor.RED; + case WHITE: + return BossColor.BLUE; + } + return BossColor.RED; + } + + public ChatColor getNextChatColor() { + if (bossBar == null) return ChatColor.RED; + switch (bossBar.getColor()) { + case RED: + return ChatColor.RED; + case BLUE: + return ChatColor.BLUE; + case WHITE: + return ChatColor.WHITE; + } + return ChatColor.RED; + } + +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/independenceday/IndependenceDayListener.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/independenceday/IndependenceDayListener.java new file mode 100644 index 0000000..b2cc093 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/independenceday/IndependenceDayListener.java @@ -0,0 +1,24 @@ +package net.grandtheftmc.gtm.holidays.independenceday; + +import net.grandtheftmc.core.voting.events.PlayerVoteEvent; +import net.grandtheftmc.gtm.GTM; +import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +public class IndependenceDayListener implements Listener { + private IndependenceDay independenceDay; + + public IndependenceDayListener(IndependenceDay independenceDay) { + Bukkit.getPluginManager().registerEvents(this, GTM.getInstance()); + this.independenceDay = independenceDay; + } + + @EventHandler + public void playerVoteEvent(PlayerVoteEvent event) { + float health = independenceDay.getBossBar().getHealth() - 0.01F; + if (health < 0) health = 0F; + independenceDay.getBossBar().setHealth(health); + independenceDay.addVote(1); + } +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/independenceday/IndependenceDayTask.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/independenceday/IndependenceDayTask.java new file mode 100644 index 0000000..1345073 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/holidays/independenceday/IndependenceDayTask.java @@ -0,0 +1,57 @@ +package net.grandtheftmc.gtm.holidays.independenceday; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.title.NMSTitle; +import net.grandtheftmc.gtm.GTM; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ThreadLocalRandom; + +public class IndependenceDayTask extends BukkitRunnable { + private IndependenceDay independenceDay; + + public IndependenceDayTask(IndependenceDay independenceDay) { + this.independenceDay = independenceDay; + if (this.independenceDay.getIndependenceDayTask().isPresent()) return; + this.runTaskTimer(GTM.getInstance(), 300, 20); + } + + @Override + public void run() { + if (independenceDay.getBossBar() == null) return; + independenceDay.getBossBar().setTitle( + independenceDay.getNextChatColor() + "" + ChatColor.BOLD + + "HAPPY 4TH OF JULY! VOTES UNTIL REWARD DROP: " + + ChatColor.GREEN + String.valueOf(100 - independenceDay.getVoteCount())); + independenceDay.getBossBar().setColor(independenceDay.getNextBossColor()); + if (independenceDay.getVoteCount() != 0 && independenceDay.getVoteCount() % 100 == 0) { + List<? extends Player> onlinePlayers = new ArrayList<>(Bukkit.getOnlinePlayers()); + Player randomPlayer = onlinePlayers.get(ThreadLocalRandom.current().nextInt(onlinePlayers.size())); + User randomUser = Core.getUserManager().getLoadedUser(randomPlayer.getUniqueId()); + randomUser.addCrowbars(100); + Bukkit.broadcastMessage(Lang.REWARDS.f(randomUser.getColoredName(randomPlayer) + " &7WON &9&l100 CROWBARS&7!")); + randomPlayer.sendMessage(Lang.CROWBARS_ADD.f("100")); + + onlinePlayers.forEach(onlinePlayer -> { + onlinePlayer.playSound(onlinePlayer.getLocation(), Sound.ENTITY_FIREWORK_TWINKLE, 1.0F, 1.0F); + onlinePlayer.playSound(onlinePlayer.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1.0F, 1.0F); + if (onlinePlayer == randomPlayer) return; + User user = Core.getUserManager().getLoadedUser(onlinePlayer.getUniqueId()); + user.addCrowbars(5); + onlinePlayer.sendMessage(Lang.CROWBARS_ADD.f("5")); + onlinePlayer.sendTitle("", Utils.f("&9&l+5 Crowbars"), 1, 1, 3); + }); + + independenceDay.resetVotes(); + } + } +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/AmmoType.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/AmmoType.java new file mode 100644 index 0000000..ef47025 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/AmmoType.java @@ -0,0 +1,93 @@ +package net.grandtheftmc.gtm.items; + +import java.util.Arrays; +import java.util.Optional; + +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +import net.grandtheftmc.gtm.GTM; + +public enum AmmoType { + + PISTOL("pistolAmmo"), SMG("smgAmmo"), SHOTGUN("shotgunShell"), ASSAULT_RIFLE("assaultRifleAmmo"), MG( + "mgAmmo"), SNIPER("sniperRifleAmmo"), ROCKET("rocket"), MINIGUN("minigunAmmo"), GRENADE("grenade", true); + + private final String gameItem; + private final boolean inInventory; + + AmmoType(String gameItem) { + this.gameItem = gameItem; + this.inInventory = false; + } + + AmmoType(String gameItem, boolean inInventory) { + this.gameItem = gameItem; + this.inInventory = inInventory; + } + + /** + * Get the identifier of the ammo type. + * + * @return The string representation for the id for the ammo type. + */ + public String getId(){ + return name(); + } + + public String getGameItemName() { + return this.gameItem; + } + + public GameItem getGameItem() { + return GTM.getItemManager().getItem(this.gameItem); + } + + public static AmmoType[] getTypes() { + return values(); + } + + public static AmmoType getAmmoType(Material material, short dataValue) { + for (AmmoType type : AmmoType.getTypes()) { + ItemStack item = type.getGameItem().getItem(); + if (material == item.getType() && dataValue == item.getDurability()) + return type; + } + return null; + } + + /** + * Get the ammo type based off the identifier. + * + * @param id - the id to use + * + * @return The ammo type, if found, otherwise empty. + */ + public static Optional<AmmoType> getAmmoTypeByID(String id) { + + for (AmmoType at : values()){ + if (at.getId().equalsIgnoreCase(id)){ + return Optional.of(at); + } + } + + return Optional.empty(); + } + + public static AmmoType getAmmoType(String ammoType) { + return Arrays.stream(AmmoType.getTypes()).filter(type -> type.toString().equalsIgnoreCase(ammoType)).findFirst().orElse(null); + } + + public static AmmoType getAmmoTypeFriendly(String ammoType) { + return Arrays.stream(AmmoType.getTypes()).filter(type -> type.toString().equalsIgnoreCase(ammoType) || type.gameItem.equalsIgnoreCase(ammoType)).findFirst().orElse(null); + } + + public static boolean isAmmo(ItemStack item) { + return getAmmoType(item.getType(), item.getDurability()) != null; + } + + public boolean isInInventory() { + return this.inInventory; + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/ArmorType.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/ArmorType.java new file mode 100644 index 0000000..0a8d04c --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/ArmorType.java @@ -0,0 +1,77 @@ +package net.grandtheftmc.gtm.items; + +import net.grandtheftmc.core.util.Slot; +import org.bukkit.inventory.ItemStack; + +import java.util.Arrays; + +/** + * Created by Timothy Lampen on 7/6/2017. + */ +public enum ArmorType { + HELMET(Slot.HEAD, 5, "titaniumhelmet", "tacticalmask", "pimpcrown", "nightvisiongoggles", "baseballcap"), + CHESTPLATE(Slot.CHEST, 6, "titaniumvest", "ceramicvest", "kevlarvest", "shirt"), + LEGGINGS(Slot.LEGS, 7, "pants"), + BOOTS(Slot.FEET, 8, "nikes", "samurisairjordans"), + JETPACK(Slot.CHEST, 6, "jetpack"), + WINGSUIT(Slot.CHEST, 6, "wingsuit"); + + private final Slot slot; + private final String[] gameItems; + private final int rawSlot; + + ArmorType(Slot slot, int rawSlot, String... gameItems) { + this.slot = slot; + this.rawSlot =rawSlot; + this.gameItems = gameItems; + } + + public String getName() { + String[] a = this.toString().split("_"); + String s = ""; + for (int i = 0; i < a.length; ++i) { + s = s + a[i].charAt(0) + a[i].substring(1).toLowerCase() + (i == a.length - 1 ? "" : " "); + } + return s; + } + + + public Slot getSlot() { + return this.slot; + } + + public String[] getGameItems() { + return this.gameItems; + } + + public boolean hasGameItem(String gameItem) { + return Arrays.stream(this.gameItems).anyMatch(s -> s.equalsIgnoreCase(gameItem)); + } + + public static ArmorType getArmorType(String gameItem) { + return Arrays.stream(ArmorType.values()).filter(type -> type.hasGameItem(gameItem)).findFirst().orElse(null); + } + + public int getRawSlot() { + return rawSlot; + } + + public static ArmorType matchType(ItemStack is){ + if(is==null) + return null; + String type = is.getType().toString().toLowerCase(); + if(type.contains("chestplate")){ + return ArmorType.CHESTPLATE; + } + else if(type.contains("leggings")){ + return ArmorType.LEGGINGS; + } + else if(type.contains("boots")){ + return ArmorType.BOOTS; + } + else if(type.contains("helmet")){ + return ArmorType.HELMET; + } + return null; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/ArmorUpgrade.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/ArmorUpgrade.java new file mode 100644 index 0000000..1304bf4 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/ArmorUpgrade.java @@ -0,0 +1,283 @@ +package net.grandtheftmc.gtm.items; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.Attribute; +import net.grandtheftmc.core.util.AttributeModifier; +import net.grandtheftmc.core.util.ItemAttributes; +import net.grandtheftmc.gtm.users.GTMRank; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import java.util.*; + + +/** + * Created by Liam on 25/10/2016. + */ +public enum ArmorUpgrade { + + LIGHT(2000, GTMRank.THUG, UserRank.VIP, ArmorType.CHESTPLATE), + DURABLE(2000, GTMRank.GANGSTER, UserRank.VIP, ArmorType.HELMET, ArmorType.CHESTPLATE, ArmorType.LEGGINGS, ArmorType.BOOTS), + ULTRA_LIGHT(5000, GTMRank.MUGGER, UserRank.PREMIUM, ArmorType.CHESTPLATE), + TANK(3000, GTMRank.HUNTER, UserRank.PREMIUM, ArmorType.HELMET, ArmorType.CHESTPLATE, ArmorType.LEGGINGS, ArmorType.BOOTS), + REINFORCED(2500, GTMRank.DEALER, UserRank.ELITE, ArmorType.HELMET, ArmorType.CHESTPLATE, ArmorType.JETPACK, ArmorType.WINGSUIT), + BOMB_SQUAD(3000, GTMRank.PIMP, UserRank.ELITE, ArmorType.HELMET, ArmorType.CHESTPLATE), + EXOSKELETON(5000, GTMRank.MOBSTER, UserRank.SPONSOR, ArmorType.CHESTPLATE), + ENHANCED(50000, GTMRank.GODFATHER, UserRank.SUPREME, ArmorType.CHESTPLATE), + NEON(5000, null, UserRank.VIP, ArmorType.HELMET, ArmorType.CHESTPLATE, ArmorType.LEGGINGS, ArmorType.BOOTS, ArmorType.JETPACK, ArmorType.WINGSUIT), + LEAD_LINED(5000, null, null, ArmorType.HELMET, ArmorType.CHESTPLATE, ArmorType.LEGGINGS, ArmorType.BOOTS, ArmorType.JETPACK, ArmorType.WINGSUIT); + + + private final double price; + private final GTMRank rank; + private final UserRank userRank; + private final ArmorType[] types; + + ArmorUpgrade(double price, GTMRank rank, UserRank userRank, ArmorType... types) { + this.price = price; + this.rank = rank; + this.userRank = userRank; + this.types = types; + } + + public double getPrice() { + return this.price; + } + + /* public double getPrice(GameItem item) { + Core.log(item.getSellPrice() + " / " + this.price); + return this.price * item.getSellPrice(); + }*/ + + public GTMRank getGTMRank() { + return this.rank; + } + + public UserRank getUserRank() { + return this.userRank; + } + + public boolean canUseUpgrade(GTMRank rank, UserRank userRank) { + return this.rank == rank || rank.isHigherThan(this.rank) || this.userRank == userRank || userRank.isHigherThan(this.userRank) || (userRank==null && rank==null); + } + + public String getDisplayName() { + String[] a = this.toString().split("_"); + String s = ""; + for (int i = 0; i < a.length; ++i) { + s = s + a[i].charAt(0) + a[i].substring(1).toLowerCase() + (i == a.length - 1 ? "" : " "); + } + return s; + } + + public ArmorType[] getTypes() { + return this.types; + } + + public String getTypesString() { + String s = ""; + int length = this.types.length; + for (int i = 0; i < length; i++) { + ArmorType type = this.types[i]; + s += type.getName() + (i == length - 1 ? "" : i == length - 2 ? " or " : ", "); + } + return s; + } + + public static boolean isArmorUpgrade(String s) { + try { + ArmorUpgrade.valueOf(s); + } catch (IllegalArgumentException | NullPointerException e) { + return false; + } + return true; + } + + public static boolean playerHasArmorUpgrade(Player victim, ArmorUpgrade upgrade){ + ItemStack[] armor = victim.getInventory().getArmorContents(); + for (ItemStack itemStack : armor) { + if(itemStack==null) + continue; + HashSet<ArmorUpgrade> upgrades = ArmorUpgrade.getArmorUpgrades(itemStack); + if (upgrades.stream().anyMatch(up -> up == upgrade)) { + return true; + } + } + return false; + } + + //Does not return null when no upgrades, returns an empty set. + public static HashSet<ArmorUpgrade> getArmorUpgrades(ItemStack is) { + HashSet<ArmorUpgrade> returnSet = new HashSet<>(); + if (is==null || is.getItemMeta() == null || is.getItemMeta().getLore() == null) + return returnSet; + List<String> lore = is.getItemMeta().getLore(); + lore.stream().forEach(line -> { + line = ChatColor.stripColor(line); + Core.log(line); + if (line.equalsIgnoreCase("") || !ArmorUpgrade.isArmorUpgrade(line.toUpperCase().replace(" ", "_"))) + return; + returnSet.add(ArmorUpgrade.valueOf(line.toUpperCase().replace(" ", "_"))); + }); + + return returnSet; + } + + public boolean canBeUsedOn(ArmorType type) { + return Arrays.stream(this.types).anyMatch(t -> t == type); + } + + public boolean canBeUsedOn(String gameItem) { + return Arrays.stream(this.types).anyMatch(t -> t.hasGameItem(gameItem)); + } + + public HashSet<PotionEffect> getPotionEffects() { + HashSet<PotionEffect> effects = new HashSet<>(); + switch (this) { + case ULTRA_LIGHT: + effects.add(new PotionEffect(PotionEffectType.FAST_DIGGING, Integer.MAX_VALUE, 0)); + break; + case EXOSKELETON: + effects.add(new PotionEffect(PotionEffectType.REGENERATION, Integer.MAX_VALUE, 0)); + effects.add(new PotionEffect(PotionEffectType.INCREASE_DAMAGE, Integer.MAX_VALUE, 0)); + break; + case NEON: + effects.add(new PotionEffect(PotionEffectType.GLOWING, Integer.MAX_VALUE, 0, true, false)); + } + + return effects; + } + + public ItemStack getUpgradedItem(GameItem gameItem, ItemStack item) { + if (gameItem == null) return item; + ArmorType type = ArmorType.getArmorType(gameItem.getName()); + if (type == null) return item; + ItemAttributes att = new ItemAttributes(); + ItemMeta meta = item.getItemMeta(); + List<String> lore = new ArrayList<>(meta.hasLore() ? meta.getLore() : Collections.singletonList("")); + if (ArmorUpgrade.getArmorUpgrades(item).size() == 0) { + lore.add(Utils.f("&7Upgrades:")); + lore.add(" "); + } + lore.add(Utils.f("&b&l" + this.getDisplayName())); + meta.setLore(lore); + meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES); + meta.addItemFlags(ItemFlag.HIDE_ENCHANTS); + switch (this) { + case LIGHT: + att.getFromStack(item); + att.addModifier(new AttributeModifier(Attribute.MOVEMENT_SPEED, "LightSpeed", type.getSlot(), 0, 0.02, UUID.randomUUID())); + item = att.apply(item); + meta.addEnchant(Enchantment.DEPTH_STRIDER, 1, true); + break; + case ULTRA_LIGHT: + att.getFromStack(item); + att.addModifier(new AttributeModifier(Attribute.MOVEMENT_SPEED, "UltraLightSpeed", type.getSlot(), 0, 0.04, UUID.randomUUID())); + item = att.apply(item); + meta.addEnchant(Enchantment.DEPTH_STRIDER, meta.getEnchantLevel(Enchantment.DEPTH_STRIDER) + 2, true); + meta.addEnchant(Enchantment.DIG_SPEED, meta.getEnchantLevel(Enchantment.DIG_SPEED) + 1, true); + break; + case TANK: { + att.getFromStack(item); + att.addModifier(new AttributeModifier(Attribute.MOVEMENT_SPEED, "TankSpeed", type.getSlot(), 0, -0.04, UUID.randomUUID())); + att.addModifier(new AttributeModifier(Attribute.KNOCKBACK_RESISTANCE, "TankKnockback", type.getSlot(), 0, .5d, UUID.randomUUID())); + item = att.apply(item); + meta.addEnchant(Enchantment.PROTECTION_ENVIRONMENTAL, 9, true); + break; + } + case REINFORCED: { + att.getFromStack(item); + item = att.apply(item); + meta.addEnchant(Enchantment.PROTECTION_ENVIRONMENTAL, 4, true); + break; + } + case DURABLE: + att.getFromStack(item); + item = att.apply(item); + meta.addItemFlags(ItemFlag.HIDE_UNBREAKABLE); + meta.spigot().setUnbreakable(true); + break; + case BOMB_SQUAD: + att.getFromStack(item); + att.addModifier(new AttributeModifier(Attribute.MOVEMENT_SPEED, "BombSquadSpeed", type.getSlot(), 0, -0.02, UUID.randomUUID())); + att.addModifier(new AttributeModifier(Attribute.KNOCKBACK_RESISTANCE, "BombSquadKnockback", type.getSlot(), 0, 0.5, UUID.randomUUID())); + item = att.apply(item); + meta.addEnchant(Enchantment.PROTECTION_EXPLOSIONS, 5, true); + meta.addEnchant(Enchantment.PROTECTION_FIRE, 5, true); + break; + } + item.setItemMeta(meta); + att.removeModifier(new AttributeModifier(Attribute.ARMOR)); + att.removeModifier(new AttributeModifier(Attribute.ARMOR_THOUGHNESS)); + att.addModifier(new AttributeModifier(Attribute.ARMOR, "darmor", type.getSlot(), 0, getDefaultArmorAttribute(item.getType()), UUID.randomUUID())); + att.addModifier(new AttributeModifier(Attribute.ARMOR_THOUGHNESS, "darmorthoughness", type.getSlot(), 0, getDefaultArmorToughness(item.getType()), UUID.randomUUID())); + item = att.apply(item); + //Utils.b(this.enchantment == null ? "null" : this.enchantment.getName()); + // item.addUnsafeEnchantment(this.enchantment, 1); + // for (Enchantment e : item.getEnchantments().keySet()) + // Utils.b(e.getName()); + return item; + } + + public static ArmorUpgrade getArmorUpgrade(String s) { + return Arrays.stream(ArmorUpgrade.values()).filter(u -> u.toString().equalsIgnoreCase(s)).findFirst().orElse(null); + } + + public static ArmorUpgrade getArmorUpgradeFromDisplayName(String s) { + return Arrays.stream(ArmorUpgrade.values()).filter(u -> u.toString().replace("_", " ").equalsIgnoreCase(s)).findFirst().orElse(null); + } + + private static int getDefaultArmorAttribute(Material material){ + switch (material){ + case IRON_BOOTS: + case LEATHER_LEGGINGS: + case CHAINMAIL_HELMET: + case GOLD_HELMET: + return 2; + case GOLD_CHESTPLATE: + case CHAINMAIL_CHESTPLATE: + case IRON_LEGGINGS: + return 5; + case GOLD_LEGGINGS: + case DIAMOND_HELMET: + case DIAMOND_BOOTS: + case LEATHER_CHESTPLATE: + return 3; + case CHAINMAIL_LEGGINGS: + return 4; + case LEATHER_BOOTS: + case LEATHER_HELMET: + case CHAINMAIL_BOOTS: + case IRON_HELMET: + case GOLD_BOOTS: + return 1; + case IRON_CHESTPLATE: + case DIAMOND_LEGGINGS: + return 6; + case DIAMOND_CHESTPLATE: + return 8; + } + return 0; + } + + private static int getDefaultArmorToughness(Material material){ + switch (material){ + case DIAMOND_CHESTPLATE: + case DIAMOND_LEGGINGS: + case DIAMOND_HELMET: + case DIAMOND_BOOTS: + return 2; + } + return 0; + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/BackpackManager.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/BackpackManager.java new file mode 100644 index 0000000..5a45ba5 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/BackpackManager.java @@ -0,0 +1,180 @@ +package net.grandtheftmc.gtm.items; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryAction; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.users.GTMRank; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.users.JobMode; + +public class BackpackManager implements Listener { + + private final Map<Integer, Inventory> corpses = new HashMap<>(); + + public void openBackpack(Player player) { + this.openBackpack(player, GTM.getUserManager().getLoadedUser(player.getUniqueId()), Core.getUserManager().getLoadedUser(player.getUniqueId())); + } + + public Inventory getBackpack(Player player, boolean monitor) { + GTMUser gtmUser = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + User coreUser = Core.getUserManager().getLoadedUser(player.getUniqueId()); + int size = 9 * GTMUtils.getBackpackRows(coreUser.getUserRank()); + Inventory inv = Bukkit.createInventory(null, size, monitor ? Utils.f(player.getName()) : Utils.f("&6&lBackpack")); + ItemStack[] backpackContents = gtmUser.getBackpackContents(); + if (backpackContents != null) + for (int i = 0; i < backpackContents.length && i < size; i++) + inv.setItem(i, backpackContents[i]); + return inv; + } + + public void openBackpack(Player player, GTMUser user, User u) { + if (user == null){ + player.sendMessage(Lang.GTM.f("&7Your backpack may not be opened at this time! Please relog!")); + return; + } + + if (user.isArrested()) { + player.sendMessage(Lang.JAIL.f("&7You can't open your backpack in jail!")); + return; + } + if (user.isInCombat()) { + player.sendMessage(Lang.COMBATTAG.f("&7You can't open your backpack in combat!")); + return; + } + if (user.getBackpackOpen()) { + player.sendMessage(Lang.GTM.f("&7Your backpack may not be opened at this time!")); + return; + } + if (player.getOpenInventory() != null + && Objects.equals("Backpack", ChatColor.stripColor(player.getOpenInventory().getTitle()))) + return; + Inventory inv = this.getBackpack(player, false); + + // remove stuck phones and GPS + inv.remove(Material.COMPASS); + inv.remove(Material.WATCH); + + player.openInventory(inv); + user.setBackpackOpen(true); + } + + @EventHandler + public void onClick(InventoryClickEvent event){ + Inventory inv = event.getInventory(); + + // ignore inven events that aren't backback + if (!"backpack".equalsIgnoreCase(ChatColor.stripColor(inv.getTitle()))) + return; + + // grab event variables + Inventory clickedInven = event.getClickedInventory(); + InventoryAction action = event.getAction(); + ItemStack item = event.getCurrentItem(); + ItemStack cur = event.getCursor(); + + // if they are swapping + if (action == InventoryAction.HOTBAR_SWAP || action == InventoryAction.HOTBAR_MOVE_AND_READD){ + + // if they are using number key + if (event.getClick() == ClickType.NUMBER_KEY){ + + int hotbar = event.getHotbarButton(); + + // if there was a click on the inventory + if (clickedInven != null){ + + // get the item they are swapping with + ItemStack swappingItem = event.getWhoClicked().getInventory().getItem(hotbar); + + if (swappingItem != null){ + if (swappingItem.getType() == Material.COMPASS || swappingItem.getType() == Material.WATCH){ + event.setCancelled(true); + } + } + } + } + } + + if (item != null){ + + // stops moving of GPS and Phone + if (item.getType() == Material.COMPASS || item.getType() == Material.WATCH){ + event.setCancelled(true); + } + } + } + + @EventHandler + public void onClose(InventoryCloseEvent e) { + Inventory inv = e.getInventory(); + if (!Objects.equals("Backpack", ChatColor.stripColor(inv.getTitle())) && Bukkit.getPlayer(inv.getTitle()) != null) { + Player target = Bukkit.getPlayer(inv.getTitle()); + if (target.getOpenInventory() != null && Objects.equals("Backpack", ChatColor.stripColor(target.getOpenInventory().getTitle()))) + target.getOpenInventory().close(); + GTMUser user = GTM.getUserManager().getLoadedUser(target.getUniqueId()); + user.setBackpackContents(inv.getContents()); + user.setBackpackOpen(false); + return; + } + if (!"backpack".equalsIgnoreCase(ChatColor.stripColor(inv.getTitle()))) + return; + Player player = (Player) e.getPlayer(); + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + user.setBackpackContents(inv.getContents()); + user.setBackpackOpen(false); + } + + private final int[] glassSlots = new int[]{0, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}; + private final ItemStack glass = Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a"); + + public void kitPreview(Player player, Kit kit) { + String name = kit.getName(); + JobMode mode = JobMode.getModeOrNull(kit.getName()); + UserRank ur = UserRank.getUserRankOrNull(kit.getName()); + GTMRank rank = GTMRank.getRankOrNull(kit.getName()); + if (mode != null) + name = mode.getColoredNameBold(); + else if (ur != null) + name = ur.getColoredNameBold(); + else if (rank != null) + name = rank.getColoredNameBold(); + Inventory inv = Bukkit.createInventory(null, 54, Utils.f("&b&lKit Preview: " + name)); + + for (int i : this.glassSlots) + inv.setItem(i, this.glass); + inv.setItem(1, kit.getHelmet() == null ? this.glass : kit.getHelmet().getItem().getItem()); + inv.setItem(2, kit.getChestPlate() == null ? this.glass : kit.getChestPlate().getItem().getItem()); + inv.setItem(3, kit.getLeggings() == null ? this.glass : kit.getLeggings().getItem().getItem()); + inv.setItem(4, kit.getBoots() == null ? this.glass : kit.getBoots().getItem().getItem()); + inv.setItem(6, kit.getOffHand() == null ? this.glass : kit.getOffHand().getItem().getItem()); + for (int i = 0; i < kit.getItems().size(); i++) { + if (i < 9) + inv.setItem(45 + i, kit.getItems().get(i)); + else + inv.setItem(9 + i, kit.getItems().get(i)); + } + player.openInventory(inv); + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/GameItem.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/GameItem.java new file mode 100644 index 0000000..bd9bcfc --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/GameItem.java @@ -0,0 +1,316 @@ +package net.grandtheftmc.gtm.items; + +import java.util.*; +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.Collectors; + +import net.grandtheftmc.gtm.utils.RandomUtil; +import net.grandtheftmc.gtm.weapon.melee.Dildo; +import net.grandtheftmc.gtm.weapon.ranged.special.GoldMinigun; +import net.grandtheftmc.guns.GTMGuns; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import org.bukkit.Material; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import com.j0ach1mmall3.wastedvehicles.api.VehicleProperties; + +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.drugs.Drug; +import net.grandtheftmc.gtm.drugs.DrugService; +import net.grandtheftmc.gtm.drugs.item.DrugItem; +import net.grandtheftmc.gtm.utils.ItemStackUtil; +import net.grandtheftmc.guns.weapon.Weapon; + +public class GameItem { + + private final ItemType type; + private final String name; + private ItemStack item; + private String weaponOrVecicleOrDrug; + private String displayName; + private double sellPrice, buyPrice; + private AmmoType ammoType; + private ArmorUpgrade armorUpgrade; + private boolean stackable = false; + private boolean hideDurability; + + public GameItem(String name, ItemStack item, String displayName) { + this.type = ItemType.ITEMSTACK; + this.name = name; + this.item = item; + this.displayName = displayName; + this.hideDurability = false; + } + + public GameItem(String name, ItemStack item, String displayName, double sellPrice) { + this.type = ItemType.ITEMSTACK; + this.name = name; + this.item = item; + this.displayName = displayName; + this.sellPrice = sellPrice; + this.hideDurability = false; + } + + public GameItem(String name, ItemStack item, String displayName, double sellPrice, double buyPrice) { + this.type = ItemType.ITEMSTACK; + this.name = name; + this.item = item; + this.displayName = displayName; + this.sellPrice = sellPrice; + this.buyPrice = buyPrice; + this.hideDurability = false; + } + + public GameItem(String name, ItemStack item, String displayName, double sellPrice, double buyPrice, boolean hideDurability, boolean stackable) { + this.type = ItemType.ITEMSTACK; + this.name = name; + this.item = item; + this.displayName = displayName; + this.sellPrice = sellPrice; + this.buyPrice = buyPrice; + this.hideDurability = hideDurability; + this.stackable = stackable; + } + + public GameItem(String name, ItemStack item, AmmoType type, String displayName) { + this.type = ItemType.AMMO; + this.name = name; + this.item = item; + this.ammoType = type; + this.displayName = displayName; + this.hideDurability = false; + } + + public GameItem(String name, ItemStack item, AmmoType type, String displayName, double sellPrice, double buyPrice) { + this.type = ItemType.AMMO; + this.name = name; + this.item = item; + this.ammoType = type; + this.displayName = displayName; + this.sellPrice = sellPrice; + this.buyPrice = buyPrice; + this.hideDurability = false; + } + + public GameItem(ItemType type, String name, String weaponOrVecicleOrDrug, String displayName) { + this.type = type; + this.name = name; + this.displayName = displayName; + this.weaponOrVecicleOrDrug = weaponOrVecicleOrDrug; + this.hideDurability = false; + this.getItem(); + } + + public GameItem(ItemType type, String name, String weaponOrVecicleOrDrug, String displayName, boolean hideDurability) { + this.type = type; + this.name = name; + this.displayName = displayName; + this.weaponOrVecicleOrDrug = weaponOrVecicleOrDrug; + this.hideDurability = hideDurability; + this.getItem(); + } + + public GameItem(ItemType type, String name, String weaponOrVecicleOrDrug, String displayName, double sellPrice, double buyPrice) { + this.type = type; + this.name = name; + this.displayName = displayName; + this.weaponOrVecicleOrDrug = weaponOrVecicleOrDrug; + this.sellPrice = sellPrice; + this.buyPrice = buyPrice; + this.hideDurability = false; + this.getItem(); + } + + public GameItem(ItemType type, String name, String weaponOrVecicleOrDrug, String displayName, double sellPrice, double buyPrice, + boolean hideDurability) { + this.type = type; + this.name = name; + this.displayName = displayName; + this.weaponOrVecicleOrDrug = weaponOrVecicleOrDrug; + this.sellPrice = sellPrice; + this.buyPrice = buyPrice; + this.hideDurability = hideDurability; + this.getItem(); + } + + public GameItem(String name, ArmorUpgrade armorUpgrade, String displayName) { + this.type = ItemType.ARMOR_UPGRADE; + this.name = name; + this.armorUpgrade = armorUpgrade; + this.displayName = displayName; + this.hideDurability = false; + this.getItem(); + } + + public GameItem(String name, ArmorUpgrade armorUpgrade, String displayName, double sellPrice, double buyPrice) { + this.type = ItemType.ARMOR_UPGRADE; + this.name = name; + this.displayName = displayName; + this.armorUpgrade = armorUpgrade; + this.sellPrice = sellPrice; + this.buyPrice = buyPrice; + this.hideDurability = false; + this.getItem(); + } + + public boolean isStackable() { + return stackable; + } + + public String getName() { + return this.name; + } + + public ItemStack getItem() { + return this.getItem(1); + } + + public ItemStack getItem(int amount) { + switch (this.type) { + case WEAPON: { +// Optional<Weapon> opt = GTM.getWastedGuns().getWeapon(this.weaponOrVecicleOrDrug); +// opt.ifPresent(weapon -> this.item = weapon.getItemStack()); + Optional<Weapon<?>> opt = GTM.getWastedGuns().getWeaponManager().getWeapon(this.weaponOrVecicleOrDrug); + opt.ifPresent(weapon -> { + switch (weapon.getWeaponType()) { + case THROWABLE: + case DROPPABLE: + this.item = weapon.createItemStack(); + break; + + default: + this.item = ItemStackUtil.addTag(weapon.createItemStack(), "stackFix", UUID.randomUUID().toString()); + break; + } + }); + break; + } + case DRUG: { + Optional<Drug> drug = ((DrugService) GTM.getDrugManager().getService()).getDrug(this.weaponOrVecicleOrDrug); + if (drug.isPresent()) { + DrugItem drugItem = DrugItem.getByDrug(drug.get()); + if (drugItem != null) { + this.item = drugItem.getItemStack(); + } + } + break; + } + + case VEHICLE: + Optional<VehicleProperties> opt = GTM.getWastedVehicles().getVehicle(this.weaponOrVecicleOrDrug); + opt.ifPresent(vehicleProperties -> this.item = vehicleProperties.getItem()); + break; + + case SKIN: + Random random = RandomUtil.RANDOM; + List<Weapon<?>> weapons = GTMGuns.getInstance().getWeaponManager().getRegisteredWeapons().stream() + .filter(weapon -> !(weapon instanceof Dildo) && !(weapon instanceof GoldMinigun)).collect(Collectors.toList()); + + Weapon<?> randomWeapon = weapons.get(random.nextInt(weapons.size())); + if (randomWeapon == null) break; + + WeaponSkin randomSkin = null; + + if(randomWeapon.getWeaponSkins() != null && randomWeapon.getWeaponSkins().length > 1) { + short[] commonSkins = { + 5, 7 + }; + + short[] rareSkins = { + 2, 6 + }; + + if (this.displayName.equals("weapon_skin_common")) { + randomSkin = GTM.getWeaponSkinManager().getWeaponSkinFromIdentifier(randomWeapon, commonSkins[random.nextInt(commonSkins.length)]); + } + else if (this.displayName.equals("weapon_skin_rare")) { + randomSkin = GTM.getWeaponSkinManager().getWeaponSkinFromIdentifier(randomWeapon, rareSkins[random.nextInt(rareSkins.length)]); + } + + if (randomSkin == null) { + break; + } + + this.item = GTM.getWeaponSkinManager().createSkinItem(randomWeapon, randomSkin); + } + break; + + case ARMOR_UPGRADE: + this.item = Utils.createItem(Material.LEATHER, "&e&l" + this.armorUpgrade.getDisplayName() + " Upgrade &a&lBUY&f: &a&l$" + this.armorUpgrade.getPrice()); + default: + break; + } + if (hideDurability) { + ItemMeta itemMeta = this.item.getItemMeta(); + itemMeta.spigot().setUnbreakable(true); + itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE); + this.item.setItemMeta(itemMeta); + } + if(stackable) + this.item = ItemStackUtil.makeStackable(item,64); + if (item != null) + item.setAmount(amount); + return this.item == null ? new ItemStack(Material.STONE) : this.item.clone(); + } + + public String getWeaponOrVehicleOrDrug() { + return this.weaponOrVecicleOrDrug; + } + + public String getDisplayName() { + if (this.displayName != null) + return this.displayName; + String name = (this.item.hasItemMeta() && this.item.getItemMeta().hasDisplayName()) ? this.item.getItemMeta().getDisplayName() + : this.item.getType().name(); + String amnt = this.item.getAmount() > 1 ? " &7x &a" + this.item.getAmount() : ""; + return name + amnt; + } + + public void setDisplayName(String s) { + this.displayName = s; + } + + public double getSellPrice() { + return this.sellPrice; + } + + public double getBuyPrice() { + return this.buyPrice; + } + + public void setSellPrice(double i) { + this.sellPrice = i; + } + + public boolean canSell() { + return this.sellPrice > 0; + } + + public boolean canBuy() { + return this.buyPrice > 0; + } + + public ItemType getType() { + return this.type; + } + + public AmmoType getAmmoType() { + return this.ammoType; + } + + public ArmorUpgrade getArmorUpgrade() { + return this.armorUpgrade; + } + + public boolean getHideDurability() { + return this.hideDurability; + } + + public enum ItemType { + ITEMSTACK, WEAPON, VEHICLE, AMMO, ARMOR_UPGRADE, DRUG, SKIN + } + +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/GameItemCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/GameItemCommand.java new file mode 100644 index 0000000..df52826 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/GameItemCommand.java @@ -0,0 +1,526 @@ +package net.grandtheftmc.gtm.items; + +import java.util.Iterator; +import java.util.List; +import java.util.Optional; + +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import com.j0ach1mmall3.wastedvehicles.api.VehicleProperties; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.drugs.Drug; +import net.grandtheftmc.gtm.drugs.DrugService; +import net.grandtheftmc.gtm.drugs.item.DrugItem; +import net.grandtheftmc.gtm.items.GameItem.ItemType; +import net.grandtheftmc.guns.weapon.Weapon; + +public class GameItemCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!s.hasPermission("command.gameitem")) { + s.sendMessage(Lang.NOPERM.s()); + return true; + } + + boolean consoleGive = false; + if (!(s instanceof Player)) { + if(!(args.length >= 1 && args[0].equalsIgnoreCase("give"))) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + else consoleGive = true; + } + +// Player player = (Player) s; + if (args.length == 0) { + s.sendMessage(Utils.f("&c/gameitem add <itemName> [displayName]")); + s.sendMessage(Utils.f("&c/gameitem adds <itemName> <sellPrice> [displayName]")); + s.sendMessage(Utils.f("&c/gameitem addweapon <itemName> <weapon> [displayName]")); + s.sendMessage(Utils.f("&c/gameitem addvehicle <itemName> <vehicle> [displayName]")); + s.sendMessage(Utils.f("&c/gameitem addarmorupgrade <itemName> <armorupgrade> [displayName]")); + s.sendMessage(Utils.f("&c/gameitem adddrug <itemName> <drug> [displayName]")); + s.sendMessage(Utils.f("&c/gameitem remove <itemName>")); + s.sendMessage(Utils.f("&c/gameitem displayName <itemName> [displayName]")); + s.sendMessage(Utils.f("&c/gameitem sellprice <itemName> <price>")); + s.sendMessage(Utils.f("&c/gameitem get <itemName> <amount>")); + s.sendMessage(Utils.f("&c/gameitem give <player> <itemName> <amount>")); + s.sendMessage(Utils.f("&c/gameitem list [page]")); + s.sendMessage(Utils.f("&c/gameitem load")); + s.sendMessage(Utils.f("&c/gameitem save")); + return true; + } + ItemManager im = GTM.getItemManager(); + switch (args[0].toLowerCase()) { + case "add": { + if (args.length < 2) { + s.sendMessage(Utils.f("&c/gameitem add <itemName> [displayName]")); + return true; + } + ItemStack item = ((Player) s).getInventory().getItemInMainHand(); + if (item == null) { + ((Player) s).sendMessage(Lang.GAMEITEMS.f("&cYou need to hold an item in your hand!")); + return true; + } + GameItem gi = im.getItem(args[1]); + if (gi != null) { + im.removeItem(gi); + ((Player) s).sendMessage(Lang.GAMEITEMS + .f("&7That item already existed, so it has been deleted and replaced with the new one.")); + } + + String displayName; + if (args.length > 2) { + displayName = args[2]; + for (int i = 3; i < args.length; i++) + displayName += ' ' + args[i]; + } else { + ItemMeta meta = item.getItemMeta(); + displayName = meta == null || meta.getDisplayName() == null ? item.getType().name() : meta.getDisplayName(); + + } + im.addItem(new GameItem(args[1], item, displayName)); + s.sendMessage(Lang.GAMEITEMS + .f("&7You added an item with name &a" + args[1] + "&7 and Display Name " + displayName + "&7!")); + return true; + } + case "adds": { + if (args.length < 3) { + s.sendMessage(Utils.f("&c/gameitem adds <itemName> <sellPrice> [displayName]")); + return true; + } + ItemStack item = ((Player) s).getInventory().getItemInMainHand(); + if (item == null) { + ((Player) s).sendMessage(Lang.GAMEITEMS.f("&cYou need to hold an item in your hand!")); + return true; + } + GameItem gi = im.getItem(args[1]); + if (gi != null) { + im.removeItem(gi); + ((Player) s).sendMessage(Lang.GAMEITEMS + .f("&7That item already existed, so it has been deleted and replaced with the new one.")); + } + double price; + try { + price = Double.parseDouble(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Lang.GAMEITEMS.f("&7The price must be a number! (double)")); + return true; + } + if (price < 0) { + s.sendMessage(Lang.GAMEITEMS.f("&7The price must be 0 or higher!")); + return true; + + } + String displayName; + if (args.length > 3) { + displayName = args[3]; + for (int i = 4; i < args.length; i++) + displayName = displayName + ' ' + args[i]; + } else { + ItemMeta meta = item.getItemMeta(); + displayName = meta == null || meta.getDisplayName() == null ? item.getType().name() : meta.getDisplayName(); + } + gi = im.addItem(new GameItem(args[1], item, displayName, price)); + s.sendMessage(Lang.GAMEITEMS.f("&7You added an item with name &a" + args[1] + "&7 and sell price &a$&l" + + gi.getSellPrice() + "&7 and Display Name " + displayName + "&7!")); + return true; + } + case "addweapon": { + if (args.length < 3) { + s.sendMessage(Utils.f("&c/gameitem addweapon <itemName> <weapon> [displayName]")); + return true; + } + GameItem gi = im.getItem(args[1]); + if (gi != null) { + im.removeItem(gi); + ((Player) s).sendMessage(Lang.GAMEITEMS + .f("&7That item already existed, so it has been deleted and replaced with the new one.")); + } + Optional<Weapon<?>> w = GTM.getWastedGuns().getWeaponManager().getWeapon(args[2]); + if (w == null || !w.isPresent()) { + s.sendMessage(Lang.GAMEITEMS.f("&7That weapon does not exist!")); + return true; + } + Weapon weapon = w.get(); + if (weapon == null) { + s.sendMessage(Lang.GAMEITEMS.f("&7That weapon does not exist!")); + return true; + } + String displayName; + if (args.length > 3) { + displayName = args[3]; + for (int i = 4; i < args.length; i++) + displayName = displayName + ' ' + args[i]; + } else { + ItemStack item = weapon.getBaseItemStack(); + ItemMeta meta = item.getItemMeta(); + displayName = meta == null || meta.getDisplayName() == null ? item.getType().name() : meta.getDisplayName(); + } + im.addItem(new GameItem(ItemType.WEAPON, args[1], weapon.getName(), displayName)); + s.sendMessage(Lang.GAMEITEMS.f("&7You added an item with name &a" + args[1] + "&7 and weapon &a" + + weapon.getUniqueIdentifier() + "&7 and Display Name " + displayName + "&7!")); + return true; + } + case "adddrug": { + if (args.length < 3) { + s.sendMessage(Utils.f("&c/gameitem addweapon <itemName> <weapon> [displayName]")); + return true; + } + GameItem gi = im.getItem(args[1]); + if (gi != null) { + im.removeItem(gi); + ((Player) s).sendMessage(Lang.GAMEITEMS + .f("&7That item already existed, so it has been deleted and replaced with the new one.")); + } + Optional<Drug> drug = ((DrugService) GTM.getInstance().getDrugManager().getService()).getDrug(args[2]); + if (drug.isPresent()) { + DrugItem drugItem = DrugItem.getByDrug(drug.get()); + if (drugItem == null) { + s.sendMessage(Lang.GAMEITEMS.f("&7That drug does not exist!")); + return true; + } + String displayName; + if (args.length > 3) { + displayName = args[3]; + for (int i = 4; i < args.length; i++) + displayName = displayName + ' ' + args[i]; + } else { + ItemStack item = drugItem.getItemStack(); + ItemMeta meta = item.getItemMeta(); + displayName = meta == null || meta.getDisplayName() == null ? item.getType().name() : meta.getDisplayName(); + } + im.addItem(new GameItem(ItemType.DRUG, args[1], drug.get().getName(), displayName)); + s.sendMessage(Lang.GAMEITEMS.f("&7You added an item with name &a" + args[1] + "&7 and drug &a" + + drug.get().getName() + "&7 and Display Name " + displayName + "&7!")); + } + return true; + } + case "addweapons": { + if (args.length < 4) { + s.sendMessage(Utils.f("&c/gameitem addweapons <itemName> <weapon> <sellPrice> [displayName]")); + return true; + } + GameItem gi = im.getItem(args[1]); + if (gi != null) { + im.removeItem(gi); + ((Player) s).sendMessage(Lang.GAMEITEMS + .f("&7That item already existed, so it has been deleted and replaced with the new one.")); + } + Optional<Weapon<?>> w = GTM.getWastedGuns().getWeaponManager().getWeapon(args[2]); + if (w == null || !w.isPresent()) { + s.sendMessage(Lang.GAMEITEMS.f("&7That weapon does not exist!")); + return true; + } + Weapon weapon = w.get(); + if (weapon == null) { + s.sendMessage(Lang.GAMEITEMS.f("&7That weapon does not exist!")); + return true; + } + double price; + try { + price = Double.parseDouble(args[3]); + } catch (NumberFormatException e) { + s.sendMessage(Lang.GAMEITEMS.f("&7The price must be a number! (double)")); + return true; + } + if (price < 0) { + s.sendMessage(Lang.GAMEITEMS.f("&7The price must be 0 or higher!")); + return true; + } + String displayName; + if (args.length > 4) { + displayName = args[4]; + for (int i = 5; i < args.length; i++) + displayName = displayName + ' ' + args[i]; + } else { + ItemStack item = weapon.getBaseItemStack(); + ItemMeta meta = item.getItemMeta(); + displayName = meta == null || meta.getDisplayName() == null ? item.getType().name() : meta.getDisplayName(); + } + im.addItem(new GameItem(ItemType.WEAPON, args[1], weapon.getName(), displayName, price, 0)); + s.sendMessage(Lang.GAMEITEMS + .f("&7You added an item with name &a" + args[1] + "&7 and weapon &a" + weapon.getName() + + "&7 and sell price &a$&l" + price + "&7 and Display Name " + displayName + "&7!")); + return true; + } + case "addvehicle": { + if (args.length < 3) { + s.sendMessage(Utils.f("&c/gameitem addvehicle <itemName> <vehicle> [displayName]")); + return true; + } + GameItem gi = im.getItem(args[1]); + if (gi != null) { + im.removeItem(gi); + ((Player) s).sendMessage(Lang.GAMEITEMS + .f("&7That item already existed, so it has been deleted and replaced with the new one.")); + } + Optional<VehicleProperties> v = GTM.getWastedVehicles().getVehicle(args[2]); + if (v == null || !v.isPresent()) { + s.sendMessage(Lang.GAMEITEMS.f("&7That vehicle does not exist!")); + return true; + } + VehicleProperties vehicle = v.get(); + if (vehicle == null) { + s.sendMessage(Lang.GAMEITEMS.f("&7That vehicle does not exist!")); + return true; + } + String displayName; + if (args.length > 3) { + displayName = args[3]; + for (int i = 4; i < args.length; i++) + displayName += ' ' + args[i]; + } else { + ItemStack item = vehicle.getItem(); + ItemMeta meta = item.getItemMeta(); + displayName = meta == null || meta.getDisplayName() == null ? item.getType().name() : meta.getDisplayName(); + } + im.addItem(new GameItem(ItemType.VEHICLE, args[1], vehicle.getIdentifier(), displayName)); + s.sendMessage(Lang.GAMEITEMS.f("&7You added an item with name &a" + args[1] + "&7 and vehicle &a" + + vehicle.getIdentifier() + "&7 and Display Name " + displayName + "&7!")); + return true; + } + case "addvehicles": { + if (args.length < 3) { + s.sendMessage(Utils.f("&c/gameitem addweapons <itemName> <vehicle> <sellPrice> [displayName]")); + return true; + } + GameItem gi = im.getItem(args[1]); + if (gi != null) { + im.removeItem(gi); + ((Player) s).sendMessage(Lang.GAMEITEMS + .f("&7That item already existed, so it has been deleted and replaced with the new one.")); + } + Optional<VehicleProperties> v = GTM.getWastedVehicles().getVehicle(args[2]); + if (v == null || !v.isPresent()) { + s.sendMessage(Lang.GAMEITEMS.f("&7That vehicle does not exist!")); + return true; + } + VehicleProperties vehicle = v.get(); + if (vehicle == null) { + s.sendMessage(Lang.GAMEITEMS.f("&7That vehicle does not exist!")); + return true; + } + double price; + try { + price = Double.parseDouble(args[3]); + } catch (NumberFormatException e) { + s.sendMessage(Lang.GAMEITEMS.f("&7The price must be a number! (double)")); + return true; + } + if (price < 0) { + s.sendMessage(Lang.GAMEITEMS.f("&7The price must be 0 or higher!")); + return true; + } + String displayName; + if (args.length > 4) { + displayName = args[4]; + for (int i = 5; i < args.length; i++) + displayName += ' ' + args[i]; + } else { + ItemStack item = vehicle.getItem(); + ItemMeta meta = item.getItemMeta(); + displayName = meta == null || meta.getDisplayName() == null ? item.getType().name() : meta.getDisplayName(); + } + im.addItem(new GameItem(ItemType.VEHICLE, args[1], vehicle.getIdentifier(), displayName, price, 0)); + s.sendMessage(Lang.GAMEITEMS + .f("&7You added an item with name &a" + args[1] + "&7 and vehicle &a" + vehicle.getIdentifier() + + "&7 and sell price &a$&l" + price + "&7 and Display Name " + displayName + "&7!")); + return true; + } + case "addarmorupgrade": { + if (args.length < 3) { + s.sendMessage(Utils.f("&c/gameitem addarmorupgrade <itemName> <armorupgrade> [displayName]")); + return true; + } + GameItem gi = im.getItem(args[1]); + if (gi != null) { + im.removeItem(gi); + ((Player) s).sendMessage(Lang.GAMEITEMS + .f("&7That item already existed, so it has been deleted and replaced with the new one.")); + } + ArmorUpgrade upgrade = ArmorUpgrade.getArmorUpgrade(args[2]); + if (upgrade == null) { + s.sendMessage(Lang.GAMEITEMS.f("&7That vehicle does not exist!")); + return true; + } + String displayName = Utils.f("&b&l" + upgrade.getDisplayName() + " Armor Upgrade: &a" + upgrade.getDisplayName()); + im.addItem(new GameItem(args[1], upgrade, displayName)); + s.sendMessage(Lang.GAMEITEMS.f("&7You added an item with name &a" + args[1] + "&7 and armor upgrade &a" + + upgrade.getDisplayName() + "&7 and Display Name " + displayName + "&7!")); + return true; + } + case "remove": { + if (args.length < 2) { + s.sendMessage(Utils.f("&c/gameitem remove <itemName>")); + return true; + } + GameItem gi = im.getItem(args[1]); + if (gi == null) { + s.sendMessage(Lang.GAMEITEMS.f("&7That GameItem does not exist!")); + return true; + } + im.removeItem(gi); + s.sendMessage(Lang.GAMEITEMS.f("&7GameItem &a" + gi.getName() + "&7 was removed!")); + return true; + } + case "displayname": { + if (args.length < 2) { + s.sendMessage(Utils.f("&c/gameitem displayName <itemName> [displayName]")); + return true; + } + GameItem gi = im.getItem(args[1]); + if (gi == null) { + s.sendMessage(Lang.GAMEITEMS.f("&7That GameItem does not exist!")); + return true; + } + String displayName = args[2]; + for (int i = 3; i < args.length; i++) + displayName = displayName + ' ' + args[i]; + gi.setDisplayName(displayName); + s.sendMessage(Lang.GAMEITEMS.f("&7You set the display name of GameItem &a" + gi.getName() + "&7 to &a" + + gi.getDisplayName() + '!')); + return true; + } + case "sellprice": { + if (args.length < 2) { + s.sendMessage(Utils.f("&c/gameitem sellprice <itemName> <price>")); + return true; + } + GameItem gi = im.getItem(args[1]); + if (gi == null) { + s.sendMessage(Lang.GAMEITEMS.f("&7That GameItem does not exist!")); + return true; + } + double price; + try { + price = Double.parseDouble(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Lang.GAMEITEMS.f("&7The price must be a number! (double)")); + return true; + } + if (price < 0) { + s.sendMessage(Lang.GAMEITEMS.f("&7The price must be 0 or higher!")); + return true; + + } + gi.setSellPrice(price); + s.sendMessage(Lang.GAMEITEMS.f("&7You set the sell price of GameItem &a" + gi.getName() + "&7 to &a$&l" + + gi.getSellPrice() + '!')); + return true; + } + case "get": { + if (args.length < 2) { + s.sendMessage(Utils.f("&c/gameitem get <itemName> <amount>")); + return true; + } + GameItem gi = im.getItem(args[1]); + if (gi == null) { + s.sendMessage(Lang.GAMEITEMS.f("&7That GameItem does not exist!")); + return true; + } + ItemStack item = gi.getItem(); + if (args.length > 2) + try { + item.setAmount(Integer.parseInt(args[2])); + } catch (NumberFormatException e) { + s.sendMessage(Lang.GAMEITEMS.f("&7The amount must be a number! (integer)")); + return true; + } + ((Player) s).getInventory().addItem(item); + s.sendMessage(Lang.GAMEITEMS.f((args.length > 2 ? "&a" + args[2] + "&7 of " : "") + "&7GameItem &a" + + gi.getName() + "&7 was added to your inventory!")); + return true; + } + case "give": { + if (args.length < 3) { + s.sendMessage(Utils.f("&c/gameitem give <player> <itemName> <amount>")); + return true; + } + Player pl = Bukkit.getPlayer(args[1]); + if (pl == null) { + s.sendMessage(Lang.GAMEITEMS.f("&7That player is not online!")); + return true; + } + GameItem gi = im.getItem(args[2]); + if (gi == null) { + s.sendMessage(Lang.GAMEITEMS.f("&7That GameItem does not exist!")); + return true; + } + ItemStack item = gi.getItem(); + if (args.length > 3) + try { + item.setAmount(Integer.parseInt(args[3])); + } catch (NumberFormatException e) { + s.sendMessage(Lang.GAMEITEMS.f("&7The amount must be a number! (integer)")); + return true; + } + pl.getInventory().addItem(item); + s.sendMessage(Lang.GAMEITEMS.f("&7You gave " + (args.length > 3 ? "&a" + args[3] + "&7 of " : "") + + "GameItem &a" + gi.getName() + "&7 to &a" + pl.getName() + '!')); + return true; + } + case "list": + List<GameItem> items = GTM.getItemManager().getItems(); + int page = 1; + if (args.length > 1) { + try { + page = Integer.parseInt(args[1]); + } catch (NumberFormatException e) { + s.sendMessage(Lang.GAMEITEMS.f("&cThe page must be a number!")); + return true; + } + } + if (page < 1) { + s.sendMessage(Lang.GAMEITEMS.f("&7The page must be a positive number!")); + return true; + } + int pages = items.size() / 6 + 1; + s.sendMessage(Utils.f(" &7&m---------------&7[&a&l Game Items &7Page &a" + page + "&7/&a" + pages + + " &7&m]---------------")); + Iterator<GameItem> it = items.iterator(); + for (int i = 0; i < page * 6; i++) { + if (!it.hasNext()) + return true; + GameItem item = it.next(); + if (i < page * 6 - 6) + continue; + s.sendMessage(Utils.f("&a&l" + item.getType() + "&a " + item.getName() + + " &7| &7Display Name: &r" + item.getDisplayName() + + (item.getSellPrice() >= 0 ? "&7 Sell Price: &a$&l" + item.getSellPrice() : ""))); + } + return true; + case "load": + GTM.getSettings().setItemsConfig(Utils.loadConfig("items")); + GTM.getItemManager().loadItems(); + s.sendMessage(Lang.GAMEITEMS.f("&7Loaded GameItems!")); + return true; + case "save": + GTM.getItemManager().saveItems(); + s.sendMessage(Lang.GAMEITEMS.f("&7Saved GameItems!")); + return true; + default: + s.sendMessage(Utils.f("&c/gameitem add <itemName> [displayName]")); + s.sendMessage(Utils.f("&c/gameitem addweapon <itemName> [displayName]")); + s.sendMessage(Utils.f("&c/gameitem addvehicle <itemName> [displayName]")); + s.sendMessage(Utils.f("&c/gameitem remove <itemName>")); + s.sendMessage(Utils.f("&c/gameitem displayName <itemName> [displayName]")); + s.sendMessage(Utils.f("&c/gameitem sellprice <itemName> <price>")); + s.sendMessage(Utils.f("&c/gameitem get <itemName>")); + s.sendMessage(Utils.f("&c/gameitem give <player> <itemName>")); + s.sendMessage(Utils.f("&c/gameitem list [page]")); + s.sendMessage(Utils.f("&c/gameitem load")); + s.sendMessage(Utils.f("&c/gameitem save")); + return true; + } + } +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/Head.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/Head.java new file mode 100644 index 0000000..ea1a36c --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/Head.java @@ -0,0 +1,263 @@ +package net.grandtheftmc.gtm.items; + +import java.util.Objects; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.SkullMeta; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.users.GTMUserDAO; + +/** + * Created by Liam on 4/10/2016. + */ +public class Head { + + private final UUID sellerUUID; + private final String sellerName; + private final String head; + private final long expiry; + private boolean done; + private boolean paid; + private boolean gaveHead; + private UUID bidderUUID; + private String bidderName; + private double bid = -1; + + public Head(UUID sellerUUID, String sellerName, String head) { + this.sellerUUID = sellerUUID; + this.sellerName = sellerName; + this.head = head; + this.expiry = System.currentTimeMillis() + 86400000; +// Core.sql.updateAsyncLater("insert into " + Core.name() + "_heads(sellerUUID, sellerName, head, expiry) values ('" + this.sellerUUID + "','" + this.sellerName + "','" + this.head + "'," + this.expiry + ");"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("insert into " + Core.name() + "_heads(sellerUUID, sellerName, head, expiry) values ('" + this.sellerUUID + "','" + this.sellerName + "','" + this.head + "'," + this.expiry + ");")); + + } + + public Head(UUID sellerUUID, String sellerName, String head, long expiry, boolean done, boolean paid, boolean gaveHead, UUID bidderUUID, String bidderName, double bid) { + this.sellerUUID = sellerUUID; + this.sellerName = sellerName; + this.head = head; + this.expiry = expiry; + this.done = done; + this.paid = paid; + this.gaveHead = gaveHead; + this.bidderUUID = bidderUUID; + this.bidderName = bidderName; + this.bid = bid; + } + + public UUID getSellerUUID() { + return this.sellerUUID; + } + + public String getSellerName() { + return this.sellerName; + } + + public String getHead() { + return this.head; + } + + public long getExpiry() { + return this.expiry; + } + + public UUID getBidderUUID() { + return this.bidderUUID; + } + + public String getBidderName() { + return this.bidderName; + } + + public double getBid() { + return this.bid; + } + + public boolean hasBid() { + return this.bidderUUID != null; + } + + public boolean hasExpired() { + return this.hasBid() ? this.expiry < System.currentTimeMillis() : this.expiry - 82800000 < System.currentTimeMillis(); + } + + public boolean hasExpiredOverAWeekAgo() { + return this.expiry + 604800000 < System.currentTimeMillis(); + } + + public Long getTimeUntilExpiry() { + return this.expiry - System.currentTimeMillis(); + } + + public boolean isDone() { + return this.done; + } + + public boolean isPaid() { + return this.paid; + } + + public boolean gaveHead() { + return this.gaveHead; + } + + public ItemStack getItem() { +// ItemStack i = Utils.createItem(Material.SKULL_ITEM, 3, "&e&l" + this.head + "'s Head", "&7Value: &a$&l" + (this.hasBid() ? "10,000" : this.bid), "&7Sell me in the sewer!"); + ItemStack i = new ItemFactory(Material.SKULL_ITEM, (byte) 3) + .setName(C.YELLOW + C.BOLD + this.head + "'s Head") + .setLore(C.GRAY + "Value: " + C.GREEN + C.BOLD + (this.hasBid() ? "10,000" : this.bid), C.GRAY + "Sell me in the sewer!") + .build(); + + SkullMeta meta = (SkullMeta) i.getItemMeta(); + meta.setOwner(this.head); + i.setItemMeta(meta); + + return i; + } + + public boolean giveHead() { + if (this.gaveHead) return false; + if (!this.hasBid()) { + this.gaveHead = true; + return true; + } + + Player bidder = Bukkit.getPlayer(this.bidderUUID); + if (bidder == null) return false; + + if (bidder.getInventory().firstEmpty() < 0) { + bidder.sendMessage(Lang.HEAD_AUCTION.f("&7The auction for &e&l" + this.head + "'s Head&7 has finished! Please clear a slot in your inventory and wait a few seconds.")); + return false; + } + + bidder.getInventory().addItem(this.getItem()); + bidder.updateInventory(); + bidder.sendMessage(Lang.HEAD_AUCTION.f("&7The auction for &e&l" + this.head + "'s Head&7 has finished! Congratulations on winning the bid.")); + this.gaveHead = true; + return true; + } + + public boolean paySeller() { + if (this.paid) return false; + Player seller = Bukkit.getPlayer(this.sellerUUID); + if (seller == null) + return false; + GTMUser user = GTM.getUserManager().getLoadedUser(seller.getUniqueId()); + if (!this.hasBid()) { + seller.sendMessage(Lang.HEAD_AUCTION.f("&7The auction for &e&l" + this.head + "'s Head&7 has finished with no bids!")); + this.paid = true; + return true; + } + if (this.bid > 10000) + user.addBank(this.bid - 10000); + GTMUtils.updateBoard(seller, user); + seller.sendMessage(Lang.HEAD_AUCTION.f("&7The auction for &e&l" + this.head + "'s Head&7 has finished with &a$&l" + this.bid + "&7! You received &a$&l" + (this.bid - 10000) + "&7 from &a&l" + this.bidderName + "&7!")); + this.paid = true; + return true; + } + + public boolean delete() { + if ((this.done && this.gaveHead && this.paid) || this.hasExpiredOverAWeekAgo()) { +// Core.sql.updateAsyncLater("delete from " + Core.name() + "_heads where sellerUUID='" + this.sellerUUID + "' and head='" + this.head + "' and expiry=" + this.expiry + ';'); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("delete from " + Core.name() + "_heads where sellerUUID='" + this.sellerUUID + "' and head='" + this.head + "' and expiry=" + this.expiry + ';')); + GTM.getShopManager().removeHead(this); + return true; + } + return false; + } + + public void update() { + if (!this.hasExpired()) + return; + boolean update = !this.done; + this.done = true; + if (this.giveHead()) update = true; + if (this.paySeller()) update = true; + if (this.delete()) update = true; + if (update) + this.updateDB(); + } + + + public void updateDB() { +// Core.sql.updateAsyncLater("update " + Core.name() + "_heads set paid=" + this.paid + ", gaveHead=" + this.gaveHead + ", done=" + this.done + ", bidderUUID=" + (this.bidderUUID == null ? null : "'" + this.bidderUUID + '\'') + ",bidderName = '" + +// this.bidderName + "', bid=" + this.bid + " where sellerUUID='" + this.sellerUUID + "' and head='" + this.head + "' and expiry=" + this.expiry + ';'); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + Core.name() + "_heads set paid=" + this.paid + ", gaveHead=" + this.gaveHead + ", done=" + this.done + ", bidderUUID=" + (this.bidderUUID == null ? null : "'" + this.bidderUUID + '\'') + ",bidderName = '" + + this.bidderName + "', bid=" + this.bid + " where sellerUUID='" + this.sellerUUID + "' and head='" + this.head + "' and expiry=" + this.expiry + ';')); + } + + public void returnBidderMoney() { + Player bidder = Bukkit.getPlayer(this.bidderUUID); + if (bidder == null) { +// Core.sql.updateAsyncLater("update " + Core.name() + " set bank=bank+" + this.bid + " where uuid='" + this.bidderUUID + "';"); + final UUID prevBidder = this.bidderUUID; + final double amt = this.bid; + ServerUtil.runTaskAsync(() -> GTMUserDAO.addBank(prevBidder, amt)); + this.bidderName = null; + this.bidderUUID = null; + this.bid = -1; + return; + } + GTMUser user = GTM.getUserManager().getLoadedUser(bidder.getUniqueId()); + user.addBank(this.bid); + GTMUtils.updateBoard(bidder, user); + bidder.sendMessage(Lang.HEAD_AUCTION.f("&7You were outbid for the &e&l" + this.head + "'s Head&7! Your bid of &a$&l" + this.bid + "&7 was returned to your bank account.")); + this.bidderName = null; + this.bidderUUID = null; + this.bid = -1; + } + + public void bid(Player player, GTMUser user, double bid) { + bid = Utils.round(bid); + if (this.hasExpired() || this.done) { + player.sendMessage(Lang.HEAD_AUCTION.f("&7The bidding has expired!")); + return; + } + if (!user.hasMoney(bid)) { + player.sendMessage(Lang.HEAD_AUCTION.f("&7You don't have &c$&l" + bid + "&7!")); + return; + } + + if (this.hasBid()) { + if (this.bid * 1.05 > bid) { + player.sendMessage(Lang.HEAD_AUCTION.f("&7You must bid at least &a&l5%&7 more than the current bid of &a$&l" + this.bid + "&7 (&a$&l" + (this.bid * 1.05) + "&7)!")); + return; + } + this.returnBidderMoney(); + } else if (bid < 10000) { + player.sendMessage(Lang.HEAD_AUCTION.f("&7You must bid at least the starting bid of &a$&l10,000&7!")); + return; + } + this.setBid(player, bid); + user.takeMoney(bid); + GTMUtils.updateBoard(player, user); + player.sendMessage(Lang.HEAD_AUCTION.f("&7You have bid &a$&l" + this.bid + "&7 for &e&l" + this.head + "'s Head&7! Please wait &c&l" + Utils.timeInMillisToText(this.getTimeUntilExpiry()) + "&7 for the auction to end.")); + Player seller = Bukkit.getPlayer(this.sellerUUID); + if (seller != null && !Objects.equals(seller, player)) + seller.sendMessage(Lang.HEAD_AUCTION.f("&a&l" + player.getName() + "&7 has bid &a$&l" + this.bid + "&7 on &e&l" + this.head + "'s Head&7!")); + } + + public void setBid(Player player, double bid) { + this.bidderUUID = player.getUniqueId(); + this.bidderName = player.getName(); + this.bid = bid; + this.updateDB(); + } + + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/ItemManager.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/ItemManager.java new file mode 100644 index 0000000..16973d3 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/ItemManager.java @@ -0,0 +1,410 @@ +package net.grandtheftmc.gtm.items; + +import com.j0ach1mmall3.jlib.methods.Parsing; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.State; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.items.GameItem.ItemType; +import net.grandtheftmc.gtm.users.CheatCode; +import net.grandtheftmc.gtm.users.GTMRank; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.users.JobMode; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class ItemManager { + + private List<GameItem> items = new ArrayList<>(); + private List<Kit> kits = new ArrayList<>(); + + public ItemManager() { + this.loadItems(); + this.loadKits(); + } + + public void m(int i) { + Bukkit.broadcastMessage(String.valueOf(i)); + } + + public void m(String s) { + Bukkit.broadcastMessage(s); + } + + public void loadItems() { + this.items = new ArrayList<>(); + YamlConfiguration c = GTM.getSettings().getItemsConfig(); + if (c == null) + return; + for (String name : c.getKeys(false)) { + try { + String displayName = c.getString(name + ".displayName"); + double sellPrice = -1, buyPrice = -1; + boolean hideDurability = false, stackable = false; + if (c.get(name + ".sellPrice") != null) sellPrice = c.getDouble(name + ".sellPrice"); + if (c.get(name + ".buyPrice") != null) buyPrice = c.getDouble(name + ".buyPrice"); + if (c.get(name + ".hideDurability") != null) hideDurability = c.getBoolean(name + ".hideDurability"); + if(c.get(name + ".stackable") !=null) stackable = c.getBoolean(name + ".stackable"); + + if (displayName.equals("weapon_skin_common") || displayName.equals("weapon_skin_common") + || displayName.equals("weapon_skin_common") || displayName.equals("weapon_skin_common")) { + this.items.add(new GameItem(ItemType.SKIN, name, "null", displayName, sellPrice, buyPrice, hideDurability)); + continue; + } + + if (c.get(name + ".weapon") != null) + this.items.add(new GameItem(ItemType.WEAPON, name, c.getString(name + ".weapon"), displayName, sellPrice, buyPrice, hideDurability)); + else if (!Core.getSettings().isSister() && c.get(name + ".drug") != null) + this.items.add(new GameItem(ItemType.DRUG, name, c.getString(name + ".drug"), displayName, sellPrice, buyPrice, hideDurability)); + else if (c.get(name + ".vehicle") != null) + this.items.add(new GameItem(ItemType.VEHICLE, name, c.getString(name + ".vehicle"), displayName, sellPrice, buyPrice, hideDurability)); + else if (c.get(name + ".ammo") != null) + this.items.add(new GameItem(name, Parsing.parseItemStack(c.getString(name + ".item")), + AmmoType.getAmmoType(c.getString(name + ".ammo")), displayName, sellPrice, buyPrice)); + else if (c.get(name + ".armorupgrade") != null) { + ArmorUpgrade upgrade = ArmorUpgrade.getArmorUpgrade(c.getString(name + ".armorupgrade")); + if (upgrade == null) + GTM.error("Error while loading item " + name + ": " + c.getString(name + ".ammo") + " is not a valid ArmorUpgrade!"); + else + this.items.add(new GameItem(name, upgrade, displayName, sellPrice, buyPrice)); + } else if (c.get(name + ".item") != null) + this.items.add(new GameItem(name, Parsing.parseItemStack(c.getString(name + ".item")), displayName, sellPrice, buyPrice, hideDurability, stackable)); + } catch (Exception e) { + GTM.error("Error while loading item " + name + '!'); + e.printStackTrace(); + } + } + } + + public void saveItems() { + YamlConfiguration c = GTM.getSettings().getItemsConfig(); + for (String s : c.getKeys(false)) + c.set(s, null); + for (GameItem item : this.items) { + String name = item.getName(); + c.set(name + ".displayName", item.getDisplayName()); + if (item.getSellPrice() > 0) { + c.set(name + ".sellPrice", item.getSellPrice()); + } + if (item.getBuyPrice() > 0) { + c.set(name + ".buyPrice", item.getBuyPrice()); + } + if (item.getHideDurability()) { + c.set(name + ".hideDurability", item.getHideDurability()); + } + if(item.isStackable()) + c.set(name + ".stackable", item.isStackable()); + if (item.getType() == ItemType.WEAPON) { + c.set(name + ".weapon", item.getWeaponOrVehicleOrDrug()); + } else if (item.getType() == ItemType.DRUG) { + c.set(name + ".drug", item.getWeaponOrVehicleOrDrug()); + } else if (item.getType() == ItemType.VEHICLE) { + c.set(name + ".vehicle", item.getWeaponOrVehicleOrDrug()); + } else if (item.getType() == ItemType.AMMO) { + c.set(name + ".ammo", item.getAmmoType().toString().toLowerCase()); + c.set(name + ".item", Parsing.parseString(item.getItem())); + } else if (item.getType() == ItemType.ARMOR_UPGRADE) { + c.set(name + ".armorupgrade", item.getArmorUpgrade().toString().toLowerCase()); + } else { + c.set(name + ".item", Parsing.parseString(item.getItem())); + } + } + Utils.saveConfig(c, "items"); + } + + public void loadKits() { + YamlConfiguration c = GTM.getSettings().getKitsConfig(); + this.kits = new ArrayList<>(); + for (String name : c.getKeys(false)) { + try { + double cost = 0; + CheatCode code = null; + int delay = 60; + if(c.get(name + ".cheatcode") !=null) + code = CheatCode.valueOf(c.getString(name + ".cheatcode")); + if (c.get(name + ".cost") != null) + cost = c.getDouble(name + ".cost"); + if (c.get(name + ".delay") != null) + delay = c.getInt(name + ".delay"); + List<KitItem> contents = c.getStringList(name + ".contents").stream().map(this::kitItemFromString).collect(Collectors.toList()); + KitItem helmet = this.kitItemFromString(c.getString(name + ".helmet")); + KitItem chestplate = this.kitItemFromString(c.getString(name + ".chestplate")); + KitItem leggings = this.kitItemFromString(c.getString(name + ".leggings")); + KitItem boots = this.kitItemFromString(c.getString(name + ".boots")); + KitItem offHand = this.kitItemFromString(c.getString(name + ".offHand")); + String perm = c.getString(name + ".permission"); + this.kits.add(new Kit(name, cost, delay, contents, helmet, chestplate, leggings, boots, offHand, perm, code)); + } catch (Exception e) { + Core.error("Error while loading kit " + name); + e.printStackTrace(); + } + } + } + + public KitItem kitItemFromString(String s) { + if (s == null) + return null; + String[] a = s.split(":"); + if (a.length == 0) + return null; + GameItem item = this.getItem(a[0]); + try { + return new KitItem(item, a.length > 1 ? Integer.parseInt(a[1]) : 1); + } catch (NumberFormatException e) { + Core.error("Error parsing kititem: " + s); + return null; + } + + } + + public void saveKits() { + YamlConfiguration c = GTM.getSettings().getKitsConfig(); + for (String s : c.getKeys(false)) + c.set(s, null); + for (Kit kit : this.kits) { + String name = kit.getName(); + try { + if (kit.getCost() > 0) + c.set(name + ".cost", kit.getCost()); + if(kit.getCode()!=null) + c.set(name + ".cheatcode", kit.getCode().toString()); + if (kit.getDelay() > 0) + c.set(name + ".delay", kit.getDelay()); + List<String> contents = kit.getContents().stream().map(this::kitItemToString).collect(Collectors.toList()); + c.set(name + ".contents", contents); + c.set(name + ".helmet", this.kitItemToString(kit.getHelmet())); + c.set(name + ".chestplate", this.kitItemToString(kit.getChestPlate())); + c.set(name + ".leggings", this.kitItemToString(kit.getLeggings())); + c.set(name + ".boots", this.kitItemToString(kit.getBoots())); + c.set(name + ".offHand", this.kitItemToString(kit.getOffHand())); + c.set(name + ".permission", kit.getPermission()); + } catch (Exception e) { + Core.error("Error while saving kit " + name); + e.printStackTrace(); + } + } + Utils.saveConfig(c, "kits"); + } + + public String kitItemToString(KitItem item) { + if (item == null || item.getGameItem() == null) + return null; + return item.getGameItem().getName() + (item.getAmount() > 1 ? ":" + item.getAmount() : ""); + } + + public GameItem getItem(String itemName) { + return this.items.stream().filter(item -> item.getName().equalsIgnoreCase(itemName)).findFirst().orElse(null); + + } + + public GameItem getItemFromDisplayName(String itemName) { + return this.items.stream().filter(item -> ChatColor.stripColor(Utils.f(item.getDisplayName())).equalsIgnoreCase(ChatColor.stripColor(Utils.f(itemName)))).findFirst().orElse(null); + } + + public GameItem getItem(ItemStack item) { + if (item != null) + return this.items.stream().filter(g -> { + boolean namesMatch = true; + if(g.getItem().hasItemMeta() && g.getItem().getItemMeta().hasDisplayName() && item.hasItemMeta() && item.getItemMeta().hasDisplayName()) { + if(g.getType() == ItemType.WEAPON && /*g.getItem().getItemMeta().getDisplayName().contains("»") && */g.getItem().getItemMeta().getDisplayName().contains("«")) { + String a = ChatColor.stripColor(g.getItem().getItemMeta().getDisplayName()).split("«")[0]; + String b = ChatColor.stripColor(item.getItemMeta().getDisplayName()).split("«")[0]/*.replace("/0", "")*/; + if(!a.equalsIgnoreCase(b)) { + namesMatch = false; + } + } + } + return g.getItem().getType() == item.getType() && g.getItem().getDurability() == item.getDurability() && namesMatch; + }).findFirst().orElse(null); return null; + } + + public GameItem getSellableItem(ItemStack is, int range) { + return this.items.stream().filter(g -> + g.canSell() && + g.getType() == ItemType.WEAPON && + g.getItem().getType() == is.getType() && + is.getDurability() > g.getItem().getDurability() && + is.getDurability() < g.getItem().getDurability() + range + ).findFirst().orElse(null); + } + + /** + * @param damagableItem if the item can be damaged during normal use, ex. Armor + */ + public GameItem getSellableItem(ItemStack is, boolean damagableItem) { + return this.items.stream().filter(g -> g.canSell() && g.getItem().getType()==is.getType() && (damagableItem || g.getItem().getDurability() == is.getDurability())).findFirst().orElse(null); + } + + public GameItem getSellableItem(ItemStack is) { + return getSellableItem(is, false); + } + + public GameItem getItem(Material material) { + return this.items.stream().filter(g -> g.getItem().getType() == material).findFirst().orElse(null); + } + + public GameItem getItemFromWeapon(String s) { + return this.items.stream().filter(g -> g.getType() == ItemType.WEAPON && g.getWeaponOrVehicleOrDrug().equalsIgnoreCase(s)).findFirst().orElse(null); + } + + public GameItem getItemFromVehicle(String s) { + return this.items.stream().filter(g -> g.getType() == ItemType.VEHICLE && g.getWeaponOrVehicleOrDrug().equalsIgnoreCase(s)).findFirst().orElse(null); + } + + public GameItem getItem(ArmorUpgrade upgrade) { + return this.items.stream().filter(g -> g.getType() == ItemType.ARMOR_UPGRADE && upgrade == g.getArmorUpgrade()).findFirst().orElse(null); + } + + + public List<Kit> getKits() { + return this.kits; + } + + public boolean giveKit(Player player, User user, GTMUser gtmUser, String name) { + if (gtmUser.isArrested()) { + player.sendMessage(Lang.JAIL.f("&7You can't get a kit in jail!")); + return true; + } + Kit kit = this.getKit(name); + if (kit == null) { + player.sendMessage(Utils.f(Lang.KITS.f("&cThat kit does not exist!"))); + return false; + } + if (kit.getPermission() != null && !player.hasPermission(kit.getPermission())) { + player.sendMessage(Lang.KITS.f("&7You don't have permission to use this kit!")); + return false; + } + if(kit.getCode()!=null && gtmUser.getCheatCodeState(kit.getCode()).getState() == State.LOCKED) { + player.sendMessage(Lang.CHEAT_CODES.f("&7You haven't unlocked this cheat code yet!")); + return false; + } + JobMode mode = JobMode.getMode(kit.getName()); + UserRank ur = UserRank.getUserRankOrNull(kit.getName()); + GTMRank rank = GTMRank.getRankOrNull(kit.getName()); + if (ur == null && mode != null && mode != gtmUser.getJobMode()) { + player.sendMessage(Lang.KITS.f("&7You need to be on the " + mode.getColoredNameBold() + + "&7 job to use this kit!")); + return false; + } else if (ur != null && !(ur == user.getUserRank() + || (ur == UserRank.SUPREME && user.getUserRank().isHigherThan(UserRank.SUPREME)))) { + player.sendMessage( + Lang.KITS.f("&7You need to be " + ur.getColoredNameBold() + "&7 to use this kit!")); + return false; + } else if (rank != null && !(rank == GTMRank.HOBO || rank == gtmUser.getRank() + || (rank == GTMRank.CRIMINAL && gtmUser.getRank() != GTMRank.HOBO))) { + player.sendMessage(Lang.KITS.f("&7You need to be rank " + rank.getColoredNameBold() + + "&7 to use this kit!")); + return false; + } + if (kit.getCost() > 0 && !gtmUser.hasMoney(kit.getCost())) { + player.sendMessage( + Lang.KITS.f("&7You do not have the &c$&l" + kit.getCost() + "&7 to pay for this kit!")); + return false; + } + if (!gtmUser.canUseKit(kit.getName())) { + player.sendMessage(Lang.KITS.f("&7You need to wait &c" + + Utils.timeInMillisToText(gtmUser.getKitExpiry(kit.getName()) - System.currentTimeMillis()) + + "&7 to use this kit again!")); + return false; + } + gtmUser.setKitExpiry(kit.getName(), kit.getDelay()); + if (kit.getCost() > 0) { + gtmUser.takeMoney(kit.getCost()); + player.sendMessage(Lang.MONEY_TAKE.toString() + kit.getCost()); + GTMUtils.updateBoard(player, user, gtmUser); + } + player.sendMessage(Lang.KITS.f("&7You received the kit &b" + kit.getName() + "&7!")); + this.giveKitItems(player, gtmUser, kit); + return true; + } + + public void giveKitItems(Player player, GTMUser gtmUser, Kit kit) { + List<ItemStack> items = new ArrayList<>(kit.getItems()); + ItemStack helmet = this.kitItemToItemStack(kit.getHelmet()); + ItemStack chestPlate = this.kitItemToItemStack(kit.getChestPlate()); + ItemStack leggings = this.kitItemToItemStack(kit.getLeggings()); + ItemStack boots = this.kitItemToItemStack(kit.getBoots()); + ItemStack offHand = this.kitItemToItemStack(kit.getOffHand()); + if (helmet != null) + if (player.getInventory().getHelmet() == null) + player.getInventory().setHelmet(helmet); + else + items.add(helmet); + if (chestPlate != null) + if (player.getInventory().getChestplate() == null) + player.getInventory().setChestplate(chestPlate); + else + items.add(chestPlate); + if (leggings != null) + if (player.getInventory().getLeggings() == null) + player.getInventory().setLeggings(leggings); + else + items.add(leggings); + if (boots != null) + if (player.getInventory().getBoots() == null) + player.getInventory().setBoots(boots); + else + items.add(boots); + if (offHand != null) + if (player.getInventory().getItemInOffHand() == null) + player.getInventory().setItemInOffHand(offHand); + else + items.add(offHand); + for (ItemStack stack : new ArrayList<>(items)) { + AmmoType type = AmmoType.getAmmoType(stack.getType(), stack.getDurability()); + if (type != null && !type.isInInventory()) { + gtmUser.addAmmo(type, stack.getAmount()); + player.sendMessage(Lang.AMMO_ADD.f(stack.getAmount() + "&7 " + type.getGameItem().getDisplayName())); + items.remove(stack); + } + } + if (Utils.giveItems(player, Utils.toArray(items))) + player.sendMessage( + Utils.f(Lang.KITS + "&cYour inventory was full so some items were dropped on the ground!")); + } + + public ItemStack kitItemToItemStack(KitItem item) { + if (item == null || item.getGameItem() == null) + return null; + ItemStack i = item.getGameItem().getItem(); + i.setAmount(item.getAmount()); + return i; + } + + public Kit getKit(String name) { + return this.kits.stream().filter(kit -> kit.getName().equalsIgnoreCase(name)).findFirst().orElse(null); + } + + public GameItem addItem(GameItem gameItem) { + this.items.add(gameItem); + return gameItem; + } + + public void removeItem(GameItem gi) { + this.items.remove(gi); + + } + + public void addKit(Kit kit) { + this.kits.add(kit); + } + + public List<GameItem> getItems() { + return this.items; + } + + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/Kit.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/Kit.java new file mode 100644 index 0000000..31f73ea --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/Kit.java @@ -0,0 +1,163 @@ +package net.grandtheftmc.gtm.items; + +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.gtm.users.CheatCode; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; +import java.util.List; + +public class Kit { + + private String name; + private double cost; + private int delay; + private List<KitItem> contents; + private KitItem helmet; + private KitItem chestPlate; + private KitItem leggings; + private KitItem boots; + private KitItem offHand; + private CheatCode code; + + private String permission; + + public Kit(String name, double cost, int delay, List<KitItem> contents, KitItem helmet, KitItem chestPlate, + KitItem leggings, KitItem boots, KitItem offHand, String permission, CheatCode code) { + this.name = name; + this.cost = cost; + this.delay = delay; + this.contents = contents; + this.helmet = helmet; + this.chestPlate = chestPlate; + this.leggings = leggings; + this.boots = boots; + this.offHand = offHand; + this.permission = permission; + this.code = code; + } + + public List<ItemStack> getItems() { + List<ItemStack> items = new ArrayList<>(); + for (KitItem item : this.contents) { + GameItem g = item.getItem(); + if (g != null) { + ItemStack i = g.getItem(); + i.setAmount(item.getAmount()); + items.add(i); + } + } + return items; + + } + + public CheatCode getCode() { + return code; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public double getCost() { + return this.cost; + } + + public void setCost(double cost) { + this.cost = cost; + } + + public int getDelay() { + return this.delay; + } + + public void setDelay(int delay) { + this.delay = delay; + } + + public List<KitItem> getContents() { + return this.contents; + } + + public void setContents(List<KitItem> contents) { + this.contents = contents; + } + + public KitItem getHelmet() { + return this.helmet; + } + + public void setHelmet(KitItem helmet) { + this.helmet = helmet; + } + + public KitItem getChestPlate() { + return this.chestPlate; + } + + public void setChestPlate(KitItem chestPlate) { + this.chestPlate = chestPlate; + } + + public KitItem getLeggings() { + return this.leggings; + } + + public void setLeggings(KitItem leggings) { + this.leggings = leggings; + } + + public KitItem getBoots() { + return this.boots; + } + + public void setBoots(KitItem boots) { + this.boots = boots; + } + + public KitItem getOffHand() { + return this.offHand; + } + + public void setOffHand(KitItem offHand) { + this.offHand = offHand; + } + + public String getPermission() { + return this.permission; + } + + public void setPermission(String permission) { + this.permission = permission; + } + + public Material getMaterial() { + KitItem i = this.contents.get(0); + if (i == null) + return Material.STONE; + GameItem g = i.getItem(); + if (g == null) + return Material.STONE; + ItemStack it = g.getItem(); + if (it == null) + return Material.STONE; + return it.getType(); + } + + public String getDisplayName() { + UserRank rank = UserRank.getUserRankOrNull(this.name); + return Utils.f(rank == null ? "&e&l" + String.valueOf(this.name.charAt(0)).toUpperCase() + this.name.substring(1) + : rank.getColoredNameBold()); + } + + public boolean hasArmor() { + return this.helmet != null || this.chestPlate != null || this.leggings != null || this.boots != null; + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/KitCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/KitCommand.java new file mode 100644 index 0000000..ace2337 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/KitCommand.java @@ -0,0 +1,387 @@ +package net.grandtheftmc.gtm.items; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.gtm.GTM; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class KitCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (s instanceof Player && !s.hasPermission("command.kit")) { + MenuManager.openMenu((Player) s, "kits"); + return true; + } + if (args.length == 0) { + s.sendMessage(Utils.f("&c/kit add <name> <cost> <delay> [permission] ")); + s.sendMessage(Utils.f("&c/kit setcost <name> <cost>")); + s.sendMessage(Utils.f("&c/kit setdelay <name> <delay>")); + s.sendMessage(Utils.f("&c/kit give <player> <kit>")); + s.sendMessage(Utils.f("&c/kit give [r=5] <kit> <x,y,z>")); + s.sendMessage(Utils.f("&c/kit setpermission <name> <permission/none>")); + s.sendMessage(Utils.f("&c/kit set <name>")); + s.sendMessage(Utils.f("&c/kit list [page]")); + s.sendMessage(Utils.f("&c/kit load")); + s.sendMessage(Utils.f("&c/kit save")); + return true; + } + ItemManager im = GTM.getItemManager(); + switch (args[0]) { + case "setcost": { + if (args.length < 3) { + s.sendMessage(Utils.f("&c/kit setcost <name> <cost>")); + return true; + } + String name = args[1]; + Kit kit = im.getKit(name); + if (kit == null) { + s.sendMessage(Lang.KITS.f("&7That kit does not exist!")); + return true; + } + double cost = 0; + try { + cost = Double.parseDouble(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Lang.KITS.f("&7The cost must be a number!")); + } + kit.setCost(cost); + s.sendMessage( + Lang.KITS.f("&7The cost of kit &a" + kit.getName() + "&7 has been set to &a$&l" + cost + "&7!")); + return true; + } + case "setdelay": { + if (args.length < 3) { + s.sendMessage(Utils.f("&c/kit setdelay <name> <delay>")); + return true; + } + String name = args[1]; + Kit kit = im.getKit(name); + if (kit == null) { + s.sendMessage(Lang.KITS.f("&7That kit does not exist!")); + return true; + } + int delay = 0; + try { + delay = Integer.parseInt(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Lang.KITS.f("&7The cost must be a number!")); + } + kit.setDelay(delay); + s.sendMessage( + Lang.KITS.f("&7The delay of kit &a" + kit.getName() + "&7 has been set to &a" + delay + "&7!")); + return true; + } + case "setpermission": { + if (args.length < 3) { + s.sendMessage(Utils.f("&c/kit setpermission <name> <permission/none>")); + return true; + } + String name = args[1]; + Kit kit = im.getKit(name); + if (kit == null) { + s.sendMessage(Lang.KITS.f("&7That kit does not exist!")); + return true; + } + kit.setPermission("none".equalsIgnoreCase(args[2]) ? null : args[2]); + s.sendMessage( + Lang.KITS.f("&7The delay of kit &a" + kit.getName() + "&7 has been set to &a" + args[2] + "&7!")); + return true; + } + case "set": { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + Player player = (Player)s; + if (args.length < 2) { + s.sendMessage(Utils.f("&c/kit set <name>")); + return true; + } + String name = args[1]; + Kit kit = im.getKit(name); + if (kit == null) { + s.sendMessage(Lang.KITS.f("&7That kit does not exist!")); + return true; + } + PlayerInventory inv = player.getInventory(); + List<KitItem> contents = new ArrayList<>(); + for (int i = 0; i <= 35; i++) { + ItemStack item = inv.getItem(i); + if (item == null || i == 16 || i == 17) + continue; + GameItem gameItem = im.getItem(item); + if (gameItem == null) { + s.sendMessage(Lang.KITS.f("&7The item in slot &a" + i + + "&7 of your inventory is not registered as a GameItem! Use &a/additem&7 or &a/addweapon&7 to add it!")); + return true; + } + contents.add(new KitItem(gameItem, item.getAmount())); + } + kit.setContents(contents); + if (inv.getHelmet() != null) { + GameItem item = im.getItem(inv.getHelmet()); + if (item == null) { + s.sendMessage(Lang.KITS.f( + "&7The item in your helmet slot is not registered as a GameItem! Use &a/additem&7 or &a/addweapon&7 to add it!")); + return true; + } + kit.setHelmet(new KitItem(item, inv.getHelmet().getAmount())); + } + if (inv.getChestplate() != null) { + GameItem item = im.getItem(inv.getChestplate()); + if (item == null) { + s.sendMessage(Lang.KITS.f( + "&7The item in your chestplate slot is not registered as a GameItem! Use &a/additem&7 or &a/addweapon&7 to add it!")); + return true; + } + kit.setChestPlate(new KitItem(item, inv.getChestplate().getAmount())); + } + if (inv.getLeggings() != null) { + GameItem item = im.getItem(inv.getLeggings()); + if (item == null) { + s.sendMessage(Lang.KITS.f( + "&7The item in your leggings slot is not registered as a GameItem! Use &a/additem&7 or &a/addweapon&7 to add it!")); + return true; + } + kit.setLeggings(new KitItem(item, inv.getLeggings().getAmount())); + } + if (inv.getBoots() != null) { + GameItem item = im.getItem(inv.getBoots()); + if (item == null) { + s.sendMessage(Lang.KITS.f( + "&7The item in your boots slot is not registered as a GameItem! Use &a/additem&7 or &a/addweapon&7 to add it!")); + return true; + } + kit.setBoots(new KitItem(item, inv.getBoots().getAmount())); + } + if (inv.getItemInOffHand() != null && inv.getItemInOffHand().getType() != Material.AIR) { + GameItem item = im.getItem(inv.getItemInOffHand()); + if (item == null) { + s.sendMessage(Lang.KITS.f( + "&7The item in your offhand item slot is not registered as a GameItem! Use &a/additem&7 or &a/addweapon&7 to add it!")); + return true; + } + kit.setOffHand(new KitItem(item, inv.getItemInOffHand().getAmount())); + } + s.sendMessage( + Lang.KITS.f("&7You set the contents, armor and offhand item for kit &a" + kit.getName() + "&7!")); + return true; + } + case "add": { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + Player player = (Player)s; + if (args.length < 4) { + s.sendMessage(Utils.f("&c/kit add <name> <cost> <delay> [permission]")); + return true; + } + String name = args[1]; + Kit kit = im.getKit(name); + if (kit != null) { + s.sendMessage(Lang.KITS.f("&7A kit with that names already exists!")); + return true; + } + double cost = 0; + int delay = 0; + try { + cost = Double.parseDouble(args[2]); + delay = Integer.parseInt(args[3]); + } catch (NumberFormatException e) { + s.sendMessage(Lang.KITS.f("&7The cost/delay must be a number!")); + } + String permission = args.length > 4 ? args[4] : null; + PlayerInventory inv = player.getInventory(); + List<KitItem> contents = new ArrayList<>(); + for (int i = 0; i <= 35; i++) { + ItemStack item = inv.getItem(i); + if (item == null || i == 16 || i == 17) + continue; + GameItem gameItem = im.getItem(item); + if (gameItem == null) { + s.sendMessage(Lang.KITS.f("&7The item in slot &a" + i + + "&7 of your inventory is not registered as a GameItem! Use &a/additem&7 or &a/addweapon&7 to add it!")); + return true; + } + contents.add(new KitItem(gameItem, item.getAmount())); + } + KitItem helmet = null; + KitItem chestPlate = null; + KitItem leggings = null; + KitItem boots = null; + KitItem offHand = null; + if (inv.getHelmet() != null) { + GameItem item = im.getItem(inv.getHelmet()); + if (item == null) { + s.sendMessage(Lang.KITS.f( + "&7The item in your helmet slot is not registered as a GameItem! Use &a/additem&7 or &a/addweapon&7 to add it!")); + return true; + } + helmet = new KitItem(item, inv.getHelmet().getAmount()); + } + if (inv.getChestplate() != null) { + GameItem item = im.getItem(inv.getChestplate()); + if (item == null) { + s.sendMessage(Lang.KITS.f( + "&7The item in your chestplate slot is not registered as a GameItem! Use &a/additem&7 or &a/addweapon&7 to add it!")); + return true; + } + chestPlate = new KitItem(item, inv.getChestplate().getAmount()); + } + if (inv.getLeggings() != null) { + GameItem item = im.getItem(inv.getLeggings()); + if (item == null) { + s.sendMessage(Lang.KITS.f( + "&7The item in your leggings slot is not registered as a GameItem! Use &a/additem&7 or &a/addweapon&7 to add it!")); + return true; + } + leggings = new KitItem(item, inv.getLeggings().getAmount()); + } + if (inv.getBoots() != null) { + GameItem item = im.getItem(inv.getBoots()); + if (item == null) { + s.sendMessage(Lang.KITS.f( + "&7The item in your boots slot is not registered as a GameItem! Use &a/additem&7 or &a/addweapon&7 to add it!")); + return true; + } + boots = new KitItem(item, inv.getBoots().getAmount()); + } + if (inv.getItemInOffHand() != null && inv.getItemInOffHand().getType() != Material.AIR) { + GameItem item = im.getItem(inv.getItemInOffHand()); + if (item == null) { + s.sendMessage(Lang.KITS.f( + "&7The item in your offhand item slot is not registered as a GameItem! Use &a/additem&7 or &a/addweapon&7 to add it!")); + return true; + } + offHand = new KitItem(item, inv.getItemInOffHand().getAmount()); + } + s.sendMessage(Lang.KITS.f("&7Your kit with name &a" + name + "&7 has been added!")); + im.addKit(new Kit(name, cost, delay, contents, helmet, chestPlate, leggings, boots, offHand, permission, null)); + return true; + } + case "list": + List<Kit> kits = GTM.getItemManager().getKits(); + int page = 1; + if (args.length > 1) { + try { + page = Integer.parseInt(args[1]); + } catch (NumberFormatException e) { + s.sendMessage(Lang.KITS.f("&cThe page must be a number!")); + return true; + } + } + if (page < 1) { + s.sendMessage(Lang.KITS.f("&7The page must be a positive number!")); + return true; + } + int pages = kits.size() / 6 + 1; + s.sendMessage(Utils.f( + " &7&m---------------&7[&a&l Kits &7Page &a" + page + "&7/&a" + pages + " &7&m]---------------")); + Iterator<Kit> it = kits.iterator(); + for (int i = 0; i < page * 6; i++) { + if (!it.hasNext()) + return true; + Kit kit = it.next(); + if (i < page * 6 - 6) + continue; + s.sendMessage(Utils + .f(kit.getDisplayName() + "&7 | Cost: &a$&l" + kit.getCost() + "&7 Delay: &a&l" + kit.getDelay() + + (kit.getPermission() == null ? "" : "&7 Permission: &a" + kit.getPermission()))); + } + return true; + case "load": + GTM.getSettings().setKitsConfig(Utils.loadConfig("kits")); + GTM.getItemManager().loadKits(); + s.sendMessage(Lang.KITS.f("&7Loaded Kits!")); + return true; + case "save": + GTM.getItemManager().saveKits(); + s.sendMessage(Lang.KITS.f("&7Saved Kits!")); + return true; + case "give": + if (args.length != 3) { + if(args[1].contains("[r=")) { + Kit kit = im.getKit(args[2]); + if (kit == null) { + s.sendMessage(Lang.KITS.f("&7That kit does not exist!")); + return true; + } + Location point = new Location(Bukkit.getWorld("minesantos"), 0, 0, 0); + int radius; + try { + String[] test = args[1].split("="); + radius = Integer.valueOf(test[1].replace("]", "")); + if(args.length == 4) { + String[] cords = args[3].split(","); + point.setX(Integer.valueOf(cords[0])); + point.setY(Integer.valueOf(cords[1])); + point.setZ(Integer.valueOf(cords[2])); + } else { + s.sendMessage(Utils.f("Error in your syntax")); + s.sendMessage(Utils.f("Example: /kit give [r=5] hobo x,y,z")); + return true; + } + } catch (Exception exception) { + s.sendMessage(Utils.f("Error in your syntax")); + return true; + } + for(LivingEntity entity : point.getWorld().getLivingEntities()) { + if(entity.getLocation().distance(point) > radius) continue; + if(entity.getType() == EntityType.PLAYER) { + Player target = (Player)entity; + im.giveKitItems(target, GTM.getUserManager().getLoadedUser(target.getUniqueId()), kit); + } + } + return true; + } else { + s.sendMessage(Utils.f("&c/kit give <player> <kit>")); + return true; + } + } + String name = args[2]; + Kit kit = im.getKit(name); + if (kit == null) { + s.sendMessage(Lang.KITS.f("&7That kit does not exist!")); + return true; + } + Player target = Bukkit.getPlayer(args[1]); + if(target == null) { + s.sendMessage(Lang.KITS.f("&7Player not found")); + return false; + } + im.giveKitItems(target, GTM.getUserManager().getLoadedUser(target.getUniqueId()), kit); + s.sendMessage(Lang.KITS.f("&7Kit " + kit.getDisplayName() + " &7has been given to " + target.getDisplayName())); + return true; + default: + s.sendMessage(Utils.f("&c/kit add <name> <cost> <delay> [permission]")); + s.sendMessage(Utils.f("&c/kit setcost <name> <cost>")); + s.sendMessage(Utils.f("&c/kit setdelay <name> <delay>")); + s.sendMessage(Utils.f("&c/kit give <player> <kit>")); + s.sendMessage(Utils.f("&c/kit give [r=5] <kit> <x,y,z>")); + s.sendMessage(Utils.f("&c/kit setpermission <name> <permission/none>")); + s.sendMessage(Utils.f("&c/kit set <name>")); + s.sendMessage(Utils.f("&c/kit list [page]")); + s.sendMessage(Utils.f("&c/kit load")); + s.sendMessage(Utils.f("&c/kit save")); + return true; + } + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/KitItem.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/KitItem.java new file mode 100644 index 0000000..619d30a --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/KitItem.java @@ -0,0 +1,37 @@ +package net.grandtheftmc.gtm.items; + +public class KitItem { + + private final GameItem item; + private int amount; + + public KitItem(GameItem item) { + this.item = item; + this.amount = 1; + } + + public KitItem(GameItem item, int amount) { + this.item = item; + this.amount = amount; + } + + public GameItem getItem() { + return this.item; + } + + public GameItem getGameItem() { + return this.item; + } + + public String getDescription() { + return (this.amount > 1 ? "&7" + this.amount + "x " : "") + this.item.getDisplayName(); + } + + public int getAmount() { + return this.amount; + } + + public void setAmount(int amount) { + this.amount = amount; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/ShopCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/ShopCommand.java new file mode 100644 index 0000000..5a9a917 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/ShopCommand.java @@ -0,0 +1,48 @@ +package net.grandtheftmc.gtm.items; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class ShopCommand implements CommandExecutor { + + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!s.hasPermission("command.shop")) { + s.sendMessage(Lang.NOPERM.s()); + return true; + } + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + if (args.length == 0) { + s.sendMessage(Utils.f("&c/shop armorupgrade <armorupgrade>")); + s.sendMessage(Utils.f("&c/shop <item> <amount> <price>")); + return true; + } + switch (args[0].toLowerCase()) { + case "armorupgrade": + if (args.length != 2) { + s.sendMessage(Utils.f("&c/shop armorupgrade <armorupgrade>")); + return true; + } + GTM.getShopManager().addArmorUpgradeShop((Player) s, args[1]); + return true; + default: + if (args.length != 3) { + s.sendMessage(Utils.f("&c/shop <item> <amount> <price>")); + } + GTM.getShopManager().addShop((Player) s, args[0], Integer.parseInt(args[1]), Double.parseDouble(args[2])); + return true; + } + + } + +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/ShopManager.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/ShopManager.java new file mode 100644 index 0000000..34070e8 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/ShopManager.java @@ -0,0 +1,321 @@ +package net.grandtheftmc.gtm.items; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.users.LockedWeapon; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.scheduler.BukkitRunnable; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; +import java.util.stream.Collectors; + +public class ShopManager { + + public ShopManager() { + this.load(); + this.startSchedule(); + } + + + private List<Head> heads = new ArrayList<>(); + + private void load() { + new BukkitRunnable() { + @Override + public void run() { + List<Head> heads = new ArrayList<>(); + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("select * from " + Core.name() + "_heads;")) { + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + UUID sellerUUID = null; + UUID bidderUUID = null; + + try { + sellerUUID = result.getString("sellerUUID") == null ? null : UUID.fromString(result.getString("sellerUUID")); + bidderUUID = result.getString("bidderUUID") == null ? null : UUID.fromString(result.getString("bidderUUID")); + } catch (Exception ignored) { + } + heads.add(new Head(sellerUUID, result.getString("sellerName"), result.getString("head"), + result.getLong("expiry"), result.getBoolean("done"), + result.getBoolean("paid"), result.getBoolean("gaveHead"), + bidderUUID, result.getString("bidderName"), result.getDouble("bid"))); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + +// try (ResultSet rs = Core.sql.query("select * from " + Core.name() + "_heads;")) { +// while (rs.next()) { +// UUID sellerUUID = null; +// UUID bidderUUID = null; +// try { +// sellerUUID = rs.getString("sellerUUID") == null ? null : UUID.fromString(rs.getString("sellerUUID")); +// bidderUUID = rs.getString("bidderUUID") == null ? null : UUID.fromString(rs.getString("bidderUUID")); +// } catch (Exception ignored) { +// } +// heads.add(new Head(sellerUUID, rs.getString("sellerName"), +// rs.getString("head"), rs.getLong("expiry"), rs.getBoolean("done"), rs.getBoolean("paid"), rs.getBoolean("gaveHead"), bidderUUID, +// rs.getString("bidderName"), rs.getDouble("bid"))); +// } +// rs.close(); +// } catch (SQLException e) { +// e.printStackTrace(); +// } + new BukkitRunnable() { + @Override + public void run() { + GTM.getShopManager().setHeads(heads); + } + }.runTask(GTM.getInstance()); + } + }.runTaskAsynchronously(GTM.getInstance()); + } + + private void startSchedule() { + new BukkitRunnable() { + @Override + public void run() { + new ArrayList<>(GTM.getShopManager().getHeads()).forEach(Head::update); + } + }.runTaskTimer(GTM.getInstance(), 200L, 200L); + } + + + public void setHeads(List<Head> list) { + this.heads = list; + } + + public List<Head> getHeads() { + return this.heads; + } + + public void removeHead(Head head) { + this.heads.remove(head); + } + + public List<Head> getNonExpiredHeads() { + return this.heads.stream().filter(h -> !h.hasExpired()).collect(Collectors.toList()); + } + + public Set<Head> getNonExpiredHeadsByBid() { + HashMap<Head, Double> unsortMap = new HashMap<>(); + this.heads.stream().filter(h -> !h.hasExpired()).collect(Collectors.toList()).forEach(h -> unsortMap.put(h, h.getBid())); + return sort(unsortMap).keySet(); + } + + public static Map<Head, Double> sort(Map<Head, Double> unsortMap) { + List<Map.Entry<Head, Double>> list = new LinkedList<>(unsortMap.entrySet()); + list.sort(Comparator.comparing(Map.Entry::getValue)); + Map<Head, Double> sortedMap = new LinkedHashMap<>(); + for (Map.Entry<Head, Double> entry : list) { + sortedMap.put(entry.getKey(), entry.getValue()); + } + return sortedMap; + } + + public Head getHead(String head) { + return this.heads.stream().filter(h -> h.getHead().equalsIgnoreCase(head)).findFirst().orElse(null); + } + + public Head getHead(String head, long expiry) { + return this.heads.stream().filter(h -> h.getHead().equalsIgnoreCase(head) && h.getExpiry() == expiry).findFirst().orElse(null); + } + + public Head auctionHead(Player seller, GTMUser user) { + ItemStack item = seller.getInventory().getItemInMainHand(); + if (item == null || item.getType() != Material.SKULL_ITEM || item.getDurability() != 3) { + seller.sendMessage(Lang.HEAD_AUCTION.f("&7That's not a player head!")); + return null; + } + + if (item.getAmount() > 1) { + seller.sendMessage(Lang.HEAD_AUCTION.f("&7Please auction 1 head at a time!")); + return null; + } + + SkullMeta meta = (SkullMeta) item.getItemMeta(); + if (meta.getOwner() == null) { + seller.sendMessage(Lang.HEAD_AUCTION.f("&7That's not a player head!")); + return null; + } + + Head head = new Head(seller.getUniqueId(), seller.getName(), meta.getOwner()); + this.heads.add(head); + seller.sendMessage(Lang.HEAD_AUCTION.f("&7You received &a$&l10,000&7 for putting up &e&l" + head.getHead() + "'s Head&7 for auction.")); + user.addBank(10000); + GTMUtils.updateBoard(seller, user); + seller.getInventory().setItemInMainHand(null); + seller.updateInventory(); + return head; + } + + public void buy(Player player, ItemStack i) { + if (i == null || !i.hasItemMeta() || !i.getItemMeta().hasDisplayName()) + return; + String disp = ChatColor.stripColor(i.getItemMeta().getDisplayName()).toLowerCase(); + if (!disp.contains("buy: $")) + return; + disp = disp.replace("buy: $", ""); + String[] array = disp.split(" "); + if (array.length == 1) + return; + int amount = 1; + double buyPrice; + boolean hasAmount = array[0].endsWith("x"); + String itemName = array[hasAmount ? 1 : 0]; + for (int n = hasAmount ? 2 : 1; n < (array.length - 1); n++) + itemName = itemName + ' ' + array[n]; + try { + if (hasAmount) + amount = Integer.parseInt(array[0].replaceAll("x", "")); + buyPrice = Double.parseDouble(array[array.length - 1]); + } catch (NumberFormatException e) { + for (String anArray : array) player.sendMessage(anArray); + player.sendMessage(Utils.f(Lang.SHOP + + "&cThere was an error while parsing the prices for this shop. Please contact a staff member.")); + return; + } + GameItem item = GTM.getItemManager().getItemFromDisplayName(itemName); + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + if (user.isArrested()) { + player.sendMessage(Lang.JAIL.f("&7You can't buy items in jail!")); + return; + } + if (item.getType() == GameItem.ItemType.WEAPON) { + LockedWeapon l = LockedWeapon.getWeapon(item.getWeaponOrVehicleOrDrug()); + if (l != null && !l.canUseWeapon(user.getRank(), Core.getUserManager().getLoadedUser(player.getUniqueId()).getUserRank())) { + player.sendMessage(Lang.HEY.f("&7You need to rank up to " + l.getGTMRank().getColoredNameBold() + "&7 or donate for " + l.getUserRank().getColoredNameBold() + "&7 at &a&l" + Core.getSettings().getStoreLink() + "&7 to use the " + item.getDisplayName() + "&7!")); + return; + } + } else if (item.getType() == GameItem.ItemType.ARMOR_UPGRADE) { + player.sendMessage(Lang.HEY.f("&7There is an error with this shop. Please contact an administrator.")); + return; + } + if (user.hasMoney(buyPrice)) { + user.takeMoney(buyPrice); + } else { + if (user.hasBank(buyPrice)) { + user.takeBank(buyPrice); + player.sendMessage(Lang.BANK_TAKE.f(String.valueOf(buyPrice))); + } else { + player.sendMessage(Lang.MONEY.f("&7You do not have enough money!")); + return; + } + } + GTMUtils.updateBoard(player, Core.getUserManager().getLoadedUser(player.getUniqueId()), user); + switch (item.getType()) { + case VEHICLE: + user.setActionVehicle(item.getWeaponOrVehicleOrDrug()); + MenuManager.openMenu(player, "vehicleshop"); + return; + case AMMO: + AmmoType type = item.getAmmoType(); + if (type != null) + user.addAmmo(type, amount); + player.sendMessage(Lang.SHOP.f("&7You bought " + (amount > 1 ? "&a&l" + amount + "&7x " : "") + + item.getDisplayName() + "&7 for &a$&l" + buyPrice + "&7!")); + return; + case WEAPON: + case ITEMSTACK: + ItemStack stack = item.getItem(); + stack.setAmount(amount); + Utils.giveItems(player, stack); + player.sendMessage(Lang.SHOP.f("&7You bought " + (amount > 1 ? "&a&l" + amount + "&7x " : "") + + item.getDisplayName() + "&7 for &a$&l" + buyPrice + "&7!")); + break; + default: + break; + } + } + + public void buyArmorUpgrade(Player player, String disp) { + disp = disp.toLowerCase(); + disp = ChatColor.stripColor(disp); + ArmorUpgrade upgrade = ArmorUpgrade.getArmorUpgradeFromDisplayName(disp.split(" upgrade")[0]); + if (upgrade == null) return; + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + if (!upgrade.canUseUpgrade(user.getRank(), Core.getUserManager().getLoadedUser(player.getUniqueId()).getUserRank())) { + player.sendMessage(Lang.HEY.f("&7You need to rank up to " + upgrade.getGTMRank().getColoredNameBold() + "&7 or donate for " + upgrade.getUserRank().getColoredNameBold() + "&7 at &a&l" + Core.getSettings().getStoreLink() + "&7 to use the &b&l" + upgrade.getDisplayName() + " Armor Upgrade&7!")); + return; + } + ItemStack item = player.getInventory().getItemInMainHand(); + GameItem gameItem = item == null ? null : GTM.getItemManager().getItem(item.getType()); + if (item == null || gameItem == null || !upgrade.canBeUsedOn(gameItem.getName())) { + player.sendMessage(Lang.HEY.f("&7The &b&l" + upgrade.getDisplayName() + " Armor Upgrade&7 can be applied to the following types of items: " + upgrade.getTypesString() + "&7!")); + return; + } + for (Enchantment e : item.getEnchantments().keySet()) + Utils.b(e.getName()); + if (ArmorUpgrade.getArmorUpgrades(item).contains(upgrade)) { + player.sendMessage(Lang.ARMOR_UPGRADE.f("&7That piece of armor already has the &b&l" + upgrade.getDisplayName() + " Armor Upgrade&7!")); + return; + } + if (!user.hasMoney(upgrade.getPrice())) { + player.sendMessage(Lang.ARMOR_UPGRADE.f("&7You can't afford the &b&l" + upgrade.getDisplayName() + " Armor Upgrade&7!")); + return; + } + user.setBuyingArmorUpgrade(upgrade); + MenuManager.openMenu(player, "armorupgrade"); + } + + public void addShop(Player player, String itemName, int amount, double buyPrice) { + GameItem item = GTM.getItemManager().getItem(itemName); + if (item == null) { + player.sendMessage(Lang.SHOP.f("&cThat item does not exist!")); + return; + } + if (buyPrice < 0) { + player.sendMessage(Lang.SHOP.f("&7The price must be 0 or higher!")); + return; + } + ItemStack i = item.getItem().clone(); + ItemMeta meta = i.getItemMeta(); + meta.setDisplayName(Utils.f("&a&l" + amount + "&7x " + item.getDisplayName() + " &a&lBUY&f: &a$&l" + buyPrice)); + i.setItemMeta(meta); + i.setAmount(1); + player.getInventory().addItem(i); + player.sendMessage(Lang.SHOP.f("&7Please add the item into an itemframe to create a shop!")); + } + + public void addArmorUpgradeShop(Player player, String name) { + ArmorUpgrade armorUpgrade = ArmorUpgrade.getArmorUpgrade(name); + if (armorUpgrade == null) { + player.sendMessage(Lang.SHOP.f("&cThat armor upgrade does not exist!")); + return; + } + GameItem item = GTM.getItemManager().getItem(armorUpgrade); + if (item == null) { + player.sendMessage(Lang.SHOP.f("&cThat game item does not exist!")); + return; + } + ItemStack i = item.getItem().clone(); + ItemMeta meta = i.getItemMeta(); + meta.setDisplayName(Utils.f("&b&lArmor Upgrade: &a&l" + armorUpgrade.getDisplayName())); + i.setItemMeta(meta); + i.setAmount(1); + player.getInventory().addItem(i); + player.sendMessage(Lang.SHOP.f("&7Please add the item into an itemframe to create a shop!")); + } + + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/events/ArmorEquipEvent.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/events/ArmorEquipEvent.java new file mode 100644 index 0000000..acf31bd --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/events/ArmorEquipEvent.java @@ -0,0 +1,148 @@ +package net.grandtheftmc.gtm.items.events; + +import net.grandtheftmc.gtm.items.ArmorType; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.bukkit.inventory.ItemStack; + +/** + * @Author Borlea + * @Github https://github.com/borlea/ + * @Website http://codingforcookies.com/ + * @since Jul 30, 2015 + */ +public final class ArmorEquipEvent extends PlayerEvent implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + private boolean cancel = false; + private final EquipArmorType armorSlot; + private final EquipMethod equipType; + private final EquipArmorType type; + private ItemStack oldArmorPiece, newArmorPiece; + + /** + * Constructor for the ArmorEquipEvent. + * + * @param player The player who put on / removed the armor. + * @param type The EquipArmorType of the armor added + * @param oldArmorPiece The ItemStack of the armor removed. + * @param newArmorPiece The ItemStack of the armor added. + */ + public ArmorEquipEvent(final Player player, final EquipMethod equipType, final EquipArmorType type, final ItemStack oldArmorPiece, final ItemStack newArmorPiece, EquipArmorType armorSlot){ + super(player); + this.equipType = equipType; + this.armorSlot = armorSlot; + this.type = type; + this.oldArmorPiece = oldArmorPiece; + this.newArmorPiece = newArmorPiece; + } + + /** + * Gets a list of handlers handling this event. + * + * @return A list of handlers handling this event. + */ + public final static HandlerList getHandlerList(){ + return handlers; + } + + /** + * Gets a list of handlers handling this event. + * + * @return A list of handlers handling this event. + */ + @Override + public final HandlerList getHandlers(){ + return handlers; + } + + /** + * Sets if this event should be cancelled. + * + * @param cancel If this event should be cancelled. + */ + public final void setCancelled(final boolean cancel){ + this.cancel = cancel; + } + + /** + * Gets if this event is cancelled. + * + * @return If this event is cancelled + */ + public final boolean isCancelled(){ + return cancel; + } + + public final EquipArmorType getType(){ + return type; + } + + /** + * Returns the last equipped armor piece, could be a piece of armor, {@link Material Air}, or null. + */ + public final ItemStack getOldArmorPiece(){ + return oldArmorPiece; + } + + public final void setOldArmorPiece(final ItemStack oldArmorPiece){ + this.oldArmorPiece = oldArmorPiece; + } + + /** + * Returns the newly equipped armor, could be a piece of armor, {@link Material Air}, or null. + */ + public final ItemStack getNewArmorPiece(){ + return newArmorPiece; + } + + public final void setNewArmorPiece(final ItemStack newArmorPiece){ + this.newArmorPiece = newArmorPiece; + } + + /** + * Gets the method used to either equip or unequip an armor piece. + */ + public EquipMethod getMethod(){ + return equipType; + } + + public EquipArmorType getArmorSlot() { + return this.armorSlot; + } + + public enum EquipMethod{ + /** + * When you shift click an armor piece to equip or unequip + */ + SHIFT_CLICK, + /** + * When you drag and drop the item to equip or unequip + */ + DRAG, + /** + * When you right click an armor piece in the hotbar without the inventory open to equip. + */ + HOTBAR, + /** + * When you press the hotbar slot number while hovering over the armor slot to equip or unequip + */ + HOTBAR_SWAP, + /** + * When in range of a dispenser that shoots an armor piece to equip. + */ + DISPENSER, + /** + * When an armor piece breaks to unequip + */ + BROKE, + /** + * When you die causing all armor to unequip + */ + DEATH, + ; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/events/EquipArmorType.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/events/EquipArmorType.java new file mode 100644 index 0000000..e4d9167 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/items/events/EquipArmorType.java @@ -0,0 +1,75 @@ +package net.grandtheftmc.gtm.items.events; + +import net.grandtheftmc.gtm.listeners.ArmorEquip; +import org.bukkit.Color; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.LeatherArmorMeta; + +/** + * Created by Timothy Lampen on 2017-08-11. + */ +public enum EquipArmorType { + + HELMET(39), CHESTPLATE(38), LEGGINGS(37), BOOTS(36), CUSTOM(-1); + + private final int slot; + + EquipArmorType(int slot){ + this.slot = slot; + } + + + public static EquipArmorType fromSlot(int slot){ + for(EquipArmorType t : EquipArmorType.values()) + if(t.getSlot()==slot) + return t; + return null; + } + + /** + * Attempts to match the ArmorType for the specified ItemStack. + * + * @param itemStack The ItemStack to parse the type of. + * @return The parsed ArmorType. (null if none were found.) + */ + public static EquipArmorType matchType(final ItemStack itemStack){ + if(itemStack == null) { return null; } + if(itemStack.getType().toString().contains("LEATHER") && ArmorEquip.isCustomColor(((LeatherArmorMeta)itemStack.getItemMeta()).getColor())) + return CUSTOM; + switch (itemStack.getType()){ + case DIAMOND_SWORD: + return CUSTOM; + case DIAMOND_HELMET: + case GOLD_HELMET: + case IRON_HELMET: + case CHAINMAIL_HELMET: + case LEATHER_HELMET: + return HELMET; + case DIAMOND_CHESTPLATE: + case GOLD_CHESTPLATE: + case IRON_CHESTPLATE: + case CHAINMAIL_CHESTPLATE: + case LEATHER_CHESTPLATE: + return CHESTPLATE; + case DIAMOND_LEGGINGS: + case GOLD_LEGGINGS: + case IRON_LEGGINGS: + case CHAINMAIL_LEGGINGS: + case LEATHER_LEGGINGS: + return LEGGINGS; + case DIAMOND_BOOTS: + case GOLD_BOOTS: + case IRON_BOOTS: + case CHAINMAIL_BOOTS: + case LEATHER_BOOTS: + return BOOTS; + default: + return null; + } + } + + public int getSlot(){ + return slot; + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/ArmorEquip.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/ArmorEquip.java new file mode 100644 index 0000000..755819d --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/ArmorEquip.java @@ -0,0 +1,263 @@ +package net.grandtheftmc.gtm.listeners; + +import java.util.HashSet; + +import org.bukkit.Color; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerPickupItemEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.LeatherArmorMeta; +import org.bukkit.potion.PotionEffect; +import org.bukkit.scheduler.BukkitRunnable; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.items.ArmorUpgrade; +import net.grandtheftmc.gtm.items.events.ArmorEquipEvent; +import net.grandtheftmc.gtm.items.events.EquipArmorType; + +/** + * Created by Timothy Lampen on 7/6/2017. + */ +public class ArmorEquip implements Listener { + + @EventHandler + public void onPickupCustomLeatherArmor(PlayerPickupItemEvent event) { + ItemStack is = event.getItem().getItemStack(); +// new Location("", x,y,z), + if(is.getType().toString().contains("LEATHER") && is.getType() != Material.LEATHER) { + if(!isCustomColor(((LeatherArmorMeta)is.getItemMeta()).getColor())) + return; + event.setCancelled(true); + event.getItem().remove(); + } + } + + @EventHandler(ignoreCancelled = true) + public void onEquipCustom(ArmorEquipEvent event) { + + Player player = event.getPlayer(); + + // only handle custom equips + if(event.getType()!=EquipArmorType.CUSTOM) + return; + + // only handle drag events + if(event.getMethod()!= ArmorEquipEvent.EquipMethod.DRAG && event.getMethod() != ArmorEquipEvent.EquipMethod.DEATH) + return; + + ItemStack newArmor = event.getNewArmorPiece(); + ItemStack oldArmor = event.getOldArmorPiece(); + + ItemStack toSlot = newArmor; + ItemStack toHand = oldArmor; + if(oldArmor.getType().toString().contains("LEATHER")) { + LeatherArmorMeta meta = (LeatherArmorMeta)oldArmor.getItemMeta(); + if(isCustomColor(meta.getColor())) + toHand = getGameItemFromLeather(meta, event.getArmorSlot()); + } + if(newArmor.getType() == Material.DIAMOND_SWORD) { + ItemStack is = null; + switch (event.getArmorSlot()) { + case BOOTS: + is = new ItemStack(Material.LEATHER_BOOTS); + break; + case LEGGINGS: + is = new ItemStack(Material.LEATHER_LEGGINGS); + break; + case CHESTPLATE: + is = new ItemStack(Material.LEATHER_CHESTPLATE); + break; + case HELMET: + is = new ItemStack(Material.LEATHER_HELMET); + break; + } + LeatherArmorMeta meta = (LeatherArmorMeta)is.getItemMeta(); + meta.setColor(getColorFromSwordDurability(newArmor.getDurability())); + is.setItemMeta(meta); + toSlot = is; + } + + if(newArmor.getType() != Material.AIR && event.getArmorSlot()!=getArmorSlotFromSwordDura(newArmor.getDurability()) && event.getMethod() == ArmorEquipEvent.EquipMethod.DRAG) { + event.setCancelled(true); + return; + } + + ItemStack finalToHand = toHand; + ItemStack finalToSlot = toSlot; + + if (event.getMethod() != ArmorEquipEvent.EquipMethod.DEATH){ + event.setCancelled(true); + player.getInventory().setItem(event.getArmorSlot().getSlot(), finalToSlot); + player.setItemOnCursor(finalToHand); + } + + ServerUtil.runTaskLater(() -> { + if(event.getMethod()== ArmorEquipEvent.EquipMethod.DEATH) { + player.getWorld().dropItem(player.getLocation(), finalToHand); + // TODO note: cancelling the event here does nothing, as its ran 2 ticks later...? + event.setCancelled(true); + } + + player.updateInventory(); + }, 2); + } + + @EventHandler + public void onArmorEquip(ArmorEquipEvent event){ + if(event.getType()== EquipArmorType.CUSTOM) + return; + Player player = event.getPlayer(); + player.setMaxHealth(20); + ItemStack is = event.getNewArmorPiece(); + if(is!=null && is.getAmount()>1) { + player.sendMessage(Lang.GTM.f("&7You cannot equip stacked armor!")); + event.setCancelled(true); + return; + } + for (PotionEffect e : player.getActivePotionEffects()) { + player.removePotionEffect(e.getType()); + } + new BukkitRunnable() { + @Override + public void run() { + for(ItemStack is : player.getInventory().getArmorContents()){ + for(ArmorUpgrade upgrade : ArmorUpgrade.getArmorUpgrades(is)){ + if(upgrade==ArmorUpgrade.ENHANCED){ + player.setMaxHealth(player.getMaxHealth()+10); + } + HashSet<PotionEffect> effects = upgrade.getPotionEffects(); + for (PotionEffect effect : effects) { + if(player.hasPotionEffect(effect.getType())){ + int base = player.getPotionEffect(effect.getType()).getAmplifier()==0 ? 1 : player.getPotionEffect(effect.getType()).getAmplifier(); + int effectAmp = effect.getAmplifier()==0 ? 1 : effect.getAmplifier(); + player.removePotionEffect(effect.getType()); + player.addPotionEffect(new PotionEffect(effect.getType(), Integer.MAX_VALUE, base+effectAmp)); + } + else{ + player.addPotionEffect(effect); + } + } + } + } + } + }.runTaskLater(GTM.getInstance(), 1); + } + + /* + * + * + * + * If anyone can suggest a better way to handle this, I am open to suggestions. ~ Tim. + * + * + * */ + + public static boolean isCustomColor(Color c) { + if(c.getRed()==153 && c.getGreen()==0 && c.getBlue()==0)//is santa + return true; + else if(c.getRed()==0 && c.getGreen()==77 && c.getBlue()==26)//is elf + return true; + else if(c.getRed()==102 && c.getGreen()==51 && c.getBlue()==0)// is rudolf + return true; + return false; + } + + private EquipArmorType getArmorSlotFromSwordDura(short durability){ + switch (durability) { + case 1007: + case 1008: + case 1009: + return EquipArmorType.HELMET; + case 1014: + case 1017: + case 1020: + return EquipArmorType.CHESTPLATE; + case 1015: + case 1018: + case 1021: + return EquipArmorType.LEGGINGS; + case 1016: + case 1019: + case 1022: + return EquipArmorType.BOOTS; + } + return null; + } + + /** + * @param m the item meta of the leather armor + * @param type the slot of the item + * @return the diamond sword item that represents the item + */ + private ItemStack getGameItemFromLeather(LeatherArmorMeta m, EquipArmorType type) { + Color c = m.getColor(); + + if(c.getRed()==153 && c.getGreen()==0 && c.getBlue()==0) {//is santa + switch (type) { + case BOOTS: + return GTM.getItemManager().getItem("santaboots").getItem(); + case LEGGINGS: + return GTM.getItemManager().getItem("santapants").getItem(); + case CHESTPLATE: + return GTM.getItemManager().getItem("santatunic").getItem(); + case HELMET: + return GTM.getItemManager().getItem("santahat").getItem(); + } + } + else if(c.getRed()==0 && c.getGreen()==77 && c.getBlue()==26) {//is elf + switch (type) { + case BOOTS: + return GTM.getItemManager().getItem("elfboots").getItem(); + case LEGGINGS: + return GTM.getItemManager().getItem("elfpants").getItem(); + case CHESTPLATE: + return GTM.getItemManager().getItem("elftunic").getItem(); + case HELMET: + return GTM.getItemManager().getItem("elfhat").getItem(); + } + } + else if(c.getRed()==102 && c.getGreen()==51 && c.getBlue()==0) {// is rudolf + switch (type) { + case BOOTS: + return GTM.getItemManager().getItem("rudolfboots").getItem(); + case LEGGINGS: + return GTM.getItemManager().getItem("rudolfpants").getItem(); + case CHESTPLATE: + return GTM.getItemManager().getItem("rudolftunic").getItem(); + case HELMET: + return GTM.getItemManager().getItem("rudolfhat").getItem(); + } + } + return null; + } + + /** + * @param durability the durability of the sword + * @return the color that is associated with the diamond sword 'armor' to set the leather + */ + private Color getColorFromSwordDurability(short durability){ + switch (durability) { + case 1009: + case 1014: + case 1015: + case 1016: + return Color.fromRGB(153, 0, 0);//santa + case 1008: + case 1017: + case 1018: + case 1019: + return Color.fromRGB(0, 77, 26);//elf + case 1007: + case 1020: + case 1021: + case 1022: + return Color.fromRGB(102, 51, 0);//rudolf + } + return Color.BLACK; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/BreakBlock.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/BreakBlock.java new file mode 100644 index 0000000..4fd7573 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/BreakBlock.java @@ -0,0 +1,25 @@ +package net.grandtheftmc.gtm.listeners; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.gtm.GTM; +import org.bukkit.block.Block; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; + +public class BreakBlock implements Listener{ + + @EventHandler(ignoreCancelled = true) + public void onBreak(BlockBreakEvent event) { + Block block = event.getBlock(); + switch (block.getType()) { + case CHEST: + if (GTM.getCrateManager().getCrate(block.getLocation()) == null) return; + event.setCancelled(true); + event.getPlayer().sendMessage(Lang.LOOTCRATES.f("&7You can't break this Loot Crate!")); + default: + break; + } + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/ChangeWorld.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/ChangeWorld.java new file mode 100644 index 0000000..6f82741 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/ChangeWorld.java @@ -0,0 +1,28 @@ +package net.grandtheftmc.gtm.listeners; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.gtm.GTM; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerChangedWorldEvent; +import org.bukkit.potion.PotionEffectType; + +import java.util.Objects; + +public class ChangeWorld implements Listener { + + @EventHandler + public void onSwitch(PlayerChangedWorldEvent e) { + Player player = e.getPlayer(); + if (Objects.equals(player.getWorld(), GTM.getWarpManager().getSpawn().getLocation().getWorld())) { + player.setHealth(player.getMaxHealth()); + player.setFireTicks(0); + + if (!Core.getSettings().isSister()) + GTM.getDrugManager().getEffectManager().cancelEffects(player); + } else { + player.removePotionEffect(PotionEffectType.SPEED); + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Chat.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Chat.java new file mode 100644 index 0000000..a65be4b --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Chat.java @@ -0,0 +1,773 @@ +package net.grandtheftmc.gtm.listeners; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import org.bukkit.BanList.Type; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.scheduler.BukkitRunnable; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserDAO; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.users.eventtag.EventTag; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.gang.Gang; +import net.grandtheftmc.gtm.gang.GangManager; +import net.grandtheftmc.gtm.items.GameItem; +import net.grandtheftmc.gtm.items.Head; +import net.grandtheftmc.gtm.tasks.LotteryPlayer; +import net.grandtheftmc.gtm.users.ChatAction; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.users.GTMUserDAO; +import net.grandtheftmc.gtm.users.JobMode; +import net.grandtheftmc.gtm.users.PersonalVehicle; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.houses.House; +import net.grandtheftmc.houses.houses.PremiumHouse; +import net.grandtheftmc.houses.users.HouseUser; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; + +public class Chat implements Listener { + private final Pattern p = Pattern.compile("-?\\d+"); + + /** The server ids that players can transfer to */ + public static final Set<Integer> TRANSFER_SERVER_ALLOWED = new HashSet<Integer>(Arrays.asList(1,4)); + + /** + * If what you are adding is something where players type a value in chat please use the methods in the GTMUser class seen here: + * - GTMUser#clearCurrentChatAction + * - GTMUser#resetCurrentChatTimer + * - GTMUser#setCurrentChatAction + * <p> + * These will also work if you get two values, but that is the limit currently. + */ + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onChat(AsyncPlayerChatEvent e) { + Player player = e.getPlayer(); + UUID uuid = player.getUniqueId(); + String msg = e.getMessage(); + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + User coreUser = Core.getUserManager().getLoadedUser(player.getUniqueId()); + + if (user == null){ + return; + } + + if (user.getCurrentChatAction() != null) { + e.setCancelled(true); + new BukkitRunnable() { + @Override + public void run() { + switch (user.getCurrentChatAction()) { + + case CONFIRM_TRANSFER_2: { + TransferPayload payload = (TransferPayload) user.getCurrentChatValue(); + + if (msg.equalsIgnoreCase("cancel")) { + user.clearCurrentChatAction(); + player.sendMessage(Lang.GTM.f("&cYou have cancelled the transfer process.")); + return; + } + + int id; + try { + Matcher matcher = p.matcher(msg); + + String found = ""; + while (matcher.find()) + found = matcher.group(); + + id = Integer.parseInt(found); + id = Math.abs(id); + } catch (Exception nfe) { + player.sendMessage(Lang.GTM.f("&cCannot parse &6" + msg + " &cas a number. &6Please enter a number type '&ccancel&6'")); + user.resetCurrentChatActionTimer(payload.getGeneratedNumber()); + return; + } + + if (id != payload.getGeneratedNumber()) { + user.clearCurrentChatAction(); + player.sendMessage(Lang.GTM.f("&cYou have cancelled the transfer process.")); + return; + } + + //the selling of the houses and such must be done BEFORE the player logs off. + HouseUser houseUser = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + + List<House> houses = houseUser.getHouses().stream().map(userHouse -> Houses.getHousesManager().getHouse(userHouse.getId())).collect(Collectors.toList()); + houses.forEach(house -> house.sellHouse(player, user, houseUser)); + + List<PremiumHouse> premiumHouses = new ArrayList<>(houseUser.getPremiumHouses()); + premiumHouses.forEach(premHouse -> premHouse.sell(player, user, houseUser)); + + int vehicleSum = 0; + // if user has vehicles + if (user.getVehicles() != null && user.getVehicles().size() > 0){ + for (PersonalVehicle v : user.getVehicles()){ + GameItem gameItem = GTM.getItemManager().getItemFromVehicle(v.getVehicle()); + if (gameItem != null){ + + // Note: this "price" is the BUY price in MenuListener. + int price = (int) (gameItem.getSellPrice() * 2); + vehicleSum += price; + } + } + } + + // TODO debug remove + Core.log("[Chat][Transfer] Vehicle sum for " + player.getName() + " was " + vehicleSum); + if (vehicleSum >= 0){ + user.addMoney(vehicleSum); + } + + // get unlocked user tags + Set<EventTag> userTags = coreUser.getUnlockedTags(); + + ServerUtil.runTaskLater(() -> { + GTM.getInstance().getTransferingPlayers().add(player.getUniqueId()); + + String playerName = player.getName(); + UUID playerUUID = player.getUniqueId(); + UserRank rank = coreUser.getUserRank(); + + String commandLine = "tempban " + playerName + " 5m Transferring data"; + Core.log("[Chat][TRANSFER][DEBUG] Running command: " + commandLine); + Bukkit.dispatchCommand(Bukkit.getServer().getConsoleSender(), commandLine); + + //player.kickPlayer(Lang.GTM.f("&e&lYour data is being transferred.")); + ServerUtil.runTaskLaterAsync(() -> { + Core.log("[Chat][TRANSFER][DEBUG] Transferring data for " + playerName); + GTMUserDAO.transferData(player.getUniqueId(), payload.getGtmID()); + + if (userTags != null){ + userTags.forEach(ut -> { + + // TODO debug remove + Core.log("[Chat][Transfer] UserTag=" + ut + ", serverKey=GTM" + payload.getGtmID()); + + if (!ut.isGlobal()){ + UserDAO.addPlayerTag(uuid, "GTM" + payload.getGtmID(), ut); + } + }); + } + }, 20 * 5); + + ServerUtil.runTask(() -> { + if (!rank.hasRank(UserRank.HELPOP)){ + Bukkit.getBanList(Type.NAME).addBan(playerName, "TRANSFER TO GTM" + payload.getGtmID(), null, "SERVER"); + } + }); + }, 20 * 3); + ServerUtil.runTaskLater(() -> GTM.getInstance().getTransferingPlayers().remove(player.getUniqueId()), 20 * 60); + + return; + } + + case CONFIRM_TRANSFER: { + + if (msg.equalsIgnoreCase("cancel")) { + user.clearCurrentChatAction(); + player.sendMessage(Lang.GTM.f("&cYou have cancelled the transfer process.")); + return; + } + int id; + try { + id = Integer.parseInt(msg.replace("GTM", "")); + } catch (NumberFormatException nfe) { + player.sendMessage(Lang.GTM.f("&cCannot parse &6" + msg + " &cas a GTM server. &6Please enter a GTM server (ex. GTM1) or type '&ccancel&6'")); + user.resetCurrentChatActionTimer(null); + return; + } + + if (!TRANSFER_SERVER_ALLOWED.contains(id)){ + player.sendMessage(Lang.GTM.f("&cSorry, but you cannot currently transfer to that server. &6Please enter a different GTM server or type '&ccancel&6'")); + user.resetCurrentChatActionTimer(null); + } + + int generatedNumber = ThreadLocalRandom.current().nextInt(10000000, 100000000); + user.setCurrentChatAction(ChatAction.CONFIRM_TRANSFER_2, new TransferPayload(generatedNumber, id)); + player.sendMessage(Lang.GTM.f("&cAre you 100% sure you would like to complete this irreversible transfer? &aIf so please type &6" + generatedNumber + "&a in chat.")); + player.sendMessage(Lang.GTM.f("&cYou will be banned from the network while we transfer the data.")); + return; + } + case BRIBING: { + if ("quit".equalsIgnoreCase(msg)) { + user.clearCurrentChatAction(); + player.sendMessage(Lang.BRIBE.f("&7You canceled bribing the cop who arrested you.")); + return; + } + + if (!user.isArrested()) { + user.clearCurrentChatAction(); + player.sendMessage(Lang.BRIBE.f("&7You are not in jail!")); + return; + } + + if (user.getJailTimer() < 5) { + user.clearCurrentChatAction(); + player.sendMessage(Lang.BRIBE.f("&7You are already being released!")); + return; + } + + Player cop = Bukkit.getPlayer(user.getJailCop()); + GTMUser copUser = cop == null ? null : GTM.getUserManager().getLoadedUser(cop.getUniqueId()); + if (cop == null || copUser.getJobMode() != JobMode.COP) { + player.sendMessage(Lang.BRIBE.f("&7The cop who arrested you (&3&l" + user.getJailCopName() + "&7) is off duty!")); + user.clearCurrentChatAction(); + return; + } + + double amnt; + try { + amnt = Utils.round(Double.parseDouble(msg)); + } catch (NumberFormatException e1) { + player.sendMessage(Utils.f(Lang.BRIBE + "&7Please enter a valid number or type &a\"quit\"&7!")); + user.resetCurrentChatActionTimer(0); + return; + } + + if (amnt < 5000) { + player.sendMessage(Lang.BRIBE.f("&7Bribes must be at least &a$&l5,000!")); + user.resetCurrentChatActionTimer(0); + return; + } + + if (user.getBribe() * 1.05 > amnt) { + player.sendMessage(Lang.BRIBE.f("&7You must raise the bribe by at least &a&l5%&7 of &a$&l" + user.getBribe() + "&7 (&a$&l" + (user.getBribe() * 1.05) + "&7)! Please enter a valid number or type &a\"quit\"&7!")); + user.resetCurrentChatActionTimer(0); + return; + } + + if (!user.hasMoney(amnt)) { + player.sendMessage(Lang.BRIBE.f("&7You don't have &c$&l" + amnt + "&7! Please enter a valid number or type &a\"quit\"&7!")); + user.resetCurrentChatActionTimer(0); + return; + } + + user.clearCurrentChatAction(); + user.setBribe(amnt); + player.sendMessage(Lang.BRIBE.f("&7You sent a bribe offer of &a$&l" + amnt + "&7 to &3&l" + cop.getName() + "&7. You can negotiate with them using &a\"/msg " + cop.getName() + "\"&7!")); + cop.spigot().sendMessage(new ComponentBuilder(Lang.BRIBE.f("&7A bribe offer of &a$&l" + amnt + "&7 was sent to you by &3&l" + player.getName() + "&7!")).append(" [ACCEPT] ").color(ChatColor.GREEN).bold(true).event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/bribe accept " + player.getName())).append("[DENY]").color(ChatColor.DARK_RED).bold(true).event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/bribe deny " + player.getName())).create()); + break; + } + + case BIDDING_HEAD: { + if ("quit".equalsIgnoreCase(msg)) { + user.clearCurrentChatAction(); + player.sendMessage(Lang.HEAD_AUCTION.f("&7You canceled bidding.")); + return; + } + Head head = user.getBiddingHead(); + if (head == null) { + user.clearCurrentChatAction(); + player.sendMessage(Lang.HEAD_AUCTION.f("&7You canceled bidding.")); + return; + } + double amnt; + try { + amnt = Utils.round(Double.parseDouble(msg)); + } catch (NumberFormatException e1) { + player.sendMessage( + Utils.f(Lang.HEAD_AUCTION + "&7Please enter a valid number or type &a\"quit\"&7!")); + user.resetCurrentChatActionTimer(0); + return; + } + if (head.hasExpired() || head.isDone()) { + user.clearCurrentChatAction(); + player.sendMessage(Lang.HEAD_AUCTION.f("&7The bidding has expired!")); + return; + } + if (!user.hasMoney(amnt)) { + player.sendMessage(Lang.HEAD_AUCTION.f("&7You don't have &c$&l" + amnt + "&7! &7Please enter a valid number or type &a\"quit\"&7!")); + user.resetCurrentChatActionTimer(0); + return; + } + + if (head.hasBid()) { + if (head.getBid() * 1.05 > amnt) { + player.sendMessage(Lang.HEAD_AUCTION.f("&7You must bid at least &a&l5%&7 more than the current bid of &a$&l" + head.getBid() + "&7 (&a$&l" + (head.getBid() * 1.05) + "&7)!")); + user.resetCurrentChatActionTimer(0); + return; + } + head.returnBidderMoney(); + } else if (amnt < 10000) { + player.sendMessage(Lang.HEAD_AUCTION.f("&7You must bid at least the starting bid of &a$&l10,000&7! &7Please enter a valid number or type &a\"quit\"&7!")); + user.resetCurrentChatActionTimer(0); + return; + } + user.clearCurrentChatAction(); + head.setBid(player, amnt); + user.takeMoney(amnt); + GTMUtils.updateBoard(player, user); + player.sendMessage(Lang.HEAD_AUCTION.f("&7You have bid &a$&l" + head.getBid() + "&7 for &e&l" + head.getHead() + "'s Head&7! Please wait &c&l" + Utils.timeInMillisToText(head.getTimeUntilExpiry()) + "&7 for the auction to end.")); + Player seller = Bukkit.getPlayer(head.getSellerUUID()); + if (seller != null && !Objects.equals(seller, player)) + seller.sendMessage(Lang.HEAD_AUCTION.f("&a&l" + player.getName() + "&7 has bid &a$&l" + head.getBid() + "&7 on &e&l" + head.getHead() + "'s Head&7!")); + break; + } + case PICKING_BOUNTY: { + if ("quit".equalsIgnoreCase(msg)) { + user.clearCurrentChatAction(); + player.sendMessage(Utils.f(Lang.BOUNTIES + "&7You cancelled picking the amount.")); + MenuManager.openMenu(player, "bountiesplace"); + return; + } + int amnt; + try { + amnt = Integer.parseInt(msg); + } catch (NumberFormatException e1) { + player.sendMessage( + Utils.f(Lang.BOUNTIES + "&7Please enter a valid number or type &a\"quit\"&7!")); + user.resetCurrentChatActionTimer(0); + return; + } + if (amnt < 2000) { + player.sendMessage(Utils.f(Lang.BOUNTIES + + "&7The minimum bid is &a$&l2.000&7! Enter a valid number or type &a\"quit\"&7!")); + user.resetCurrentChatActionTimer(0); + return; + } + if (!user.hasMoney(amnt)) { + player.sendMessage(Lang.BOUNTIES.f("&7You don't have &a$&l" + amnt + + "&7 to place this bounty! Enter a valid amount or type &a\"quit\"&7!")); + user.resetCurrentChatActionTimer(0); + return; + } + user.clearCurrentChatAction(); + user.setBountyAmount(amnt); + player.sendMessage(Utils.f(Lang.BOUNTIES + "&7You have chosen the amount &a$&l" + amnt + "&7!")); + MenuManager.openMenu(player, "bountiesplace"); + break; + } + case PICKING_BOUNTY_TARGET: { + if ("quit".equalsIgnoreCase(msg)) { + user.clearCurrentChatAction(); + player.sendMessage(Utils.f(Lang.BOUNTIES + "&7You cancelled choosing the target.")); + MenuManager.openMenu(player, "bountiesplace"); + return; + } + Player target = Bukkit.getPlayer(msg); + if (target == null) { + player.sendMessage(Utils.f(Lang.BOUNTIES + + "&7That player is not online! Please enter a valid player name or type &a\"quit\"&7!")); + user.resetCurrentChatActionTimer(0); + player.sendMessage(Utils.f(Lang.BOUNTIES + "&7You cancelled choosing the target.")); + return; + } + user.clearCurrentChatAction(); + user.setBountyName(target.getName()); + user.setBountyUUID(target.getUniqueId()); + player.sendMessage(Utils.f(Lang.BOUNTIES + "&7You have chosen the player &a" + target.getName() + "&7!")); + MenuManager.openMenu(player, "bountiesplace"); + break; + } + + case BANK_DEPOSITING: { + if ("quit".equalsIgnoreCase(msg)) { + user.setCurrentChatAction(ChatAction.BANK_DEPOSITING, null); + player.sendMessage(Utils.f(Lang.BANK + "&7You cancelled depositing money into your bank!")); + MenuManager.openMenu(player, "bank"); + return; + } + + double amnt; + try { + amnt = Utils.round(Double.parseDouble(msg)); + } catch (NumberFormatException e1) { + player.sendMessage(Utils.f(Lang.BANK + "&7Please enter a valid number or type &a\"quit\"&7!")); + user.resetCurrentChatActionTimer(0); + user.setCurrentChatAction(ChatAction.BANK_DEPOSITING, null); + return; + } + + if (amnt <= 100) { + player.sendMessage(Utils.f(Lang.BANK + + "&7The minimum amount is &a$&l100&7! Enter a valid number or type &a\"quit\"&7!")); + user.resetCurrentChatActionTimer(0); + user.setCurrentChatAction(ChatAction.BANK_DEPOSITING, null); + return; + } + + if (!user.hasMoney(amnt)) { + player.sendMessage(Lang.BANK.f("&7You don't have &a$&l" + amnt + + "&7 to deposit into your bank account! Enter a valid amount or type &a\"quit\"&7!")); + user.resetCurrentChatActionTimer(0); + user.setCurrentChatAction(ChatAction.BANK_DEPOSITING, null); + return; + } + + user.clearCurrentChatAction(); + user.depositToBank(amnt); + GTMUtils.updateBoard(player, user); + player.sendMessage(Utils.f(Lang.BANK + "&7You deposited &a$&l" + amnt + "&7 into your bank account!")); + break; + } + + case BANK_WITHDRAWING: { + if ("quit".equalsIgnoreCase(msg)) { + user.setCurrentChatAction(ChatAction.BANK_WITHDRAWING, null); + player.sendMessage(Utils.f(Lang.BANK + "&7You cancelled withdrawing money from your bank!")); + MenuManager.openMenu(player, "bank"); + return; + } + double amnt; + try { + amnt = Utils.round(Double.parseDouble(msg)); + } catch (NumberFormatException e1) { + player.sendMessage(Utils.f(Lang.BANK + "&7Please enter a valid number or type &a\"quit\"&7!")); + user.resetCurrentChatActionTimer(0); + user.setCurrentChatAction(ChatAction.BANK_WITHDRAWING, null); + return; + } + if (amnt <= 100) { + player.sendMessage(Utils.f(Lang.BANK + + "&7The minimum amount is &a$&l100&7! Enter a valid number or type &a\"quit\"&7!")); + user.resetCurrentChatActionTimer(0); + user.setCurrentChatAction(ChatAction.BANK_WITHDRAWING, null); + return; + } + if (!user.hasBank(amnt)) { + player.sendMessage(Lang.BANK.f("&7You don't have &a$&l" + amnt + + "&7 in your bank account! Enter a valid amount or type &a\"quit\"&7!")); + user.resetCurrentChatActionTimer(0); + user.setCurrentChatAction(ChatAction.BANK_WITHDRAWING, null); + return; + } + user.clearCurrentChatAction(); + user.withdrawFromBank(amnt); + GTMUtils.updateBoard(player, user); + player.sendMessage( + Utils.f(Lang.BANK + "&7You withdrew &a$&l" + amnt + "&7 from your bank account!")); + break; + } + case BANK_TRANSFERRING: { + if ("quit".equalsIgnoreCase(msg)) { + user.clearCurrentChatAction(); + player.sendMessage(Utils.f(Lang.BANK + "&7You cancelled transferring money to another player!")); + MenuManager.openMenu(player, "bank"); + return; + } + if ((double) user.getCurrentChatValue() == 0) { + double amnt; + try { + amnt = Utils.round(Double.parseDouble(msg)); + } catch (NumberFormatException e1) { + player.sendMessage( + Utils.f(Lang.BANK + "&7Please enter a valid number or type &a\"quit\"&7!")); + user.resetCurrentChatActionTimer(0); + return; + } + if (amnt <= 0) { + player.sendMessage(Utils.f(Lang.BANK + + "&7The minimum amount is &a$&l0&7! Enter a valid number or type &a\"quit\"&7!")); + user.resetCurrentChatActionTimer(0); + return; + } + if (!user.hasBank(amnt)) { + player.sendMessage(Lang.BANK.f("&7You don't have &a$&l" + amnt + + "&7 in your bank account! Enter a valid amount or type &a\"quit\"&7!")); + user.resetCurrentChatActionTimer(0); + return; + } + user.resetCurrentChatActionTimer(amnt); + player.sendMessage(Utils + .f(Lang.BANK + "&7Please type the name of the player you would like to transfer &a$&l" + + amnt + "&7 to, or type &a\"quit\"&7!")); + return; + } + double amnt = (double) user.getCurrentChatValue(); + if (!user.hasBank(amnt)) { + player.sendMessage(Lang.BANK.f("&7You don't have &a$&l" + amnt + + "&7 in your bank account! Enter a valid amount or type &a\"quit\"&7!")); + user.resetCurrentChatActionTimer(0); + return; + } + Player target = Bukkit.getPlayer(msg); + if (target == null) { + player.sendMessage(Lang.BANK + .f("&7That player is not online! Enter a valid player name or type &a\"quit\"&7!")); + user.resetCurrentChatActionTimer(amnt); + return; + } + GTMUser targetGtmUser = GTM.getUserManager().getLoadedUser(target.getUniqueId()); + user.takeBank(amnt); + targetGtmUser.addBank(amnt); + user.clearCurrentChatAction(); + User playerUser = Core.getUserManager().getLoadedUser(player.getUniqueId()); + User targetUser = Core.getUserManager().getLoadedUser(target.getUniqueId()); + player.sendMessage(Lang.BANK.f("&7You transferred &a$&l" + amnt + "&7 into &a" + + targetUser.getColoredName(target) + "&7's bank account!")); + target.sendMessage(Lang.BANK.f("&a" + playerUser.getColoredName(player) + "&7 transferred &a$&l" + amnt + + "&7 into your bank account!")); + GTMUtils.updateBoard(player, playerUser, user); + GTMUtils.updateBoard(target, targetUser, targetGtmUser); + break; + } + case BUYING_LOTTERY_TICKETS: { + if ("quit".equalsIgnoreCase(msg)) { + user.clearCurrentChatAction(); + player.sendMessage(Utils.f(Lang.LOTTERY + "&7You cancelled buying lottery tickets!")); + MenuManager.openMenu(player, "lottery"); + return; + } + + int amnt; + try { + amnt = Integer.parseInt(msg); + } catch (NumberFormatException e1) { + player.sendMessage(Utils.f(Lang.LOTTERY + "&7Please enter a valid number or type &a\"quit\"&7!")); + user.resetCurrentChatActionTimer(0); + return; + } + + if (amnt < 1) { + player.sendMessage(Utils.f(Lang.LOTTERY + + "&7The minimum amount is &e&l1&7! Enter a valid number or type &a\"quit\"&7!")); + user.resetCurrentChatActionTimer(0); + return; + } + + if (amnt > 100000) { + player.sendMessage(Utils.f(Lang.LOTTERY + + "&7The maximum amount is &e&l100000&7! Enter a valid number or type &a\"quit\"&7!")); + user.resetCurrentChatActionTimer(0); + return; + } + + if (!user.hasMoney(amnt * 500)) { + player.sendMessage(Lang.LOTTERY.f("&7You don't have &a$&l" + (amnt * 500) + + "&7 to buy &e&l" + amnt + " Tickets&7! Enter a valid amount or type &a\"quit\"&7!")); + user.resetCurrentChatActionTimer(0); + return; + } + + user.clearCurrentChatAction(); + user.takeMoney(amnt * 500); + LotteryPlayer p = GTM.getLottery().getLotteryPlayer(player.getUniqueId()); + if (p == null) { + p = new LotteryPlayer(player.getUniqueId(), player.getName()); + GTM.getLottery().addLotteryPlayer(p); + } + + p.addTickets(amnt); + GTMUtils.updateBoard(player, user); + player.sendMessage(Utils.f(Lang.LOTTERY + "&7You bought &e&l" + amnt + " Tickets&7 for &a$&l" + (amnt * 500) + "&7!")); + break; + } + case GANG_CHAT_ACTION: { + new BukkitRunnable() { + @Override + public void run() { + if ("quit".equalsIgnoreCase(msg)) { + user.clearCurrentChatAction(); + player.sendMessage(Lang.GANGS.f("&7You cancelled this gang action!")); + MenuManager.openMenu(player, "mygang"); + return; + } + + Gang userGang = GangManager.getInstance().getGangByMember(player.getUniqueId()).orElse(null); + + String ac = (String) user.getCurrentChatValue(); + switch (ac) { + case "create": + if (userGang != null) return; + GangManager.getInstance().createGang(player, msg); + user.clearCurrentChatAction(); + return; + case "leader": { + Player target = Bukkit.getPlayer(msg); + if (target == null) { + player.sendMessage(Lang.GANGS.f("&7That player is not online!")); + return; + } + + if (userGang == null) { + player.sendMessage(Lang.GANGS.f("&7You are not in any gang!")); + return; + } + + user.clearCurrentChatAction(); + userGang.setOwner(player, Core.getUserManager().getLoadedUser(uuid), user, target); + return; + } + case "description": { + if (userGang == null) { + player.sendMessage(Lang.GANGS.f("&7You are not in any gang!")); + return; + } + user.clearCurrentChatAction(); + userGang.description(player, Core.getUserManager().getLoadedUser(uuid), user, msg); + return; + } + case "name": { + if (userGang == null) { + player.sendMessage(Lang.GANGS.f("&7You are not in any gang!")); + return; + } + user.clearCurrentChatAction(); + userGang.rename(player, Core.getUserManager().getLoadedUser(uuid), user, msg); + return; + } + case "relation": { + if (userGang == null) { + player.sendMessage(Lang.GANGS.f("&7You are not in any gang!")); + return; + } + + if (!userGang.isViewingGang(uuid)) { + Gang view = GangManager.getInstance().getGang(msg).orElse(null); + if (view == null) { + Lang.GANGS.f("&7That gang does not exist or no one in that gang is online!"); + return; + } + + user.clearCurrentChatAction(); + user.setCurrentChatAction(ChatAction.GANG_CHAT_ACTION, "relation"); + userGang.setViewingGang(uuid, view); + player.sendMessage(Lang.GANGS.f("&7Please type in the relation (ally, neutral or enemy) you would like to set towards gang &a" + msg + "&7, or type &a\"quit\" to quit!")); + return; + } + + Gang viewingGang = userGang.getViewingGang(uuid).orElse(null); + if (viewingGang == null) return; + userGang.setViewingGang(uuid, null); + user.clearCurrentChatAction(); + switch (msg) { + case "ally": + userGang.ally(player, Core.getUserManager().getLoadedUser(uuid), user, viewingGang.getName()); + return; + case "neutral": + userGang.neutral(player, Core.getUserManager().getLoadedUser(uuid), user, viewingGang.getName()); + return; + case "enemy": + userGang.enemy(player, Core.getUserManager().getLoadedUser(uuid), user, viewingGang.getName()); + return; + default: + player.sendMessage(Lang.GANGS.f("&7The relation must be one of ally, neutral or enemy!")); + return; + } + } + case "invite": + if (userGang == null) { + player.sendMessage(Lang.GANGS.f("&7You are not in any gang!")); + return; + } + + Player target = Bukkit.getPlayer(msg); + if (target == null) { + player.sendMessage(Lang.GANGS.f("&7That player is not online!")); + return; + } + + user.clearCurrentChatAction(); + userGang.invite(player, Core.getUserManager().getLoadedUser(uuid), target); + return; + default: + MenuManager.openMenu(player, "mygang"); + player.sendMessage(Lang.GANGS.f("&7That is not a gang action!")); + break; + } + } + }.runTask(GTM.getInstance()); + } + } + } + }.runTask(GTM.getInstance()); + } + + Gang userGang = GangManager.getInstance().getGangByMember(uuid).orElse(null); + + if (userGang != null && userGang.isGangChat(uuid)) { + e.setCancelled(true); + new BukkitRunnable() { + @Override + public void run() { + Player player = Bukkit.getPlayer(uuid); + if (player == null) return; + + GTMUser user = GTM.getUserManager().getLoadedUser(uuid); + userGang.chat(player, Core.getUserManager().getLoadedUser(uuid), user, msg); + Core.log("[GangChat] " + player.getName() + ": " + msg); + return; + + } + }.runTask(GTM.getInstance()); + } + + if (msg.startsWith("@")) { + if (userGang != null) { + String gangMsg = msg.replace("@", ""); + userGang.chat(player, coreUser, user, gangMsg); + e.setCancelled(true); + } + } + /*if (!coreUser.isRank(UserRank.MOD)) { + if (this.recentChats.containsKey(player.getName())) { + if (this.recentChats.get(player.getName()).containsKey(msg)) { + if (this.recentChats.get(player.getName()).get(msg) == 4) { + e.getRecipients().removeAll(e.getRecipients()); + e.getRecipients().add(player); + } else if (this.recentChats.get(player.getName()).get(msg) >= 5) { + e.setCancelled(true); + } + player.sendMessage(Lang.HEY.f("&7Slow down! Spamming can get you in trouble.")); + this.recentChats.get(player.getName()).put(msg, this.recentChats.get(player.getName()).get(msg) + 1); + } else { + this.recentChats.get(player.getName()).put(msg, 1); + } + } else { + this.recentChats.put(player.getName(), new HashMap<>()); + this.recentChats.get(player.getName()).put(msg, 1); + } + new BukkitRunnable() { + @Override + public void run() { + Chat.this.recentChats.get(player.getName()).remove(msg); + } + }.runTaskLater(GTM.getInstance(), 800); + }*/ + } + + private class TransferPayload { + private int generatedNumber; + private int gtmID; + + public TransferPayload(int generatedNumber, int gtmID) { + this.gtmID = gtmID; + this.generatedNumber = generatedNumber; + } + + public int getGeneratedNumber() { + return this.generatedNumber; + } + + public int getGtmID() { + return this.gtmID; + } + } +} + + diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/CommandPreProcess.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/CommandPreProcess.java new file mode 100644 index 0000000..76be5c1 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/CommandPreProcess.java @@ -0,0 +1,44 @@ +package net.grandtheftmc.gtm.listeners; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.users.CheatCode; +import net.grandtheftmc.gtm.users.GTMUser; +import org.bukkit.GameMode; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; + +/** + * Created by Timothy Lampen on 2017-09-25. + */ +public class CommandPreProcess implements Listener { + + @EventHandler + public void onCommand(PlayerCommandPreprocessEvent event){ + Player player = event.getPlayer(); + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + String msg = event.getMessage().toLowerCase(); + + if(player.getGameMode()== GameMode.SPECTATOR && !Core.getUserManager().getLoadedUser(player.getUniqueId()).isStaff()) { + player.sendMessage(Lang.GTM.f("&7You cannot execute commands while in spectator mode!")); + event.setCancelled(true); + return; + } + + + for(CheatCode code : CheatCode.getCodes()) { + switch (code){ + case FEED: + case STACK: + continue; + } + if(msg.equalsIgnoreCase("/" + code.toString())) { + code.activate(Core.getUserManager().getLoadedUser(player.getUniqueId()), user, player, user.getCheatCodeState(code)); + event.setCancelled(true); + } + } + } +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Craft.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Craft.java new file mode 100644 index 0000000..6b58117 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Craft.java @@ -0,0 +1,28 @@ +package net.grandtheftmc.gtm.listeners; + +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.CraftItemEvent; +import org.bukkit.event.inventory.PrepareItemCraftEvent; + +public class Craft implements Listener { + + @EventHandler + public void craftItem(CraftItemEvent event) { + if (event.getWhoClicked().getType() != EntityType.PLAYER) return; + Player player = (Player) event.getWhoClicked(); + + if (!player.isOp()) { + event.setCancelled(true); + event.setResult(Event.Result.DENY); + player.getInventory().remove(event.getRecipe().getResult()); + } + } + + @EventHandler + public void prepareItemCraft(PrepareItemCraftEvent event) { + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Damage.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Damage.java new file mode 100644 index 0000000..0a13588 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Damage.java @@ -0,0 +1,412 @@ +package net.grandtheftmc.gtm.listeners; + +import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeUnit; + +import org.bukkit.GameMode; +import org.bukkit.Material; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.ItemFrame; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Projectile; +import org.bukkit.entity.Tameable; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityRegainHealthEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import com.j0ach1mmall3.wastedguns.api.events.explosives.ExplosionDamageEntityEvent; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserManager; +import net.grandtheftmc.core.util.State; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.drugs.Drug; +import net.grandtheftmc.gtm.drugs.DrugService; +import net.grandtheftmc.gtm.gang.Gang; +import net.grandtheftmc.gtm.gang.GangManager; +import net.grandtheftmc.gtm.users.CheatCode; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.users.GTMUserManager; +import net.grandtheftmc.gtm.users.JobMode; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.users.HouseUser; + +public class Damage implements Listener { + + @EventHandler + public void onDamage(EntityDamageEvent e) { + Entity victimEntity = e.getEntity(); + if (!(victimEntity instanceof Player)) + return; + Player victim = (Player) victimEntity; + if (victim.getGameMode() == GameMode.SPECTATOR || victim.getWorld().equals(GTM.getWarpManager().getSpawn().getLocation().getWorld())) { + e.setCancelled(true); + } + else if (e.getCause() == EntityDamageEvent.DamageCause.ENTITY_EXPLOSION || e.getCause() == EntityDamageEvent.DamageCause.BLOCK_EXPLOSION) { + + GTMUser user = GTMUserManager.getInstance().getUser(victim.getUniqueId()).orElse(null); + if (user != null && user.hasTeleportProtection()){ + e.setCancelled(true); + } + } + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onDamageMonitor(EntityDamageEvent e) { + + if (!(e.getEntity() instanceof Player)) { + return; + } + + // grab event variables + Player player = (Player) e.getEntity(); + + // grab gtm user and and user + GTMUser gtmUser = GTMUserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + if (gtmUser != null) { + + User user = UserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + if (user != null) { + + // update tint health + gtmUser.updateTintHealth(player, user); + } + } + } + + /** + * Listens in on explosion damage entity event. + * <p> + * This is called when a launcher weapon or a throwable weapon explodes. + * This is mainly used as a permission listen. + * </p> + * + * @param event - the event + */ + @EventHandler + public void onExplosionDamageEntityEvent(ExplosionDamageEntityEvent event) { + + // if shooter not player, ignore + if (event.getShooter().getType() != EntityType.PLAYER) + return; + + // grab event variables + Player damager = (Player) event.getShooter(); + + // for each entity in event + for (LivingEntity livingEntity : event.getVictims()) { + + // only iterate over players + if (livingEntity.getType() != EntityType.PLAYER){ + continue; + } + + Player victim = (Player) livingEntity; + GTMUser victimGameUser = GTMUserManager.getInstance().getUser(victim.getUniqueId()).orElse(null); + + // if null victim, skip perm check + if (victimGameUser == null){ + continue; + } + + // if victim has protection + if (victimGameUser.hasTeleportProtection()) { + event.getVictims().remove(livingEntity); + continue; + } + + // if shooter has protection + GTMUser damagerGameUser = GTMUserManager.getInstance().getUser(damager.getUniqueId()).orElse(null); + + // if null user, remove victim from being damaged + if (damagerGameUser == null){ + event.getVictims().remove(livingEntity); + continue; + } + + if (damagerGameUser.hasTeleportProtection()) { + event.getVictims().remove(livingEntity); + continue; + } + + // if player is in gang + Optional<Gang> victimOpt = GangManager.getInstance().getGangByMember(victim.getUniqueId()), + damagerOpt = GangManager.getInstance().getGangByMember(damager.getUniqueId()); + if (victimOpt.isPresent() && damagerOpt.isPresent() && !Objects.equals(victim, damager)) { + if (Objects.equals(victimOpt.get(), damagerOpt.get())) { + event.getVictims().remove(livingEntity); + continue; + } + + if (victimOpt.get().isAllied(damagerOpt.get())) { + event.getVictims().remove(livingEntity); + continue; + } + } + + // if they have a job mode + switch (damagerGameUser.getJobMode()) { + case COP: + JobMode mode = victimGameUser.getJobMode(); + if (victimGameUser.getJobMode() == JobMode.COP) { + event.getVictims().remove(livingEntity); + continue; + } + if (mode == JobMode.CRIMINAL && victimGameUser.getWantedLevel() == 0) { + event.getVictims().remove(livingEntity); + continue; + } + case CRIMINAL: + if (victimGameUser.getJobMode() == JobMode.COP && damagerGameUser.getKillCounter() == 0) { + int wantedLevelBefore = damagerGameUser.getWantedLevel(); + damagerGameUser.addKillCounter(1); + int wantedLevelAfter = damagerGameUser.getWantedLevel(); + if (wantedLevelBefore < wantedLevelAfter) + damager.sendMessage(Utils.f(Lang.WANTED + "&7Oh " + (Core.getSettings().isSister() ? "snap" : "shit") + " the cops are onto you! &r" + GTMUtils.getWantedLevelStars(wantedLevelAfter) + " &7(&c" + wantedLevelAfter + "&7) ")); + } + default: + break; + } + } + } + + @EventHandler(ignoreCancelled = true) + public void onDamageByEntity(EntityDamageByEntityEvent e) { + if (e.getDamager() == null) + return; + Entity entity = e.getDamager(); + if (entity == null) + return; + + if (entity instanceof Projectile) + entity = (Entity) ((Projectile) entity).getShooter(); + else if (entity instanceof Tameable) + entity = (Entity) ((Tameable) entity).getOwner(); + + if (!(e.getEntity() instanceof Player && entity instanceof Player)) + return; + Player damager = (Player) entity; + Player victim = (Player) e.getEntity(); + + // if pvp is disabled, cancel event + if (!GTM.getSettings().isPvp()) { + e.setCancelled(true); + return; + } + + GTMUser victimGameUser = GTM.getUserManager().getLoadedUser(victim.getUniqueId()); + User coreVictimUser = Core.getUserManager().getLoadedUser(victim.getUniqueId()); + + // not loaded user should probably still take damage + if (victimGameUser == null){ + return; + } + + if (victimGameUser.hasTeleportProtection()) { + e.setCancelled(true); + long expires = TimeUnit.MILLISECONDS.toSeconds(victimGameUser.getTimeUntilTeleportProtectionExpires()); + if (expires <= 1) { + victimGameUser.setLastTeleport(0); + return; + } + damager.sendMessage(Lang.GTM.f(coreVictimUser.getColoredName(victim) + " &7has teleport protection for &a" + expires + "&7 seconds!")); + return; + } + + GTMUser damagerGameUser = GTM.getUserManager().getLoadedUser(damager.getUniqueId()); + if (damagerGameUser.hasTeleportProtection()) { + e.setCancelled(true); + damagerGameUser.setLastTeleport(0); + if (damagerGameUser.getCheatCodeState(CheatCode.SNEAKY).getState() == State.ON && damager.hasPotionEffect(PotionEffectType.INVISIBILITY)) + damager.removePotionEffect(PotionEffectType.INVISIBILITY); + damager.sendMessage(Lang.COMBATTAG.f("&7Your teleport protection has ended!")); + return; + } + + Optional<Gang> victimOpt = GangManager.getInstance().getGangByMember(victim.getUniqueId()), + damagerOpt = GangManager.getInstance().getGangByMember(damager.getUniqueId()); + if (victimOpt.isPresent() && damagerOpt.isPresent() && !Objects.equals(victim, damager)) { + if (Objects.equals(victimOpt.get(), damagerOpt.get())) { + e.setCancelled(true); + damager.sendMessage(Lang.GANGS.f("&7You can't hurt players that are in your gang!")); + return; + } + + if (victimOpt.get().isAllied(damagerOpt.get()) || damagerOpt.get().isAllied(victimOpt.get())) { + e.setCancelled(true); + damager.sendMessage(Lang.GANGS.f("&7You can't hurt players that are in an allied gang!")); + return; + } + } + + switch (damagerGameUser.getJobMode()) { + case COP: { + JobMode mode = victimGameUser.getJobMode(); + if (victimGameUser.getJobMode() == JobMode.COP) { + e.setCancelled(true); + damager.sendMessage(Utils.f(Lang.HEY + "&cYou can't kill cops!")); + break; + } + if (mode == JobMode.CRIMINAL && victimGameUser.getWantedLevel() == 0) { + damager.sendMessage(Lang.HEY.f("&7You can't damage citizens that are not wanted!")); + e.setCancelled(true); + break; + } + } + case CRIMINAL: + if (victimGameUser.getJobMode() == JobMode.COP && damagerGameUser.getKillCounter() == 0) { + int wantedLevelBefore = damagerGameUser.getWantedLevel(); + damagerGameUser.addKillCounter(1); + int wantedLevelAfter = damagerGameUser.getWantedLevel(); + if (wantedLevelBefore < wantedLevelAfter) + damager.sendMessage(Utils.f(Lang.WANTED + "&7Oh " + (Core.getSettings().isSister() ? "snap" : "shit") + " the cops are onto you! &r" + GTMUtils.getWantedLevelStars(wantedLevelAfter) + " &7(&c" + wantedLevelAfter + "&7) ")); + } + default: + break; + } + + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onDamageByEntityMonitor(EntityDamageByEntityEvent e) { + Entity damager = e.getDamager(); + Entity entity = e.getEntity(); + switch (entity.getType()) { + case PLAYER: { + if (e.isCancelled()) + return; + Player player = (Player) entity; + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + if (damager == null) + return; + if (damager instanceof Projectile) + damager = (Entity) ((Projectile) damager).getShooter(); + else if (entity instanceof Tameable) + damager = (Entity) ((Tameable) entity).getOwner(); + if (!(damager instanceof Player && entity instanceof Player)) + return; + if (!user.isInCombat()) + player.sendMessage(Utils.f(Lang.COMBATTAG + "&7You are now in combat! Do not log out for 10 seconds!")); + user.setLastTag(System.currentTimeMillis()); + if (GTM.getWarpManager().cancelTaxi(player, user)) + player.sendMessage(Utils.f(Lang.TAXI + "&eYour cab was cancelled!")); + Player dmger = (Player) damager; + GTMUser damagerUser = GTM.getUserManager().getLoadedUser(dmger.getUniqueId()); + if (!damagerUser.isInCombat()) + dmger.sendMessage(Utils.f(Lang.COMBATTAG + "&7You are now in combat! Do not log out for 20 seconds!")); + damagerUser.setLastTag(System.currentTimeMillis()); + if (GTM.getWarpManager().cancelTaxi(dmger, damagerUser)) + player.sendMessage(Utils.f(Lang.TAXI + "&eYour cab was cancelled!")); + if (dmger.getInventory().getItemInMainHand() != null) { + if (!Core.getSettings().isSister()) { + Optional<Drug> heroin = ((DrugService) GTM.getDrugManager().getService()).getDrug("heroin"); + if (heroin.isPresent()) { + if (dmger.getInventory().getItemInMainHand().getDurability() == 5 && dmger.getInventory().getItemInMainHand().getType() == Material.FLINT_AND_STEEL) { + heroin.get().apply(player); + player.damage(2); + player.sendMessage(Lang.DRUGS.f("&7You have been drugged.")); + if (dmger.getInventory().getItemInMainHand().getAmount() == 1) + dmger.getInventory().setItemInMainHand(new ItemStack(Material.AIR)); + else + dmger.getInventory().getItemInMainHand().setAmount(dmger.getInventory().getItemInMainHand().getAmount() - 1); + dmger.updateInventory(); + } + } + } + } + if (damager.getType() == EntityType.SNOWBALL) { + player.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 20 * 3, 1)); + } + return; + + } + case ITEM_FRAME: + if (!(damager instanceof Player)) + return; + Player player = (Player) damager; + ItemFrame frame = (ItemFrame) entity; + if (Core.getUserManager().getLoadedUser(player.getUniqueId()).hasEditMode()) + return; + ItemStack item = frame.getItem(); + if (item == null) + return; + switch (item.getType()) { + case PAPER: + MenuManager.openMenu(player, "atm"); + return; + default: + GTM.getShopManager().buy(player, frame.getItem()); + return; + } + default: + break; + } + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onHealthChangeMonitor(EntityRegainHealthEvent e) { + + if (!(e.getEntity() instanceof Player)) + return; + + // grab event variables + Player player = (Player) e.getEntity(); + + GTMUser gtmUser = GTMUserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + if (gtmUser != null){ + + User coreUser = UserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + if (coreUser != null){ + gtmUser.updateTintHealth(player, coreUser); + } + } + } + + @EventHandler(priority = EventPriority.MONITOR) + protected final void onPlayerDamage(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) + return; + Player damager = (Player) event.getDamager(); + HouseUser user = Houses.getUserManager().getLoadedUser(damager.getUniqueId()); + if (user == null) + return; + + if (!event.isCancelled() && (user.isInsideHouse() || user.isInsidePremiumHouse())) { + user.setInsideHouse(-1); + user.setInsidePremiumHouse(-1); + user.updateVisibility(damager); + } + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + protected final void onPlayerDamage(EntityDamageEvent event) { + if (event.getEntity() == null) + return; + if (!(event.getEntity() instanceof Player)) + return; + + if (((Player) event.getEntity()).isBlocking() && ThreadLocalRandom.current().nextBoolean()) { + ((Player) event.getEntity()).damage(event.getDamage() / 2); + } + + if (event.getCause() == EntityDamageEvent.DamageCause.CUSTOM || event.getCause() == EntityDamageEvent.DamageCause.ENTITY_ATTACK) { + ((Player) event.getEntity()).closeInventory(); + ((Player) event.getEntity()).updateInventory(); + } + } +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Death.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Death.java new file mode 100644 index 0000000..0889eba --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Death.java @@ -0,0 +1,354 @@ +package net.grandtheftmc.gtm.listeners; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; + +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.nametags.NametagManager; +import net.grandtheftmc.core.users.Pref; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserManager; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.bounties.Bounty; +import net.grandtheftmc.gtm.bounties.BountyManager; +import net.grandtheftmc.gtm.items.events.ArmorEquipEvent; +import net.grandtheftmc.gtm.items.events.EquipArmorType; +import net.grandtheftmc.gtm.users.CompassTarget; +import net.grandtheftmc.gtm.users.CompassTarget.TargetType; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.users.JobMode; +import net.grandtheftmc.guns.weapon.Weapon; + +public class Death implements Listener { + + @EventHandler + public void onDeath(PlayerDeathEvent e) { + Player victim = e.getEntity(); + Player killer = victim.getKiller(); + + if (killer == null){ + + // TODO test remove + Entity last = getLastDamageCauseSource(victim).orElse(null); + if (last != null){ + Core.log("[Death][DEBUG] No killer found for the death of " + victim.getName() + ", last damage entity was=" + last.toString()); + } + } + + boolean brokenDeath = killer == null || victim.getUniqueId().equals(killer.getUniqueId()); + + UUID victimUUID = victim.getUniqueId(); + GTMUser victimGameUser = GTM.getUserManager().getLoadedUser(victimUUID); + User victimUser = Core.getUserManager().getLoadedUser(victimUUID); + + if (!Core.getSettings().isSister()) { + GTM.getDrugManager().getEffectManager().cancelEffects(victim); + } + + int wantedLevel = victimGameUser.getWantedLevel(); + JobMode jobMode = victimGameUser.getJobMode(); + + victimGameUser.addDeaths(1); + victimGameUser.setLastTag(-1); + + Collection<Player> hiddenStaff = new ArrayList<>(); + victim.getNearbyEntities(30, 30, 30).forEach(entity -> { + if (entity.getType() != EntityType.PLAYER) return; + Player target = (Player) entity; + if (target.getGameMode() == GameMode.SPECTATOR) { + hiddenStaff.add(target); + victim.hidePlayer(target); + } + }); + victimGameUser.setDead(true); + if (victimGameUser.getVehicleTaskId() != -1) { + victimGameUser.cancelVehicleTeleport(); + victim.sendMessage(Lang.VEHICLES.f("&7You can't " + (victimGameUser.isSendAway() ? "send away" : "call") + " while you're dead!")); + } + victimGameUser.setKillCounter(0); + victimGameUser.setKillStreak(0); + victimGameUser.unsetCompassTarget(victim, victimUser); + if (GTM.getWarpManager().cancelTaxi(victim, victimGameUser)) + victim.sendMessage(Utils.f(Lang.TAXI + "&eThe taxi was cancelled!")); + victim.setHealth(victim.getMaxHealth()); + victim.spigot().respawn(); + victim.setFireTicks(0); + for (PotionEffect p : victim.getActivePotionEffects()) { + victim.removePotionEffect(p.getType()); + } + victim.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 180, 0), false); + victim.setGameMode(GameMode.SPECTATOR); + victim.setFlying(true); + victim.setFoodLevel(20); + victim.playSound(victim.getLocation(), Sound.ENTITY_WITHER_SPAWN, 1, 0.5F); + victim.setFlySpeed(0); + GTMUtils.removeBoard(victim); +// new JLibPlayer(victim).setWorldborderTint(0); + + // how much money is available to be "lost", half their money bal + double availableLostMoney = (int) (victimGameUser.getMoney() / 2.0); + + // cannot lose more than this amount + if (availableLostMoney > 50000) { + GTMUtils.log("moneyalert", victim.getName() + " has died and been prevented from dropping " + Utils.formatMoney(availableLostMoney)); + availableLostMoney = 50000; + } + + // how much money should be lost forever (to the server) + double serverTax = 0; + + // is the server taking some of the "lost" money + if (GTM.getSettings().isServerDeathTax()) { + + // get the base tax percent + double taxPercent = GTM.getSettings().getServerDeathBasePercent(); + + // if tax is scaled off rank + if (GTM.getSettings().isServerDeathTaxScaled()) { + taxPercent += victimGameUser.getRank().getServerTax(); + } + + // taxPercent is typically 20.0, so convert to percent, and multiply + serverTax = (int) ((taxPercent / 100.0) * availableLostMoney); + + // if there is a minimum death tax set, i.e. $500 + if (GTM.getSettings().getServerDeathTaxMin() > 0) { + if (serverTax < GTM.getSettings().getServerDeathTaxMin()) { + serverTax = GTM.getSettings().getServerDeathTaxMin(); + } + } + + // if there is a maximum death tax set, i.e. $1000 + // and it's higher than the deathMin + if (GTM.getSettings().getServerDeathTaxMax() > 0 && GTM.getSettings().getServerDeathTaxMax() > GTM.getSettings().getServerDeathTaxMin()) { + if (serverTax > GTM.getSettings().getServerDeathTaxMax()) { + serverTax = GTM.getSettings().getServerDeathTaxMax(); + } + } + } + + // TODO remove + Core.log("[Death][DEBUG] serverTax final=" + serverTax); + + // how much money the user is dropping on floor + double dropMoney = (int) (availableLostMoney - serverTax); + + // TODO remove + Core.log("[Death][DEBUG] init dropMoney=" + dropMoney); + if (dropMoney < 0) { + dropMoney = 0; + } + + // how much money the USER must lose + double finalLostMoney = availableLostMoney; + // how much money the USER "drops" to other players + double finalDropMoney = dropMoney; + + // TODO remove + Core.log("[Death][DEBUG] Player " + victim.getName() + " has died and is attempting to drop $" + finalDropMoney + " because of finalLostMoney=$" + finalLostMoney); + + if (finalLostMoney > 2) + victimGameUser.takeMoney(finalLostMoney); + String money = String.valueOf(finalLostMoney); + + new BukkitRunnable() { + @Override + public void run() { + + Player victim = Bukkit.getPlayer(victimUUID); + if (victim == null) return; + + User victimUser = Core.getUserManager().getLoadedUser(victim.getUniqueId()); + GTMUser victimGameUser = GTM.getUserManager().getLoadedUser(victim.getUniqueId()); + + if (Double.valueOf(money) > 0) { + victim.sendMessage(Utils.f(Lang.MONEY_TAKE.toString() + money)); + } + + // victimGameUser.figureOutSpawn(); + victim.teleport(GTM.getWarpManager().getSpawn().getLocation()); + for (PotionEffect p : victim.getActivePotionEffects()) { + victim.removePotionEffect(p.getType()); + } + hiddenStaff.forEach(target -> { + if (target == null || !target.isOnline()) return; + victim.showPlayer(target); + }); + hiddenStaff.clear(); + victim.setFoodLevel(20); + victim.setGameMode(GameMode.ADVENTURE); + victim.setFlying(false); + victim.setFlySpeed(0.1F); + GTMUtils.giveGameItems(victim); + JobMode job = victimGameUser.getJobMode(); + if (job != JobMode.CRIMINAL) { + victimGameUser.setJobMode(JobMode.CRIMINAL); + UserRank rank = victimUser.getUserRank(); + victim.sendMessage( + Lang.JOBS.f("&7You are no longer a " + job.getColoredNameBold() + "&7! Please wait &c&l" + Utils.timeInMillisToText(victimGameUser.getTimeUntilJobModeSwitch(rank)) + "&7 before switching Job Mode again!" + + (rank.isHigherThan(UserRank.SPONSOR) ? "" : " Buy a rank a &a&l" + Core.getSettings().getStoreLink() + "&7 to be able to switch faster!"))); + NametagManager.updateNametag(victim); + } + GTMUtils.updateBoard(victim, victimGameUser); + victimGameUser.setDead(false); + } + }.runTaskLater(GTM.getInstance(), 150); + + double moneyToDrop = ((killer == null || killer.equals(victim)) ? 0 : Utils.randomNumber(250, 1000)) + finalDropMoney; + new ArrayList<>(e.getDrops()).stream().filter(stack -> stack != null && (stack.getType() == Material.WATCH || stack.getType() == Material.COMPASS || stack.getType() == Material.CHEST)).forEach(e.getDrops()::remove); + + if (!brokenDeath && moneyToDrop > 0){ + e.getDrops().add(Utils.createItem(Material.PAPER, "&a$&l" + moneyToDrop)); + } + + Utils.sendTitle(victim, "&c&lWASTED", brokenDeath ? null : "&7" + GTMUtils.getMessageKilledBy(killer.getName()), 80, 50, 20); + if (killer == null || killer.equals(victim)) { + e.setDeathMessage(Utils.f("&e" + victim.getName() + "&7 " + (victim.getLastDamageCause() instanceof EntityDamageByEntityEvent ? "was killed by &c" + ((EntityDamageByEntityEvent) victim.getLastDamageCause()).getDamager().getCustomName() + "&7!" : "died!"))); + return; + } + Weapon killerWeapon = GTM.getWastedGuns().getWeaponManager().getWeaponInHand(killer); + Utils.b((killerWeapon != null && killerWeapon.getCompactName().equalsIgnoreCase("katana"))+""); + if (Utils.calculateChance(killerWeapon != null && killerWeapon.getCompactName().equalsIgnoreCase("katana") ? 5 : 2)) { + + e.getDrops().add(Utils.setSkullOwner(Utils.createItem(Material.SKULL_ITEM, 3, "&e&l" + victim.getName() + "'s Head", "&7Value: &a$&l10,000", "&7Sell me in the sewer!"), victim.getName())); + killer.sendMessage(Lang.HEY.f(victimUser.getColoredName(victim) + "&7's head dropped on the ground! Sell it at the auction house for a guaranteed &a$&l10,000&7 or more!")); + } + + e.setDeathMessage(Utils.f("&e" + victim.getName() + "&7 was killed by &c" + (brokenDeath ? "Unkown" : killer.getName()) + "&7!")); + UUID killerUUID = killer.getUniqueId(); + GTMUser killerGameUser = GTM.getUserManager().getLoadedUser(killerUUID); + User killerUser = Core.getUserManager().getLoadedUser(killerUUID); + killerGameUser.addKills(1); + killerGameUser.addKillStreak(1); + switch (killerGameUser.getJobMode()) { + case CRIMINAL: + int wantedLevelBefore = killerGameUser.getWantedLevel(); + if (jobMode == JobMode.COP) { + killerGameUser.addKillCounter(2); + } else { + if (ThreadLocalRandom.current().nextInt(1, 4) == 2) { + killerGameUser.addKillCounter(1); + } + } + int wantedLevelAfter = killerGameUser.getWantedLevel(); + killer.sendMessage(Lang.GTM.f("&7You killed &a" + victimUser.getColoredName(victim) + "&7! &a$&l" + + moneyToDrop + "&7 was dropped on the ground!")); + if (wantedLevelBefore < wantedLevelAfter) + killer.sendMessage(Utils.f(Lang.WANTED + "&7Oh " + (Core.getSettings().isSister() ? "snap" : "shit") + " the cops are onto you! &r" + + GTMUtils.getWantedLevelStars(wantedLevelAfter) + "&7 (&c" + wantedLevelAfter + "&7) ")); + break; + case COP: + int copMoney = GTMUtils.getCopMoney(wantedLevel); + if (copMoney > 0) { + killerGameUser.addMoney(copMoney); + killer.sendMessage(Utils.f(Lang.COP_MODE + "&7You were rewarded &a$&l" + copMoney + "&7 for killing &c" + + victimUser.getColoredName(victim) + " &7with &e" + GTMUtils.getWantedLevelStars(wantedLevel) + + " (" + wantedLevel + ")&7!")); + } else + killer.sendMessage(Lang.GTM.f("&7You killed &a" + victimUser.getColoredName(victim) + "&7! &a$&l" + + moneyToDrop + "&7 was dropped on the ground!")); + break; + case HITMAN: + CompassTarget compassTarget = killerGameUser.getCompassTarget(); + if (compassTarget != null && compassTarget.getType() == TargetType.PLAYER + && Objects.equals(compassTarget.getTargetPlayer(), victim)) + killerGameUser.unsetCompassTarget(killer, killerUser); + BountyManager bm = GTM.getBountyManager(); + Bounty bounty = bm.getBounty(victimUUID); + if (bounty == null) { + killer.sendMessage(Lang.GTM.f("&7You killed &a" + victimUser.getColoredName(victim) + "&7! &a$&l" + + moneyToDrop + "&7 was dropped on the ground!")); + break; + } + killerGameUser.addMoney(bounty.getAmount()); + bm.removeBounty(bounty); + Utils.broadcastExcept(killer, Lang.BOUNTIES + "&a" + killer.getName() + "&7 claimed the bounty of &a$&l" + + bounty.getAmount() + "&7 on &c" + bounty.getName() + "&7!"); + killer.sendMessage(Utils.f(Lang.HITMAN_MODE + "&7You claimed the bounty of &a$&l" + bounty.getAmount() + + "&7 on &a" + victim.getName() + "&7!")); + killer.sendMessage(Utils.f(Lang.MONEY_ADD + String.valueOf(bounty.getAmount()))); + break; + } + GTMUtils.updateBoard(killer, killerGameUser); + victim.setBedSpawnLocation(GTM.getWarpManager().getSpawn().getLocation(), true); + killer.setBedSpawnLocation(GTM.getWarpManager().getSpawn().getLocation(), true); + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onDeathMonitor(PlayerDeathEvent e) { + + // send death message to everyone online + for (Player player : Bukkit.getOnlinePlayers()) { + User user = UserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + if (user != null){ + if (!Objects.equals(player, e.getEntity().getKiller()) && user.getPref(Pref.DEATH_MESSAGES)){ + player.sendMessage(e.getDeathMessage()); + } + } + } + + // set event death message to null + e.setDeathMessage(null); + + Player p = e.getEntity(); + int slot = 39; + for (ItemStack i : p.getInventory().getArmorContents()) { + if (i != null && !i.getType().equals(Material.AIR)) { + ArmorEquipEvent event = new ArmorEquipEvent(p, ArmorEquipEvent.EquipMethod.DEATH, EquipArmorType.matchType(i), i, new ItemStack(Material.AIR), EquipArmorType.fromSlot(slot)); + Bukkit.getServer().getPluginManager().callEvent(event); + slot--; + } + } + } + + public static Optional<Entity> getLastDamageCauseSource(Entity entity){ + + // grab the last damage cause + EntityDamageEvent ede = entity.getLastDamageCause(); + + if (ede == null){ + return Optional.empty(); + } + + if (ede instanceof EntityDamageByEntityEvent) { + + EntityDamageByEntityEvent edbee = (EntityDamageByEntityEvent) ede; + + Entity damager = edbee.getDamager(); + if (damager instanceof Player) { + + Player killer = (Player) damager; + return Optional.of(killer); + } + } + + return Optional.of(ede.getEntity()); + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Dispense.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Dispense.java new file mode 100644 index 0000000..8d4c31e --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Dispense.java @@ -0,0 +1,43 @@ +package net.grandtheftmc.gtm.listeners; + +import net.grandtheftmc.gtm.items.events.ArmorEquipEvent; +import net.grandtheftmc.gtm.items.events.EquipArmorType; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockDispenseEvent; + +/** + * Created by Timothy Lampen on 2017-08-11. + */ +public class Dispense implements Listener { + + @EventHandler + public void onDispense(BlockDispenseEvent e){ + EquipArmorType type = EquipArmorType.matchType(e.getItem()); + if(EquipArmorType.matchType(e.getItem()) != null){ + Location loc = e.getBlock().getLocation(); + for(Player p : loc.getWorld().getPlayers()){ + if(loc.getBlockY() - p.getLocation().getBlockY() >= -1 && loc.getBlockY() - p.getLocation().getBlockY() <= 1){ + if(p.getInventory().getHelmet() == null && type.equals(EquipArmorType.HELMET) || p.getInventory().getChestplate() == null && type.equals(EquipArmorType.CHESTPLATE) || p.getInventory().getLeggings() == null && type.equals(EquipArmorType.LEGGINGS) || p.getInventory().getBoots() == null && type.equals(EquipArmorType.BOOTS)){ + org.bukkit.block.Dispenser dispenser = (org.bukkit.block.Dispenser) e.getBlock().getState(); + org.bukkit.material.Dispenser dis = (org.bukkit.material.Dispenser) dispenser.getData(); + BlockFace directionFacing = dis.getFacing(); + // Someone told me not to do big if checks because it's hard to read, look at me doing it -_- + if(directionFacing == BlockFace.EAST && p.getLocation().getBlockX() != loc.getBlockX() && p.getLocation().getX() <= loc.getX() + 2.3 && p.getLocation().getX() >= loc.getX() || directionFacing == BlockFace.WEST && p.getLocation().getX() >= loc.getX() - 1.3 && p.getLocation().getX() <= loc.getX() || directionFacing == BlockFace.SOUTH && p.getLocation().getBlockZ() != loc.getBlockZ() && p.getLocation().getZ() <= loc.getZ() + 2.3 && p.getLocation().getZ() >= loc.getZ() || directionFacing == BlockFace.NORTH && p.getLocation().getZ() >= loc.getZ() - 1.3 && p.getLocation().getZ() <= loc.getZ()){ + ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(p, ArmorEquipEvent.EquipMethod.DISPENSER, EquipArmorType.matchType(e.getItem()), null, e.getItem(), null); + Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent); + if(armorEquipEvent.isCancelled()){ + e.setCancelled(true); + } + return; + } + } + } + } + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Drop.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Drop.java new file mode 100644 index 0000000..a33cca7 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Drop.java @@ -0,0 +1,37 @@ +package net.grandtheftmc.gtm.listeners; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.gtm.GTMUtils; + +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.LeatherArmorMeta; + +public class Drop implements Listener { + + @EventHandler + public void onDrop(PlayerDropItemEvent e) { + ItemStack item = e.getItemDrop().getItemStack().clone(); + if(item==null) + return; + switch (item.getType()) { + case CHEST: + case WATCH: + case COMPASS: + e.getItemDrop().remove(); + item.setAmount(1); + GTMUtils.giveGameItems(e.getPlayer()); + return; + } + + if(item.getType().toString().contains("LEATHER_")) { + if(ArmorEquip.isCustomColor(((LeatherArmorMeta)item.getItemMeta()).getColor())) { + e.getItemDrop().remove(); + e.getPlayer().updateInventory(); + } + } + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/DrugBlockRemovalListener.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/DrugBlockRemovalListener.java new file mode 100644 index 0000000..50544da --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/DrugBlockRemovalListener.java @@ -0,0 +1,89 @@ +package net.grandtheftmc.gtm.listeners; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.ListeningWhitelist; +import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.events.PacketListener; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.gtm.GTM; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.block.BrewingStand; +import org.bukkit.plugin.Plugin; + +import java.util.ArrayList; +import java.util.List; + +public class DrugBlockRemovalListener implements PacketListener { + + private final List<Location> locations = new ArrayList<>(); + + public DrugBlockRemovalListener() { + } + + @Override + public void onPacketSending(PacketEvent event) { +// net.minecraft.server.v1_12_R1.PacketPlayOutMapChunk + if (event.isAsync()) System.out.println("MAP_CHUNK ASYNC"); + + int cx = event.getPacket().getIntegers().read(0), cz = event.getPacket().getIntegers().read(1); + int[] count = {0}; + Chunk chunk = event.getPlayer().getWorld().getChunkAt(cx, cz); + + ServerUtil.runTaskAsync(() -> { + for (BlockState tile : chunk.getTileEntities()) { + if (!(tile instanceof BrewingStand)) continue; + locations.add(tile.getLocation()); + count[0] += 1; + } + + for (int x = 0; x < 16; x++) { + for (int z = 0; z < 16; z++) { + for (int y = 0; y < 250; y++) { + Block block = chunk.getBlock(x, y, z); + if (block.getType() == Material.CARPET && block.getData() == (byte) 5) { + locations.add(block.getLocation()); + count[0] += 1; + } + } + } + } + + if (count[0] >= 1) { + ServerUtil.runTask(() -> { + for (Location location : locations) { + location.getBlock().setType(Material.AIR); + } + + event.getPlayer().sendMessage("Blocks removed: " + count[0]); + }); + } + }); + } + + @Override + public void onPacketReceiving(PacketEvent packetEvent) { + //404 DO NOTHING. + } + + @Override + public ListeningWhitelist getSendingWhitelist() { + return ListeningWhitelist.newBuilder() + .lowest() + .types(PacketType.Play.Server.MAP_CHUNK) + .build(); + } + + @Override + public ListeningWhitelist getReceivingWhitelist() { + return ListeningWhitelist.EMPTY_WHITELIST; + } + + @Override + public Plugin getPlugin() { + return GTM.getInstance(); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/FireListener.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/FireListener.java new file mode 100644 index 0000000..312455f --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/FireListener.java @@ -0,0 +1,29 @@ +package net.grandtheftmc.gtm.listeners; + +import net.grandtheftmc.gtm.tasks.PlayerTask; +import org.bukkit.Material; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBurnEvent; +import org.bukkit.event.block.BlockSpreadEvent; + +public class FireListener implements Listener { + + @EventHandler + public void blockBurnEvent(BlockBurnEvent event) { + event.setCancelled(true); + } + + @EventHandler + public void blockSpreadEvent(BlockSpreadEvent event) { + if (event.getSource().getType() == Material.FIRE) event.getSource().setType(Material.AIR); + event.setCancelled(true); + } + + public static void clearFire() { + PlayerTask.fireBlocks.forEach(block -> { + block.setType(Material.AIR); + PlayerTask.fireBlocks.remove(block); + }); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/FoodChange.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/FoodChange.java new file mode 100644 index 0000000..59be573 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/FoodChange.java @@ -0,0 +1,18 @@ +package net.grandtheftmc.gtm.listeners; + +import net.grandtheftmc.gtm.GTM; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.FoodLevelChangeEvent; + +import java.util.Objects; + +public class FoodChange implements Listener { + + @EventHandler + public void onFoodChange(FoodLevelChangeEvent event) { + if (Objects.equals(event.getEntity().getLocation().getWorld(), GTM.getWarpManager().getSpawn().getLocation().getWorld())) { + event.setFoodLevel(20); + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/GamemodeChange.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/GamemodeChange.java new file mode 100644 index 0000000..a8e39b9 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/GamemodeChange.java @@ -0,0 +1,47 @@ +package net.grandtheftmc.gtm.listeners; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.items.ArmorUpgrade; +import org.bukkit.GameMode; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerGameModeChangeEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; + +/** + * Created by Timothy Lampen on 7/20/2017. + */ +public class GamemodeChange implements Listener { + + @EventHandler + public void onChange(PlayerGameModeChangeEvent event){ + Player player = event.getPlayer(); + + if(event.getNewGameMode()== GameMode.CREATIVE){ + player.setMaxHealth(20); + player.getActivePotionEffects().stream().forEach(potionEffect -> player.removePotionEffect(potionEffect.getType())); + } + else if(event.getNewGameMode()!=GameMode.CREATIVE){ + int amtOfEnchaned = 0; + ItemStack[] armor = player.getInventory().getArmorContents(); + for(ItemStack piece : armor){ + if(piece==null) + continue; + for(ArmorUpgrade upgrade : ArmorUpgrade.getArmorUpgrades(piece)){ + if(upgrade==ArmorUpgrade.ENHANCED){ + player.setMaxHealth(player.getMaxHealth()+5); + } + for(PotionEffect effect : upgrade.getPotionEffects()){ + player.addPotionEffect(effect); + } + } + amtOfEnchaned += ArmorUpgrade.getArmorUpgrades(piece).contains(ArmorUpgrade.ENHANCED) ? 10 : 0; + } + player.setMaxHealth(20 + amtOfEnchaned); + player.setHealth(player.getMaxHealth()); + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Interact.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Interact.java new file mode 100644 index 0000000..678d2d1 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Interact.java @@ -0,0 +1,408 @@ +package net.grandtheftmc.gtm.listeners; + +import com.j0ach1mmall3.jlib.methods.ReflectionAPI; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.drugs.Drug; +import net.grandtheftmc.gtm.drugs.DrugService; +import net.grandtheftmc.gtm.items.ArmorType; +import net.grandtheftmc.gtm.items.GameItem; +import net.grandtheftmc.gtm.items.Kit; +import net.grandtheftmc.gtm.items.events.ArmorEquipEvent; +import net.grandtheftmc.gtm.items.events.EquipArmorType; +import net.grandtheftmc.gtm.lootcrates.LootCrate; +import net.grandtheftmc.gtm.users.ChatAction; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.users.JobMode; +import net.grandtheftmc.gtm.users.TaxiTarget; +import net.grandtheftmc.gtm.utils.ParticleColor; +import net.grandtheftmc.gtm.utils.ReflectionUtil; +import net.grandtheftmc.guns.weapon.Weapon; +import org.bukkit.*; +import org.bukkit.block.BlockState; +import org.bukkit.block.Chest; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; +import org.bukkit.entity.ItemFrame; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractAtEntityEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Optional; +import java.util.concurrent.ThreadLocalRandom; + +public class Interact implements Listener { + private static final Class BLOCK_POSITION_CLASS = ReflectionAPI.getNmsClass("BlockPosition"); + + public Interact() { +// ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(GTM.getInstance(), PacketType.Play.Server.ENTITY_METADATA, PacketType.Play.Server.ENTITY_DESTROY, PacketType.Play.Server.ENTITY_EQUIPMENT, PacketType.Play.Server.ENTITY_STATUS, PacketType.Play.Client.ENTITY_ACTION) { +// @Override +// public void onPacketReceiving(PacketEvent event) { +//// super.onPacketReceiving(event); +// if (event.getPacket().getType() == PacketType.Play.Server.ENTITY_METADATA) { +// PacketPlayOutEntityMetadata +// } +// ServerUtil.debug(event.getPlayer().getName() + " -> " + event.getPacket().toString()); +// } +// +// @Override +// public void onPacketSending(PacketEvent event) { +//// super.onPacketSending(event); +// ServerUtil.debug(event.getPlayer().getName() + " -> " + event.getPacket().toString()); +// } +// }); + } + + @EventHandler + public void armorEquipRunner(PlayerInteractEvent e) { + if (e.getAction() == Action.PHYSICAL) return; + if (e.getAction() == Action.RIGHT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_BLOCK) { + final Player player = e.getPlayer(); + ArmorType newArmorType = ArmorType.matchType(e.getItem()); + if (newArmorType != null) { + if (newArmorType.equals(ArmorType.HELMET) && e.getPlayer().getInventory().getHelmet() == null || newArmorType.equals(ArmorType.CHESTPLATE) && e.getPlayer().getInventory().getChestplate() == null || newArmorType.equals(ArmorType.LEGGINGS) && e.getPlayer().getInventory().getLeggings() == null || newArmorType.equals(ArmorType.BOOTS) && e.getPlayer().getInventory().getBoots() == null) { + ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(e.getPlayer(), ArmorEquipEvent.EquipMethod.HOTBAR, EquipArmorType.matchType(e.getItem()), null, e.getItem(), null); + Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent); + if (armorEquipEvent.isCancelled()) { + e.setCancelled(true); + player.updateInventory(); + } + } + } + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onInteractHigh(PlayerInteractEvent e) { + Player player = e.getPlayer(); + ItemStack is = e.getItem(); + + if (is == null) return; + if (!player.hasPotionEffect(PotionEffectType.INVISIBILITY)) return; + + Optional<Weapon<?>> weapon = GTM.getWastedGuns().getWeaponManager().getWeapon(is); + if (weapon.isPresent()) { + player.removePotionEffect(PotionEffectType.INVISIBILITY); + player.sendMessage(Lang.CHEAT_CODES.f("&7Your invisibility was removed because you used a weapon!")); + } + } + + @EventHandler + public void onInteract(PlayerInteractEvent e) { + Player player = e.getPlayer(); + ItemStack item = player.getInventory().getItemInMainHand(); + if (e.getAction() != Action.RIGHT_CLICK_AIR && e.getAction() != Action.RIGHT_CLICK_BLOCK) + return; + if (item != null) { + switch (item.getType()) { + case GOLD_RECORD: + if (e.getClickedBlock() == null) return; + if (e.getClickedBlock().getType() == Material.JUKEBOX) return; + return; + case WATCH: + MenuManager.openMenu(player, "phone"); + return; + case COMPASS: + MenuManager.openMenu(player, "gps"); + return; + case RECORD_5: + if (e.getClickedBlock() != null && e.getClickedBlock().getType() == GTM.getItemManager().getItem("bong").getItem().getType()) { + if (item.getAmount() > 1) { + item.setAmount(item.getAmount() - 1); + player.getInventory().setItemInMainHand(item); + } else { + player.getInventory().remove(item); + } + Optional<Drug> weed = ((DrugService) GTM.getInstance().getDrugManager().getService()).getDrug("weed"); + if (weed.isPresent()) { + weed.get().apply(player); + } else { + return; + } + final Location blockLoc = e.getClickedBlock().getLocation(); + final long startTime = System.currentTimeMillis(); + player.playSound(player.getLocation(), Sound.BLOCK_BREWING_STAND_BREW, 1, 1); + new BukkitRunnable() { + @Override + public void run() { + if (startTime + (1000 * 5) <= System.currentTimeMillis()) + cancel(); + double locX = blockLoc.getX() + (ThreadLocalRandom.current().nextDouble(-.15, .15) + .5); + double locZ = blockLoc.getZ() + (ThreadLocalRandom.current().nextDouble(-.15, .15) + .5); + double locY = blockLoc.getY() + 1.2; + ParticleColor color = ParticleColor.AQUA; + player.spigot().playEffect(new Location(blockLoc.getWorld(), locX, locY, locZ), Effect.SPELL, 1, 1, color.getRed(), color.getGreen(), color.getBlue(), 1, 1, 10); + } + }.runTaskTimerAsynchronously(GTM.getInstance(), 0, 1); + } + return; + default: + break; + } + } + if (e.getClickedBlock() == null) + return; + + if (e.getClickedBlock().getType() == Material.CAULDRON) { + e.setCancelled(true); + return; + } + + BlockState block = e.getClickedBlock().getState(); + switch (block.getType()) { + case CHEST: + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + if (user.isAddingLootCrate()) { + try { + Chest chest = (Chest) block; + Class<?> craftChestClass = ReflectionUtil.getOBCClass("block.CraftChest"); + Object craftChest = craftChestClass.cast(chest); + Method getTileEntity = craftChestClass.getMethod("getTileEntity"); + Object tileEntity = getTileEntity.invoke(craftChest); + Class<?> tileEntityClass = ReflectionUtil.getNMSClass("TileEntityChest"); + Method setTitle = tileEntityClass.getMethod("a", String.class); + setTitle.invoke(tileEntity, Utils.f("&e&lLoot Crate")); + } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ex) { + ex.printStackTrace(); + } + GTM.getCrateManager().addCrate(block.getLocation()); + player.sendMessage(Lang.LOOTCRATES.f("&7You added a loot crate at location &a" + + Utils.blockLocationToString(block.getLocation()) + "&7!")); + user.setAddingLootCrate(false); + e.setCancelled(true); + return; + } else if (user.isRemovingLootCrate()) { + LootCrate crate = GTM.getCrateManager().getCrate(block.getLocation()); + if (crate == null) { + player.sendMessage(Lang.LOOTCRATES.f("&7This is not a Loot Crate!")); + user.setRemovingLootCrate(false); + return; + } + GTM.getCrateManager().removeCrate(block.getLocation()); + player.sendMessage(Lang.LOOTCRATES.f("&7You removed a loot crate at location &a" + + Utils.blockLocationToString(block.getLocation()) + "&7!")); + user.setRemovingLootCrate(false); + e.setCancelled(true); + return; + } else if (user.isCheckingLootCrate()) { + LootCrate crate = GTM.getCrateManager().getCrate(block.getLocation()); + if (crate == null) { + player.sendMessage(Lang.LOOTCRATES.f("&7This is not a Loot Crate!")); + user.setCheckingLootCrate(false); + return; + } + player.sendMessage(Lang.LOOTCRATES.f("&7The Loot Crate at location &a" + + Utils.blockLocationToString(block.getLocation()) + "&7 will restock in &a" + + Utils.timeInSecondsToText(crate.getTimer()) + "&7! (+- 10s)")); + user.setCheckingLootCrate(false); + e.setCancelled(true); + return; + } else if (user.isRestockingLootCrate()) { + LootCrate crate = GTM.getCrateManager().getCrate(block.getLocation()); + if (crate == null) { + player.sendMessage(Lang.LOOTCRATES.f("&7This is not a Loot Crate!")); + user.setRestockingLootCrate(false); + return; + } + crate.restock(); + player.sendMessage(Lang.LOOTCRATES.f("&7The Loot Crate at location &a" + + Utils.blockLocationToString(block.getLocation()) + "&7 was restocked.")); + user.setRestockingLootCrate(false); + e.setCancelled(true); + return; + } + LootCrate crate = GTM.getCrateManager().getCrate(block.getLocation()); + if (crate == null) return; + if (crate.getTimer() <= 0) { + crate.resetTimer(); + + int money = Utils.randomNumber(20, 150); + user.addMoney(money); + player.sendMessage(Lang.MONEY_ADD.f(money + ".00")); + } + return; + default: + break; + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void onInteractEntity(PlayerInteractEntityEvent e) { + Player player = e.getPlayer(); + Entity en = e.getRightClicked(); + switch (en.getType()) { + case ARMOR_STAND: + if (GTM.getDrugManager().getDrugDealer().isDrugDealer(en)) { + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + if (user.getJobMode() == JobMode.COP) { + user.setMoney(user.getMoney() + 10000); + player.sendMessage(Lang.GTM + "" + ChatColor.GREEN + "You have arrested a drug dealer and recieved $10,000!"); + player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 1); + en.remove(); + return; + } + } + break; + case ITEM_FRAME: + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (user.hasEditMode()) { + e.setCancelled(false); + return; + } + if (user.isInTutorial()) { + e.setCancelled(true); + return; + } + e.setCancelled(true); + ItemFrame frame = (ItemFrame) en; + ItemStack item = frame.getItem(); + if (item == null) + return; + switch (item.getType()) { + case PAPER: { + GTMUser gtmUser = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + if (gtmUser.isArrested()) { + if (gtmUser.getJailTimer() < 5) { + player.sendMessage(Lang.BRIBE.f("&7You are already being released!")); + return; + } + Player cop = Bukkit.getPlayer(gtmUser.getJailCop()); + GTMUser copUser = cop == null ? null : GTM.getUserManager().getLoadedUser(cop.getUniqueId()); + if (cop == null || copUser.getJobMode() != JobMode.COP) { + player.sendMessage(Lang.BRIBE.f("&7The cop who arrested you (&3&l" + gtmUser.getJailCopName() + "&7) is off duty!")); + return; + } + gtmUser.setCurrentChatAction(ChatAction.BRIBING, 0); + player.sendMessage(Lang.BRIBE.f("&7Please type the amount you would like to offer as a bribe to &3&l" + gtmUser.getJailCopName() + "&7 or type &a\"/quit\"&7!")); + return; + } + frame.setRotation(Rotation.NONE); + MenuManager.openMenu(player, "bank"); + break; + } + case ENDER_PEARL: + frame.setRotation(Rotation.NONE); + GTM.getWarpManager().warp(player, user, GTM.getUserManager().getLoadedUser(player.getUniqueId()), + new TaxiTarget(GTM.getWarpManager().getRandomWarp()), 0, user.isPremium() ? 1 : 10); + break; + case IRON_FENCE: + if (GTMUtils.getJailedPlayers().isEmpty()) { + player.sendMessage(Lang.JAIL.f("&7There are currently no prisoners in jail!")); + return; + } + MenuManager.openMenu(player, "jail"); + break; + case STORAGE_MINECART: + MenuManager.openMenu(player, "taxi"); + break; + case MINECART: { + String name = item.hasItemMeta() && item.getItemMeta().hasDisplayName() + ? ChatColor.stripColor(item.getItemMeta().getDisplayName()) : null; + if (name.startsWith("Buy Vehicle: ")) + name = name.replace("Buy Vehicle: ", ""); + else if (name.startsWith("Vehicle Shop: ")) + name = name.replace("Vehicle Shop: ", ""); + else if (name.startsWith("Buy ")) + name = name.replace("Buy ", ""); + else break; + GameItem gameItem = GTM.getItemManager().getItemFromDisplayName(name); + if (gameItem == null || gameItem.getType() != GameItem.ItemType.VEHICLE) return; + GTMUser gtmUser = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + gtmUser.setActionVehicle(gameItem.getWeaponOrVehicleOrDrug()); + MenuManager.openMenu(player, "vehicleshop"); + return; + } + case LEATHER: { + String name = item.hasItemMeta() && item.getItemMeta().hasDisplayName() + ? ChatColor.stripColor(frame.getItem().getItemMeta().getDisplayName()).toLowerCase() : null; + Core.log(name); + if (name != null && name.contains("upgrade buy: $")) { + GTM.getShopManager().buyArmorUpgrade(player, name); + return; + } + break; + } + case EMPTY_MAP: + case MAP: { + frame.setRotation(Rotation.NONE); + MenuManager.openMenu(player, "lottery"); + break; + } + default: + String name = item.hasItemMeta() && item.getItemMeta().hasDisplayName() + ? ChatColor.stripColor(frame.getItem().getItemMeta().getDisplayName()) : null; + if (name != null && name.startsWith("Preview Kit: ")) { + Kit kit = GTM.getItemManager().getKit(name.replace("Preview Kit: ", "")); + if (kit != null) + GTM.getBackpackManager().kitPreview(player, kit); + return; + } + GTM.getShopManager().buy(player, frame.getItem()); + break; + } + return; + default: + break; + } + } + + @EventHandler + public void onInteractAtEntity(PlayerInteractAtEntityEvent e) { + Player player = e.getPlayer(); + Entity en = e.getRightClicked(); + switch (en.getType()) { + case ARMOR_STAND: + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (Core.getSettings().isUseEditMode() + && user.hasEditMode()) + break; + ArmorStand armorStand = (ArmorStand) e.getRightClicked(); + String name = ChatColor.stripColor(armorStand.getCustomName()); + if (name == null) break; + switch (name.toLowerCase()) { + case "mechanic": + MenuManager.openMenu(player, "mechanic"); + return; + case "cab driver": + MenuManager.openMenu(player, "taxi"); + return; + case "warden": + MenuManager.openMenu(player, "jail"); + return; + case "drug dealer": + MenuManager.openMenu(player, "drugdealer"); + return; + case "arms dealer": + MenuManager.openMenu(player, "weapons"); + return; + case "head salesman": + ItemStack item = player.getInventory().getItemInMainHand(); + MenuManager.openMenu(player, item != null && item.getType() == Material.SKULL_ITEM ? "auctionhead" : "heads"); + return; + default: + JobMode mode = JobMode.getModeOrNull(name); + if (mode == null) return; + GTMUtils.chooseJobMode(player, user, + GTM.getUserManager().getLoadedUser(player.getUniqueId()), mode); + return; + } + default: + break; + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/InventoryClick.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/InventoryClick.java new file mode 100644 index 0000000..ab73b4a --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/InventoryClick.java @@ -0,0 +1,279 @@ +package net.grandtheftmc.gtm.listeners; + +import java.util.Objects; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryAction; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryPickupItemEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.player.PlayerSwapHandItemsEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.events.ItemStackEvent; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.util.ItemStackManager; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.items.events.ArmorEquipEvent; +import net.grandtheftmc.gtm.items.events.EquipArmorType; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.users.GTMUserManager; +import net.grandtheftmc.guns.GTMGuns; +import net.grandtheftmc.guns.weapon.Weapon; +import net.md_5.bungee.api.ChatColor; + +public class InventoryClick implements Listener { + + @EventHandler + public void onPickup(InventoryPickupItemEvent event) { + if (event.getInventory() == null) return; +// if (event.getItem() == null) return; +// if (event.getItem().getLocation().getWorld().getName().equalsIgnoreCase("minesantos")) { +// if (event.getInventory().getType() == InventoryType.HOPPER) { +// event.setCancelled(true); +// } +// } + + if (event.getInventory().getType() == InventoryType.HOPPER) { + event.setCancelled(true); + } + } + + @EventHandler + public void equipEventRunner(InventoryClickEvent e){ + boolean shift = false, numberkey = false; + Player player = (Player)e.getWhoClicked(); + if(e.isCancelled()) return; + if(e.getClick().equals(ClickType.SHIFT_LEFT) || e.getClick().equals(ClickType.SHIFT_RIGHT)){ + shift = true; + } + if(e.getClick().equals(ClickType.NUMBER_KEY)){ + numberkey = true; + } + if(e.getSlotType() != InventoryType.SlotType.ARMOR && e.getSlotType() != InventoryType.SlotType.QUICKBAR && e.getSlotType() != InventoryType.SlotType.CONTAINER) return; + if(e.getClickedInventory() != null && !e.getClickedInventory().getType().equals(InventoryType.PLAYER)) return; + if (!e.getInventory().getType().equals(InventoryType.CRAFTING) && !e.getInventory().getType().equals(InventoryType.PLAYER)) return; + if(!(e.getWhoClicked() instanceof Player)) return; + EquipArmorType newEquipArmorType = EquipArmorType.matchType(shift ? e.getCurrentItem() : e.getCursor()); + if(!shift && newEquipArmorType != null && e.getSlot() != newEquipArmorType.getSlot() && newEquipArmorType!=EquipArmorType.CUSTOM){ + // Used for drag and drop checking to make sure you aren't trying to place a helmet in the boots place. + return; + } + if(shift){ + newEquipArmorType = EquipArmorType.matchType(e.getCurrentItem()); + if(newEquipArmorType != null){ + boolean equipping = true; + if(e.getSlot()== newEquipArmorType.getSlot()){ + equipping = false; + } + if(newEquipArmorType==EquipArmorType.CUSTOM) { + if(e.getCurrentItem()!=null && e.getCurrentItem().getType().toString().contains("LEATHER_")) + e.setCancelled(true); + return; + } + if(equipping && e.getCurrentItem() !=null && e.getCurrentItem().getAmount()>1) { + e.setCancelled(true); + player.sendMessage(Lang.GTM.f("&cYou cannot equip stacked armor!")); + return; + } + if(newEquipArmorType.equals(EquipArmorType.HELMET) && (equipping ? e.getWhoClicked().getInventory().getHelmet() == null : e.getWhoClicked().getInventory().getHelmet() != null) || newEquipArmorType.equals(EquipArmorType.CHESTPLATE) && (equipping ? e.getWhoClicked().getInventory().getChestplate() == null : e.getWhoClicked().getInventory().getChestplate() != null) || newEquipArmorType.equals(EquipArmorType.LEGGINGS) && (equipping ? e.getWhoClicked().getInventory().getLeggings() == null : e.getWhoClicked().getInventory().getLeggings() != null) || newEquipArmorType.equals(EquipArmorType.BOOTS) && (equipping ? e.getWhoClicked().getInventory().getBoots() == null : e.getWhoClicked().getInventory().getBoots() != null)){ + ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent((Player) e.getWhoClicked(), ArmorEquipEvent.EquipMethod.SHIFT_CLICK, newEquipArmorType, equipping ? null : e.getCurrentItem(), equipping ? e.getCurrentItem() : null,EquipArmorType.fromSlot(e.getSlot())); + Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent); + if(armorEquipEvent.isCancelled()){ + e.setCancelled(true); + } + } + } + }else{ + ItemStack newArmorPiece = e.getCursor(); + ItemStack oldArmorPiece = e.getCurrentItem(); + if(numberkey){ + if(e.getClickedInventory().getType().equals(InventoryType.PLAYER)){// Prevents shit in the 2by2 crafting + // e.getClickedInventory() == The players inventory + // e.getHotBarButton() == key people are pressing to equip or unequip the item to or from. + // e.getRawSlot() == The slot the item is going to. + // e.getSlot() == Armor slot, can't use e.getRawSlot() as that gives a hotbar slot ;-; + ItemStack hotbarItem = e.getClickedInventory().getItem(e.getHotbarButton()); + if(hotbarItem != null){// Equipping + newEquipArmorType = EquipArmorType.matchType(hotbarItem); + newArmorPiece = hotbarItem; + oldArmorPiece = e.getClickedInventory().getItem(e.getSlot()); + }else{// Unequipping + newEquipArmorType = EquipArmorType.matchType(e.getCurrentItem() != null && e.getCurrentItem().getType() != Material.AIR ? e.getCurrentItem() : e.getCursor()); + } + } + } + else{ + // e.getCurrentItem() == Unequip + // e.getCursor() == Equip + newEquipArmorType = EquipArmorType.matchType(e.getCurrentItem() != null && e.getCurrentItem().getType() != Material.AIR ? e.getCurrentItem() : e.getCursor()); + } + + if(newEquipArmorType == EquipArmorType.CUSTOM && e.getSlotType()!= InventoryType.SlotType.ARMOR) + return; + if(newArmorPiece!=null && newArmorPiece.getAmount()>1 && e.getSlotType()== InventoryType.SlotType.ARMOR) { + e.setCancelled(true); + player.sendMessage(Lang.GTM.f("&cYou cannot equip stacked armor!")); + return; + } + + if(newEquipArmorType != null && (e.getSlot() == newEquipArmorType.getSlot() || newEquipArmorType == EquipArmorType.CUSTOM)){ + ArmorEquipEvent.EquipMethod method = ArmorEquipEvent.EquipMethod.DRAG; + if(e.getAction().equals(InventoryAction.HOTBAR_SWAP) || numberkey) method = ArmorEquipEvent.EquipMethod.HOTBAR_SWAP; + ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent((Player) e.getWhoClicked(), method, newEquipArmorType, oldArmorPiece, newArmorPiece, EquipArmorType.fromSlot(e.getSlot())); + Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent); + if(armorEquipEvent.isCancelled()){ + e.setCancelled(true); + } + } + } + } + + @EventHandler + public void onClick(InventoryClickEvent e) { + + Player player = (Player) e.getWhoClicked(); + Inventory inv = e.getInventory(); + GTMUser user = GTMUserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + if (e.getClickedInventory() == null || e.getClickedInventory().getType() == InventoryType.CRAFTING) + return; + if (e.getClickedInventory().getType() == InventoryType.PLAYER) { + if (e.getSlot() == 17) { + e.getWhoClicked().closeInventory(); + GTM.getBackpackManager().openBackpack(player); + e.setCancelled(true); + return; + } else if (e.getSlot() == 16) { + e.getWhoClicked().closeInventory(); + MenuManager.openMenu(player, "ammopouch"); + e.setCancelled(true); + return; + } + } + String title = ChatColor.stripColor(e.getClickedInventory().getTitle()); + if (title.startsWith("Kit Preview: ")) { + e.setCancelled(true); + return; + } + if (title.endsWith("Corpse") && e.getCurrentItem().getType() == Material.STAINED_GLASS_PANE) { + e.setCancelled(true); + return; + } + + if (user != null){ + if(user.getBackpackOpen()){ + ItemStack selected = e.isShiftClick() ? e.getCurrentItem() : e.getCursor(); + if(selected.getType().toString().contains("SHULKER_BOX")){ + e.setCancelled(true); + return; + } + } + } + + /* + * m("--------------------------------------------------"); m("Inv = " + + * inv.getTitle() + " - " + inv.getType()); m("ClickedInv = " + + * e.getClickedInventory().getTitle() + " - " + + * e.getClickedInventory().getType()); m("Slot = " + e.getSlot() + " (" + * + e.getRawSlot() + ") - " + e.getSlotType()); m("Item in Slot = " + + * (inv.getItem(e.getSlot()) == null ? null : + * inv.getItem(e.getSlot()).getType().toString())); m("CurrentItem = " + + * (e.getCurrentItem() == null ? null : + * e.getCurrentItem().getType().toString())); m("Cursor Item = " + + * (e.getCursor() == null ? null : e.getCursor().getType().toString())); + * m("Action = " + e.getAction() + " - " + e.getClick()); m("Hotbar = " + * + e.getHotbarButton()); + */ + + ItemStack current = e.getCurrentItem(); + ItemStack cursor = e.getCursor(); + if (GTMUtils.isPhoneOrGPS(cursor) && e.getClick() == ClickType.DOUBLE_CLICK) { + e.setCancelled(true); + player.updateInventory(); + return; + } + switch (e.getAction()) { + case MOVE_TO_OTHER_INVENTORY: + if (!GTMUtils.isPhoneOrGPS(current) || inv.getType() == InventoryType.CRAFTING + || Objects.equals(inv, e.getClickedInventory())) + break; + e.setCancelled(true); + player.updateInventory(); + break; + case PLACE_ALL: + case PLACE_ONE: + case PLACE_SOME: + if (!GTMUtils.isPhoneOrGPS(cursor) || e.getClickedInventory().getType() == InventoryType.PLAYER) + break; + e.setCancelled(true); + player.updateInventory(); + break; + case SWAP_WITH_CURSOR: + if (!GTMUtils.isPhoneOrGPS(cursor) || e.getClickedInventory().getType() == InventoryType.PLAYER) + break; + e.setCancelled(true); + player.updateInventory(); + break; + case HOTBAR_SWAP: + ItemStack i = player.getInventory().getItem(e.getHotbarButton()); + if (!GTMUtils.isPhoneOrGPS(i) || e.getClickedInventory().getType() == InventoryType.PLAYER) + return; + e.setCancelled(true); + player.updateInventory(); + break; + default: + break; + } + + } + + @EventHandler(ignoreCancelled = true) + protected final void onItemClick(InventoryClickEvent event) { + if(event.getInventory() == null) return; + if(event.getInventory().getType() != InventoryType.CRAFTING) return; + + if(event.getRawSlot() > 0 && event.getRawSlot() < 5) { + event.setCancelled(true); + ((Player)event.getWhoClicked()).updateInventory(); + } + } + + @EventHandler + public void onSwitchToOffhand(PlayerSwapHandItemsEvent e) { + e.setCancelled(true); + } + + @EventHandler + public void onItemStack(ItemStackEvent event){ + + Weapon weapon = GTMGuns.getInstance().getWeaponManager().getWeapon(event.getItemStack()).orElse(null); + if (weapon != null){ + switch (weapon.getWeaponType()){ + case THROWABLE: + // throwable weapons are stackable + event.setCancelled(false); + break; + default: + event.setCancelled(true); + break; + } + } + else{ + // if the itemstack manager says this type cannot be stacked + if(!ItemStackManager.STACKABLES.containsKey(event.getItemStack())){ + event.setCancelled(true); + return; + } + } + + + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/InventoryOpen.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/InventoryOpen.java new file mode 100644 index 0000000..73fe742 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/InventoryOpen.java @@ -0,0 +1,50 @@ +package net.grandtheftmc.gtm.listeners; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.items.AmmoType; +import net.grandtheftmc.gtm.users.GTMUser; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryOpenEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +public class InventoryOpen implements Listener { + + @EventHandler + public void onOpen(InventoryOpenEvent event) { + String disp = ChatColor.stripColor(event.getInventory().getTitle()); + Player player = (Player) event.getPlayer(); + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + GTMUser gtmUser = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + Inventory inv = event.getInventory(); + if (!user.isRank(UserRank.BUILDER)) { + if (inv.getType() == InventoryType.ANVIL + || inv.getType() == InventoryType.WORKBENCH + || inv.getType() == InventoryType.FURNACE) { + event.setCancelled(true); + return; + } + } + if ("Loot Crate".equalsIgnoreCase(disp)) { + for (int i = 0; i < inv.getSize(); i++) { + ItemStack item = inv.getItem(i); + if (item == null) + continue; + AmmoType type = AmmoType.getAmmoType(item.getType(), item.getDurability()); + if (type == null || type.isInInventory()) + continue; + gtmUser.addAmmo(type, item.getAmount()); + player.sendMessage(Lang.AMMO_ADD.f(item.getAmount() + "&7 " + type.getGameItem().getDisplayName())); + inv.setItem(i, null); + } + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/ItemBreak.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/ItemBreak.java new file mode 100644 index 0000000..f1860d7 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/ItemBreak.java @@ -0,0 +1,42 @@ +package net.grandtheftmc.gtm.listeners; + +import net.grandtheftmc.gtm.items.ArmorType; +import net.grandtheftmc.gtm.items.ArmorUpgrade; +import net.grandtheftmc.gtm.items.events.ArmorEquipEvent; +import net.grandtheftmc.gtm.items.events.EquipArmorType; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerItemBreakEvent; +import org.bukkit.inventory.ItemStack; + +/** + * Created by Timothy Lampen on 7/6/2017. + */ +public class ItemBreak implements Listener { + + @EventHandler + public void armorEquipRunner(PlayerItemBreakEvent e) { + EquipArmorType type = EquipArmorType.matchType(e.getBrokenItem()); + if(type != null){ + Player p = e.getPlayer(); + ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(p, ArmorEquipEvent.EquipMethod.BROKE, type, e.getBrokenItem(), null, null); + Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent); + if(armorEquipEvent.isCancelled()){ + ItemStack i = e.getBrokenItem().clone(); + i.setAmount(1); + i.setDurability((short) (i.getDurability() - 1)); + if(type.equals(EquipArmorType.HELMET)){ + p.getInventory().setHelmet(i); + }else if(type.equals(EquipArmorType.CHESTPLATE)){ + p.getInventory().setChestplate(i); + }else if(type.equals(EquipArmorType.LEGGINGS)){ + p.getInventory().setLeggings(i); + }else if(type.equals(EquipArmorType.BOOTS)){ + p.getInventory().setBoots(i); + } + } + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Join.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Join.java new file mode 100644 index 0000000..f7ddf4b --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Join.java @@ -0,0 +1,491 @@ +package net.grandtheftmc.gtm.listeners; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Objects; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Statistic; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.scheduler.BukkitRunnable; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.achivements.Achievement; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.database.mutex.Mutexable; +import net.grandtheftmc.core.database.mutex.event.MutexLoadCompleteEvent; +import net.grandtheftmc.core.resourcepack.ResourcePack; +import net.grandtheftmc.core.resourcepack.ResourcePackEvent; +import net.grandtheftmc.core.resourcepack.ResourcePackManager; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserManager; +import net.grandtheftmc.core.users.eventtag.PreTagEquipEvent; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.NMSVersion; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.database.dao.MutexDAO; +import net.grandtheftmc.gtm.database.mutex.common.LoadGTMUserTask; +import net.grandtheftmc.gtm.holidays.independenceday.IndependenceDay; +import net.grandtheftmc.gtm.items.Head; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.users.GTMUserManager; +import net.grandtheftmc.gtm.users.JobMode; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; + +public class Join implements Listener { + + private final ResourcePackManager resourcePackManager; + + public Join(ResourcePackManager resourcePackManager) { + this.resourcePackManager = resourcePackManager; + } + + /** + * Listens in on player join events. + * <p> + * Note: This is LOW so that events can listen in BEFORE or AFTER this + * event is called since the player will be added to the container. + * </p> + * + * @param event - the event + */ + @EventHandler (priority = EventPriority.LOW) + public void onJoin(PlayerJoinEvent event) { + + // do not display join messages + event.setJoinMessage(null); + + // grab event variables + Player player = event.getPlayer(); + + // General stuff + GTMUtils.giveGameItems(player); + player.setCollidable(false); + player.setFlying(false); + player.setWalkSpeed(0.2F); + +// long start = System.currentTimeMillis(); +// +// // create the GTMUser +// GTMUser gtmUser = new GTMUser(player.getUniqueId(), player.getName()); +// +// // NOTE: This is called on an async thread +// new LoadGTMUserTask(GTM.getInstance(), gtmUser) { +// +// @Override +// protected boolean onLoad() { +// try (Connection conn = BaseDatabase.getInstance().getConnection()) { +// +// // execute a data check to create new entries if needed +// gtmUser.dataCheck(); +// +// // load the user +// gtmUser.onLoad(conn); +// } +// catch (SQLException e) { +// e.printStackTrace(); +// return false; +// } +// +// return true; +// } +// +// @Override +// protected void onLoadFailure() { +// // Back to main thread +// Bukkit.getScheduler().runTask(getPlugin(), () -> { +// player.kickPlayer("[GTM] Load failure; contact staff if this issue persists."); +// +// // TODO this is to reset mutex issues +// Bukkit.getScheduler().runTaskAsynchronously(getPlugin(), () -> { +// try (Connection conn = BaseDatabase.getInstance().getConnection()){ +// MutexDAO.setGTMUserMutex(conn, player.getUniqueId(), false); +// } +// catch(Exception e){ +// e.printStackTrace(); +// } +// }); +// }); +// } +// +// @Override +// protected void onLoadComplete() { +// +// // add to the container +// GTMUserManager.getInstance().addUser(gtmUser); +// +// // TODO check for user state transactions +// +// // Back to main thread +// Bukkit.getScheduler().runTask(plugin, () -> { +// +// // can update name or other things on thread +// // like teleport them +// +// User coreUser = UserManager.getInstance().getUser(gtmUser.getUUID()).orElse(null); +// +// // Timing related stuff +// gtmUser.setJointime(System.currentTimeMillis()); +// if (gtmUser.getPlaytime() == 0L) { +// int playOneTick = player.getStatistic(Statistic.PLAY_ONE_TICK); +// gtmUser.setPlaytime((long) (playOneTick / 20)); +// } +// +// if (player.getGameMode() == GameMode.SPECTATOR) { +// player.getActivePotionEffects().clear(); +// player.setFoodLevel(20); +// player.setGameMode(GameMode.ADVENTURE); +// player.setFlying(false); +// player.setFlySpeed(0.1F); +// } +// +// // if found core user +// if (coreUser != null) { +// GTMUtils.sendJoinMessage(player, coreUser); +// +// if (!player.hasPlayedBefore()) { +// Utils.broadcastExcept(player, Lang.GTM.f("&7Welcome " + coreUser.getColoredName(player) + "&7 to &7&l" + Core.getSettings().getServer_GTM_name() + "&r!")); +// player.teleport(GTM.getWarpManager().getTutorialSpawn().getLocation()); +// player.spigot().sendMessage(new ComponentBuilder(Lang.TUTORIALS.s()).append("Welcome newcomer! Would you like to go through a simple tutorial?").color(ChatColor.GRAY).append(" [ACCEPT] ").color(ChatColor.GREEN).bold(true).event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/tutorial")).create()); +// } +// else { +// player.teleport(gtmUser.isArrested() ? GTM.getWarpManager().getJail().getLocation() : GTM.getWarpManager().getSpawn().getLocation()); +// } +// +// GTM.getLottery().joinCheck(player, coreUser, gtmUser); +// } +// +// GTMUtils.updateBoard(player, gtmUser); +// +// Head head = GTM.getShopManager().getHead(player.getName()); +// if (head != null && head.getBidderUUID() != null && !Objects.equals(head.getBidderUUID(), player.getUniqueId()) && !head.isDone()) { +// player.sendMessage(Lang.HEAD_AUCTION.f("&7Your head is currently being auctioned by &a&l" + head.getSellerName() + "&7! The last bidder was &a&l" + head.getBidderName() + "&7 for &a$&l" + head.getBid() + "&7!")); +// } +// +// // Achievement, idk why it's still here. +// if (player.getUniqueId().toString().equals("0e4a6028-3d9a-4a2e-9797-eb1ddcb0aca9")) { +// Bukkit.getOnlinePlayers().forEach(target -> { +// User targetUser = Core.getUserManager().getLoadedUser(target.getUniqueId()); +// targetUser.addAchievement(Achievement.Witness); +// }); +// } +// +// // TODO this isn't fired correctly all the time +// try{ +// gtmUser.checkAchievements(); +// } +// catch(Exception e){ +// // TODO fix +// } +// +// IndependenceDay independenceDay = GTM.getHolidayManager().getIndependenceDay(); +// if (independenceDay != null) { +// if (independenceDay.isActive()) { +// independenceDay.getBossBar().addPlayer(player.getUniqueId()); +// } +// } +// +// // attempt to send resource pack +// attemptToSendPack(player); +// +// // Log to console, version and time to join from [PostLogin +// // -> +// // JoinEvent] +// NMSVersion ver = NMSVersion.getVersion(player); +// Bukkit.getConsoleSender().sendMessage(C.LIGHT_PURPLE + player.getName() + " Logged in. (" + C.WHITE + "Version: " + C.GREEN + ver.name() + C.LIGHT_PURPLE + ") [" + C.YELLOW + (System.currentTimeMillis() - start) + "ms" + C.LIGHT_PURPLE + "]"); +// }); +// } +// }; + } + + /** + * Listens in on mutex load complete events. + * <p> + * This can be fired when a mutex load event is finished loading, typically something like a core User. + * + * @param event - the event to listen on + */ + @EventHandler + public void onMutexLoadComplete(MutexLoadCompleteEvent event){ + + // grab event variables + Mutexable mutexable = event.getMutexable(); + if (!(mutexable instanceof User)){ + return; + } + + // conver to user and grab player + User user = (User) mutexable; + Player player = Bukkit.getPlayer(user.getUUID()); + if (player == null){ + return; + } + + long start = System.currentTimeMillis(); + + // create the GTMUser + GTMUser gtmUser = new GTMUser(player.getUniqueId(), player.getName()); + + // NOTE: This is called on an async thread + new LoadGTMUserTask(GTM.getInstance(), gtmUser) { + + @Override + protected boolean onLoad() { + try (Connection conn = BaseDatabase.getInstance().getConnection()) { + + // execute a data check to create new entries if needed + gtmUser.dataCheck(); + + // load the user + gtmUser.onLoad(conn); + } + catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + @Override + protected void onLoadFailure() { + // Back to main thread + Bukkit.getScheduler().runTask(getPlugin(), () -> { + player.kickPlayer("[GTM] Load failure; contact staff if this issue persists."); + + // TODO this is to reset mutex issues + Bukkit.getScheduler().runTaskAsynchronously(getPlugin(), () -> { + try (Connection conn = BaseDatabase.getInstance().getConnection()){ + MutexDAO.setGTMUserMutex(conn, player.getUniqueId(), false); + } + catch(Exception e){ + e.printStackTrace(); + } + }); + }); + } + + @Override + protected void onLoadComplete() { + + // add to the container + GTMUserManager.getInstance().addUser(gtmUser); + + // TODO check for user state transactions + + // Back to main thread + Bukkit.getScheduler().runTask(plugin, () -> { + + // can update name or other things on thread + // like teleport them + + User coreUser = UserManager.getInstance().getUser(gtmUser.getUUID()).orElse(null); + + // Timing related stuff + gtmUser.setJointime(System.currentTimeMillis()); + if (gtmUser.getPlaytime() == 0L) { + int playOneTick = player.getStatistic(Statistic.PLAY_ONE_TICK); + gtmUser.setPlaytime((long) (playOneTick / 20)); + } + + if (player.getGameMode() == GameMode.SPECTATOR) { + player.getActivePotionEffects().clear(); + player.setFoodLevel(20); + player.setGameMode(GameMode.ADVENTURE); + player.setFlying(false); + player.setFlySpeed(0.1F); + } + + // if found core user + if (coreUser != null) { + GTMUtils.sendJoinMessage(player, coreUser); + + if (!player.hasPlayedBefore()) { + Utils.broadcastExcept(player, Lang.GTM.f("&7Welcome " + coreUser.getColoredName(player) + "&7 to &7&l" + Core.getSettings().getServer_GTM_name() + "&r!")); + player.teleport(GTM.getWarpManager().getTutorialSpawn().getLocation()); + player.spigot().sendMessage(new ComponentBuilder(Lang.TUTORIALS.s()).append("Welcome newcomer! Would you like to go through a simple tutorial?").color(ChatColor.GRAY).append(" [ACCEPT] ").color(ChatColor.GREEN).bold(true).event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/tutorial")).create()); + } + else { + player.teleport(gtmUser.isArrested() ? GTM.getWarpManager().getJail().getLocation() : GTM.getWarpManager().getSpawn().getLocation()); + } + + GTM.getLottery().joinCheck(player, coreUser, gtmUser); + } + + GTMUtils.updateBoard(player, gtmUser); + + Head head = GTM.getShopManager().getHead(player.getName()); + if (head != null && head.getBidderUUID() != null && !Objects.equals(head.getBidderUUID(), player.getUniqueId()) && !head.isDone()) { + player.sendMessage(Lang.HEAD_AUCTION.f("&7Your head is currently being auctioned by &a&l" + head.getSellerName() + "&7! The last bidder was &a&l" + head.getBidderName() + "&7 for &a$&l" + head.getBid() + "&7!")); + } + + // Achievement, idk why it's still here. + if (player.getUniqueId().toString().equals("0e4a6028-3d9a-4a2e-9797-eb1ddcb0aca9")) { + Bukkit.getOnlinePlayers().forEach(target -> { + User targetUser = Core.getUserManager().getLoadedUser(target.getUniqueId()); + targetUser.addAchievement(Achievement.Witness); + }); + } + + // TODO this isn't fired correctly all the time + try{ + gtmUser.checkAchievements(); + } + catch(Exception e){ + // TODO fix + } + + IndependenceDay independenceDay = GTM.getHolidayManager().getIndependenceDay(); + if (independenceDay != null) { + if (independenceDay.isActive()) { + independenceDay.getBossBar().addPlayer(player.getUniqueId()); + } + } + + // attempt to send resource pack + attemptToSendPack(player); + + // Log to console, version and time to join from [PostLogin + // -> + // JoinEvent] + NMSVersion ver = NMSVersion.getVersion(player); + Bukkit.getConsoleSender().sendMessage(C.LIGHT_PURPLE + player.getName() + " Logged in. (" + C.WHITE + "Version: " + C.GREEN + ver.name() + C.LIGHT_PURPLE + ") [" + C.YELLOW + (System.currentTimeMillis() - start) + "ms" + C.LIGHT_PURPLE + "]"); + }); + } + }; + + } + + /** + * Listens in on ResourcePackEvent. + * <p> + * This event is called after the player receives a PacketType of + * RESOURCE_PACK_STATUS. + * + * @param event - the event + */ + @EventHandler + protected final void onResourcePack(ResourcePackEvent event) { + Player player = event.getPlayer(); + if (player == null) + return; + +// player.sendTitle(new Title(Utils.f("&6&lWelcome to &oGrand Theft Minecart&6&l!"), "", 60, 30, 40)); + } + + /** + * Stop EventTags from being set/changed when a JobMode is enabled. This is + * a fix for 'COP' & 'HITMAN' nametags being overridden. + */ + @EventHandler + protected final void onTagChange(PreTagEquipEvent event) { + if (event.getPlayer() == null){ + return; + } + + GTMUser gameUser = GTM.getUserManager().getUser(event.getPlayer().getUniqueId()).orElse(null); + + if (gameUser != null){ + if (gameUser.getJobMode() == null || gameUser.getJobMode() == JobMode.CRIMINAL){ + return; + } + } + + event.setCancelled(true); + } + + /** + * Attempt to send the pack to the player. + * + * @param player - the player that needs the resource pack. + */ + private void attemptToSendPack(Player player) { + + //Send pack here in-case exceptions are thrown + NMSVersion ver = NMSVersion.getVersion(player); + + // according to minecraft wiki on resource packs + // Requires 1 for 1.6-1.9, 2 for 1.9 and 1.10, 3 for 1.11 and 1.12, and 4 for 1.13. + + // if its 1.13.x or higher + if (ver.getProtocol() >= NMSVersion.MC_1_13.getProtocol()) { + Core.log("[GTM][Join] Texture pack code #4 (1.13.x AND ABOVE) due to NMS protocol version=" + ver.name()); + + ResourcePack pack = GTM.getResourcePackManager().getResourcePack(NMSVersion.MC_1_13); + sendPackToPlayer(player, pack, resourcePackManager); + } + // if its 1.11.x or 1.12.x + else if (ver.getProtocol() >= NMSVersion.MC_1_11.getProtocol() && ver.getProtocol() <= NMSVersion.MC_1_12_2.getProtocol()) { + Core.log("[GTM][Join] Texture pack code #3 (1.11.x TO 1.12.x) due to NMS protocol version=" + ver.name()); + + ResourcePack pack = GTM.getResourcePackManager().getResourcePack(NMSVersion.MC_1_11); + sendPackToPlayer(player, pack, resourcePackManager); + } + // if its 1.9.x or 1.10.x + else if (ver.getProtocol() >= NMSVersion.MC_1_9.getProtocol() && ver.getProtocol() <= NMSVersion.MC_1_10.getProtocol()) { + Core.log("[GTM][Join] Texture pack code #2 (1.9.x TO 1.10.x) due to NMS protocol version=" + ver.name()); + + ResourcePack pack = GTM.getResourcePackManager().getResourcePack(NMSVersion.MC_1_10); + sendPackToPlayer(player, pack, resourcePackManager); + } + else if (ver.getProtocol() >= NMSVersion.MC_1_8.getProtocol() && ver.getProtocol() < NMSVersion.MC_1_9.getProtocol()) { + Core.log("[GTM][Join] Texture pack code #1 (1.6.x TO 1.9.x) due to NMS protocol version=" + ver.name()); + + // TODO Note: This is not supported by us. + } + else { + Core.log("[GTM][Join] Unknown texture pack code for NMS version=" + ver.name() + ", protocol=" + ver.getProtocol()); + } + } + + /** + * Attempt to send the pack to the player using a runnable, and attempt to + * re-apply. + * + * @param player - the player getting the pack + * @param pack - the resource pack to send + * @param resourcePackManager - the manager of the resource packs + */ + private void sendPackToPlayer(Player player, ResourcePack pack, ResourcePackManager resourcePackManager) { + + // grab the uuid of the player + UUID uuid = player.getUniqueId(); + + new BukkitRunnable() { + @Override + public void run() { + Player p = Bukkit.getPlayer(uuid); + if (p == null || !p.isOnline()) { + return; + } + + if (!p.isValid()) { + // TODO note this could possibly be recursively forever + // as player might log in and log out in 2 seconds. + sendPackToPlayer(p, pack, resourcePackManager); + return; + } + + if (pack != null) { + + // setting player resource pack sends + // PacketType.Play.Client.RESOURCE_PACK_STATUS + // byte[] hash = + // BaseEncoding.base16().lowerCase().decode(pack.getHash().toLowerCase()); + p.setResourcePack(pack.getPack()); + } + } + }.runTaskLater(GTM.getInstance(), 20 * 8); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Leave.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Leave.java new file mode 100644 index 0000000..16a1c26 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Leave.java @@ -0,0 +1,172 @@ +package net.grandtheftmc.gtm.listeners; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerKickEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.ItemStack; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserManager; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.util.debug.Log; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.commands.SpectatorCommand; +import net.grandtheftmc.gtm.database.mutex.common.SaveGTMUserTask; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.users.GTMUserManager; +import net.grandtheftmc.gtm.users.JobMode; +import net.grandtheftmc.gtm.users.PersonalVehicle; + +public class Leave implements Listener { + + /** + * Listens in on player kick events. + * + * @param event - the event + */ + @EventHandler + public void onPlayerKick(PlayerKickEvent event) { + + // grab event variables + Player p = event.getPlayer(); + + GTMUser gtmUser = GTMUserManager.getInstance().getUser(p.getUniqueId()).orElse(null); + if (gtmUser != null) { + gtmUser.setKicked(!event.getReason().contains("spam")); + } + } + + /** + * Listens in on player quit events. + * <p> + * Note: This is HIGH so that events can listen in BEFORE or AFTER this + * event is called since the player will be removed from the container. + * </p> + * + * @param event - the event + */ + @EventHandler (priority = EventPriority.HIGH) + public void onPlayerQuit(PlayerQuitEvent event) { + + // grab event varialbes + Player player = event.getPlayer(); + UUID uuid = player.getUniqueId(); + + // always set no quit message + event.setQuitMessage(null); + + // grab gtm user + GTMUser gtmUser = GTMUserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + Long leaveTime = System.currentTimeMillis(); + + if (gtmUser != null){ + + // if join time is specified, update playtime + if (gtmUser.getJoinTime() != null) { + Long playtimeSeconds = TimeUnit.MILLISECONDS.toSeconds(leaveTime - gtmUser.getJoinTime()); + gtmUser.setPlaytime(gtmUser.getPlaytime() + playtimeSeconds); + } + + // remove vehicle + if (gtmUser.getPersonalVehicle() != null && gtmUser.getPersonalVehicle().onMap() && !gtmUser.getPersonalVehicle().isStolen()) { + gtmUser.getPersonalVehicle().getEntity().remove(); + } + + // if player is a spectator + if (player.getGameMode() == GameMode.SPECTATOR) { + player.getActivePotionEffects().clear(); + player.setFoodLevel(20); + player.setGameMode(GameMode.ADVENTURE); + player.setFlying(false); + player.setFlySpeed(0.1F); + if (gtmUser.isArrested()) { + player.teleport(GTM.getWarpManager().getJail().getLocation()); + } + else { + player.teleport(GTM.getWarpManager().getSpawn().getLocation()); + } + if (gtmUser.getJobMode() != JobMode.CRIMINAL) { + gtmUser.setJobMode(JobMode.CRIMINAL); + } + } + + // grab location + Location loc = player.getLocation(); + World world = loc.getWorld(); + + // if player was in combat + if (gtmUser.isInCombat() && !gtmUser.isKicked() && !"spawn".equalsIgnoreCase(world.getName())) { + + ItemStack[] contents = player.getInventory().getContents(); + player.getInventory().clear(); + + for (ItemStack item : contents) { + if (item != null && !(item.getType() == Material.WATCH || item.getType() == Material.COMPASS) && item.getType() != Material.WATCH && item.getType() != Material.CHEST) { + world.dropItemNaturally(loc, item); + } + } + player.getInventory().clear(); + + User coreUser = UserManager.getInstance().getUser(uuid).orElse(null); + if (coreUser != null) { + Utils.broadcast(Lang.COMBATTAG + "&c" + coreUser.getColoredName(player) + "&7 has logged off during combat! All his items have been dropped on the ground."); + + } + + if (GTM.getWarpManager().getSpawn() != null) { + player.teleport(GTM.getWarpManager().getSpawn().getLocation()); + } + } + + if (gtmUser.hasPersonalVehicle()) { + PersonalVehicle vehicle = gtmUser.getPersonalVehicle(); + if (vehicle.onMap()){ + vehicle.updateVehicleInDatabase(player, 0); + } + } + + if (SpectatorCommand.getActiveStaff().contains(player.getName())) { + player.setGameMode(GameMode.ADVENTURE); + SpectatorCommand.getActiveStaff().remove(player.getName()); + } + + // REMOVE from local container and save + final GTMUser removedUser = GTMUserManager.getInstance().removeUser(player.getUniqueId()).orElse(null); + if (removedUser != null) { + + new SaveGTMUserTask(GTM.getInstance(), removedUser) { + @Override + protected boolean onSave() { + try (Connection conn = BaseDatabase.getInstance().getConnection()) { + gtmUser.onSave(conn); + } + catch (SQLException e) { + e.printStackTrace(); + } + + return true; + } + + @Override + protected void onSaveFailure() { + Log.error("GTM", "Unhandled exception while saving " + removedUser.getName()); + } + }; + } + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Login.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Login.java new file mode 100644 index 0000000..76a7eba --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Login.java @@ -0,0 +1,40 @@ +package net.grandtheftmc.gtm.listeners; + +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerPreLoginEvent; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.gtm.GTM; + +public class Login implements Listener { + + /** + * Listens in on the async player pre login event. + * + * @param event - the event + */ + @EventHandler + public void onAsyncPlayerPreLogin(AsyncPlayerPreLoginEvent event) { + + // if the server is restarting + if (Core.getInstance().isRestarting()) { + event.setKickMessage(Lang.ALERTS.f("&cThe server is restarting!")); + event.disallow(org.bukkit.event.player.AsyncPlayerPreLoginEvent.Result.KICK_OTHER, "&cThe server is currently restarting!"); + return; + } + + // if the gtm plugin isn't enabled + if (!GTM.getInstance().isEnabled()) { + event.setKickMessage(Lang.ALERTS.f("&cWaiting on GTM...")); + event.disallow(org.bukkit.event.player.AsyncPlayerPreLoginEvent.Result.KICK_OTHER, "&cWaiting on GTM..."); + return; + } + + // if the player is transferring + if (GTM.getInstance().getTransferingPlayers().contains(event.getUniqueId())) { + event.disallow(org.bukkit.event.player.AsyncPlayerPreLoginEvent.Result.KICK_OTHER, Lang.GTM.f("&eYour data is being transfered.")); + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/MenuListener.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/MenuListener.java new file mode 100644 index 0000000..a9e3186 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/MenuListener.java @@ -0,0 +1,4327 @@ +package net.grandtheftmc.gtm.listeners; + +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Color; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; + +import com.j0ach1mmall3.jlib.inventory.JLibItem; +import com.j0ach1mmall3.wastedvehicles.api.VehicleProperties; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.events.MoneyEvent; +import net.grandtheftmc.core.menus.Menu; +import net.grandtheftmc.core.menus.MenuClickEvent; +import net.grandtheftmc.core.menus.MenuCloseEvent; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.menus.MenuOpenEvent; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.users.eventtag.EventTag; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.State; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.bounties.Bounty; +import net.grandtheftmc.gtm.bounties.BountyManager; +import net.grandtheftmc.gtm.bounties.BountyPlacer; +import net.grandtheftmc.gtm.drugs.DrugService; +import net.grandtheftmc.gtm.drugs.item.DrugDealerItem; +import net.grandtheftmc.gtm.drugs.item.DrugItem; +import net.grandtheftmc.gtm.event.christmas.ChristmasEvent; +import net.grandtheftmc.gtm.gang.Gang; +import net.grandtheftmc.gtm.gang.GangManager; +import net.grandtheftmc.gtm.gang.member.GangMember; +import net.grandtheftmc.gtm.gang.relation.GangRelation; +import net.grandtheftmc.gtm.items.AmmoType; +import net.grandtheftmc.gtm.items.ArmorUpgrade; +import net.grandtheftmc.gtm.items.GameItem; +import net.grandtheftmc.gtm.items.Head; +import net.grandtheftmc.gtm.items.Kit; +import net.grandtheftmc.gtm.items.KitItem; +import net.grandtheftmc.gtm.tasks.LotteryPlayer; +import net.grandtheftmc.gtm.users.ChatAction; +import net.grandtheftmc.gtm.users.CheatCode; +import net.grandtheftmc.gtm.users.CheatCodeState; +import net.grandtheftmc.gtm.users.CompassTarget; +import net.grandtheftmc.gtm.users.GTMRank; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.users.GTMUserManager; +import net.grandtheftmc.gtm.users.JobMode; +import net.grandtheftmc.gtm.users.LockedWeapon; +import net.grandtheftmc.gtm.users.PersonalVehicle; +import net.grandtheftmc.gtm.users.TaxiTarget; +import net.grandtheftmc.gtm.warps.Warp; +import net.grandtheftmc.guns.GTMGuns; +import net.grandtheftmc.guns.weapon.Weapon; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.houses.House; +import net.grandtheftmc.houses.houses.HouseDoor; +import net.grandtheftmc.houses.houses.PremiumHouse; +import net.grandtheftmc.houses.houses.PremiumHouseDoor; +import net.grandtheftmc.houses.users.HouseUser; +import net.grandtheftmc.houses.users.UserHouse; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.minecraft.server.v1_12_R1.NBTTagCompound; + + +public class MenuListener implements Listener { + private final static List<Integer> SLOTS = Arrays.asList(11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42); + + @EventHandler(priority = EventPriority.HIGH) + public void onMenuOpen(MenuOpenEvent e) { + Player player = e.getPlayer(); + UUID uuid = player.getUniqueId(); + Menu menu = e.getMenu(); + switch (menu.getName()) { + case "transferconfirm": { + this.setConfirmDefaults(e, "&a&lConfirm Transfer", "&c&lCancel Transfer", "&c- This transfer is irreversible", "&c- All of your items will be deleted off", "&cyour current server and put onto", "&cyour target server.", "&c- Staff are unable to undo this decision."); + return; + } + case "christmasshop": { + this.setPhoneDefaults(e); + String p = "&7Price: [&6@&7]"; + e.setItem(2, Utils.setLore(GTM.getItemManager().getItem("santahat").getItem(), p.replace("@", "20"))); + e.setItem(3, Utils.setLore(GTM.getItemManager().getItem("santatunic").getItem(), p.replace("@", "32"))); + e.setItem(5, Utils.setLore(GTM.getItemManager().getItem("santapants").getItem(), p.replace("@", "24"))); + e.setItem(6, Utils.setLore(GTM.getItemManager().getItem("santaboots").getItem(), p.replace("@", "16"))); + + e.setItem(11, Utils.setLore(GTM.getItemManager().getItem("elfhat").getItem(), p.replace("@", "5"))); + e.setItem(12, Utils.setLore(GTM.getItemManager().getItem("elftunic").getItem(), p.replace("@", "8"))); + e.setItem(14, Utils.setLore(GTM.getItemManager().getItem("elfpants").getItem(), p.replace("@", "6"))); + e.setItem(15, Utils.setLore(GTM.getItemManager().getItem("elfboots").getItem(), p.replace("@", "4"))); + + e.setItem(20, Utils.setLore(GTM.getItemManager().getItem("rudolfhat").getItem(), p.replace("@", "10"))); + e.setItem(21, Utils.setLore(GTM.getItemManager().getItem("rudolftunic").getItem(), p.replace("@", "16"))); + e.setItem(23, Utils.setLore(GTM.getItemManager().getItem("rudolfpants").getItem(), p.replace("@", "12"))); + e.setItem(24, Utils.setLore(GTM.getItemManager().getItem("rudolfboots").getItem(), p.replace("@", "8"))); + + + e.setItem(4, Utils.setLore(Utils.createItem(Material.NAME_TAG, "&b&lFestive Tag"), p.replace("@", "35"))); + e.setItem(13, Utils.setLore(Utils.createItem(Material.NAME_TAG, "&2&lXMAS Tag"), p.replace("@", "35"))); + e.setItem(22, Utils.setLore(Utils.createItem(Material.NAME_TAG, "&r&lSnowman Tag"), p.replace("@", "50"))); + e.setItem(31, Utils.setLore(Utils.createItem(Material.NAME_TAG, "&c&lSanta Tag"), p.replace("@", "50"))); + e.setItem(40, Utils.setLore(Utils.createItem(Material.NAME_TAG, "&c&lH&2&lo&c&lH&2&lo&c&lH&2&lo Tag"), p.replace("@", "50"))); + + + e.setItem(48, Utils.setLore(GTM.getItemManager().getItem("christmascake").getItem(), p.replace("@", "4"))); + e.setItem(49, Utils.setLore(GTMGuns.getInstance().getWeaponManager().getWeapon("clausinator").get().createItemStack(), p.replace("@", "250"),"&7Shooting at players stack a", "&7slowness effect on them", "&7for a short duration")); + e.setItem(50, Utils.setLore(Utils.createItem(Material.MAGMA_CREAM, "&c&lDevil's Snowballs x16", 16), p.replace("@", "3"))); + return; + } + case "sellinvconfirm": { + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + this.setConfirmDefaults(e, "&aSell inventory for " + Utils.formatMoney(user.getSellInvConfirmAmt()), "&cCancel the transaction"); + return; + } + case "cheatcodes": { + this.setPhoneDefaults(e); + int[] slots = new int[] { 11, 13, 15, 20, 22, 24, 29, 31, 33, 40 }; + for (int i = 0; i < CheatCode.getCodes().length; i++) {//will only work with a max of 9 codes + int slot = slots[i]; + CheatCode code = CheatCode.getCodes()[i]; + State state = GTM.getUserManager().getLoadedUser(uuid).getCheatCodeState(code).getState(); + e.setItem(slot, code.getDisplayItem(Core.getUserManager().getLoadedUser(uuid), state)); + } + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the contacts page!")); + e.setItem(51, Utils.createItem(Material.BOOK, "&2&lActivating Cheatcodes", "&7You can activate cheatcodes by clicking the item in this menu,", "&7by using &a&l/<cheatcode>&7, and &a&l/cheatcode <cheatcode>&7!")); + return; + } + case "drugdealer": { + this.setPhoneDefaults(e); + Iterator<Integer> slots = Arrays.asList(11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42).iterator(); + Collection<DrugDealerItem> drugDealerItems = + GTM.getDrugManager().getDrugDealer().getItems() + .stream() + .filter(drugDealerItem -> !drugDealerItem.isShouldDisplay()) + .collect(Collectors.toList()); + drugDealerItems.forEach(drugDealerItem -> { + if (!slots.hasNext()) return; + e.setItem(slots.next(), drugDealerItem.getItemStack()); + }); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lClose", "&7Click to close this menu.")); + e.setItem(49, Utils.createItem(Material.SAPLING, 2, "&3&lDrug Dealer", "&7Score some dope!")); + return; + } + case "phone": + this.setPhoneDefaults(e); + e.setItem(11, + Utils.createItem(Material.ENDER_CHEST, "&e&lCosmetics", "&7Stand out from the crowd!")); + e.setItem(13, + Utils.setArmorColor( + Utils.createItem(Material.LEATHER_CHESTPLATE, "&a&lMy Gang", "&7Play with friends,", "&7and dominate the city!"), + Color.fromRGB(102, 127, 51))); + e.setItem(15, Utils.createItem(Material.POWERED_MINECART, "&2&lProperty", "&7Houses, Online ATM and Vehicles!")); + e.setItem(29, + Utils.setSkullOwner( + Utils.createItem(Material.SKULL_ITEM, 1, "&5&lBounties", "&7Place hits on other players!"), + player.getName())); + e.setItem(31, Utils.createItem(Material.NETHER_STAR, "&d&lMy Account", "&7Stats, Ranks and Prefs!")); + e.setItem(33, Utils.createItem(Material.CHEST, "&b&lKits", "&7Gear up!")); + e.setItem(47, Utils.createItem(Material.BOOK, "&6&lContacts", "&7Call your associates!")); + e.setItem(49, Utils.createItem(Material.EMERALD, "&a&l" + Core.getSettings().getServer_GTM_shortName() + " Store", "&7Support the server!")); + + e.setItem(51, Utils.createItem(Material.EXP_BOTTLE, "&a&lRewards", "&7" + (Core.getSettings().isSister() ? "" : "Voting, ") + "daily and donor bonuses!")); + return; + case "cosmetics": + case "rewards": + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the home page!")); + return; + case "vote": + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the rewards page!")); + return; + case "account": + this.setPhoneDefaults(e); + e.setItem(22, Utils.createItem(Material.NAME_TAG, "&6&lUnlocked Tags", "&7Change your name prefix!")); + e.setItem(11, Utils.createItem(Material.EMPTY_MAP, "&a&lRanks", "&7Working my way to the top!")); + e.setItem(13, Utils.createItem(Material.BOOK, "&d&lStats", "&7You got skills!")); + e.setItem(15, Utils.createItem(Material.REDSTONE_COMPARATOR, "&5&lPreferences", "&7Toggle your stuff!")); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the home page!")); + e.setItem(49, Utils.createItem(Material.NETHER_STAR, "&d&lMy Account", "&7Take care of your biz!")); + return; + case "prefs": + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the account page!")); + return; + case "ranks": { + this.setPhoneDefaults(e); + int[] gtmRankSlots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24}; + + int[] donorSlots = new int[]{38, 39, 40, 41, 42}; + int i = 0; + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + for (GTMRank rank : GTMRank.getGTMRanks()) { + if (rank == GTMRank.HOBO) + continue; + List<String> lore = new ArrayList<>(); + lore.add(""); + if (rank.getPrice() > 0) { + lore.add("&7Price: &a$&l" + rank.getPrice()); + lore.add(""); + } + lore.add("&aPerks:"); + lore.add(""); + lore.add("&bKit " + rank.getColoredNameBold() + "&7!"); + switch (rank) { + case CRIMINAL: + lore.add("&7Drivers License! (&a&lCars&7)"); + break; + case HOMIE: + lore.add("&7Team up! (Join a &a&lGang&7)"); + lore.add("&7Unlock &e&lMarksman Pistol&7!"); + break; + case THUG: + lore.add("&7A place to crash! (1 &3&lHouse&7)"); + lore.add("&7Unlock &e&lHeavy Shotgun&7!"); + lore.add("&7Unlock &a&lLight &bArmor Upgrade&7!"); + break; + case GANGSTER: + lore.add("&7Create your own &a&lGang&7!"); + lore.add("&7Use &b&lCOP Mode&7!"); + lore.add("&7Unlock &e&lChainsaw&7!"); + lore.add("&7Unlock &e&lGusenberg Sweeper&7!"); + lore.add("&7Unlock &a&lDurable &bArmor Upgrade&7!"); + break; + case MUGGER: + lore.add("&7Growing! (3 &a&lGang Members&7)"); + lore.add("&7Another hideout! (2 &3&lHouses&7)"); + lore.add("&7Unlock &e&lRPG&7!"); + lore.add("&7Unlock &a&lUltra Light &bArmor Upgrade&7!"); + break; + case HUNTER: + lore.add("&7Use &8&lHITMAN Mode&7!"); + lore.add("&7Connecting! (&a&l5 Gang Members&7)"); + lore.add("&7Unlock &e&lHeavy Sniper&7!"); + lore.add("&7Unlock &a&lTank &bArmor Upgrade&7!"); + break; + case DEALER: + lore.add("&7Fly &3&lPlanes&7!"); + lore.add("&7Unlock &e&lSpecial Carbine&7!"); + lore.add("&7Unlock &a&lReinforced &bArmor Upgrade&7!"); + break; + case PIMP: + lore.add("&7Spreading! (&a&l10 Gang Members&7)"); + lore.add("&7Unlock &e&lGrenade Launcher&7!"); + lore.add("&7Unlock &a&lBomb Squad &bArmor Upgrade&7!"); + break; + case MOBSTER: + lore.add("&7Buy a crib! (3 &3&lHouses&7)"); + lore.add("&7Unlock &e&lCombat MG&7!"); + lore.add("&7Unlock &a&lExoskeleton &bArmor Upgrade&7!"); + lore.add("&7Up, up and away! (&4&lJetpack&7)"); + break; + case GODFATHER: + lore.add("&7Broadening! (&a&l20 Gang Members&7)"); + lore.add("&7Unlock &e&lHoming Launcher&7!"); + lore.add("&7Unlock &e&lMinigun&7!"); + lore.add("&7Unlock &a&lEnhanced &bArmor Upgrade&7!"); + break; + default: + lore.add("&7Rank up for cool perks!"); + } + e.setItem(gtmRankSlots[i], + Utils.createItem(rank.getMaterial(), rank.getColoredNameBold(), Utils.f(lore))); + i++; + } + i = 0; + for (UserRank rank : new UserRank[]{UserRank.VIP, UserRank.PREMIUM, UserRank.ELITE, UserRank.SPONSOR, UserRank.SUPREME}) { + List<String> lore = new ArrayList<>(); + lore.add(""); + lore.add("&7Price: &a$&l" + rank.getPrice()); + lore.add(""); + lore.add("&aPerks:"); + lore.add(""); + lore.add("&a+ &e&l" + rank.getMonthlyTokens() + " Tokens &a&lmonthly&7!"); + lore.add("&bKit " + rank.getColoredNameBold() + "&7!"); + lore.add("&a&l" + GTMUtils.getBackpackRows(rank) + "&6&l Backpack &7rows!"); + lore.add("&a+ $&l" + GTMUtils.getStartingMoney(rank) + "&7 in-game money!"); + lore.add("&a+ &l" + GTMUtils.getHouses(rank) + "&7 extra &3&lHouses&7"); + lore.add("&a+ &7Expanding! (&a&l" + GTMUtils.getGangMembers(rank) + "&7 Gang Members)"); + lore.add("&a+ &7Call a &6&lCab&7! (&a&l/tpa&7)"); + lore.add("&a+ " + GTMUtils.getWarpDelay(rank) + "&7s delay &6&lTaxi Service&7!"); + if (rank.isHigherThan(UserRank.VIP)) { + lore.add("&a+ Instantly&7 teleport to the map!"); + lore.add("&a+ &7Upgraded GPS! (&a+~&l" + GTMUtils.getExtraCompassAccuracy(rank) + "&a%&7)"); + lore.add("&a+ &7Join &c&lFull&7 servers!"); + lore.add("&a+ &7Unlock &3&lCOP Mode&7!"); + } + lore.add("&a+ &7Switch &3&lJob Mode&7 faster! (&a" + GTMUtils.getJobModeDelay(rank) + "&7)"); + if (rank.isHigherThan(UserRank.PREMIUM)) { + lore.add("&a+ &7Unlock &8&lHITMAN Mode&7!"); + lore.add("&a+ &7Pick up your friend! (&a&l/tpahere&7)"); + } + if (rank.isHigherThan(UserRank.ELITE)) { + lore.add("&a+ &7Satisfy yourself! (&a&l/feed&7)"); + lore.add("&a+ &7Up, up and away! (&4&lJetpack&7)"); + } + if (rank.isHigherThan(UserRank.SUPREME)) { + lore.add("&a+ &7Quick sell Cheatcode"); + } + for (LockedWeapon w : LockedWeapon.values()) { + if (w.getUserRank() == rank || rank.isHigherThan(w.getUserRank())) { + GameItem g = GTM.getItemManager().getItemFromWeapon(w.toString()); + if (g != null) + lore.add("&a+ &7Unlock " + g.getDisplayName() + "&7 instantly!"); + } + } + for (ArmorUpgrade u : ArmorUpgrade.values()) + if (u.getUserRank() == rank || rank.isHigherThan(u.getUserRank())) + lore.add("&a+ &7Unlock " + u.getDisplayName() + " &b&lArmor Upgrade&7 instantly!"); + e.setItem(donorSlots[i], Utils.createItem(rank.getMaterial(), rank.getColoredNameBold(), lore)); + i++; + + } + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to my account!")); + GTMRank next = user.getRank().getNext(); + if (next != null) + e.setItem(31, Utils.createItem(Material.PAPER, "&a&lRankup to " + next.getColoredNameBold() + "&a&l!", + "&7Price: &" + (user.hasMoney(next.getPrice()) ? "a" : "c") + "$&l" + next.getPrice())); + return; + } + case "gtmstats": { + this.setPhoneDefaults(e); + GTMUser u = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + e.setItem(11, Utils.createItem(Material.PAPER, "&a&lMoney: &f" + Utils.round(u.getMoney()))); + e.setItem(13, Utils.createItem(Material.ITEM_FRAME, "&a&lBank: &f" + Utils.round(u.getBank()))); + e.setItem(15, Utils.createItem(Material.EMPTY_MAP, "&3&lPermits: &f" + u.getPermits())); + e.setItem(29, Utils.createItem(Material.IRON_SWORD, "&e&lKills: &f" + u.getKills())); + e.setItem(31, Utils.createItem(Material.SKULL_ITEM, "&c&lDeaths: &f" + u.getDeaths())); + e.setItem(33, Utils.createItem(Material.IRON_SWORD, "&a&lK/D Ratio: &f" + u.getKDR())); + e.setItem(49, Utils.createItem(Material.BOOK_AND_QUILL, "&6&lKillstreak: &f" + u.getKillStreak())); + e.setItem(51, Utils.createItem(Material.NETHER_STAR, "&c&lWanted Level: &f" + + GTMUtils.getWantedLevelStars(u.getWantedLevel()) + " (" + u.getWantedLevel() + ')')); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to my account!")); + return; + } + case "bounties": + this.setPhoneDefaults(e); + e.setItem(11, + Utils.createItem(Material.BOOK_AND_QUILL, "&5&lBounties List", "&7View all active bounties!")); + e.setItem(15, Utils.createItem(Material.COMPASS, "&5&lFind Player", + GTM.getUserManager().getLoadedUser(player.getUniqueId()).getJobMode() + == JobMode.HITMAN ? "&7Track wanted players down with your GPS Tracker!" : "&cRequires HITMAN Mode!")); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the home page!")); + e.setItem(49, Utils.createItem(Material.PAPER, "&5&lPlace Bounty", "&7Place a hit on a player!")); + e.setItem(51, Utils.createItem(Material.BOOK, "&5&lBounties Help", "&7Some helpful information!")); + return; + case "bountieslist": { + BountyManager bm = GTM.getBountyManager(); + this.setPhoneDefaults(e); + Set<Bounty> bounties = bm.getBountiesByAmount(); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + Iterator<Bounty> it = bounties.iterator(); + for (int i = 0; i < 20; i++) { + if (!it.hasNext()) + break; + Bounty b = it.next(); + List<String> lore = new ArrayList<>(); + lore.add("&7Bounty Total: &a$&l" + b.getAmount()); + lore.add(""); + double anon = 0; + for (BountyPlacer p : b.getPlacers()) + if (p.isAnonymous()) + anon += p.getAmount(); + else + lore.add("&7" + p.getName() + ": &a$&l" + p.getAmount()); + if (anon > 0) { + lore.add("&7Anonymous: &a$&l" + anon); + } + lore.add(""); + lore.add("&7Expires: &a&l" + Utils.timeInMillisToText(b.getTimeUntilExpiryInMillis())); + e.setItem(slots[i], Utils.setSkullOwner( + Utils.createItem(Material.SKULL_ITEM, 3, "&5&l" + b.getName(), lore), b.getName())); + } + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the bounties page!")); + e.setItem(49, Utils.createItem(Material.BOOK_AND_QUILL, "&5&lBounty List", "&7Page 1")); + if (bounties.size() > 20) + e.setItem(50, Utils.createItem(Material.ARROW, "&5&lNext Page", "&7Page 2")); + return; + } + case "bountieshelp": { + this.setPhoneDefaults(e); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 30, 31, 32, 33, 34, 38, 39, 40, 41, 42}; + List<ItemStack> items = new ArrayList<>(); + items.add(Utils.createItem(Material.PAPER, "&5&lWho can claim bounties?", + "&7Only players that are on the Hitman Job", "&7can claim the money from bounties.")); + items.add(Utils.createItem(Material.PAPER, "&5&lWho can place bounties?", "&7Anyone with at least $2.000", + "&7can place a bounty on a player.")); + items.add(Utils.createItem(Material.PAPER, "&5&lWhat are Anonymous bounties?", + "&7Your name will not be shown in the List", "&7for placing an Anonymous Bounty.")); + items.add(Utils.createItem(Material.PAPER, "&5&lHow long do bounties last?", + "&7If a bounty hasn't been claimed within", "&724 hours, all money will be lost.")); + items.add(Utils.createItem(Material.PAPER, "&5&lCan 2 people pay for the same bounty?", + "&7Multiple people can place a bounty", "&7on the same player.", "&7The hitman will receive the total amount.")); + for (int i = 0; i < items.size(); i++) + e.setItem(slots[i], items.get(i)); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the bounties page!")); + e.setItem(49, Utils.createItem(Material.BOOK, "&5&lBounties Help", "&7Some helpful information!")); + return; + } + case "bountiesplace": { + this.setPhoneDefaults(e); + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + if (user.getBountyName() == null) + e.setItem(11, Utils.createItem(Material.SKULL_ITEM, 3, "&5&lChoose Player", "&7Pick your target!")); + else + e.setItem(11, Utils.setSkullOwner( + Utils.createItem(Material.SKULL_ITEM, 3, "&5&lChoose Player", "&7" + user.getBountyName()), + user.getBountyName())); + if (user.getBountyAmount() <= 0) + e.setItem(15, Utils.createItem(Material.PAPER, 1, "&5&lChoose Amount", "&7Name your price!")); + else + e.setItem(15, Utils.createItem(Material.PAPER, "&5&lChoose Amount", "&a$&l" + user.getBountyAmount())); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the bounties page!")); + e.setItem(49, Utils.createItem(Material.SLIME_BALL, "&5&lConfirm Bounty", "&7Click to place the hit!")); + e.setItem(51, Utils.createItem(Material.SKULL_ITEM, 1, "&5&lPlace Anonymously", "&7No one will know!")); + return; + } + case "kits": { + this.setPhoneDefaults(e); + GTMUser gtmUser = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the home page!")); + int[] grSlots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29}; + int[] jobSlots = new int[]{31, 33}; + int[] otherSlots = new int[]{30, 32,}; + int[] urSlots = new int[]{38, 39, 40, 41, 42}; + int i = 0; + GTMRank gtmRank = gtmUser.getRank(); + for (GTMRank rank : GTMRank.getGTMRanks()) { + Kit kit = GTM.getItemManager().getKit(rank.getName().toLowerCase()); + if (kit == null) { + continue; + } + List<String> lore = new ArrayList<>(); + + lore.add(""); + lore.addAll(kit.getContents().stream().map(KitItem::getDescription).collect(Collectors.toList())); + if (kit.getHelmet() != null) + lore.add("&7Helmet: " + kit.getHelmet().getDescription()); + if (kit.getChestPlate() != null) + lore.add("&7Chestplate: " + kit.getChestPlate().getDescription()); + if (kit.getLeggings() != null) + lore.add("&7Leggings: " + kit.getLeggings().getDescription()); + if (kit.getBoots() != null) + lore.add("&7Boots: " + kit.getBoots().getDescription()); + if (kit.getOffHand() != null) + lore.add("&7Offhand: " + kit.getOffHand().getDescription()); + + lore.add(""); + if (gtmUser.getJobMode() != JobMode.CRIMINAL) + lore.add("&cRequires " + JobMode.CRIMINAL.getColoredNameBold() + " Mode"); + if (!(rank == GTMRank.HOBO || rank == gtmRank)) + lore.add("&7Requires exact rank " + rank.getColoredNameBold()); + if (kit.getCost() > 0) + lore.add("&7Cost: &a$&l" + kit.getCost()); + if (kit.getDelay() > 0) + lore.add(gtmUser.canUseKit(kit.getName()) + ? "&7Delay: &a&l" + Utils.timeInSecondsToText(kit.getDelay()) + : "&cTime Left: &l" + Utils.timeInMillisToText( + gtmUser.getKitExpiry(kit.getName()) - System.currentTimeMillis())); + + ItemStack item = Utils.createItem(rank.getMaterial(), rank.getColoredNameBold(), lore); + ItemMeta meta = item.getItemMeta(); + meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_DESTROYS, + ItemFlag.HIDE_ENCHANTS, ItemFlag.HIDE_POTION_EFFECTS); + item.setItemMeta(meta); + e.setItem(grSlots[i], item); + i++; + } + i = 0; + for (JobMode job : new JobMode[]{JobMode.COP, JobMode.HITMAN}) { + Kit kit = GTM.getItemManager().getKit(job.getName().toLowerCase()); + if (kit == null) { + continue; + } + + List<String> lore = new ArrayList<>(); + lore.add(""); + + lore.addAll(kit.getContents().stream().map(KitItem::getDescription).collect(Collectors.toList())); + if (kit.getHelmet() != null) + lore.add("&7Helmet: " + kit.getHelmet().getDescription()); + if (kit.getChestPlate() != null) + lore.add("&7Chestplate: " + kit.getChestPlate().getDescription()); + if (kit.getLeggings() != null) + lore.add("&7Leggings: " + kit.getLeggings().getDescription()); + if (kit.getBoots() != null) + lore.add("&7Boots: " + kit.getBoots().getDescription()); + if (kit.getOffHand() != null) + lore.add("&7Offhand: " + kit.getOffHand().getDescription()); + + lore.add(""); + if (gtmUser.getJobMode() != job) + lore.add("&cRequires " + job.getColoredNameBold() + " Mode"); + if (kit.getCost() > 0) + lore.add("&7Cost: &a$&l" + kit.getCost()); + if (kit.getDelay() > 0) + lore.add(gtmUser.canUseKit(kit.getName()) + ? "&7Delay: &a&l" + Utils.timeInSecondsToText(kit.getDelay()) + : "&cTime Left: &l" + Utils.timeInMillisToText( + gtmUser.getKitExpiry(kit.getName()) - System.currentTimeMillis())); + + ItemStack item = Utils.createItem(job.getMaterial(), job.getColoredNameBold(), lore); + if (job.getMaterial() == Material.LEATHER_CHESTPLATE) + item = Utils.setArmorColor(item, Color.BLUE); + else if (job.getMaterial() == Material.SKULL_ITEM) + item.setDurability((short) 1); + ItemMeta meta = item.getItemMeta(); + meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_DESTROYS, + ItemFlag.HIDE_ENCHANTS, ItemFlag.HIDE_POTION_EFFECTS); + item.setItemMeta(meta); + e.setItem(jobSlots[i], item); + i++; + } + i = 0; + for (UserRank rank : UserRank.getDonorRanks()) { + Kit kit = GTM.getItemManager().getKit(rank.getName().toLowerCase()); + if (kit == null) { + i++; + continue; + } + List<String> lore = new ArrayList<>(); + + lore.add(""); + lore.addAll(kit.getContents().stream().map(KitItem::getDescription).collect(Collectors.toList())); + if (kit.getHelmet() != null) + lore.add("&7Helmet: " + kit.getHelmet().getDescription()); + if (kit.getChestPlate() != null) + lore.add("&7Chestplate: " + kit.getChestPlate().getDescription()); + if (kit.getLeggings() != null) + lore.add("&7Leggings: " + kit.getLeggings().getDescription()); + if (kit.getBoots() != null) + lore.add("&7Boots: " + kit.getBoots().getDescription()); + if (kit.getOffHand() != null) + lore.add("&7Offhand: " + kit.getOffHand().getDescription()); + + lore.add(""); + if (!(rank == user.getUserRank() + || (rank == UserRank.SUPREME && user.getUserRank().isHigherThan(UserRank.SUPREME)))) + lore.add("&cRequires " + rank.getColoredNameBold()); + if (kit.getCost() > 0) + lore.add("&7Cost: &a$&l" + kit.getCost()); + if (kit.getDelay() > 0) + lore.add(gtmUser.canUseKit(kit.getName()) + ? "&7Delay: &a&l" + Utils.timeInSecondsToText(kit.getDelay()) + : "&cTime Left: &l" + Utils.timeInMillisToText( + gtmUser.getKitExpiry(kit.getName()) - System.currentTimeMillis())); + + ItemStack item = Utils.createItem(rank.getMaterial(), rank.getColoredNameBold(), lore); + ItemMeta meta = item.getItemMeta(); + meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_DESTROYS, + ItemFlag.HIDE_ENCHANTS, ItemFlag.HIDE_POTION_EFFECTS); + item.setItemMeta(meta); + e.setItem(urSlots[i], item); + i++; + } + i = 0; + for (Kit kit : GTM.getItemManager().getKits()) { + if (GTMRank.getRankOrNull(kit.getName()) != null || UserRank.getUserRankOrNull(kit.getName()) != null + || JobMode.getModeOrNull(kit.getName()) != null) + continue; + List<String> lore = new ArrayList<>(); + + lore.add(""); + lore.addAll(kit.getContents().stream().map(KitItem::getDescription).collect(Collectors.toList())); + + lore.add(""); + if (kit.getPermission() != null && !player.hasPermission(kit.getPermission())) + lore.add("&cRequires permission " + kit.getPermission()); + if (kit.getCost() > 0) + lore.add("&7Cost: &a$&l" + kit.getCost()); + if (kit.getDelay() > 0) + lore.add(gtmUser.canUseKit(kit.getName()) + ? "&7Delay: &a&l" + Utils.timeInMillisToText((long) kit.getDelay() * 1000) + : "&cTime Left: &l" + Utils.timeInMillisToText( + gtmUser.getKitExpiry(kit.getName()) - System.currentTimeMillis())); + + ItemStack item = Utils.createItem(kit.getMaterial(), "&b&l" + kit.getName().toUpperCase(), lore); + ItemMeta meta = item.getItemMeta(); + meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_DESTROYS, + ItemFlag.HIDE_ENCHANTS, ItemFlag.HIDE_POTION_EFFECTS); + item.setItemMeta(meta); + + try { + e.setItem(otherSlots[i], item); + i++; + if (i > otherSlots.length) break; + } catch (ArrayIndexOutOfBoundsException ex) {} + } + + return; + + } + case "contacts": { + this.setPhoneDefaults(e); + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + e.setItem(11, Utils.createItem(Material.STORAGE_MINECART, "&e&lTaxi Service", "&7Click to select a destination!")); + e.setItem(13, Utils.createItem(Material.SKULL_ITEM, 2, user.getJobMode() == JobMode.COP ? "&3&lBackup" : "&3&lPolice", user.getJobMode() == JobMode.COP ? "&7Click to request help from fellow officers!" : "&7Click to call the cops to your location!")); + e.setItem(15, Utils.createItem(Material.WOOD_SWORD, "&c&lSuicide Hotline", "&7Call the Suicide Hotline!")); + + e.setItem(29, Utils.createItem(Material.ANVIL, "&2&lCheat Codes", "&7Become a cheater and rule the game!")); + + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the home page!")); + e.setItem(49, Utils.createItem(Material.WATCH, "&c&l911 Emergency", "&7Click to teleport out of here!")); + + + return; + } + case "taxi": + this.setPhoneDefaults(e); + e.setItem(11, Utils.createItem(Material.SKULL_ITEM, 3, "&e&lPlayer", "&7Click to select a player!")); + e.setItem(13, Utils.createItem(Material.EMERALD, "&a&lQuick Play", "&7Click to teleport to a random location!")); + e.setItem(22, Utils.createItem(Material.ENDER_PEARL, "&e&lWarp", "&7Click to select a warp!")); + e.setItem(15, Utils.createItem(Material.IRON_DOOR, "&3&lHouse", "&7Click to select a house!")); + e.setItem(31, Utils.createItem(Material.BED, "&e&lSpawn", "&7Click to teleport to spawn!")); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the contacts page!")); + e.setItem(49, Utils.createItem(Material.STORAGE_MINECART, "&e&lTaxi Service", + "&7Click a button to select your destination!")); + return; + case "taxiplayers": { + this.setPhoneDefaults(e); + List<Player> players = new ArrayList<>(); + for (Player bp : Bukkit.getOnlinePlayers()) { + if (!player.getUniqueId().equals(bp.getUniqueId())) { + players.add(bp); + } + } + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + Iterator<Player> it = players.iterator(); + User u = Core.getUserManager().getLoadedUser(player.getUniqueId()); + for (int i = 0; i < 20; i++) { + if (!it.hasNext()) + break; + Player p = it.next(); + e.setItem( + slots[i], Utils + .setSkullOwner( + Utils.createItem(Material.SKULL_ITEM, 3, + "&e&l" + p.getName(), u.isPremium() + ? "&7Click to send teleport request!" : "&cRequires PREMIUM!"), + p.getName())); + } + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the taxi page!")); + e.setItem(49, Utils.createItem(Material.STORAGE_MINECART, "&e&lTaxi Service: Players", "&7Page 1")); + if (players.size() > 20) + e.setItem(50, Utils.createItem(Material.ARROW, "&e&lNext Page", "&7Page 2")); + return; + } + case "taxihouses": { + this.setPhoneDefaults(e); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42, + 47, 48, 49, 50, 51}; + User u = Core.getUserManager().getLoadedUser(uuid); + GTMUser gtmUser = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + HouseUser user = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + List<UserHouse> houses = user.getHouses(); + List<PremiumHouse> premiumHouses = user.getPremiumHousesAsGuest(); + Iterator<UserHouse> it = houses.iterator(); + Iterator<PremiumHouse> it2 = premiumHouses.iterator(); + for (int i = 0; i < 20; i++) { + PremiumHouse premiumHouse = it.hasNext() ? null : it2.hasNext() ? it2.next() : null; + UserHouse userHouse = it.hasNext() ? it.next() : null; + if (premiumHouse == null && userHouse == null) + break; + if (premiumHouse != null) { + e.setItem(slots[i], + Utils.addGlow(Utils.createItem( + Material.IRON_DOOR, "&3&lPremium House: &a&l" + premiumHouse.getId(), Arrays.asList( + "Permits: &a&l" + premiumHouse.getPermits(), + "&7Chests: &a&l" + premiumHouse.getChests().size(), + "&7Owned by &a" + (Objects.equals(player.getUniqueId(), premiumHouse.getOwner()) + ? "me" : premiumHouse.getOwnerName()) + '.', + u.isRank(UserRank.ELITE) ? "&7Click to teleport!" : + gtmUser.hasMoney(500) ? "&7Click to teleport for &a$&l500&7!" : "&cYou can't afford &c$&l500&c to pay for the ride!")))) + ; + continue; + } + + House house = Houses.getHousesManager().getHouse(userHouse.getId()); + e.setItem(slots[i], + Utils.createItem(Material.IRON_DOOR, "&3&lHouse: &a&l" + house.getId(), + Arrays.asList("&7Price: &a$&l" + house.getPrice(), + "&7Chests: &a&l" + house.getChests().size(), + u.isRank(UserRank.ELITE) ? "&7Click to teleport!" : gtmUser.hasMoney(500) ? "&7Click to teleport for &a$&l500&7!" : "&cYou can't afford &c$&l500&c to pay for the ride!"))); + } + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the taxi page!")); + e.setItem(49, Utils.createItem(Material.STORAGE_MINECART, "&e&lTaxi Service: &3&lHouses", "&7Page 1")); + if (houses.size() > 20) + e.setItem(50, Utils.createItem(Material.ARROW, "&e&lNext Page", "&7Page 2")); + return; + } + case "taxiwarps": { + this.setPhoneDefaults(e); + User u = Core.getUserManager().getLoadedUser(uuid); + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + List<Warp> warps = GTM.getWarpManager().getWarps(); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + Iterator<Warp> it = warps.iterator(); + for (int i = 0; i < 20; i++) { + if (!it.hasNext()) + break; + Warp warp = it.next(); + e.setItem(slots[i], Utils.createItem(Material.ENDER_PEARL, "&e&l" + warp.getName(), + u.isRank(UserRank.ELITE) ? "&7Click to teleport!" : "&7Click to teleport for &a$&l200&7!")); + } + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the taxi page!")); + e.setItem(49, Utils.createItem(Material.STORAGE_MINECART, "&e&lTaxi Service: Warps", "&7Page 1")); + if (warps.size() > 20) + e.setItem(50, Utils.createItem(Material.ARROW, "&e&lNext Page", "&7Page 2")); + return; + } + case "bank": { + this.setPhoneDefaults(e); + GTMUser user = GTMUserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + if (user != null){ + e.setItem(13, + Utils.createItem(Material.SKULL_ITEM, 3, "&a&lTransfer Money", "&7Send money to another player!")); + e.setItem(29, Utils.createItem(Material.INK_SACK, 1, "&c&lWithdraw Money", "&7Take it all!")); + e.setItem(31, + Utils.createItem(Material.BOOK, "&3&lBank Balance: &a$&l" + Utils.formatMoney(user.getBank()), "&7You a rich fool!")); + e.setItem(33, + Utils.createItem(Material.SLIME_BALL, "&a&lDeposit Money", "&7Trust me! Your money is safe here!")); + e.setItem(49, Utils.createItem(Material.PAPER, "&3&lBanking", "&7Your financial buddy!")); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&7Return to the property page!")); + } + return; + } + case "bankwithdraw": { + this.setPhoneDefaults(e); + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + int[] slots = new int[]{12, 13, 14, 21, 22, 23, 30, 31, 32}; + int[] amnts = new int[]{100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000}; + for (int i = 0; i < 9; i++) + e.setItem(slots[i], Utils.createItem(Material.PAPER, + (user.hasBank(amnts[i]) ? "&a" : "&c") + "$&l" + amnts[i], "&7Click to withdraw!")); + e.setItem(39, Utils.createItem(Material.PAPER, "&3&lHalf: &a$&l" + Utils.round(user.getBank() / 2), + "&7Click to withdraw!")); + e.setItem(40, Utils.createItem(Material.PAPER, "&3&lAll: &a$&l" + user.getBank(), "&7Click to withdraw")); + e.setItem(41, + Utils.createItem(Material.BOOK_AND_QUILL, "&a&lCustom Amount", "&7Click to choose an amount!")); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the banking page!")); + return; + } + case "bankdeposit": { + this.setPhoneDefaults(e); + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + int[] slots = new int[]{12, 13, 14, 21, 22, 23, 30, 31, 32}; + int[] amnts = new int[]{100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000}; + for (int i = 0; i < 9; i++) + e.setItem(slots[i], Utils.createItem(Material.PAPER, + (user.hasMoney(amnts[i]) ? "&a" : "&c") + "$&l" + amnts[i], "&7Click to deposit!")); + e.setItem(39, Utils.createItem(Material.PAPER, "&3&lHalf: " + (user.hasMoney(200) ? "&a" : "&c") + "$&l" + Utils.round(user.getMoney() / 2), + "&7Click to deposit!")); + e.setItem(40, Utils.createItem(Material.PAPER, "&3&lAll: " + (user.hasMoney(200) ? "&a" : "&c") + "$&l" + user.getMoney(), "&7Click to deposit")); + e.setItem(41, + Utils.createItem(Material.BOOK_AND_QUILL, "&a&lCustom Amount", "&7Click to choose an amount!")); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the banking page!")); + return; + } + case "banktransfer": { + this.setPhoneDefaults(e); + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + int[] slots = new int[]{12, 13, 14, 21, 22, 23, 30, 31, 32}; + int[] amnts = new int[]{100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000}; + for (int i = 0; i < 9; i++) + e.setItem(slots[i], Utils.createItem(Material.PAPER, + (user.hasBank(amnts[i]) ? "&a" : "&c") + "$&l" + amnts[i], "&7Click to transfer!")); + e.setItem(39, Utils.createItem(Material.PAPER, "&3&lHalf: &a$&l" + Utils.round(user.getBank() / 2), + "&7Click to transfer!")); + e.setItem(40, Utils.createItem(Material.PAPER, "&3&lAll: &a$&l" + user.getBank(), "&7Click to transfer")); + e.setItem(41, + Utils.createItem(Material.BOOK_AND_QUILL, "&a&lCustom Amount", "&7Click to choose an amount!")); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the banking page!")); + return; + } + case "gps": { + this.setGPSDefaults(e); + GTMUser u = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + Optional<Gang> optional = GangManager.getInstance().getGangByMember(player.getUniqueId()); + + e.setItem(10, Utils.setArmorColor(Utils.createItem(Material.LEATHER_CHESTPLATE, "&a&lGang Member", !optional.isPresent() ? "&cYou don't have a gang!" : "&7Click to select a homie!"), Color.fromRGB(102, 127, 51))); + HouseUser user = Houses.getUserManager().getLoadedUser(uuid); + e.setItem(13, Utils.createItem(Material.IRON_DOOR, "&3&lHouses", user.getHouses().isEmpty() && user.getPremiumHousesAsGuest().isEmpty() ? "&cYou don't own any houses!" : "&7Click to select a house!")); + e.setItem(16, Utils.setArmorColor(Utils.createItem(Material.LEATHER_HELMET, "&b&lAssist Cop", u.getJobMode() == JobMode.COP ? "&7Click to select a cop!" : "&cRequires COP Mode!"), + Color.BLUE)); + if (u.hasPersonalVehicle()) { + PersonalVehicle vehicle = u.getPersonalVehicle(); + ItemStack stack = vehicle.getVehicleProperties().getItem().clone(); + ItemMeta meta = stack.getItemMeta(); + List<String> lore = new ArrayList<>(meta.getLore()); + lore.add(Utils.f("&7Health: " + vehicle.getFormattedHealth())); + lore.add(Utils.f("&aClick to track your personal vehicle!")); + stack.setItemMeta(meta); + e.setItem(29, Utils.addGlow(stack)); + } + e.setItem(31, Utils.createItem(Material.REDSTONE, "&c&lReset Tracker", "&7Click to reset!")); + e.setItem(46, Utils.createItem(Material.SKULL_ITEM, 3, "&e&lWanted Criminal", + u.getJobMode() == JobMode.COP ? "&7Click to select a criminal!" : "&cRequires COP Mode!")); + e.setItem(49, Utils.createItem(Material.COMPASS, "&c&lGPS Tracker", + u.hasCompassTarget() ? "&7Click to refresh!" : "&7Click a button to set your destination!")); + e.setItem(52, + Utils.createItem(Material.SKULL_ITEM, 1, "&5&lBounty Tracker", + u.getJobMode() == JobMode.HITMAN ? "&7Click to select a wanted player!" + : "&cRequires HITMAN Mode!")); + return; + } + case "gpsgangs": { + this.setGPSDefaults(e); + int[] slots = new int[]{10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, 33, 34, 37, 38, 39, 40, 41, 42, 43}; + + Optional<Gang> optional = GangManager.getInstance().getGangByMember(uuid); + if (!optional.isPresent()) { + MenuManager.openMenu(player, "gps"); + return; + } + + List<String> members = new ArrayList<>(optional.get().getMembers().stream().filter(member -> !Objects.equals(member.getUniqueId(), player.getUniqueId()) && Bukkit.getPlayer(member.getUniqueId()) != null).map(GangMember::getName).collect(Collectors.toList())); + + members.remove(player.getName()); + Iterator<String> it = members.iterator(); + for (int i = 0; i < 28; i++) { + if (!it.hasNext()) + break; + String member = it.next(); + e.setItem(slots[i], Utils.setSkullOwner( + Utils.createItem(Material.SKULL_ITEM, 3, "&a&l" + member, "&7Click to track your homie!"), + member)); + } + e.setItem(49, Utils.setArmorColor(Utils.createItem(Material.LEATHER_CHESTPLATE, "&a&lTrack Gang Member", + "&7Click on a gang member to select them!"), Color.fromRGB(102, 127, 51))); + e.setItem(46, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the home page!")); + if (members.size() > 28) + e.setItem(50, Utils.createItem(Material.ARROW, "&a&lNext Page", "&7Page 2")); + return; + } + case "gpshouses": { + int[] slots = new int[]{10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, 33, + 34, 37, 38, 39, 40, 41, 42, 43}; + this.setGPSDefaults(e); + HouseUser user = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + List<UserHouse> houses = user.getHouses(); + List<PremiumHouse> premiumHouses = user.getPremiumHousesAsGuest(); + int counter = 0; + for(PremiumHouse house : premiumHouses) { + if(counter>=28) + break; + e.setItem(slots[counter], + Utils.addGlow( + Utils.createItem(Material.IRON_DOOR, "&3&lPremium House: &a&l" + house.getId(), + Arrays.asList("&7Permits: " + house.getPermits(), + "&7Chests: " + house.getChests().size(), + "&7Owned by " + (Objects.equals(player.getUniqueId(), house.getOwner()) + ? "me" : house.getOwnerName()) + '.', + "&7Click to track!")))); + counter++; + } + for(UserHouse userHouse : houses) { + if(counter>=28) + break; + House house = Houses.getHousesManager().getHouse(userHouse.getId()); + e.setItem(slots[counter], Utils.createItem(Material.IRON_DOOR, "&3&lHouse: &a&l" + house.getId(), Arrays.asList("&7Price: " + house.getPrice(), "&7Chests: " + house.getChests().size(), "&7Click to track!"))); + counter++; + } + e.setItem(49, + Utils.setArmorColor( + Utils.createItem(Material.IRON_DOOR, "&3&lFind House", "&7Click on a house to select it!"), + Color.fromRGB(102, 127, 51))); + e.setItem(46, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the home page!")); + if ((houses.size() + premiumHouses.size()) > 28) + e.setItem(50, Utils.createItem(Material.ARROW, "&a&lNext Page", "&7Page 2")); + return; + } + case "gpscops": { + this.setGPSDefaults(e); + int[] slots = new int[]{10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, 33, + 34, 37, 38, 39, 40, 41, 42, 43}; + List<GTMUser> cops = GTMUtils.getCops(); + cops.remove(GTM.getUserManager().getLoadedUser(player.getUniqueId())); + Iterator<GTMUser> it = cops.iterator(); + for (int i = 0; i < 28; i++) { + if (!it.hasNext()) + break; + GTMUser u = it.next(); + Player p = Bukkit.getPlayer(u.getUUID()); + e.setItem(slots[i], Utils.setSkullOwner(Utils.createItem(Material.SKULL_ITEM, 3, "&b&l" + p.getName(), + "&7Click to track your colleague!"), p.getName())); + } + e.setItem(49, Utils.setArmorColor( + Utils.createItem(Material.LEATHER_CHESTPLATE, "&b&lAssist Cop", "&7Click on a cop to select them!"), + Color.fromRGB(102, 127, 51))); + e.setItem(46, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the home page!")); + if (cops.size() > 28) + e.setItem(50, Utils.createItem(Material.ARROW, "&b&lNext Page", "&7Page 2")); + return; + } + case "gpscriminals": { + this.setGPSDefaults(e); + int[] slots = new int[]{10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, 33, + 34, 37, 38, 39, 40, 41, 42, 43}; + Set<GTMUser> criminals = GTMUtils.getCriminalsByWantedLevel(2); + criminals.remove(GTM.getUserManager().getLoadedUser(player.getUniqueId())); + Iterator<GTMUser> it = criminals.iterator(); + for (int i = 0; i < 28; i++) { + if (!it.hasNext()) + break; + GTMUser u = it.next(); + Player p = Bukkit.getPlayer(u.getUUID()); + e.setItem(slots[i], Utils.setSkullOwner(Utils.createItem(Material.SKULL_ITEM, 3, "&e&l" + p.getName(), + "&7Click to track this criminal!"), p.getName())); + } + e.setItem(49, Utils.createItem(Material.COMPASS, "&e&lTrack Wanted Criminal", + "&7Click on a criminal to select them!")); + e.setItem(46, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the home page!")); + if (criminals.size() > 28) + e.setItem(50, Utils.createItem(Material.ARROW, "&e&lNext Page", "&7Page 2")); + return; + } + case "gpsbounties": { + BountyManager bm = GTM.getBountyManager(); + this.setGPSDefaults(e); + Set<Bounty> bounties = bm.getBountiesByAmount(); + int[] slots = new int[]{10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, 33, + 34, 37, 38, 39, 40, 41, 42, 43}; + Iterator<Bounty> it = bounties.iterator(); + for (int i = 0; i < 28; i++) { + if (!it.hasNext()) + break; + Bounty b = it.next(); + List<String> lore = new ArrayList<>(); + lore.add("&7Bounty Total: &a$&l" + b.getAmount()); + lore.add(""); + double anon = 0; + for (BountyPlacer p : b.getPlacers()) + if (p.isAnonymous()) + anon += p.getAmount(); + else + lore.add("&7" + p.getName() + ": &a$&l" + p.getAmount()); + if (anon > 0) { + lore.add("&7Anonymous: &a$&l" + anon); + } + e.setItem(slots[i], Utils.setSkullOwner( + Utils.createItem(Material.SKULL_ITEM, 3, "&5&l" + b.getName(), lore), b.getName())); + } + e.setItem(46, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the home page!")); + e.setItem(49, Utils.createItem(Material.COMPASS, "&5&lTrack Bounties", "&7Page 1")); + if (bounties.size() > 28) + e.setItem(50, Utils.createItem(Material.ARROW, "&5&lNext Page", "&7Page 2")); + return; + } + case "mygang": { + this.setPhoneDefaults(e); + GTMUser user = GTM.getUserManager().getLoadedUser(uuid); + + Optional<Gang> optional = GangManager.getInstance().getGangByMember(uuid); + + if (!optional.isPresent()) { + e.setItem(31, Utils.createItem(Material.SLIME_BALL, "&a&lCreate Gang", "&7Price: " + (user.hasMoney(500000) ? "&a" : "&c") + "$&l500,000")); + return; + } + + e.setItem(13, Utils.setSkullOwner(Utils.createItem(Material.SKULL_ITEM, 2, + "&a&lLeader: " + optional.get().getOwnerName(), optional.get().isLeader(uuid) + ? Collections.singletonList("&7Click to appoint a new leader!") : Collections.emptyList()), + optional.get().getOwnerName())); + + if (optional.get().isLeader(uuid)) e.setItem(31, Utils.createItem(Material.INK_SACK, 1, "&c&lDisband Gang", "&7Click to abandon your homies!")); + else e.setItem(31, Utils.createItem(Material.INK_SACK, 1, "&c&lLeave Gang", "&7Click to abandon your homies!")); + + e.setItem(29, Utils.createItem(Material.BOOK_AND_QUILL, "&a&lGang Relations", "&7Click to view your allies and enemies!")); + e.setItem(33, Utils.createItem(Material.TRIPWIRE_HOOK, "&a&lView Members", "&7Click to view your homies!")); + e.setItem(15, Utils.createItem(Material.EMPTY_MAP, "&a&lDescription", optional.get().isLeader(uuid) || optional.get().isCoLeader(uuid) + ? Arrays.asList("&7" + optional.get().getDescription(), "&7Click to change!") + : Collections.singletonList("&7" + optional.get().getDescription()))); + + e.setItem(11, Utils.createItem(Material.FEATHER, "&a&lName: " + optional.get().getName(), optional.get().isLeader(uuid) ? Collections.singletonList("&7Click to change the name!") : Collections.emptyList())); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the home page!")); + e.setItem(49, Utils.setArmorColor(Utils.createItem(Material.LEATHER_CHESTPLATE, "&a&lMy Gang: " + optional.get().getName()), Color.fromRGB(102, 127, 51))); + e.setItem(51, Utils.createItem(Material.BOOK, "&a&lGang List", "&7Click to view the most powerful gangs!")); + return; + } + case "gang": { + this.setPhoneDefaults(e); + GTMUser user = GTM.getUserManager().getLoadedUser(uuid); + + Optional<Gang> ownGang = GangManager.getInstance().getGangByMember(uuid); + if(!ownGang.isPresent()) return; + Gang gang = ownGang.get().getViewingGang(uuid).orElse(null); + + GTM.log("1"); + boolean isEnemy = ownGang.get().isEnemy(gang); + if (gang == null) { + e.setItem(31, Utils.createItem(Material.INK_SACK, 1, "&c&lGang: Unknown", "&7This gang does not exist!")); + return; + } + + GTM.log("2"); + if (Objects.equals(gang, ownGang.get())) { + ServerUtil.runTaskLater(() -> MenuManager.openMenu(player, "mygang"), 1); +// new BukkitRunnable() { +// @Override +// public void run() { +// MenuManager.openMenu(player, "mygang"); +// } +// }.runTaskLater(GTM.getInstance(), 1); + return; + } + + GTM.log("3"); + e.setItem(13, Utils.setSkullOwner(Utils.createItem(Material.SKULL_ITEM, 2, "&a&lLeader: " + gang.getOwnerName()), gang.getOwnerName())); + e.setItem(29, Utils.createItem(Material.BOOK_AND_QUILL, "&a&lGang Relations", "&7Click to view this gang's allies and enemies!")); + e.setItem(33, Utils.createItem(Material.TRIPWIRE_HOOK, "&a&lView Members", "&7Click to view this gang's homies!")); + e.setItem(15, Utils.createItem(Material.EMPTY_MAP, "&a&lDescription", "&7" + gang.getDescription())); + e.setItem(11, Utils.createItem(Material.FEATHER, "&a&lName: &7&l" + gang.getName())); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the home page!")); + e.setItem(49, Utils.setArmorColor(Utils.createItem(Material.LEATHER_CHESTPLATE, (isEnemy ? "&c" : "&a") + "&lGang: " + gang.getName()), isEnemy ? Color.RED : Color.fromRGB(102, 127, 51))); + e.setItem(51, Utils.createItem(Material.BOOK, "&a&lGang List", "&7Click to view the most powerful gangs!")); + return; + } + + case "disbandgang": + this.setConfirmDefaults(e, "&a&lClick to disband your gang!", "&c&lCancel"); + return; + + case "leavegang": + this.setConfirmDefaults(e, "&a&lClick to leave your gang!", "&c&lCancel"); + return; + + case "mygangmembers": { + this.setPhoneDefaults(e); + GTMUser user = GTM.getUserManager().getLoadedUser(uuid); + Gang gang = GangManager.getInstance().getGangByMember(uuid).orElse(null); + if(gang == null) return; + + List<GangMember> members = new ArrayList<>(gang.getMembers()); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + Iterator<GangMember> it = members.iterator(); + for (int i = 0; i < 20; i++) { + if (!it.hasNext()) break; + GangMember m = it.next(); + + e.setItem(slots[i], Utils.setSkullOwner(Utils.createItem(Material.SKULL_ITEM, 3, "&a&l" + m.getName(), "&7Rank: &a&l" + m.getRole().getFormattedTag(), + "&7Online: &a&l" + m.isOnline(), "&7Click to view this gang member!"), m.getName())); + } + + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the gang page!")); + e.setItem(49, Utils.setArmorColor(Utils.createItem(Material.LEATHER_CHESTPLATE, "&a&lMy Gang Members", "&7Page 1"), Color.fromRGB(102, 127, 51))); + if (members.size() > 20) e.setItem(50, Utils.createItem(Material.ARROW, "&a&lNext Page", "&7Page 2")); + int size = members.size(); + int max = gang.getMaxMembers(); + + List<String> lore = new ArrayList<>(); + lore.add("&7Your gang can have &a" + (max - size) + "&7 more members!"); + if (gang.isLeader(uuid)) { + if (size >= max) lore.add("&7Go to &a" + Core.getSettings().getStoreLink() + "&7 to get more gang members!"); + lore.add("&7Click to invite a player!"); + } + + if (gang.isCoLeader(uuid)) lore.add("&7Click to invite a player!"); + e.setItem(51, Utils.createItem(Material.BOOK, "&a&lMax Gang Members: &a&l" + size + "&7/&a&l" + max, lore)); + return; + } + + case "gangmember": { + this.setPhoneDefaults(e); + GTMUser user = GTM.getUserManager().getLoadedUser(uuid); + + Gang gang = GangManager.getInstance().getGangByMember(uuid).orElse(null); + if (gang == null) return; + + GangMember member = gang.getViewingGangMember(uuid).orElse(null); + if (member == null) return; + + e.setItem(31, Utils.createItem(Material.SKULL_ITEM, 2, "&a&l" + member.getName(), "&7Online: &a&l" + (Bukkit.getPlayer(member.getUniqueId()) != null))); + e.setItem(15, Utils.createItem(Material.PAPER, "&a&lRank: " + member.getRole().getFormattedTag())); + if (gang.isLeader(uuid) || gang.isCoLeader(uuid)) { + if (member.isCoLeader()) e.setItem(13, Utils.createItem(Material.BOOK_AND_QUILL, 1, "&a&lDemote", "&7Make this player a Member!")); + else e.setItem(13, Utils.createItem(Material.SLIME_BALL, "&a&lPromote", "&7Make this player a Coleader!")); + e.setItem(11, Utils.createItem(Material.INK_SACK, 1, "&a&lKick", "&7Force this player to leave the gang!")); + } + + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the gang page!")); + e.setItem(49, Utils.setArmorColor(Utils.createItem(Material.LEATHER_CHESTPLATE, "&a&lGang Member: " + member.getName()), Color.fromRGB(102, 127, 51))); + List<String> lore = new ArrayList<>(); + int size = gang.getMembers().size(); + int max = gang.getMaxMembers(); + lore.add("&7Your gang can have &a" + (max - size) + "&7 more members!"); + if (gang.isLeader(uuid) && size >= max) + lore.add("&7Go to &a" + Core.getSettings().getStoreLink() + "&7 to get more gang members!"); + + e.setItem(51, Utils.createItem(Material.BOOK, "&a&lMax Gang Members: &a&l" + size + "&7/&a&l" + max, lore)); + return; + + } + case "gangmembers": { + this.setPhoneDefaults(e); + GTMUser user = GTM.getUserManager().getLoadedUser(uuid); + Gang ownGang = GangManager.getInstance().getGangByMember(uuid).orElse(null); + if (ownGang == null) return; + + Gang gang = ownGang.getViewingGang(uuid).orElse(null); + if (gang == null) { + e.setItem(31, Utils.createItem(Material.INK_SACK, 1, "&c&lGang: &7&lUnknown", "&7This gang does not exist!")); + return; + } + + boolean isEnemy = ownGang.isEnemy(gang); + if (Objects.equals(gang, ownGang)) { + ServerUtil.runTaskLater(() -> MenuManager.openMenu(player, "mygangmembers"), 1); + return; + } + + List<GangMember> members = new ArrayList<>(gang.getMembers()); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + Iterator<GangMember> it = members.iterator(); + for (int i = 0; i < 20; i++) { + if (!it.hasNext()) break; + GangMember m = it.next(); + e.setItem(slots[i], Utils.setSkullOwner(Utils.createItem(Material.SKULL_ITEM, 3, (isEnemy ? "&c" : "&a") + "&l" + m.getName(), "&7Rank: &a&l" + m.getRole().getFormattedTag(), "&7Online: &a&l" + m.isOnline(), "&7Click to view this gang member!"), m.getName())); + } + + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the gang page!")); + e.setItem(49, Utils.setArmorColor(Utils.createItem(Material.LEATHER_CHESTPLATE, (isEnemy ? "&c" : "&a") + "&lGang Members: &7&l" + gang.getName(), "&7Page 1"), isEnemy ? Color.RED : Color.fromRGB(102, 127, 51))); + if (members.size() > 20) e.setItem(50, Utils.createItem(Material.ARROW, "&a&lNext Page", "&7Page 2")); + + int size = members.size(); + int max = gang.getMaxMembers(); + e.setItem(51, Utils.createItem(Material.BOOK, "&a&lMax Gang Members: &a&l" + size + "&7/&a&l" + max, size >= max ? "&7Go to &a" + Core.getSettings().getStoreLink() + "&7 to get more gang members!" : "&7Your gang can have &a" + (max - size) + "&7 more members!")); + return; + } + case "mygangrelations": { + this.setPhoneDefaults(e); + GTMUser user = GTM.getUserManager().getLoadedUser(uuid); + Gang gang = GangManager.getInstance().getGangByMember(uuid).orElse(null); + if (gang == null) return; + + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + Set<GangRelation> relations = gang.getRelations(); + int i = 0; + for (GangRelation r : relations) { + int online = 0; + int amnt = 0; + + Optional<Gang> optional = GangManager.getInstance().getGang(r.getRelativeId()); + if (optional.isPresent()) { + Gang ga = optional.get(); + online = ga.getOnlineMembers().size(); + amnt = ga.getMembers().size() + 1; + } + boolean isEnemy = gang.isEnemy(optional.get()); + boolean isAlly = gang.isAllied(optional.get()); + e.setItem(slots[i], Utils.setArmorColor(Utils.createItem(Material.LEATHER_CHESTPLATE, (isEnemy ? "&c" : "&a") + r.getRelativeName(), + "&7Relation: " + (isEnemy ? "&c&lEnemy" : isAlly ? "&a&lAlly" : "&a&lNeutral"), + amnt == 0 ? "&7Online Members: &c&l0" : "&7Online Members: &a&l" + online + "&7/&a&l" + amnt, + amnt == 0 ? "This gang is not online!" : "&7Click to view this gang!"), + isEnemy ? Color.RED : Color.fromRGB(102, 127, 51))); + i++; + } + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the gang page!")); + e.setItem(49, Utils.setArmorColor(Utils.createItem(Material.LEATHER_CHESTPLATE, "&a&lMy Gang Relations", "&7Page 1"), Color.fromRGB(102, 127, 51))); + if (relations.size() > 20) + e.setItem(50, Utils.createItem(Material.ARROW, "&a&lNext Page", "&7Page 2")); + + if (gang.isLeader(uuid) || gang.isCoLeader(uuid)) + e.setItem(51, Utils.createItem(Material.BOOK, "&a&lSet Relation", "&7Click to set a relation towards an other gang!")); + return; + } + case "gangrelations": { + this.setPhoneDefaults(e); + GTMUser user = GTM.getUserManager().getLoadedUser(uuid); + + Gang ownGang = GangManager.getInstance().getGangByMember(uuid).orElse(null); + if (ownGang == null) return; + + Gang gang = ownGang.getViewingGang(uuid).orElse(null); + if (gang == null) { + e.setItem(31, Utils.createItem(Material.INK_SACK, 1, "&c&lGang: &7&lUnknown", "&7This gang does not exist!")); + return; + } + + boolean isOwnEnemy = ownGang.isEnemy(gang); + if (Objects.equals(gang, ownGang)) { + ServerUtil.runTaskLater(() -> MenuManager.openMenu(player, "mygangrelations"), 1); + return; + } + + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + Set<GangRelation> relations = gang.getRelations(); + int i = 0; + for (GangRelation r : relations) { + int online = 0; + int amnt = 0; + + Optional<Gang> optional = GangManager.getInstance().getGang(r.getRelativeId()); + if (optional.isPresent()) { + Gang ga = optional.get(); + online = ga.getOnlineMembers().size(); + amnt = ga.getMembers().size() + 1; + } + boolean isEnemy = gang.isEnemy(optional.get()); + boolean isAlly = gang.isAllied(optional.get()); + e.setItem(slots[i], Utils.setArmorColor(Utils.createItem(Material.LEATHER_CHESTPLATE, (isEnemy ? "&c" : "&a") + optional.get().getName(), + "&7Relation: " + (isEnemy ? "&c&lEnemy" : isAlly ? "&a&lAlly" : "&a&lNeutral"), + amnt == 0 ? "&7Online Members: &c&l0" : "&7Online Members: &a&l" + online + "&7/&a&l" + amnt, + "&7Click to view this gang!"), + isEnemy ? Color.RED : Color.fromRGB(102, 127, 51))); + i++; + } + + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the gang page!")); + e.setItem(49, Utils.setArmorColor(Utils.createItem(Material.LEATHER_CHESTPLATE, (isOwnEnemy ? "&c" : "&a") + "&lGang Relations: &7&l" + gang.getName(), "&7Page 1"), isOwnEnemy ? Color.RED : Color.fromRGB(102, 127, 51))); + if (relations.size() > 20) + e.setItem(50, Utils.createItem(Material.ARROW, "&a&lNext Page", "&7Page 2")); + + if (ownGang.isLeader(uuid) || ownGang.isCoLeader(uuid)) + e.setItem(51, Utils.createItem(Material.BOOK, "&a&lSet Relation", "&7Click to set a relation towards this gang!")); + return; + } + case "gangs": { + this.setPhoneDefaults(e); + GTMUser user = GTM.getUserManager().getLoadedUser(uuid); + Gang gang = GangManager.getInstance().getGangByMember(uuid).orElse(null); + if (gang == null) return; + + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + Set<Gang> gangs = GangManager.getInstance().getGangs(); + Iterator<Gang> it = gangs.iterator(); + for (int i = 0; i < 20; i++) { + if (!it.hasNext()) break; + Gang g = it.next(); + int online = g.getOnlineMembers().size(); + int amnt = g.getMembers().size() + 1; + boolean isEnemy = gang.isEnemy(g); + boolean isAlly = gang.isAllied(g); + + GangMember member = gang.getMember(uuid).orElse(null); + if (member != null) { + String relation = Objects.equals(gang, g) ? "&a&l" + member.getRole().getTag() : isEnemy ? "&c&lEnemy" : isAlly ? "&a&lAlly" : "&a&lNeutral"; + e.setItem(slots[i], Utils.setArmorColor(Utils.createItem(Material.LEATHER_CHESTPLATE, (isEnemy ? "&c" : "&a") + g.getName(), + "&7Relation: " + relation, amnt == 0 ? "&7Online Members: &c&l0" : "&7Online Members: &a&l" + online + "&7/&a&l" + amnt, + amnt == 0 ? "This gang is not online!" : "&7Click to view this gang!"), + isEnemy ? Color.RED : Color.fromRGB(102, 127, 51))); + } + } + + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the gang page!")); + e.setItem(49, Utils.setArmorColor(Utils.createItem(Material.LEATHER_CHESTPLATE, "&a&lGang List", "&7Page 1"), Color.fromRGB(102, 127, 51))); + if (gangs.size() > 20) + e.setItem(50, Utils.createItem(Material.ARROW, "&a&lNext Page", "&7Page 2")); + return; + } + + case "ammopouch": { + GTMUser user = GTM.getUserManager().getLoadedUser(uuid); + int i = 0; + for (AmmoType type : AmmoType.getTypes()) { + if (type.isInInventory()) + continue; + ItemStack item = type.getGameItem().getItem(); + int a = user.getAmmo(type); + e.setItem(i, Utils.createItem(item.getType(), item.getItemMeta().getDisplayName(), a >= 127 ? 127 : a, + "&7Amount: &a&l" + a)); + e.setItem(i + 9, Utils.createItem(Material.REDSTONE, "&c&lDrop " + 50, 50)); + e.setItem(i + 18, Utils.createItem(Material.REDSTONE, "&c&lDrop " + 10, 10)); + e.setItem(i + 27, Utils.createItem(Material.REDSTONE, "&c&lDrop " + 1, 1)); + i++; + } + ItemStack grayGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a"); + for (int n : new int[]{8, 17, 26, 35}) + e.setItem(n, grayGlass); + return; + + } + case "jail": { + this.setPhoneDefaults(e); + GTMUser user = GTM.getUserManager().getLoadedUser(uuid); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + List<Player> jailedPlayers = GTMUtils.getJailedPlayers(); + Iterator<Player> it = jailedPlayers.iterator(); + for (int i = 0; i < 20; i++) { + if (!it.hasNext()) + break; + Player p = it.next(); + GTMUser u = GTM.getUserManager().getLoadedUser(p.getUniqueId()); + if (!u.isArrested()) + continue; + List<String> lore = new ArrayList<>(); + lore.add("&7Time Left: &a&l" + Utils.timeInSecondsToText(u.getJailTimer())); + if (user.getJobMode() == JobMode.COP) + lore.add("&7Click to release!"); + e.setItem(slots[i], Utils.setSkullOwner( + Utils.createItem(Material.SKULL_ITEM, 3, "&e&l" + p.getName(), lore), p.getName())); + } + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lClose", "&7Click to close this menu!")); + e.setItem(49, Utils.createItem(Material.IRON_FENCE, "&c&lPrisoner List", "&7Page 1")); + if (jailedPlayers.size() > 20) + e.setItem(50, Utils.createItem(Material.ARROW, "&c&lNext Page", "&7Page 2")); + return; + } + case "property": + this.setPhoneDefaults(e); + e.setItem(11, Utils.createItem(Material.IRON_DOOR, "&3&lHouses", "&7My place to crash!")); + e.setItem(13, Utils.createItem(Material.PAPER, "&3&lOnline Banking", "&7Keeping your money safe!")); + e.setItem(15, Utils.createItem(Material.MINECART, "&c&lVehicles", "&7Ride in style!")); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the home page!")); + e.setItem(49, Utils.createItem(Material.POWERED_MINECART, "&2&lProperty", "&7Please select a property!")); + return; + case "vehicles": { + this.setPhoneDefaults(e); + GTMUser user = GTM.getUserManager().getLoadedUser(uuid); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + List<PersonalVehicle> vehicles = new ArrayList<>(user.getVehicles()); + if (user.hasPersonalVehicle()) + vehicles.remove(user.getPersonalVehicle()); + Iterator<PersonalVehicle> it = vehicles.iterator(); + for (int i = 0; i < 20; i++) { + if (!it.hasNext()) + break; + PersonalVehicle vehicle = it.next(); + ItemStack stack = vehicle.getVehicleProperties().getItem().clone(); + ItemMeta meta = stack.getItemMeta(); + meta.spigot().setUnbreakable(true); + meta.addItemFlags(ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ATTRIBUTES); + List<String> lore = new ArrayList<>(meta.getLore()); + lore.add(Utils.f("&7Health: " + vehicle.getFormattedHealth())); + lore.add(Utils.f("&aClick to get this vehicle!")); + lore.add(Utils.f("&7Price: &a$&l200")); + meta.setLore(lore); + stack.setItemMeta(meta); + e.setItem(slots[i], stack); + } + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the property page!")); + if (user.hasPersonalVehicle()) { + PersonalVehicle vehicle = user.getPersonalVehicle(); + ItemStack stack = vehicle.getVehicleProperties().getItem().clone(); + ItemMeta meta = stack.getItemMeta(); + List<String> lore = new ArrayList<>(meta.getLore()); + lore.add(Utils.f("&7Health: " + vehicle.getFormattedHealth())); + lore.add(Utils.f("&aClick to view your personal vehicle!")); + meta.setLore(lore); + stack.setItemMeta(meta); + e.setItem(49, Utils.addGlow(stack)); + } else { + e.setItem(49, Utils.createItem(Material.MINECART, "&4&lVehicles", "&7Please select your personal vehicle!")); + } + if (vehicles.size() > 20) + e.setItem(50, Utils.createItem(Material.ARROW, "&4&lNext Page", "&7Page 2")); + return; + } + case "vehicleshop": { + this.setPhoneDefaults(e); + GTMUser user = GTM.getUserManager().getLoadedUser(uuid); + Optional<VehicleProperties> opt = GTM.getWastedVehicles().getVehicle(user.getActionVehicle()); + GameItem item = GTM.getItemManager().getItemFromVehicle(user.getActionVehicle()); + if (opt == null || !opt.isPresent() || item == null) { + player.sendMessage(Lang.VEHICLES.f("&7That vehicle does not exist!")); + return; + } + if (item.getSellPrice() <= 0) { + player.sendMessage(Lang.VEHICLES.f("&7You can't buy this vehicle!")); + player.closeInventory(); + return; + } + VehicleProperties vehicle = opt.get(); + String buyPrice = NumberFormat.getNumberInstance(Locale.US).format(Utils.round(item.getSellPrice() * 2)); + String sellPrice = NumberFormat.getNumberInstance(Locale.US).format(Utils.round(item.getSellPrice())); + e.setItem(11, Utils.createItem(Material.MINECART, "&4&lSpeed: &a&l" + vehicle.getMaxSpeed())); + e.setItem(13, Utils.createItem(Material.PAPER, "&4&lPrice: &a$&l" + buyPrice)); + if (vehicle.getWastedGunsWeapon() != null) { + Optional<Weapon<?>> o = GTM.getWastedGuns().getWeaponManager().getWeapon(vehicle.getWastedGunsWeapon()); + o.ifPresent(weapon -> e.setItem(29, weapon.createItemStack())); + } + if (!vehicle.getAllowedWeapons().isEmpty()) { + List<String> lore = vehicle.getAllowedWeapons().stream().map(s -> GTM.getItemManager().getItemFromWeapon(s)).filter(Objects::nonNull).map(GameItem::getDisplayName).collect(Collectors.toList()); + e.setItem(33, Utils.createItem(Material.WOOD_SWORD, "&4&lAllowed Weapons", lore)); + } + if (user.hasVehicle(vehicle.getIdentifier())) { + e.setItem(31, Utils.createItem(Material.INK_SACK, 1, "&c&lSell Vehicle", "&7Reward: &a$&l" + sellPrice)); + } else + e.setItem(31, Utils.createItem(Material.SLIME_BALL, "&a&lBuy Vehicle", "&7Price: &a$&l" + buyPrice)); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lClose", "&7Click to close this menu!")); + e.setItem(49, vehicle.getItem()); + return; + } + case "buyvehicle": { + this.setPhoneDefaults(e); + GTMUser user = GTM.getUserManager().getLoadedUser(uuid); + Optional<VehicleProperties> opt = GTM.getWastedVehicles().getVehicle(user.getActionVehicle()); + GameItem item = GTM.getItemManager().getItemFromVehicle(user.getActionVehicle()); + if (opt == null || !opt.isPresent() || item == null) { + player.sendMessage(Lang.VEHICLES.f("&7That vehicle does not exist!")); + return; + } + VehicleProperties vehicle = opt.get(); + if (item.getSellPrice() <= 0) { + player.sendMessage(Lang.VEHICLES.f("&7You can't buy this vehicle!")); + player.closeInventory(); + return; + } + if (user.hasVehicle(vehicle.getIdentifier())) { + player.sendMessage(Lang.VEHICLES.f("&7You already own this vehicle!")); + MenuManager.openMenu(player, "vehicles"); + return; + } + this.setConfirmDefaults(e, "&a&lBuy " + vehicle.getItem().getItemMeta().getDisplayName() + "&a&l for &a$&l" + Utils.round(item.getSellPrice() * 2), "&c&lCancel"); + return; + } + case "sellvehicle": { + this.setPhoneDefaults(e); + GTMUser user = GTM.getUserManager().getLoadedUser(uuid); + PersonalVehicle vehicle = user.getPersonalVehicle(user.getActionVehicle()); + if (vehicle == null) return; + double price = vehicle.getSellPrice(); + if (price <= 0) { + player.sendMessage(Lang.VEHICLES.f("&7You can't sell this vehicle!")); + player.closeInventory(); + return; + } + this.setConfirmDefaults(e, "&a&lSell " + vehicle.getDisplayName() + "&a&l for &a$&l" + Utils.round(price), "&c&lCancel"); + return; + } + case "repairvehicle": { + this.setPhoneDefaults(e); + GTMUser user = GTM.getUserManager().getLoadedUser(uuid); + if (user.getActionVehicle() == null) return; + PersonalVehicle vehicle = user.getPersonalVehicle(user.getActionVehicle()); + if (vehicle == null) return; + double price = vehicle.getRepairPrice(); + if (price <= 0) { + player.sendMessage(Lang.VEHICLES.f("&7You can't repair this vehicle!")); + player.closeInventory(); + return; + } + this.setConfirmDefaults(e, "&a&lRepair " + vehicle.getDisplayName() + "&a&l for &a$&l" + Utils.round(price), "&c&lCancel"); + return; + } + case "personalvehicle": { + this.setPhoneDefaults(e); + GTMUser user = GTM.getUserManager().getLoadedUser(uuid); + PersonalVehicle vehicle = user.getPersonalVehicle(); + if (vehicle == null) { + MenuManager.openMenu(player, "vehicles"); + return; + } + VehicleProperties vehicleProperties = vehicle.getVehicleProperties(); + if (vehicleProperties == null) return; + e.setItem(11, Utils.createItem(Material.MINECART, "&4&lStats", "&7Speed: &a&l" + vehicleProperties.getMaxSpeed(), "&7Health: " + vehicle.getFormattedHealth())); + e.setItem(13, Utils.createItem(Material.PAPER, "&4&lPrice: &a$&l" + Utils.round(vehicle.getPrice()))); + if (vehicle.getRepairPrice() > 0 && !vehicle.onMap()) + e.setItem(15, Utils.createItem(Material.WORKBENCH, "&4&lRepair", "&7Call the mechanic!", "&7Price: &a$&l" + Utils.round(vehicle.getRepairPrice()))); + else if (vehicle.onMap()) + e.setItem(15, Utils.createItem(Material.ENDER_PEARL, "&4&lSend Away", "&7Click to send away your vehicle!", "&7Price: &a$&l200")); + else + e.setItem(15, Utils.createItem(Material.ENDER_PEARL, "&4&lCall Vehicle", "&7Click to send your vehicle to yourself!", "&7Price: &a$&l200")); + if (vehicleProperties.getWastedGunsWeapon() != null) { + Optional<Weapon<?>> o = GTM.getWastedGuns().getWeaponManager().getWeapon(vehicleProperties.getWastedGunsWeapon()); + o.ifPresent(weapon -> e.setItem(29, weapon.createItemStack())); + } + if (!vehicleProperties.getAllowedWeapons().isEmpty()) { + List<String> lore = vehicleProperties.getAllowedWeapons().stream().map(s -> GTM.getItemManager().getItemFromWeapon(s)).filter(Objects::nonNull).map(GameItem::getDisplayName).collect(Collectors.toList()); + e.setItem(33, Utils.createItem(Material.WOOD_SWORD, "&4&lAllowed Weapons", lore)); + } + e.setItem(31, Utils.createItem(Material.INK_SACK, 1, "&c&lSell Vehicle", "&7Reward: &a$&l" + Utils.round(vehicle.getSellPrice()))); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the vehicles page!")); + ItemStack stack = vehicle.getVehicleProperties().getItem().clone(); + ItemMeta meta = stack.getItemMeta(); + meta.spigot().setUnbreakable(true); + meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE); + List<String> lore = new ArrayList<>(meta.getLore()); + lore.add(Utils.f("&7Health: " + vehicle.getFormattedHealth())); + lore.add(Utils.f("&aClick to send your vehicle to yourself!")); + lore.add(Utils.f("&7Price: &a$&l200")); + stack.setItemMeta(meta); + e.setItem(49, Utils.addGlow(stack)); + break; + } + case "mechanic": { + this.setPhoneDefaults(e); + GTMUser user = GTM.getUserManager().getLoadedUser(uuid); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + List<PersonalVehicle> vehicles = new ArrayList<>(user.getVehicles()); + new ArrayList<>(vehicles).stream().filter(vehicle -> vehicle.getRepairPrice() <= 0).forEach(vehicles::remove); + Iterator<PersonalVehicle> it = vehicles.iterator(); + for (int i = 0; i < 20; i++) { + if (!it.hasNext()) + break; + PersonalVehicle vehicle = it.next(); + if (!vehicle.isDestroyed()) + continue; + ItemStack stack = vehicle.getVehicleProperties().getItem().clone(); + ItemMeta meta = stack.getItemMeta(); + meta.spigot().setUnbreakable(true); + meta.addItemFlags(ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ATTRIBUTES); + List<String> lore = new ArrayList<>(meta.getLore()); + lore.add(Utils.f("&7Health: " + vehicle.getFormattedHealth())); + lore.add(Utils.f("&7Repair Price: &a&l$" + NumberFormat.getNumberInstance(Locale.US).format(vehicle.getRepairPrice()))); + lore.add(Utils.f("&7Click to repair this vehicle!")); + meta.setLore(lore); + stack.setItemMeta(meta); + e.setItem(slots[i], Objects.equals(vehicle, user.getPersonalVehicle()) ? Utils.addGlow(stack) : stack); + } + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lClose", "&7Click to close this menu!")); + e.setItem(49, Utils.createItem(Material.WORKBENCH, "&4&lMechanic", "&7Repair your vehicles!")); + if (vehicles.size() > 20) + e.setItem(50, Utils.createItem(Material.ARROW, "&4&lNext Page", "&7Page 2")); + return; + } + case "heads": { + this.setPhoneDefaults(e); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + Set<Head> heads = GTM.getShopManager().getNonExpiredHeadsByBid(); + Iterator<Head> it = heads.iterator(); + for (int i = 0; i < 20; i++) { + if (!it.hasNext()) break; + + Head head = it.next(); + List<String> lore = new ArrayList<>(); + lore.add(Utils.f("&7Seller: &a&l" + head.getSellerName())); + + if (head.hasBid()) { + lore.add(Utils.f("&7Bidder: &a&l" + head.getBidderName())); + lore.add(Utils.f("&7Bid: &a$&l" + head.getBid())); + } + else { + lore.add(Utils.f("&7Starting Bid: &a$&l10,000")); + } + + lore.add(Utils.f("&7Click to bid!")); + lore.add(Utils.f("&7Time Left: &a&l" + Utils.timeInMillisToText(head.getTimeUntilExpiry()))); + lore.add(Utils.f("&0" + head.getExpiry())); + e.setItem(slots[i], new JLibItem.Builder().withType(Material.SKULL_ITEM).withDurability((short) 3).withName(Utils.f("&e&l" + head.getHead())).withLore(lore).withOwner(head.getHead()).build().getItemStack()); + } + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lClose", "&7Click to close this menu!")); + e.setItem(49, Utils.createItem(Material.SKULL_ITEM, "&e&lHead Auction", "&7Buy and sell your souvenirs!")); + if (heads.size() > 20) + e.setItem(50, Utils.createItem(Material.ARROW, "&e&lNext Page", "&7Page 2")); + e.setItem(51, Utils.createItem(Material.PAPER, "&e&lAuction Head", "&7Click to auction a player head!")); + return; + } + case "auctionhead": { + this.setPhoneDefaults(e); + ItemStack item = player.getInventory().getItemInMainHand(); + if (item == null || item.getType() != Material.SKULL_ITEM || item.getDurability() != 3) { + player.sendMessage(Lang.HEAD_AUCTION.f("&7That's not a player head!")); + player.closeInventory(); + return; + } + this.setConfirmDefaults(e, "&a&lAuction " + item.getItemMeta().getDisplayName() + "&a&l!", "&c&lCancel"); + return; + } + case "armorupgrade": { + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + ArmorUpgrade upgrade = user.getBuyingArmorUpgrade(); + if (upgrade == null) { + player.closeInventory(); + return; + } + if (!upgrade.canUseUpgrade(user.getRank(), Core.getUserManager().getLoadedUser(player.getUniqueId()).getUserRank())) { + player.closeInventory(); + player.sendMessage(Lang.HEY.f("&7You need to rank up to " + upgrade.getGTMRank().getColoredNameBold() + "&7 or donate for " + upgrade.getUserRank().getColoredNameBold() + "&7 at &a&l" + Core.getSettings().getStoreLink() + "&7 to use the &b&l" + upgrade.getDisplayName() + " Armor Upgrade&7!")); + return; + } + ItemStack item = player.getInventory().getItemInMainHand(); + GameItem gameItem = item == null ? null : GTM.getItemManager().getItem(item.getType()); + if (item == null || gameItem == null || !upgrade.canBeUsedOn(gameItem.getName())) { + player.closeInventory(); + player.sendMessage(Lang.HEY.f("&7The &b&l" + upgrade.getDisplayName() + " Armor Upgrade&7 can only be applied to the following types of items: " + upgrade.getTypesString() + "&7!")); + return; + } + HashSet<ArmorUpgrade> upgradesOnItem = ArmorUpgrade.getArmorUpgrades(item); + + if (upgradesOnItem.contains(upgrade)) { + player.closeInventory(); + player.sendMessage(Lang.ARMOR_UPGRADE.f("&7That piece of armor already has the &b&l" + upgrade.getDisplayName() + " Armor Upgrade&7!")); + e.setCancelled(true); + return; + } + if ((upgradesOnItem.contains(ArmorUpgrade.LIGHT) && upgrade == ArmorUpgrade.ULTRA_LIGHT) || (upgradesOnItem.contains(ArmorUpgrade.ULTRA_LIGHT) && upgrade == ArmorUpgrade.LIGHT)) { + player.closeInventory(); + player.sendMessage(Lang.ARMOR_UPGRADE.f("&7This upgrade cannot be added to the armor piece due to conflicting upgrades.")); + e.setCancelled(true); + return; + } + double price = upgrade.getPrice(); + + if (!user.hasMoney(upgrade.getPrice())) { + player.closeInventory(); + player.sendMessage(Lang.ARMOR_UPGRADE.f("&7You can't afford the &b&l" + upgrade.getDisplayName() + " Armor Upgrade&7!")); + return; + } + this.setConfirmDefaults(e, "&a&lBuy &b&l" + upgrade.getDisplayName() + " Armor Upgrade", "&c&lCancel", + "&7Price: &a$&l" + price, "&7Item: &a&l" + (item.getItemMeta().hasDisplayName() ? item.getItemMeta().getDisplayName() : item.getType().name())); + return; + } + case "lottery": { + this.setPhoneDefaults(e); + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + LotteryPlayer p = GTM.getLottery().getLotteryPlayer(player.getUniqueId()); + int[] slots = new int[]{12, 13, 14, 21, 22, 23, 30, 31, 32, 39, 40}; + int[] amnts = new int[]{1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000}; + for (int i = 0; i < 11; i++) + e.setItem(slots[i], Utils.createItem(Material.EMPTY_MAP, + (user.hasMoney(amnts[i] * 500) ? "&e" : "&c") + "&l" + amnts[i] + " Tickets", "&7Price: &a$&l" + (amnts[i] * 500), "&7Click to buy tickets!")); + e.setItem(41, + Utils.createItem(Material.BOOK_AND_QUILL, "&e&lCustom Amount", "&7Click to choose an amount!")); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lClose", "&7Click to close this menu!")); + e.setItem(49, Utils.createItem(Material.GOLD_INGOT, "&e&lLottery", "&7Your tickets: &e&l" + (p == null ? 0 : p.getTickets()), "&7Go big or go home!")); + LotteryPlayer winner1 = GTM.getLottery().getWinner(0); + LotteryPlayer winner2 = GTM.getLottery().getWinner(1); + LotteryPlayer winner3 = GTM.getLottery().getWinner(2); + e.setItem(51, Utils.setSkullOwner(Utils.createItem(Material.SKULL_ITEM, 3, + "&e&lLast week's winners", + winner1 == null ? "" : "&a#&l1&7: &r" + winner1.getName() + " &a" + Utils.formatMoney(winner1.getAmount()) + "&7 (&a70%&7 of the pot)", + winner2 == null ? "" : "&a#&l2&7: &r" + winner2.getName() + " &a" + Utils.formatMoney(winner2.getAmount()) + "&7 (&a20%&7 of the pot", + winner3 == null ? "" : "&a#&l2&7: &r" + winner3.getName() + " &a" + Utils.formatMoney(winner3.getAmount()) + "&7 (&a10%&7 of the pot)"), winner1 == null ? "Presidentx" : winner1.getName())); + return; + } + case "realestateagent": { + this.setPhoneDefaults(e); + e.setItem(12, Utils.createItem(Material.BOOK_AND_QUILL, "&a&lPremium Houses", "")); + e.setItem(14, Utils.createItem(Material.BOOK_AND_QUILL, "&b&lNon-Premium Houses", "")); + return; + } + case "realestate-premium": { + this.setPhoneDefaults(e); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42, 47, 48, + 49, 50, 51}; + for (PremiumHouse premiumHouse : Houses.getHousesManager().getPremiumHouses()) { + if (premiumHouse.getDoors().size() < 1 || premiumHouse.getChests().size() < 1) continue; + if (premiumHouse.isOwned()) continue; + } + // TODO + return; + } + case "realestate-nonpremium": { + this.setPhoneDefaults(e); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42, 47, 48, + 49, 50, 51}; + // TODO + return; + } + default: + break; + } + + } + + private void setPhoneDefaults(MenuOpenEvent e) { + ItemStack whiteGlass = Utils.createItem(Material.STAINED_GLASS_PANE, "&a"); + ItemStack grayGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a"); + ItemStack blackGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 15, "&a"); + ItemStack lightGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 8, "&a"); + + for (int i : new int[]{0, 8, 9, 17, 18, 26, 27, 35, 36, 44, 45, 53}) e.setItem(i, lightGlass); + for (int i : new int[]{1, 10, 19, 28, 37, 46, 7, 16, 25, 34, 43, 52}) + e.setItem(i, whiteGlass); + for (int i : new int[]{2, 3, 4, 5, 6}) + e.setItem(i, blackGlass); + for (int i : new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42, 47, 48, + 49, 50, 51}) + e.setItem(i, grayGlass); + } + + private void setPhoneDefaults(Inventory inv) { + ItemStack whiteGlass = Utils.createItem(Material.STAINED_GLASS_PANE, "&a"); + ItemStack grayGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a"); + ItemStack blackGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 15, "&a"); + ItemStack lightGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 8, "&a"); + + for (int i : new int[]{0, 8, 9, 17, 18, 26, 27, 35, 36, 44, 45, 53}) inv.setItem(i, lightGlass); + for (int i : new int[]{1, 10, 19, 28, 37, 46, 7, 16, 25, 34, 43, 52}) + inv.setItem(i, whiteGlass); + for (int i : new int[]{2, 3, 4, 5, 6}) + inv.setItem(i, blackGlass); + for (int i : new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42, 47, 48, + 49, 50, 51}) + inv.setItem(i, grayGlass); + } + + private void setGPSDefaults(MenuOpenEvent e) { + ItemStack whiteGlass = Utils.createItem(Material.STAINED_GLASS_PANE, "&a"); + ItemStack grayGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a"); + ItemStack blackGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 15, "&a"); + ItemStack lightGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 8, "&a"); + + for (int i : new int[]{0, 8, 9, 17, 18, 26, 27, 35, 36, 44, 45, 53}) e.setItem(i, lightGlass); + for (int i : new int[]{0, 9, 18, 27, 36, 45, 8, 17, 26, 35, 44, 53}) + e.setItem(i, whiteGlass); + for (int i : new int[]{1, 2, 3, 4, 5, 6, 7}) + e.setItem(i, blackGlass); + for (int i : new int[]{10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, 33, 34, 37, + 38, 39, 40, 41, 42, 43, 46, 47, 48, 49, 50, 51, 52}) + e.setItem(i, grayGlass); + } + + private void setGPSDefaults(Inventory inv) { + ItemStack whiteGlass = Utils.createItem(Material.STAINED_GLASS_PANE, "&a"); + ItemStack grayGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a"); + ItemStack blackGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 15, "&a"); + ItemStack lightGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 8, "&a"); + + for (int i : new int[]{0, 8, 9, 17, 18, 26, 27, 35, 36, 44, 45, 53}) inv.setItem(i, lightGlass); + for (int i : new int[]{0, 9, 18, 27, 36, 45, 8, 17, 26, 35, 44, 53}) + inv.setItem(i, whiteGlass); + for (int i : new int[]{1, 2, 3, 4, 5, 6, 7}) + inv.setItem(i, blackGlass); + for (int i : new int[]{10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, 33, 34, 37, + 38, 39, 40, 41, 42, 43, 46, 47, 48, 49, 50, 51, 52}) + inv.setItem(i, grayGlass); + } + + private void setConfirmDefaults(MenuOpenEvent e) { + this.setConfirmDefaults(e, "&a&lConfirm", "&c&lCancel"); + } + + private void setConfirmDefaults(MenuOpenEvent e, String confirmMessage, String cancelMessage, String... lore) { + ItemStack whiteGlass = Utils.createItem(Material.STAINED_GLASS_PANE, "&a"); + ItemStack grayGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a"); + ItemStack blackGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 15, "&a"); + ItemStack greenGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 5, confirmMessage, lore); + ItemStack redGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 14, cancelMessage); + ItemStack lightGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 8, "&a"); + + for (int i : new int[]{0, 8, 9, 17, 18, 26, 27, 35, 36, 44, 45, 53}) e.setItem(i, lightGlass); + for (int i : new int[]{1, 10, 19, 28, 37, 46, 7, 16, 25, 34, 43, 52}) + e.setItem(i, whiteGlass); + for (int i : new int[]{2, 3, 4, 5, 6}) + e.setItem(i, blackGlass); + for (int i : new int[]{13, 22, 31, 40, 49,}) + e.setItem(i, grayGlass); + for (int i : new int[]{11, 12, 20, 21, 29, 30, 38, 39, 47, 48}) + e.setItem(i, greenGlass); + for (int i : new int[]{14, 15, 23, 24, 32, 33, 41, 42, 50, 51}) + e.setItem(i, redGlass); + } + + @EventHandler(priority = EventPriority.HIGH) + public void onMenuClick(MenuClickEvent e) { + Player player = e.getPlayer(); + UUID uuid = player.getUniqueId(); + Menu menu = e.getMenu(); + GTMUser user = GTM.getUserManager().getLoadedUser(uuid); + ItemStack item = e.getItem(); + Inventory inv = e.getInv(); + if (item == null || item.getType() == Material.AIR || (item.getType() == Material.STAINED_GLASS_PANE && item.getDurability() != 14 && item.getDurability() != 5)) + return; + //TODO: EACH SERVER TYPE needs one of these, because of the different GameItem systems that will be present. + /*if(menu instanceof SubCategoryMenu) { + SubCategoryMenu category = (SubCategoryMenu)menu; + if(category.getType()!=ServerType.GTM) + //some other server will handle the purchase.; + return; + + if(item.getType()==Material.REDSTONE){ + if(category.getPreviousSubCategory()==null){ + category.getShopMenu().openFor(player); + } + else{ + category.getPreviousSubCategory().openFor(player); + } + return; + } + + SubCategoryMenu subCategory = category.getSubCategory(item.getItemMeta().getDisplayName()); + if(subCategory==null){ + //at lowest level category, only displaying items currently to purchase + if(!item.getItemMeta().hasLore()) + return; + List<String> lore = item.getItemMeta().getLore(); + double price = Double.parseDouble(ChatColor.stripColor(lore.get(lore.size()-1)).replace("Price: $", "")); + + //lore.remove(lore.get(lore.size()-1));//remove price so it is back to gameitem + ItemStack gameItemStack = item.clone(); + ItemMeta im = gameItemStack.getItemMeta(); + im.setLore(null); + gameItemStack.setItemMeta(im); + GameItem gameItem = GTM.getItemManager().getItem(gameItemStack); + if(gameItem==null){ + Core.error("Problem sanitizing SubCategoryItem -> GameItem with item name: " + item.getItemMeta().getDisplayName()); + player.sendMessage(Utils.f(Lang.SHOP + "&7Error: Unable to locate gameItem from SubCategoryItem")); + return; + } + + if(user.getMoney()<price){ + player.sendMessage(Utils.f(Lang.SHOP + "&7Error: You do not have enough money to purchase this item!")); + return; + } + user.setMoney(user.getMoney()-price); + player.getInventory().addItem(gameItem.getItem()); + player.sendMessage(Utils.f(Lang.SHOP + "&7You have successfully purchased the desired item!")); + player.closeInventory(); + } + else{ + //not at lowest level category, still more categories to sort through + subCategory.openFor(player); + } + } + else {*/ + + switch (menu.getName()) { + case "transferconfirm": { + switch (item.getType()) { + case STAINED_GLASS_PANE: { + switch (item.getDurability()) { + case 5: { + user.setCurrentChatAction(ChatAction.CONFIRM_TRANSFER, true); + player.closeInventory(); + + player.sendMessage(Lang.GTM.f("&cPlease read the following points before you select your transfer target:")); + + player.sendMessage(Utils.f(" &e&lHOUSES&8&l>")); + player.sendMessage(Utils.f("&6- Your premium houses will be &c&lSOLD &6and transformed into permits.")); + player.sendMessage(Utils.f("&6- Purchased trashcans will be &c&LSOLD &6and transformed into permits.")); + player.sendMessage(Utils.f("&6- Purchased houses will be &c&LSOLD and &6transformed into cash.")); + player.sendMessage(Utils.f("&6- Any items in houses will be &c&LLOST &6so put them in your backpack.")); + + player.sendMessage(Utils.f(" &e&lCOSMETICS&8&l>")); + player.sendMessage(Utils.f("&6- Your player event tags will be &c&lTRANSFERRED &6to the target server.")); + + player.sendMessage(Utils.f(" &a&lMONEY AND ITEMS&8&l>")); + player.sendMessage(Utils.f("&6- Your Permits on this server will &c&lREPLACE &6those on the target server.")); + player.sendMessage(Utils.f("&6- Your Money on this server will &c&lREPLACE &6those on the target server.")); + player.sendMessage(Utils.f("&6- Your Bank balance on this server &c&lREPLACE &6replace those on the target server.")); + player.sendMessage(Utils.f("&6- Your GTMRank on this server will &c&lREPLACE &6those on the target server.")); + player.sendMessage(Utils.f("&6- Your backpack on this server will &c&lREPLACE &6those on the target server.")); + player.sendMessage(Utils.f("&6- Your cheatcodes on this server will &c&lREPLACE &6those on the target server.")); + player.sendMessage(Utils.f("&6- Your vehicles on this server will be &c&lSOLD &6and transformed into cash.")); + player.sendMessage(Utils.f("")); + player.sendMessage(Utils.f("&6- Your player inventory on this server will &c&lBE DELETED &6and only &c&lBACKPACK &6contents will transfer.")); + + player.sendMessage(Lang.GTM.f("&6If you agree to THESE TERMS, enter the server that you would like to transfer to out of the following options: ")); + + Chat.TRANSFER_SERVER_ALLOWED.forEach(id -> { + player.sendMessage(Lang.GTM.f("&aGTM" + id)); + }); + break; + } + + case 14: { + player.closeInventory(); + player.sendMessage(Lang.GTM.f("&cYou have cancelled the transfer process.")); + break; + } + } + } + } + } + case "christmasshop": { + if(!item.getItemMeta().hasLore()) + return; + switch (item.getType()) { + case STAINED_GLASS_PANE: + return; + default: + int cost = 0; + try{ + cost = Integer.parseInt(ChatColor.stripColor(item.getItemMeta().getLore().get(0)).replace("Price: [", "").replace("]", "")); + }catch (NumberFormatException nfe){ + nfe.printStackTrace(); + player.sendMessage(Lang.CHRISTMAS.f("&cSorry, an internal error occured while trying to purchase your item.")); + return; + } + if(!ChristmasEvent.hasCandyCanes(player, cost)) { + player.sendMessage(Lang.CHRISTMAS.f("&cYou do not have enough candy canes to purchase this item!")); + return; + } + + switch (item.getType()) { + case NAME_TAG: { + String name = ChatColor.stripColor( item.getItemMeta().getDisplayName().replace(" Tag", "").replace(" ", "_").toUpperCase()); + EventTag tag = EventTag.valueOf(name); + User coreUser = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if(coreUser.getUnlockedTags().contains(tag)) { + player.sendMessage(Lang.CHRISTMAS.f("&cYou cannot buy tags that you have already unlocked!")); + return; + } + coreUser.giveEventTag(tag); + player.sendMessage(Lang.CHRISTMAS.f("&aYou have been given the " + tag.getBoldName() + " tag. &7Select your active tag by going into Phone -> Account -> Unlocked Tags.\n&7Make sure that the '&6Show Game Rank&7' preference is toggled off.")); + break; + } + case MAGMA_CREAM: { + Utils.giveItems(player, Utils.createItem(Material.MAGMA_CREAM, "&c&lDevil's Snowball", 16,"&7Throw at players to cause slowness")); + break; + } + default: { + if(item.getItemMeta().getDisplayName().contains("Clausinator")) {//if it is the clausinator: because some of the lore is generated post + Utils.giveItems(player, GTM.getItemManager().getItem("clausinator").getItem()); + break; + } + ItemMeta im = item.getItemMeta(); + im.setLore(Collections.emptyList()); + item.setItemMeta(im); + Utils.giveItems(player, item); + break; + } + } + ChristmasEvent.removeCandyCanes(player, cost); + player.closeInventory(); + player.sendMessage(Lang.CHRISTMAS.f("&aThe item has been added to your inventory!")); + break; + } + break; + } + + /* + case "sellinvconfirm": { + switch (item.getDurability()) { + case 5: + double cPrice = TrashCanManager.getTotalInvPrice(player); + double price = user.getSellInvConfirmAmt(); + + for(int i = 9; i<36; i++){ + ItemStack is = player.getInventory().getItem(i); + if(is == null || is.getType() == Material.AIR) continue; + GameItem gameItem = GTM.getItemManager().getItem(is); + if(gameItem == null || gameItem.getType() == GameItem.ItemType.DRUG) continue; + if(!gameItem.canSell()) continue; player.getInventory().setItem(i, new ItemStack(Material.AIR)); + } + + player.updateInventory(); + user.addMoney(cPrice); + GTMUtils.updateBoard(player, user); + player.sendMessage(Utils.f(Lang.MONEY_ADD.toString() + cPrice)); + + if(cPrice!=price) { + player.sendMessage(Lang.TRASH_CAN.f("&7The final sale price was different as your inventory changed!")); + } + + user.setSellInvConfirmAmt(0); + player.closeInventory(); + break; + case 14: + user.setSellInvConfirmAmt(0); + player.closeInventory(); + break; + } + return; + }*/ + case "cheatcodes": { + User coreUser = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if(item.getType()==Material.REDSTONE) { + MenuManager.openMenu(player, "contacts"); + return; + } + Optional<CheatCode> optCode = CheatCode.getCheatCodeFromItemStack(item); + if(!optCode.isPresent()) + return; + CheatCodeState cState = user.getCheatCodeState(optCode.get()); + if(cState.getState()==State.LOCKED) { + player.sendMessage(Lang.CHEAT_CODES.f(optCode.get().getLockedLore())); + return; + } + optCode.get().activate(coreUser, user, player, cState); + + if (optCode.get() != CheatCode.QUICKSELL) + MenuManager.openMenu(player, "cheatcodes");//refresh + return; + } + case "drugdealer": { + Optional<DrugItem> drug = ((DrugService) GTM.getDrugManager().getService()).getDrugItem(item.getItemMeta().getDisplayName()); + if (drug.isPresent()) { + List<String> itemLore = item.getItemMeta().getLore(); + int drugStock = Integer.parseInt(ChatColor.stripColor(itemLore.get(0).split(" ")[2])); + int drugPrice = Integer.parseInt(ChatColor.stripColor(itemLore.get(1).split(" ")[1]).replace("$", "")); + if (drugStock > 0) { + net.minecraft.server.v1_12_R1.ItemStack nmsCopy = CraftItemStack.asNMSCopy(item); + NBTTagCompound tag = nmsCopy.hasTag() ? nmsCopy.getTag() : new NBTTagCompound(); + if ((tag != null ? tag.get("drugName") : null) != null) { + DrugItem drugItem = drug.get(); + if (DrugDealerItem.byDrugItem(drugItem).isPresent()) { + if (user.getMoney() >= drugPrice) { + user.setMoney(user.getMoney() - drugPrice); + player.getInventory().addItem(drugItem.getItemStack()); + DrugDealerItem drugDealerItem = DrugDealerItem.byDrugItem(drugItem).get(); + drugDealerItem.setStockRemaining(drugDealerItem.getStockRemaining() - 1); + e.getInv().setItem(e.getSlot(), drugDealerItem.getItemStack()); + player.updateInventory(); + GTMUtils.updateBoard(player, GTM.getUserManager().getLoadedUser(player.getUniqueId())); + } else { + player.sendMessage(Lang.DRUGS.f("&cYou do not have enough money for this drug!")); + } + } else { + player.sendMessage(Lang.DRUGS.f("&cCannot find DrugItem for this drug!")); + } + } else { + player.sendMessage(Lang.DRUGS.f("&cUnable to validate NMS tag on ItemStack")); + } + } + } else { + switch (item.getType()) { + case REDSTONE: + player.closeInventory(); + return; + default: + return; + } + } + return; + } + case "phone": + switch (item.getType()) { + case ENDER_CHEST: + MenuManager.openMenu(player, "cosmetics"); + return; + case LEATHER_CHESTPLATE: + MenuManager.openMenu(player, "mygang"); + return; + case POWERED_MINECART: + MenuManager.openMenu(player, "property"); + return; + case SKULL_ITEM: + MenuManager.openMenu(player, "bounties"); + return; + case NETHER_STAR: + MenuManager.openMenu(player, "account"); + return; + case BOOK: + MenuManager.openMenu(player, "contacts"); + return; + case EMERALD: + player.closeInventory(); + player.sendMessage(Lang.GTM.f("&7Go to &a&l" + Core.getSettings().getStoreLink() + "&7 to buy Ranks, Permits, Money and other packages!")); + return; + case EXP_BOTTLE: + MenuManager.openMenu(player, "rewards"); + return; + case CHEST: + MenuManager.openMenu(player, "kits"); + return; + default: + return; + } + case "cosmetics": + switch (item.getType()) { + case REDSTONE: + MenuManager.openMenu(player, "phone"); + return; + default: + return; + } + case "rewards": + switch (item.getType()) { + case REDSTONE: + MenuManager.openMenu(player, "phone"); + return; + default: + return; + } + case "vote": + switch (item.getType()) { + case REDSTONE: + MenuManager.openMenu(player, "reward"); + return; + default: + return; + } + case "account": + switch (item.getType()) { + case EMPTY_MAP: + MenuManager.openMenu(player, "ranks"); + return; + case NAME_TAG: + MenuManager.openMenu(player, "chooseeventtag"); + return; + case BOOK: + MenuManager.openMenu(player, "gtmstats"); + return; + case REDSTONE_COMPARATOR: + MenuManager.openMenu(player, "prefs"); + return; + case REDSTONE: + MenuManager.openMenu(player, "phone"); + default: + return; + } + case "ranks": + switch (item.getType()) { + case REDSTONE: + MenuManager.openMenu(player, "account"); + return; + case PAPER: + User u = Core.getUserManager().getLoadedUser(uuid); + user.rankup(player, u); + return; + default: + return; + } + case "gtmstats": + switch (item.getType()) { + case REDSTONE: + MenuManager.openMenu(player, "account"); + return; + default: + return; + } + case "bounties": + + if (!GTM.getSettings().isBountySystem()){ + player.sendMessage(Utils.f(Lang.BOUNTIES + "&7Bounty System is currently disabled!")); + return; + } + + switch (item.getType()) { + + case BOOK_AND_QUILL: + MenuManager.openMenu(player, "bountieslist"); + return; + case BOOK: + MenuManager.openMenu(player, "bountieshelp"); + return; + case COMPASS: + if (GTM.getUserManager().getLoadedUser(player.getUniqueId()).getJobMode() != JobMode.HITMAN) { + player.sendMessage(Lang.GPS.f("&7You are not a hitman!")); + return; + } + MenuManager.openMenu(player, "gpsbounties"); + return; + case PAPER: + MenuManager.openMenu(player, "bountiesplace"); + return; + case REDSTONE: + MenuManager.openMenu(player, "phone"); + return; + default: + return; + } + case "bountieslist": + switch (item.getType()) { + case ARROW: + int page = Integer + .parseInt(ChatColor.stripColor(item.getItemMeta().getLore().get(0)).replace("Page ", "")); + BountyManager bm = GTM.getBountyManager(); + this.setPhoneDefaults(inv); + Set<Bounty> bounties = bm.getBountiesByAmount(); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, + 42}; + Iterator<Bounty> it = bounties.iterator(); + for (int i = 0; i < page * 20; i++) { + if (!it.hasNext()) + break; + Bounty b = it.next(); + if (i < (page - 1) * 20) + continue; + List<String> lore = new ArrayList<>(); + lore.add("&7Bounty Total: &a$&l" + b.getAmount()); + lore.add(""); + double anon = 0; + for (BountyPlacer p : b.getPlacers()) + if (p.isAnonymous()) + anon += p.getAmount(); + else + lore.add("&7" + p.getName() + ": &a$&l" + p.getAmount()); + if (anon > 0) + lore.add("&7Anonymous: &a$&l" + anon); + lore.add(""); + lore.add("&7Expires: &a&l" + Utils.timeInMillisToText(b.getTimeUntilExpiryInMillis())); + inv.setItem(slots[i - (page - 1) * 20], Utils.setSkullOwner( + Utils.createItem(Material.SKULL_ITEM, 3, "&5&l" + b.getName(), lore), b.getName())); + } + inv.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the bounties page!")); + if (page > 1) + inv.setItem(48, Utils.createItem(Material.ARROW, "&5&lPrevious Page", "&7Page " + (page - 1))); + inv.setItem(49, Utils.createItem(Material.BOOK, "&5&lBounty List", "&7Page " + page)); + if (bounties.size() > (20 * page)) + inv.setItem(50, Utils.createItem(Material.ARROW, "&5&lNext Page", "&7Page " + (page + 1))); + return; + case REDSTONE: + MenuManager.openMenu(player, "bounties"); + return; + default: + return; + } + case "bountiesplace": { + BountyManager bm = GTM.getBountyManager(); + switch (item.getType()) { + case SKULL_ITEM: + if (item.getDurability() == 1) { + + if (!GTM.getSettings().isBountySystem()){ + player.sendMessage(Utils.f(Lang.BOUNTIES + "&7Bounty System is currently disabled!")); + return; + } + + if (user.getBountyName() == null) { + player.sendMessage(Utils.f(Lang.BOUNTIES + "&7Please choose a target first!")); + return; + } + if (user.getBountyAmount() <= 0) { + player.sendMessage(Utils.f(Lang.BOUNTIES + "&7Please choose an amount first!")); + return; + } + Player target = Bukkit.getPlayer(user.getBountyUUID()); + if (target == null) { + player.sendMessage(Utils.f(Lang.BOUNTIES + "&7Your target is not online!")); + return; + } + + // balance check + if (!user.hasMoney(user.getBountyAmount())) { + player.sendMessage(Utils.f(Lang.MONEY + "&7You don't have &c$&l" + user.getBountyAmount() + + " to place this bounty!")); + return; + } + + // the amount of money placed for the bounty + int bountyAmount = user.getBountyAmount(); + + // take the money from the user that they are placing + user.takeMoney(bountyAmount); + GTMUtils.updateBoard(player, user); + + // determine tax on placing new bounties + double bountyTax = 0; + if (GTM.getSettings().isBountyTax()){ + bountyTax = GTM.getSettings().getBountyTaxPercent(); + + // clamp bounds + if (bountyTax >= 100.0){ + bountyTax = 100.0; + } + if (bountyTax <= 0){ + bountyTax = 0; + } + } + + // how much we subtract from balance + int taxSubtractAmount = (int) ((bountyTax / 100.0) * bountyAmount); + // what's the final placed amount + final int finalBountyAmount = bountyAmount - taxSubtractAmount; + + // TODO test remove + Core.log("[Bounty][DEBUG] Bounty placed on " + target.getName() + " with initial amount of " + bountyAmount + ", tax=" + taxSubtractAmount + ", final=" + finalBountyAmount); + + // if bounty already exists, raise it + if (bm.placeBounty(target, finalBountyAmount, player, true)) { + player.sendMessage(Utils.f(Lang.BOUNTIES + "&7You raised the bounty on &a" + target.getName() + + "&7 by &a$&l" + finalBountyAmount + "&7, as &c$&l" + taxSubtractAmount + "&7 was for tax purposes.")); + Utils.broadcastExcept(player, Lang.BOUNTIES + "&7An anonymous player raised the bounty on &a" + + target.getName() + "&7 by &a$&l" + finalBountyAmount + "&7."); + user.setBountyAmount(0); + user.setBountyName(null); + user.setBountyUUID(null); + MenuManager.openMenu(player, "bounties"); + return; + } + + // otherwise add a new one + player.sendMessage(Utils.f(Lang.BOUNTIES + "&7You put a bounty of &a&l$" + finalBountyAmount + + "&7 on &a" + target.getName() + "&7's head!")); + player.sendMessage(Utils.f(Lang.BOUNTIES + "&7Tax for placing the new bounty was &c&l$" + taxSubtractAmount + "&7.")); + Utils.broadcastExcept(player, Lang.BOUNTIES + "&7An anonymous player put a bounty of &a$&l" + + finalBountyAmount + "&7 on &a" + target.getName() + "&7."); + user.setBountyAmount(0); + user.setBountyName(null); + user.setBountyUUID(null); + MenuManager.openMenu(player, "bounties"); + return; + } else { + user.setCurrentChatAction(ChatAction.PICKING_BOUNTY_TARGET, 0); + player.closeInventory(); + player.sendMessage(Utils.f(Lang.BOUNTIES + "&7Type the target in chat, or \"quit\" to cancel.")); + return; + } + case PAPER: + user.setCurrentChatAction(ChatAction.PICKING_BOUNTY, 0); + player.closeInventory(); + player.sendMessage(Utils.f(Lang.BOUNTIES + + "&7Please type the amount in chat, or type \"quit\" to cancel. The minimum bounty is &a$&l2.000&7!")); + return; + case REDSTONE: + MenuManager.openMenu(player, "phone"); + return; + case SLIME_BALL: + + if (!GTM.getSettings().isBountySystem()){ + player.sendMessage(Utils.f(Lang.BOUNTIES + "&7Bounty System is currently disabled!")); + return; + } + + if (user.getBountyName() == null) { + player.sendMessage(Utils.f(Lang.BOUNTIES + "&7Please choose a target first!")); + return; + } + if (user.getBountyAmount() <= 0) { + player.sendMessage(Utils.f(Lang.BOUNTIES + "&7Please choose an amount first!")); + return; + } + Player target = Bukkit.getPlayer(user.getBountyUUID()); + if (target == null) { + player.sendMessage(Utils.f(Lang.BOUNTIES + "&7Your target is not online!")); + return; + } + + // balance check + if (!user.hasMoney(user.getBountyAmount())) { + player.sendMessage(Utils.f(Lang.MONEY + "&7You don't have &c$&l" + user.getBountyAmount() + " to place this bounty!")); + return; + } + + // the amount of money placed for the bounty + int bountyAmount = user.getBountyAmount(); + + // take the money from the user that they are placing + user.takeMoney(bountyAmount); + GTMUtils.updateBoard(player, user); + + // determine tax on placing new bounties + double bountyTax = 0; + if (GTM.getSettings().isBountyTax()){ + bountyTax = GTM.getSettings().getBountyTaxPercent(); + + // clamp bounds + if (bountyTax >= 100.0){ + bountyTax = 100.0; + } + if (bountyTax <= 0){ + bountyTax = 0; + } + } + + // how much we subtract from balance + int taxSubtractAmount = (int) ((bountyTax / 100.0) * bountyAmount); + // what's the final placed amount + final int finalBountyAmount = bountyAmount - taxSubtractAmount; + + // TODO test remove + Core.log("[Bounty][DEBUG] Bounty placed on " + target.getName() + " with initial amount of " + bountyAmount + ", tax=" + taxSubtractAmount + ", final=" + finalBountyAmount); + + // if bounty already exists, raise it + if (bm.placeBounty(target, finalBountyAmount, player, true)) { + player.sendMessage(Utils.f(Lang.BOUNTIES + "&7You raised the bounty on &a" + target.getName() + + "&7 by &a$&l" + finalBountyAmount + "&7, as &c$&l" + taxSubtractAmount + "&7 was for tax purposes.")); + Utils.broadcastExcept(player, Lang.BOUNTIES + "&7An anonymous player raised the bounty on &a" + + target.getName() + "&7 by &a$&l" + finalBountyAmount + "&7."); + user.setBountyAmount(0); + user.setBountyName(null); + user.setBountyUUID(null); + MenuManager.openMenu(player, "bounties"); + return; + } + + // otherwise add a new one + player.sendMessage(Utils.f(Lang.BOUNTIES + "&7You put a bounty of &a&l$" + finalBountyAmount + + "&7 on &a" + target.getName() + "&7's head!")); + player.sendMessage(Utils.f(Lang.BOUNTIES + "&7Tax for placing the new bounty was &c&l$" + taxSubtractAmount + "&7.")); + Utils.broadcastExcept(player, Lang.BOUNTIES + "&7An anonymous player put a bounty of &a$&l" + + finalBountyAmount + "&7 on &a" + target.getName() + "&7."); + user.setBountyAmount(0); + user.setBountyName(null); + user.setBountyUUID(null); + MenuManager.openMenu(player, "bounties"); + return; + default: + return; + } + } + case "bountieshelp": + switch (item.getType()) { + case REDSTONE: + MenuManager.openMenu(player, "bounties"); + return; + default: + return; + } + case "kits": + switch (item.getType()) { + case REDSTONE: + MenuManager.openMenu(player, "phone"); + return; + default: + + if (!GTM.getSettings().isKitSystem()){ + player.sendMessage(ChatColor.RED + "Kits are currently disabled!"); + return; + } + + if (item.hasItemMeta() && item.getItemMeta().hasDisplayName() + && item.getType() != Material.STAINED_GLASS_PANE) { + GTM.getItemManager().giveKit(player, Core.getUserManager().getLoadedUser(uuid), + GTM.getUserManager().getLoadedUser(uuid), + ChatColor.stripColor(item.getItemMeta().getDisplayName())); + MenuManager.updateMenu(player, "kits"); + } + return; + } + case "contacts": { + switch (item.getType()) { + case STORAGE_MINECART: + MenuManager.openMenu(player, "taxi"); + return; + case ANVIL: + MenuManager.openMenu(player, "cheatcodes"); + return; + case SKULL_ITEM: + if (user.hasRequestedBackup()) { + player.sendMessage(Lang.COP_MODE.f("&7You have already called " + (user.getJobMode() == JobMode.COP ? "for backup" : "the police") + "! Please wait &c&l" + Utils.timeInSecondsToText(Math.round(user.getTimeUntilBackupRequestExpires()/1000.0), "&3", "&7", "&7")+ "&7 to request backup again!")); + return; + } + if (user.getJobMode() == JobMode.COP) + player.sendMessage(Lang.COP_MODE.f("&7You have called for backup! All officers have been notified, and they can teleport to you for 1 minute!")); + else { + if (user.getWantedLevel() > 0) { + player.sendMessage(Lang.WANTED.f("&7You are currently wanted by the police! It would be unwise to tip off your location.")); + return; + } + player.sendMessage(Lang.GTM.f("&7You have called the police! All officers have been notified, and they can teleport to you for 1 minute!")); + } + user.setLastBackupRequest(System.currentTimeMillis()); + for (GTMUser u : GTMUtils.getCops()) { + Player p = Bukkit.getPlayer(u.getUUID()); + if (!Objects.equals(player, p)) + p.spigot().sendMessage(new ComponentBuilder(Lang.COP_MODE.f((user.getJobMode() == JobMode.COP ? "&3&lCop " : "&7Citizen") + Core.getUserManager().getLoadedUser(p.getUniqueId()).getColoredName(p))).append(" is requesting " + (user.getJobMode() == JobMode.COP ? "backup" : "police assistance") + "! Teleport: ").color(net.md_5.bungee.api.ChatColor.GRAY). + append(" [ACCEPT] ").color(net.md_5.bungee.api.ChatColor.GREEN).bold(true).event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/backup " + player.getName())).create()); + + } + return; + case WOOD_SWORD: + player.closeInventory(); + BaseComponent[] baseComponents = + new ComponentBuilder(Lang.GTM.f("&7Do you wish to commit suicide?")) + //.color(net.md_5.bungee.api.ChatColor.GRAY) + .append(" Click here for Yes") + .color(net.md_5.bungee.api.ChatColor.GREEN) + .event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/suicide")) + .create(); + player.spigot().sendMessage(baseComponents); + return; + case REDSTONE: + MenuManager.openMenu(player, "phone"); + return; + case WATCH: + GTM.getWarpManager().warp(player, Core.getUserManager().getLoadedUser(uuid), GTM.getUserManager().getLoadedUser(uuid), new TaxiTarget(GTM.getWarpManager().getSpawn()), 0, -1); + return; + default: + return; + } + } + case "taxi": + switch (e.getItem().getType()) { + case SKULL_ITEM: + MenuManager.openMenu(player, "taxiplayers"); + return; + case BED: + GTM.getWarpManager().warp(player, Core.getUserManager().getLoadedUser(uuid), + GTM.getUserManager().getLoadedUser(uuid), new TaxiTarget(GTM.getWarpManager().getSpawn()), 0, + -1); + player.closeInventory(); + return; + case EMERALD: + GTM.getWarpManager().warp(player, Core.getUserManager().getLoadedUser(player.getUniqueId()), user, new TaxiTarget(GTM.getWarpManager().getRandomWarp()), 0, Core.getUserManager().getLoadedUser(player.getUniqueId()).isPremium() ? 1 : 10); + return; + case IRON_DOOR: + MenuManager.openMenu(player, "taxihouses"); + return; + case REDSTONE: + MenuManager.openMenu(player, "contacts"); + return; + case ENDER_PEARL: + MenuManager.openMenu(player, "taxiwarps"); + return; + default: + return; + } + case "taxiplayers": + switch (item.getType()) { + case ARROW: + int page = Integer + .parseInt(ChatColor.stripColor(item.getItemMeta().getLore().get(0)).replace("Page ", "")); + this.setPhoneDefaults(inv); + User u = Core.getUserManager().getLoadedUser(uuid); + List<Player> players = new ArrayList<>(Bukkit.getOnlinePlayers()); + players.remove(player); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, + 42}; + Iterator<? extends Player> it = players.iterator(); + for (int i = 0; i < page * 20; i++) { + if (!it.hasNext()) + break; + Player p = it.next(); + if (i < (page - 1) * 20) + continue; + + inv.setItem(slots[i - (page - 1) * 20], Utils.setSkullOwner( + Utils.createItem(Material.SKULL_ITEM, 3, "&e&l" + p.getName(), + u.isPremium() ? "&7Click to send teleport request!" : "&cRequires PREMIUM!"), + p.getName())); + } + inv.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the taxi page!")); + if (page > 1) + inv.setItem(48, Utils.createItem(Material.ARROW, "&e&lPrevious Page", "&7Page " + (page - 1))); + inv.setItem(49, + Utils.createItem(Material.STORAGE_MINECART, "&e&lTaxi Service: Players", "&7Page " + page)); + if (players.size() > (20 * page)) + inv.setItem(50, Utils.createItem(Material.ARROW, "&e&lNext Page", "&7Page " + (page + 1))); + return; + case SKULL_ITEM: + Player target = Bukkit.getPlayer(ChatColor.stripColor(item.getItemMeta().getDisplayName())); + player.closeInventory(); + GTM.getWarpManager().tpa(player, Core.getUserManager().getLoadedUser(uuid), + GTM.getUserManager().getLoadedUser(uuid), target); + return; + case REDSTONE: + MenuManager.openMenu(player, "taxi"); + return; + default: + return; + } + case "taxihouses": + switch (item.getType()) { + case REDSTONE: + MenuManager.openMenu(player, "taxi"); + return; + case IRON_DOOR: + String s = ChatColor.stripColor(item.getItemMeta().getDisplayName()); + if (Objects.equals("Find House", s)) + return; + if (s.startsWith("Premium House: ")) { + int id; + try { + id = Integer.parseInt(s.replace("Premium House: ", "")); + } catch (NumberFormatException ex) { + player.sendMessage(Utils.f(Lang.HOUSES + "&7That House ID is invalid!")); + return; + } + PremiumHouse premiumHouse = Houses.getHousesManager().getPremiumHouse(id); + if (premiumHouse == null) { + player.sendMessage(Lang.HOUSES.f("&7That house does not exist!")); + return; + } + PremiumHouseDoor door = premiumHouse.getDoor(); + if (door == null || door.getOutsideLocation() == null) { + player.sendMessage(Lang.HOUSES.f("&7That house does not have any doors!")); + return; + } + Location tpLocation = door.getOutsideLocation(); + player.closeInventory(); + GTM.getWarpManager().warp(player, Core.getUserManager().getLoadedUser(uuid), + GTM.getUserManager().getLoadedUser(uuid), new TaxiTarget(tpLocation), 500, -1); + return; + } else if (s.startsWith("House: ")) { + int id; + try { + id = Integer.parseInt(s.replace("House: ", "")); + } catch (NumberFormatException ex) { + player.sendMessage(Utils.f(Lang.HOUSES + "&7That House ID is invalid!")); + return; + } + House house = Houses.getHousesManager().getHouse(id); + if (house == null) { + player.sendMessage(Lang.HOUSES.f("&7That house does not exist!")); + return; + } + HouseDoor door = house.getDoor(); + if (door == null || door.getOutsideLocation() == null) { + player.sendMessage(Lang.HOUSES.f("&7That house does not have any doors!")); + return; + } + Location tpLocation = door.getOutsideLocation(); + player.closeInventory(); + GTM.getWarpManager().warp(player, Core.getUserManager().getLoadedUser(uuid), + GTM.getUserManager().getLoadedUser(uuid), new TaxiTarget(tpLocation), 500, -1); + return; + } + return; + case ARROW: + int page = Integer + .parseInt(ChatColor.stripColor(item.getItemMeta().getLore().get(0)).replace("Page ", "")); + this.setPhoneDefaults(inv); + int[] slots = new int[]{10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, + 33, 34, 37, 38, 39, 40, 41, 42, 43}; + GTMUser gtmUser = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + HouseUser houseUser = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + List<UserHouse> houses = houseUser.getHouses(); + List<PremiumHouse> premiumHouses = houseUser.getPremiumHousesAsGuest(); + Iterator<UserHouse> it = houses.iterator(); + Iterator<PremiumHouse> it2 = premiumHouses.iterator(); + for (int i = 0; i < page * 20; i++) { + PremiumHouse premiumHouse = it.hasNext() ? null : it2.hasNext() ? it2.next() : null; + UserHouse userHouse = it.hasNext() ? it.next() : null; + if (i < (page - 1) * 20) + continue; + if (premiumHouse == null && userHouse == null) + break; + if (premiumHouse != null) { + inv.setItem(slots[i - (page - 1) * 20], Utils.addGlow(Utils.createItem(Material.IRON_DOOR, + "&3&lPremium House: &a&l" + premiumHouse.getId(), + Arrays.asList("Permits: &a&l" + premiumHouse.getPermits(), + "&7Chests: &a&l" + premiumHouse.getChests().size(), + "&7Owned by &a" + (Objects.equals(player.getUniqueId(), premiumHouse.getOwner()) ? "me" + : premiumHouse.getOwnerName()) + '.', + gtmUser.hasMoney(500) ? "&7Click to teleport for &a$&l500&7!" : "&cYou can't afford &c$&l500&c to pay for the ride!")))); + continue; + } + + House house = Houses.getHousesManager().getHouse(userHouse.getId()); + inv.setItem(slots[i - (page - 1) * 20], + Utils.createItem(Material.IRON_DOOR, "&3&lHouse: &a&l" + house.getId(), + Arrays.asList("&7Price: &$a&l" + house.getPrice(), + "&7Chests: &a&l" + house.getChests().size(), + "&7Click to teleport for &a$&l500&7!"))); + } + inv.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the taxi page!")); + if (page > 1) + inv.setItem(48, Utils.createItem(Material.ARROW, "&e&lPrevious Page", "&7Page " + (page - 1))); + inv.setItem(49, + Utils.createItem(Material.STORAGE_MINECART, "&e&lTaxi Service: &3&lHouses", "&7Page " + page)); + if (houses.size() > (20 * page)) + inv.setItem(50, Utils.createItem(Material.ARROW, "&e&lNext Page", "&7Page " + (page + 1))); + return; + default: + return; + + } + case "taxiwarps": + switch (item.getType()) { + case ARROW: + int page = Integer + .parseInt(ChatColor.stripColor(item.getItemMeta().getLore().get(0)).replace("Page ", "")); + this.setPhoneDefaults(inv); + GTMUser gtmUser = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + List<Warp> warps = GTM.getWarpManager().getWarps(); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, + 42}; + Iterator<Warp> it = warps.iterator(); + for (int i = 0; i < page * 20; i++) { + if (!it.hasNext()) + break; + Warp warp = it.next(); + if (i < (page - 1) * 20) + continue; + inv.setItem(slots[i - (page - 1) * 20], Utils.createItem(Material.ENDER_PEARL, + "&e&l" + warp.getName(), "&7Click to teleport for &a$&l200&7!")); + } + inv.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the taxi page!")); + if (page > 1) + inv.setItem(48, Utils.createItem(Material.ARROW, "&e&lPrevious Page", "&7Page " + (page - 1))); + inv.setItem(49, + Utils.createItem(Material.STORAGE_MINECART, "&e&lTaxi Service: Warps", "&7Page " + page)); + if (warps.size() > (20 * page)) + inv.setItem(50, Utils.createItem(Material.ARROW, "&e&lNext Page", "&7Page " + (page + 1))); + return; + case ENDER_PEARL: + Warp warp = GTM.getWarpManager().getWarp(ChatColor.stripColor(item.getItemMeta().getDisplayName())); + if (warp == null) { + player.sendMessage(Lang.TAXI.f("&7That warp does not exist!")); + return; + } + player.closeInventory(); + GTM.getWarpManager().warp(player, Core.getUserManager().getLoadedUser(uuid), + GTM.getUserManager().getLoadedUser(uuid), new TaxiTarget(warp), 200, -1); + return; + case REDSTONE: + MenuManager.openMenu(player, "taxi"); + return; + default: + return; + } + case "bank": + switch (e.getItem().getType()) { + case INK_SACK: + MenuManager.openMenu(player, menu.getName() + "withdraw"); + return; + case SLIME_BALL: + MenuManager.openMenu(player, menu.getName() + "deposit"); + return; + case SKULL_ITEM: + MenuManager.openMenu(player, menu.getName() + "transfer"); + return; + case REDSTONE: + MenuManager.openMenu(player, "property"); + return; + default: + return; + } + case "bankwithdraw": { + switch (item.getType()) { + case PAPER: + double amnt = Double.parseDouble(ChatColor.stripColor(item.getItemMeta().getDisplayName()) + .replace("$", "").replace("All: ", "").replace("Half: ", "")); + if (!user.hasBank(amnt)) { + player.sendMessage(Lang.BANK.f("&7You don't have &c$&l" + amnt + " &cin your bank account!")); + return; + } + user.withdrawFromBank(amnt); + GTMUtils.updateBoard(player, user); + player.sendMessage(Lang.BANK.f("&7You withdrew &a$&l" + amnt + "&7 from your bank account!")); + player.closeInventory(); + return; + case BOOK_AND_QUILL: + user.setCurrentChatAction(ChatAction.BANK_WITHDRAWING, 0); + player.closeInventory(); + player.sendMessage(Utils.f(Lang.BANK + + "&7Please type the amount you would like to withdraw in chat, or type&a \"quit\"&7!")); + return; + case REDSTONE: + MenuManager.openMenu(player, "bank"); + return; + default: + return; + + } + } + case "bankdeposit": { + switch (item.getType()) { + case PAPER: + double amnt = Double.parseDouble(ChatColor.stripColor(item.getItemMeta().getDisplayName()).replace("$", "").replace("All: ", "").replace("Half: ", "")); + if (!user.hasMoney(amnt)) { + player.sendMessage(Lang.BANK.f("&7You don't have &c$&l" + amnt + " &con you!")); + return; + } + if(amnt < 100) { + player.sendMessage(Lang.BANK.f("&c&lYou must deposit at least $100!")); + return; + } + user.depositToBank(amnt); + GTMUtils.updateBoard(player, user); + player.sendMessage(Lang.BANK.f("&7You deposited &a$&l" + amnt + "&7 into your bank account!")); + player.closeInventory(); + return; + case BOOK_AND_QUILL: + user.setCurrentChatAction(ChatAction.BANK_DEPOSITING, 0); + player.closeInventory(); + player.sendMessage(Utils.f(Lang.BANK + + "&7Please type the amount you would like to deposit in chat, or type&a \"quit\"&7!")); + return; + case REDSTONE: + MenuManager.openMenu(player, "bank"); + return; + default: + return; + + } + } + case "banktransfer": { + switch (item.getType()) { + case PAPER: + double amnt = Double.parseDouble(ChatColor.stripColor(item.getItemMeta().getDisplayName()) + .replace("$", "").replace("All: ", "").replace("Half: ", "")); + if (!user.hasBank(amnt)) { + player.sendMessage(Lang.BANK.f("&7You don't have &c$&l" + amnt + " &con you!")); + return; + } + + if (!GTM.getSettings().isBankToBankTransfer()){ + player.sendMessage(Lang.BANK.f("&cBank to bank transferring is currently disabled!")); + return; + } + + user.setCurrentChatAction(ChatAction.BANK_TRANSFERRING, amnt); + player.closeInventory(); + player.sendMessage(Lang.BANK.f("&7Please type the name of the player you would like to transfer &a$&l" + + amnt + "&7 to, or type&a \"quit\"&7!")); + return; + case BOOK_AND_QUILL: + user.setCurrentChatAction(ChatAction.BANK_TRANSFERRING, 0); + player.closeInventory(); + player.sendMessage(Lang.BANK + .f("&7Please type the amount you would like to deposit in chat, or type &a\"quit\"&7!")); + return; + case REDSTONE: + MenuManager.openMenu(player, "bank"); + return; + default: + return; + + } + } + case "gps": + switch (item.getType()) { + case LEATHER_CHESTPLATE: { + Gang gang = GangManager.getInstance().getGangByMember(uuid).orElse(null); + if (gang == null) { + player.sendMessage(Utils.f(Lang.GPS + "&7You are not in any gang!")); + return; + } + + MenuManager.openMenu(player, "gpsgangs"); + return; + } + case IRON_DOOR: { + HouseUser houseUser = Houses.getUserManager().getLoadedUser(uuid); + if (houseUser.getHouses().isEmpty() && houseUser.getPremiumHousesAsGuest().isEmpty()) { + player.sendMessage(Utils.f(Lang.GPS + "&7You do not own any houses!")); + return; + } + MenuManager.openMenu(player, "gpshouses"); + + return; + } + case LEATHER_HELMET: { + if (user.getJobMode() != JobMode.COP) { + player.sendMessage(Utils.f(Lang.GPS + "&7You are not a cop!")); + return; + } + MenuManager.openMenu(player, "gpscops"); + return; + } + case REDSTONE: { + user.unsetCompassTarget(player, Core.getUserManager().getLoadedUser(uuid)); + player.sendMessage(Utils.f(Lang.GPS + "&7Your GPS target was unset.")); + return; + } + case SKULL_ITEM: { + if (item.getDurability() == 3) { + if (user.getJobMode() != JobMode.COP) { + player.sendMessage(Utils.f(Lang.GPS + "&7You are not a cop!")); + return; + } + MenuManager.openMenu(player, "gpscriminals"); + return; + } + if (user.getJobMode() != JobMode.HITMAN) { + player.sendMessage(Utils.f(Lang.GPS + "&7You are not a hitman!")); + return; + } + MenuManager.openMenu(player, "gpsbounties"); + return; + } + case COMPASS: { + if (!user.hasCompassTarget()) + return; + if (user.getLastCompassRefresh() > System.currentTimeMillis() - 5000) { + player.sendMessage(Utils.f(Lang.GPS + "&7Please wait 5 seconds before refreshing the tracker!")); + return; + } + if (user.refreshCompassTarget(player, Core.getUserManager().getLoadedUser(uuid))){ + player.sendMessage(Utils.f(Lang.GPS + "&7You refreshed your GPS tracker! It will refresh every 60 seconds!")); + } + return; + } + default: + PersonalVehicle vehicle = user.getPersonalVehicle(); + if (vehicle == null) return; + if (!item.hasItemMeta() || !item.getItemMeta().hasDisplayName() || !Objects.equals(item.getItemMeta().getDisplayName(), vehicle.getDisplayName())) + return; + if (!vehicle.onMap()) { + player.sendMessage(Lang.GPS.f("&7Your vehicle is not on the map!")); + return; + } + if (vehicle.isDestroyed()) { + player.sendMessage(Lang.GPS.f("&7Your vehicle is destroyed!")); + return; + } + user.setCompassTarget(player, Core.getUserManager().getLoadedUser(uuid), new CompassTarget(vehicle)); + player.sendMessage(Lang.GPS.f("&7Your GPS is now tracking your " + (vehicle.isStolen() ? "stolen " : "") + + vehicle.getDisplayName() + "&7!")); + return; + } + case "gpsgangs": + switch (item.getType()) { + case REDSTONE: + MenuManager.openMenu(player, "gps"); + return; + case SKULL_ITEM: { + String s = ChatColor.stripColor(item.getItemMeta().getDisplayName()); + Player p = Bukkit.getPlayer(s); + if (p == null) { + player.sendMessage(Utils.f(Lang.GPS + "&7That player is not online!")); + return; + } + + Gang gang = GangManager.getInstance().getGangByMember(uuid).orElse(null); + Gang targetGang = GangManager.getInstance().getGangByMember(p.getUniqueId()).orElse(null); + + if (gang == null || targetGang == null || !Objects.equals(gang, targetGang)) { + player.sendMessage(Utils.f(Lang.GPS + "&7That player is not in your gang!")); + return; + } + + player.closeInventory(); + user.setCompassTarget(player, Core.getUserManager().getLoadedUser(uuid), new CompassTarget(p)); + player.sendMessage(Utils.f(Lang.GPS + "&7Your GPS is now tracking " + Core.getUserManager().getLoadedUser(uuid).getColoredName(p) + "&7!")); + return; + } + case ARROW: + int page = Integer + .parseInt(ChatColor.stripColor(item.getItemMeta().getLore().get(0)).replace("Page ", "")); + this.setGPSDefaults(inv); + Gang gang = GangManager.getInstance().getGangByMember(uuid).orElse(null); + List<String> members = new ArrayList<>(); + if (gang != null) { + members.addAll(gang.getMembers().stream().filter(member -> !member.getUniqueId().equals(player.getUniqueId()) && Bukkit.getPlayer(member.getUniqueId()) != null).map(GangMember::getName).collect(Collectors.toList())); + } + + members.remove(player.getName()); + int[] slots = new int[]{10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, 33, 34, 37, 38, 39, 40, 41, 42, 43}; + Iterator<String> it = members.iterator(); + for (int i = 0; i < (page * 28); i++) { + if (!it.hasNext()) break; + String member = it.next(); + if (i < (page - 1) * 28) continue; + + inv.setItem(slots[i - (page - 1) * 28], Utils.setSkullOwner(Utils.createItem(Material.SKULL_ITEM, 3, "&a&l" + member, "&7Click to track your homie!"), member)); + } + inv.setItem(46, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the home page!")); + if (page > 1) inv.setItem(48, Utils.createItem(Material.ARROW, "&b&lPrevious Page", "&7Page " + (page - 1))); + inv.setItem(49, Utils.setArmorColor(Utils.createItem(Material.LEATHER_CHESTPLATE, "&a&lTrack Gang Member", "&7Click on a gang member to select them!"), Color.fromRGB(102, 127, 51))); + if (members.size() > (28 * page)) inv.setItem(50, Utils.createItem(Material.ARROW, "&b&lNext Page", "&7Page " + (page + 1))); + return; + default: + return; + } + case "gpshouses": + switch (item.getType()) { + case REDSTONE: + MenuManager.openMenu(player, "gps"); + return; + case IRON_DOOR: + String s = ChatColor.stripColor(item.getItemMeta().getDisplayName()); + if (Objects.equals("Find House", s)) + return; + if (s.startsWith("Premium House: ")) { + int id; + try { + id = Integer.parseInt(s.replace("Premium House: ", "")); + } catch (NumberFormatException e1) { + player.sendMessage(Utils.f(Lang.GPS + "&7That House ID is invalid!")); + return; + } + PremiumHouse house = Houses.getHousesManager().getPremiumHouse(id); + user.setCompassTarget(player, Core.getUserManager().getLoadedUser(player.getUniqueId()), new CompassTarget(house.getDoor().getLocation())); + player.sendMessage( + Utils.f(Lang.GPS + "&7You set your GPS target to &3&lPremium House &a&l" + id + "&7!")); + } else if (s.startsWith("House: ")) { + int id; + try { + id = Integer.parseInt(s.replace("House: ", "")); + } catch (NumberFormatException ex) { + player.sendMessage(Utils.f(Lang.GPS + "&7That House ID is invalid!")); + return; + } + House house = Houses.getHousesManager().getHouse(id); + user.setCompassTarget(player, Core.getUserManager().getLoadedUser(player.getUniqueId()), new CompassTarget(house.getDoor().getLocation())); + player.sendMessage(Utils.f(Lang.GPS + "&7You set your GPS target to &3&lHouse &a&l" + id + "&7!")); + return; + } + return; + case ARROW: + int page = Integer + .parseInt(ChatColor.stripColor(item.getItemMeta().getLore().get(0)).replace("Page ", "")); + this.setGPSDefaults(inv); + int[] slots = new int[]{10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, + 33, 34, 37, 38, 39, 40, 41, 42, 43}; + HouseUser houseUser = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + List<UserHouse> houses = houseUser.getHouses(); + List<PremiumHouse> premiumHouses = houseUser.getPremiumHousesAsGuest(); + Iterator<UserHouse> it = houses.iterator(); + Iterator<PremiumHouse> it2 = premiumHouses.iterator(); + for (int i = 0; i < (page * 28); i++) { + PremiumHouse premiumHouse = it.hasNext() ? null : it2.hasNext() ? it2.next() : null; + UserHouse userHouse = it.hasNext() ? it.next() : null; + if (i < (page - 1) * 28) + continue; + if (premiumHouse == null && userHouse == null) + break; + if (premiumHouse != null) { + inv.setItem(slots[i - (page - 1) * 20], Utils.addGlow(Utils.createItem(Material.IRON_DOOR, + "&3&lPremium House: &a&l" + premiumHouse.getId(), + Arrays.asList("Permits: " + premiumHouse.getPermits(), + "&7Chests: " + premiumHouse.getChests().size(), + "&7Owned by " + (Objects.equals(player.getUniqueId(), premiumHouse.getOwner()) ? "me" + : premiumHouse.getOwnerName()) + '.', + "&7Click to track!")))); + continue; + } + House house = Houses.getHousesManager().getHouse(userHouse.getId()); + inv.setItem(slots[i - (page - 1) * 28], + Utils.createItem(Material.IRON_DOOR, "&3&lHouse: &a&l" + house.getId(), + Arrays.asList("&7Price: " + house.getPrice(), + "&7Chests: " + house.getChests().size(), "&7Click to track!"))); + } + inv.setItem(46, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the home page!")); + if (page > 1) + inv.setItem(48, Utils.createItem(Material.ARROW, "&b&lPrevious Page", "&7Page " + (page - 1))); + inv.setItem(49, Utils.setArmorColor( + Utils.createItem(Material.IRON_DOOR, "&3&lFind House", "&7Click on a house to select it!"), + Color.fromRGB(102, 127, 51))); + if ((houses.size() + premiumHouses.size()) > (28 * page)) + inv.setItem(50, Utils.createItem(Material.ARROW, "&a&lNext Page", "&7Page 2")); + return; + default: + return; + + } + case "gpscops": + switch (item.getType()) { + case REDSTONE: + MenuManager.openMenu(player, "gps"); + return; + case SKULL_ITEM: { + if (user.getJobMode() != JobMode.COP) { + player.sendMessage(Lang.GPS.f("&7You are not a cop!")); + MenuManager.openMenu(player, "gps"); + return; + } + Player p = Bukkit.getPlayer(ChatColor.stripColor(item.getItemMeta().getDisplayName())); + if (p == null) { + player.sendMessage(Utils.f(Lang.GPS + "&7That player is not online!")); + return; + } + GTMUser u = GTM.getUserManager().getLoadedUser(p.getUniqueId()); + if (u.getJobMode() != JobMode.COP) { + player.sendMessage(Utils.f(Lang.GPS + "&7That player is not a cop!")); + return; + } + + user.setCompassTarget(player, Core.getUserManager().getLoadedUser(uuid), new CompassTarget(player)); + player.sendMessage(Utils.f(Lang.GPS + "&7Your GPS is now tracking " + + Core.getUserManager().getLoadedUser(p.getUniqueId()).getColoredName(p) + "&7!")); + return; + } + case ARROW: + if (user.getJobMode() != JobMode.COP) { + player.sendMessage(Lang.GPS.f("&7You are not a cop!")); + MenuManager.openMenu(player, "gps"); + return; + } + int page = Integer + .parseInt(ChatColor.stripColor(item.getItemMeta().getLore().get(0)).replace("Page ", "")); + this.setGPSDefaults(inv); + List<GTMUser> cops = GTMUtils.getCops(); + cops.remove(GTM.getUserManager().getLoadedUser(uuid)); + int[] slots = new int[]{10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, + 33, 34, 37, 38, 39, 40, 41, 42, 43}; + Iterator<GTMUser> it = cops.iterator(); + for (int i = 0; i < (page * 28); i++) { + if (!it.hasNext()) + break; + GTMUser u = it.next(); + if (i < (page - 1) * 28) + continue; + Player p = Bukkit.getPlayer(u.getUUID()); + inv.setItem(slots[i - (page - 1) * 28], Utils.setSkullOwner(Utils.createItem(Material.SKULL_ITEM, 3, + "&b&l" + p.getName(), "&7Click to track your colleague!"), p.getName())); + } + inv.setItem(46, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the home page!")); + if (page > 1) + inv.setItem(48, Utils.createItem(Material.ARROW, "&b&lPrevious Page", "&7Page " + (page - 1))); + inv.setItem(49, Utils.setArmorColor( + Utils.createItem(Material.LEATHER_HELMET, "&b&lAssist Cop", "&7Click on a cop to select them!"), + Color.fromRGB(102, 127, 51))); + if (cops.size() > (28 * page)) + inv.setItem(50, Utils.createItem(Material.ARROW, "&b&lNext Page", "&7Page " + (page + 1))); + return; + default: + return; + } + case "gpscriminals": + switch (item.getType()) { + case REDSTONE: + MenuManager.openMenu(player, "gps"); + return; + case SKULL_ITEM: { + if (user.getJobMode() != JobMode.COP) { + player.sendMessage(Lang.GPS.f("&7You are not a cop!")); + MenuManager.openMenu(player, "gps"); + return; + } + Player p = Bukkit.getPlayer(ChatColor.stripColor(item.getItemMeta().getDisplayName())); + if (p == null) { + player.sendMessage(Utils.f(Lang.GPS + "&7That player is not online!")); + return; + } + GTMUser u = GTM.getUserManager().getLoadedUser(p.getUniqueId()); + if (u.getJobMode() != JobMode.CRIMINAL) { + player.sendMessage(Utils.f(Lang.GPS + "&7That player is not a criminal!")); + return; + } + user.setCompassTarget(player, Core.getUserManager().getLoadedUser(uuid), new CompassTarget(player)); + player.sendMessage(Utils.f(Lang.GPS + "&7Your GPS is now tracking " + + Core.getUserManager().getLoadedUser(p.getUniqueId()).getColoredName(p) + "&7!")); + return; + } + case ARROW: + if (user.getJobMode() != JobMode.COP) { + player.sendMessage(Lang.GPS.f("&7You are not a cop!")); + MenuManager.openMenu(player, "gps"); + return; + } + int page = Integer + .parseInt(ChatColor.stripColor(item.getItemMeta().getLore().get(0)).replace("Page ", "")); + this.setGPSDefaults(inv); + Set<GTMUser> criminals = GTMUtils.getCriminalsByWantedLevel(2); + criminals.remove(GTM.getUserManager().getLoadedUser(uuid)); + Iterator<GTMUser> it = criminals.iterator(); + int[] slots = new int[]{10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, + 33, 34, 37, 38, 39, 40, 41, 42, 43}; + for (int i = 0; i < (page * 28); i++) { + if (!it.hasNext()) + break; + GTMUser u = it.next(); + if (i < (page - 1) * 28) + continue; + Player p = Bukkit.getPlayer(u.getUUID()); + inv.setItem(slots[i - (page - 1) * 28], Utils.setSkullOwner(Utils.createItem(Material.SKULL_ITEM, 3, + "&b&l" + p.getName(), "&7Click to track this criminal!"), p.getName())); + } + inv.setItem(46, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the home page!")); + if (page > 1) + inv.setItem(48, Utils.createItem(Material.ARROW, "&e&lPrevious Page", "&7Page " + (page - 1))); + inv.setItem(49, Utils.createItem(Material.COMPASS, "&e&lTrack Wanted Criminal", + "&7Click on a criminal to select them!")); + if (criminals.size() > (28 * page)) + inv.setItem(50, Utils.createItem(Material.ARROW, "&e&lNext Page", "&7Page " + (page + 1))); + return; + default: + return; + } + case "gpsbounties": + switch (item.getType()) { + case REDSTONE: + MenuManager.openMenu(player, "gps"); + return; + case SKULL_ITEM: { + if (user.getJobMode() != JobMode.HITMAN) { + player.sendMessage(Lang.GPS.f("&7You are not a hitman!")); + MenuManager.openMenu(player, "gps"); + return; + } + Player p = Bukkit.getPlayer(ChatColor.stripColor(item.getItemMeta().getDisplayName())); + if (p == null) { + player.sendMessage(Utils.f(Lang.GPS + "&7That player is not online!")); + return; + } + if (GTM.getBountyManager().getBounty(p.getUniqueId()) == null) { + player.sendMessage(Utils.f(Lang.GPS + "&7That player does not have a bounty on his head!")); + return; + } + user.setCompassTarget(player, Core.getUserManager().getLoadedUser(uuid), new CompassTarget(p)); + player.sendMessage(Utils.f(Lang.GPS + "&7Your GPS is now tracking " + Core.getUserManager().getLoadedUser(p.getUniqueId()).getColoredName(p) + "&7!")); + return; + } + case ARROW: + if (user.getJobMode() != JobMode.HITMAN) { + player.sendMessage(Lang.GPS.f("&7You are not a hitman!")); + MenuManager.openMenu(player, "gps"); + return; + } + int page = Integer + .parseInt(ChatColor.stripColor(item.getItemMeta().getLore().get(0)).replace("Page ", "")); + BountyManager bm = GTM.getBountyManager(); + this.setPhoneDefaults(inv); + Set<Bounty> bounties = bm.getBountiesByAmount(); + int[] slots = new int[]{10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, + 33, 34, 37, 38, 39, 40, 41, 42, 43}; + Iterator<Bounty> it = bounties.iterator(); + for (int i = 0; i < (page * 28); i++) { + if (!it.hasNext()) + break; + Bounty b = it.next(); + if (i < (page - 1) * 28) + continue; + List<String> lore = Arrays.asList("&7Bounty Total: &a$&l" + b.getAmount(), ""); + double anon = 0; + for (BountyPlacer p : b.getPlacers()) + if (p.isAnonymous()) + anon += p.getAmount(); + else + lore.add("&7" + p.getName() + ": &a$&l" + p.getAmount()); + if (anon > 0) + lore.add("&7Anonymous: &a$&l" + anon); + inv.setItem(slots[i - (page - 1) * 28], Utils.setSkullOwner( + Utils.createItem(Material.SKULL_ITEM, 3, "&5&l" + b.getName(), lore), b.getName())); + } + inv.setItem(46, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the bounties page!")); + if (page > 1) + inv.setItem(48, Utils.createItem(Material.ARROW, "&5&lPrevious Page", "&7Page " + (page - 1))); + inv.setItem(49, Utils.createItem(Material.COMPASS, "&5&lBounty List", "&7Page " + page)); + if (bounties.size() > (28 * page)) + inv.setItem(50, Utils.createItem(Material.ARROW, "&5&lNext Page", "&7Page " + (page + 1))); + return; + default: + return; + } + case "mygang": + switch (item.getType()) { + case SLIME_BALL: { + user.setCurrentChatAction(ChatAction.GANG_CHAT_ACTION, "create"); + player.closeInventory(); + player.sendMessage(Lang.GANGS.f("&7Please type in the name of the gang you would like to create, or type &a\"quit\"&7 to quit!")); + return; + } + case SKULL_ITEM: { + Gang gang = GangManager.getInstance().getGangByMember(uuid).orElse(null); + if (gang == null || !gang.isLeader(uuid)) return; + user.setCurrentChatAction(ChatAction.GANG_CHAT_ACTION, "leader"); + player.closeInventory(); + player.sendMessage(Lang.GANGS.f("&7Please type in the name of the player you would like to appoint as leader of your gang, or type &a\"quit\"&7 to quit!")); + return; + } + case INK_SACK: { + Gang gang = GangManager.getInstance().getGangByMember(uuid).orElse(null); + if (gang == null || !gang.isLeader(uuid)) return; + MenuManager.openMenu(player, gang.isLeader(uuid) ? "disbandgang" : "leavegang"); + return; + } + case BOOK_AND_QUILL: + MenuManager.openMenu(player, "mygangrelations"); + return; + case TRIPWIRE_HOOK: + MenuManager.openMenu(player, "mygangmembers"); + return; + case EMPTY_MAP: { + Gang gang = GangManager.getInstance().getGangByMember(uuid).orElse(null); + if (gang == null || !(gang.isLeader(uuid) || gang.isCoLeader(uuid))) return; + user.setCurrentChatAction(ChatAction.GANG_CHAT_ACTION, "description"); + player.closeInventory(); + player.sendMessage(Lang.GANGS.f("&7Please type in the description you would like to set for your gang, or type &a\"quit\"&7 to quit!")); + return; + } + case FEATHER: + Gang gang = GangManager.getInstance().getGangByMember(uuid).orElse(null); + if (gang == null || !gang.isLeader(uuid)) return; + user.setCurrentChatAction(ChatAction.GANG_CHAT_ACTION, "name"); + player.closeInventory(); + player.sendMessage(Lang.GANGS.f("&7Please type in the name you would like to set for your gang, or type &a\"quit\"&7 to quit!")); + return; + case REDSTONE: + MenuManager.openMenu(player, "phone"); + return; + case BOOK: + MenuManager.openMenu(player, "gangs"); + return; + default: + return; + } + case "gang": { + Gang own = GangManager.getInstance().getGangByMember(uuid).orElse(null); + if (own == null) return; + + Gang gang = own.getViewingGang(uuid).orElse(null); + if (gang == null) return; + + switch (item.getType()) { + case REDSTONE: + MenuManager.openMenu(player, "phone"); + return; + case BOOK: + MenuManager.openMenu(player, "gangs"); + return; + case BOOK_AND_QUILL: + MenuManager.openMenu(player, "gangrelations"); + return; + case TRIPWIRE_HOOK: + MenuManager.openMenu(player, "gangmembers"); + return; + default: + return; + } + } + case "disbandgang": + switch (item.getType()) { + case STAINED_GLASS_PANE: + switch (item.getDurability()) { + case 5: + Gang gang = GangManager.getInstance().getGangByMember(uuid).orElse(null); + if (gang == null) { + player.sendMessage(Lang.GANGS.f("&7You are not in any gang!")); + return; + } + + player.closeInventory(); + gang.disbandConfirm(player, Core.getUserManager().getLoadedUser(uuid), user); + return; + case 14: + MenuManager.openMenu(player, "mygang"); + return; + default: + return; + } + default: + return; + } + case "leavegang": + switch (item.getType()) { + case STAINED_GLASS_PANE: + switch (item.getDurability()) { + case 5: + Gang gang = GangManager.getInstance().getGangByMember(uuid).orElse(null); + if (gang == null) { + player.sendMessage(Lang.GANGS.f("&7You are not in any gang!")); + return; + } + + player.closeInventory(); + gang.leave(player, Core.getUserManager().getLoadedUser(uuid), user); + return; + case 14: + MenuManager.openMenu(player, "mygang"); + return; + default: + return; + } + default: + return; + } + case "mygangmembers": + switch (item.getType()) { + case ARROW: { + int page = Integer.parseInt(ChatColor.stripColor(item.getItemMeta().getLore().get(0)).replace("Page ", "")); + this.setPhoneDefaults(inv); + Gang gang = GangManager.getInstance().getGangByMember(uuid).orElse(null); + List<GangMember> members = new ArrayList<>(); + if (gang != null) members.addAll(gang.getMembers()); + + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + Iterator<GangMember> it = members.iterator(); + for (int i = 0; i < page * 20; i++) { + if (!it.hasNext()) break; + GangMember m = it.next(); + if (i < (page - 1) * 20) continue; + + inv.setItem(slots[i - (page - 1) * 20], Utils.setSkullOwner(Utils.createItem(Material.SKULL_ITEM, 3, "&a&l" + m.getName(), "&7Rank: &a&l" + m.getRole().getFormattedTag(), "&7Online: &a&l" + m.isOnline(), "&7Click to view this gang member!"), m.getName())); + } + inv.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the gang page!")); + if (page > 1) inv.setItem(48, Utils.createItem(Material.ARROW, "&a&lPrevious Page", "&7Page " + (page - 1))); + inv.setItem(49, Utils.setArmorColor(Utils.createItem(Material.LEATHER_CHESTPLATE, "&a&lMy Gang Members", "&7Page " + page), Color.fromRGB(102, 127, 51))); + if (members.size() > (20 * page)) inv.setItem(50, Utils.createItem(Material.ARROW, "&a&lNext Page", "&7Page " + (page + 1))); + return; + } + case SKULL_ITEM: { + String s = ChatColor.stripColor(item.getItemMeta().getDisplayName()); + Gang gang = GangManager.getInstance().getGangByMember(uuid).orElse(null); + if (gang == null) { + player.sendMessage(Lang.GANGS.f("&7You are not in any gang!")); + return; + } + + Optional<GangMember> optional = gang.getMember(s); + if (!optional.isPresent()) { + player.sendMessage(Lang.GANGS.f("&7That player is not a member of your gang!")); + return; + } + + gang.setViewingGangMember(uuid, optional.get()); + MenuManager.openMenu(player, "gangmember"); + return; + } + case BOOK: + Gang gang = GangManager.getInstance().getGangByMember(uuid).orElse(null); + if (gang == null || (!gang.isLeader(uuid) && !gang.isCoLeader(uuid))) return; + user.setCurrentChatAction(ChatAction.GANG_CHAT_ACTION, "invite"); + player.closeInventory(); + player.sendMessage(Lang.GANGS.f("&7Please type in the name of the player you would like to invite to your gang, or type &a\"quit\"&7 to quit!")); + return; + case REDSTONE: + MenuManager.openMenu(player, "mygang"); + return; + default: + return; + } + case "gangmember": + switch (item.getType()) { + case BOOK_AND_QUILL: { + Gang gang = GangManager.getInstance().getGangByMember(uuid).orElse(null); + if (gang == null) return; + + GangMember member = gang.getViewingGangMember(uuid).orElse(null); + if (member == null) return; + + gang.demote(player, Core.getUserManager().getLoadedUser(uuid), user, member.getName()); + MenuManager.updateMenu(player, "gangmember"); + return; + } + case SLIME_BALL: { + Gang gang = GangManager.getInstance().getGangByMember(uuid).orElse(null); + if (gang == null) return; + + GangMember member = gang.getViewingGangMember(uuid).orElse(null); + if (member == null) return; + + gang.promote(player, Core.getUserManager().getLoadedUser(uuid), user, member.getName()); + MenuManager.updateMenu(player, "gangmember"); + return; + } + case INK_SACK: + Gang gang = GangManager.getInstance().getGangByMember(uuid).orElse(null); + if (gang == null) return; + + GangMember member = gang.getViewingGangMember(uuid).orElse(null); + if (member == null) return; + + gang.kick(player, Core.getUserManager().getLoadedUser(uuid), user, member.getName()); + MenuManager.openMenu(player, "mygangmembers"); + return; + case REDSTONE: + MenuManager.openMenu(player, "mygangmembers"); + return; + default: + return; + } + case "gangmembers": + switch (item.getType()) { + case ARROW: + int page = Integer.parseInt(ChatColor.stripColor(item.getItemMeta().getLore().get(0)).replace("Page ", "")); + this.setPhoneDefaults(inv); + Gang ownGang = GangManager.getInstance().getGangByMember(uuid).orElse(null); + if (ownGang == null) { + MenuManager.openMenu(player, "mygangmembers"); + return; + } + + Gang gang = ownGang.getViewingGang(uuid).orElse(null); + if (gang == null) { + inv.setItem(31, Utils.createItem(Material.INK_SACK, 1, "&c&lGang: &7&lUnknown", "&7This gang does not exist!")); + return; + } + + if (Objects.equals(gang, ownGang)) { + MenuManager.openMenu(player, "mygangmembers"); + return; + } + + boolean isEnemy = ownGang.isEnemy(gang); + List<GangMember> members = new ArrayList<>(gang.getMembers()); + + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + Iterator<GangMember> it = members.iterator(); + for (int i = 0; i < page * 20; i++) { + if (!it.hasNext()) break; + GangMember m = it.next(); + if (i < (page - 1) * 20) continue; + inv.setItem(slots[i - (page - 1) * 20], Utils.setSkullOwner(Utils.createItem(Material.SKULL_ITEM, 3, (isEnemy ? "&c" : "&a") + "&l" + m.getName(), "&7Rank: &a&l" + m.getRole().getFormattedTag(), + "&7Online: &a&l" + m.isOnline(), "&7Click to view this gang member!"), m.getName())); + } + + inv.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the gang page!")); + if (page > 1) inv.setItem(48, Utils.createItem(Material.ARROW, "&a&lPrevious Page", "&7Page " + (page - 1))); + inv.setItem(49, Utils.setArmorColor(Utils.createItem(Material.LEATHER_CHESTPLATE, (isEnemy ? "&c" : "&a") + "&lGang Members: &7&l" + gang.getName(), "&7Page " + page), Color.fromRGB(102, 127, 51))); + if (members.size() > (20 * page)) inv.setItem(50, Utils.createItem(Material.ARROW, "&a&lNext Page", "&7Page " + (page + 1))); + return; + case SKULL_ITEM: + Player target = Bukkit.getPlayer(ChatColor.stripColor(item.getItemMeta().getDisplayName())); + player.closeInventory(); + GTM.getWarpManager().tpa(player, Core.getUserManager().getLoadedUser(uuid), GTM.getUserManager().getLoadedUser(uuid), target); + return; + case REDSTONE: + MenuManager.openMenu(player, "gang"); + return; + default: + return; + } + + case "mygangrelations": + switch (item.getType()) { + case ARROW: { + int page = Integer.parseInt(ChatColor.stripColor(item.getItemMeta().getLore().get(0)).replace("Page ", "")); + this.setPhoneDefaults(inv); + Gang gang = GangManager.getInstance().getGangByMember(uuid).orElse(null); + Set<GangRelation> relations = gang.getRelations(); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + int i = 0; + for (GangRelation r : relations) { + if (i < (page - 1) * 20) continue; + int online = 0; + int amnt = 0; + + Optional<Gang> optional = GangManager.getInstance().getGang(r.getRelativeId()); + if (optional.isPresent()) { + Gang ga = optional.get(); + online = ga.getOnlineMembers().size(); + amnt = ga.getMembers().size() + 1; + } + + boolean isEnemy = gang.isEnemy(optional.get()); + boolean isAlly = gang.isAllied(optional.get()); + inv.setItem(slots[i - (page - 1) * 20], Utils.setArmorColor(Utils.createItem(Material.LEATHER_CHESTPLATE, (isEnemy ? "&c" : "&a") + optional.get().getName(), + "&7Relation: " + (isEnemy ? "&c&lEnemy" : isAlly ? "&a&lAlly" : "&a&lNeutral"), + amnt == 0 ? "&7Online Members: &c&l0" : "&7Online Members: &a&l" + online + "&7/&a&l" + amnt, + "&7Click to view this gang!"), + isEnemy ? Color.RED : Color.fromRGB(102, 127, 51))); + i++; + } + inv.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the gang page!")); + + if (page > 1) inv.setItem(48, Utils.createItem(Material.ARROW, "&a&lPrevious Page", "&7Page " + (page - 1))); + inv.setItem(49, Utils.setArmorColor(Utils.createItem(Material.LEATHER_CHESTPLATE, "&a&lMy Gang Relations", "&7Page " + page), Color.fromRGB(102, 127, 51))); + if (relations.size() > (20 * page)) + inv.setItem(50, Utils.createItem(Material.ARROW, "&a&lNext Page", "&7Page " + (page + 1))); + + if (gang.isLeader(uuid) || gang.isCoLeader(uuid)) + inv.setItem(51, Utils.createItem(Material.BOOK, "&a&lSet Relation", "&7Click to set a relation towards an other gang!")); + return; + } + case LEATHER_CHESTPLATE: { + String s = ChatColor.stripColor(item.getItemMeta().getDisplayName()); + Optional<Gang> viewing = GangManager.getInstance().getGang(s); + if (Objects.equals("My Gang Relations", s) || !viewing.isPresent()) + return; + Gang gang = viewing.get(); + + Gang self = GangManager.getInstance().getGangByMember(uuid).orElse(null); + if (self == null) return; + self.setViewingGang(uuid, gang); + + MenuManager.openMenu(player, "gang"); + return; + } + case BOOK: + Gang gang = GangManager.getInstance().getGangByMember(uuid).orElse(null); + if (gang == null || !(gang.isLeader(uuid) || gang.isCoLeader(uuid))) + return; + + user.setCurrentChatAction(ChatAction.GANG_CHAT_ACTION, "relation"); + gang.setViewingGang(uuid, null); + player.closeInventory(); + player.sendMessage(Lang.GANGS.f("&7Please type in the name of the gang you would like to change your relation to, or type &a\"quit\"&7 to quit.")); + return; + case REDSTONE: + MenuManager.openMenu(player, "mygang"); + return; + default: + return; + } + case "gangrelations": + switch (item.getType()) { + case ARROW: { + int page = Integer.parseInt(ChatColor.stripColor(item.getItemMeta().getLore().get(0)).replace("Page ", "")); + this.setPhoneDefaults(inv); + Gang ownGang = GangManager.getInstance().getGangByMember(uuid).orElse(null); + if (ownGang == null) return; + + Gang gang = ownGang.getViewingGang(uuid).orElse(null); + if (gang == null) { + inv.setItem(31, Utils.createItem(Material.INK_SACK, 1, "&c&lGang: &7&lUnknown", "&7This gang does not exist!")); + return; + } + + if (Objects.equals(gang, ownGang)) { + MenuManager.openMenu(player, "mygangrelations"); + return; + } + + boolean isOwnEnemy = gang.isEnemy(ownGang); + Set<GangRelation> relations = gang.getRelations(); + int i = 0; + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + for (GangRelation r : relations) { + if (i < (page - 1) * 20) continue; + int online = 0; + int amnt = 0; + + Optional<Gang> optional = GangManager.getInstance().getGang(r.getRelativeId()); + if (optional.isPresent()) { + Gang ga = optional.get(); + online = ga.getOnlineMembers().size(); + amnt = ga.getMembers().size() + 1; + } + boolean isEnemy = gang.isEnemy(optional.get()); + boolean isAlly = gang.isAllied(optional.get()); + inv.setItem(slots[i - (page - 1) * 20], Utils.setArmorColor(Utils.createItem(Material.LEATHER_CHESTPLATE, (isEnemy ? "&c" : "&a") + optional.get().getName(), + "&7Relation: " + (isEnemy ? "&c&lEnemy" : isAlly ? "&a&lAlly" : "&a&lNeutral"), + amnt == 0 ? "&7Online Members: &c&l0" : "&7Online Members: &a&l" + online + "&7/&a&l" + amnt, + "&7Click to view this gang!"), + isEnemy ? Color.RED : Color.fromRGB(102, 127, 51))); + i++; + } + inv.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the gang page!")); + if (page > 1) inv.setItem(48, Utils.createItem(Material.ARROW, "&a&lPrevious Page", "&7Page " + (page - 1))); + + inv.setItem(49, Utils.setArmorColor(Utils.createItem(Material.LEATHER_CHESTPLATE, (isOwnEnemy ? "&c" : "&a") + "&lGang Relations: &7&l" + gang.getName(), + "&7Page " + page), isOwnEnemy ? Color.RED : Color.fromRGB(102, 127, 51))); + + if (relations.size() > (20 * page)) + inv.setItem(50, Utils.createItem(Material.ARROW, "&a&lNext Page", "&7Page " + (page + 1))); + + if (ownGang.isLeader(uuid) || ownGang.isCoLeader(uuid)) + inv.setItem(51, Utils.createItem(Material.BOOK, "&a&lSet Relation", "&7Click to set a relation towards this gang!")); + return; + } + case LEATHER_CHESTPLATE: { + String s = ChatColor.stripColor(item.getItemMeta().getDisplayName()); + Optional<Gang> optional = GangManager.getInstance().getGang(s); + if (s.startsWith("Gang Relations: ") || !optional.isPresent()) + return; + + Gang self = GangManager.getInstance().getGangByMember(uuid).orElse(null); + if (self == null) return; + + self.setViewingGang(uuid, optional.get()); + MenuManager.openMenu(player, "gang"); + return; + } + case BOOK: + Gang gang = GangManager.getInstance().getGangByMember(uuid).orElse(null); + if (gang == null) return; + + Gang viewing = gang.getViewingGang(uuid).orElse(null); + if(viewing == null) return; + + if (!(gang.isLeader(uuid) || gang.isCoLeader(uuid)) || !GangManager.getInstance().getGang(viewing.getUniqueId()).isPresent()) + return; + + + user.setCurrentChatAction(ChatAction.GANG_CHAT_ACTION, "relation"); + player.closeInventory(); + player.sendMessage(Lang.GANGS.f("&7Please type in the relation (ally, neutral or enemy) you would like to set towards gang &a" + viewing.getName() + "&7, or type &a\"quit\" to quit!")); + return; + case REDSTONE: + MenuManager.openMenu(player, "gang"); + return; + default: + return; + } + + case "gangs": + switch (item.getType()) { + case ARROW: { + int page = Integer.parseInt(ChatColor.stripColor(item.getItemMeta().getLore().get(0)).replace("Page ", "")); + this.setPhoneDefaults(inv); + Gang gang = GangManager.getInstance().getGangByMember(uuid).orElse(null); + Set<Gang> gangs = GangManager.getInstance().getGangs(); + Iterator<Gang> it = gangs.iterator(); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + for (int i = 0; i < page * 20; i++) { + if (!it.hasNext()) + break; + Gang g = it.next(); + if (i < (page - 1) * 20) + continue; + int online = g.getOnlineMembers().size(); + int amnt = g.getMembers().size() + 1; + boolean isEnemy = gang.isEnemy(g); + boolean isAlly = gang.isAllied(g); + + Optional<GangMember> optional = g.getMember(uuid); + if(optional.isPresent()) { + String relation = Objects.equals(gang, g) ? "&a&l" + optional.get().getRole().getTag() : isEnemy ? "&c&lEnemy" : isAlly ? "&a&lAlly" : "&a&lNeutral"; + inv.setItem(slots[i - (page - 1) * 20], Utils.setArmorColor(Utils.createItem(Material.LEATHER_CHESTPLATE, (isEnemy ? "&c" : "&a") + g, + "&7Relation: " + relation, amnt == 0 ? "&7Online Members: &c&l0" : "&7Online Members: &a&l" + online + "&7/&a&l" + amnt, + amnt == 0 ? "This gang is not online!" : "&7Click to view this gang!"), + isEnemy ? Color.RED : Color.fromRGB(102, 127, 51))); + } + } + inv.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the gang page!")); + if (page > 1) inv.setItem(48, Utils.createItem(Material.ARROW, "&a&lPrevious Page", "&7Page " + (page - 1))); + inv.setItem(49, Utils.setArmorColor(Utils.createItem(Material.LEATHER_CHESTPLATE, "&a&lGang List", "&7Page " + page), Color.fromRGB(102, 127, 51))); + if (gangs.size() > (20 * page)) inv.setItem(50, Utils.createItem(Material.ARROW, "&a&lNext Page", "&7Page " + (page + 1))); + return; + } + case LEATHER_CHESTPLATE: + String s = ChatColor.stripColor(item.getItemMeta().getDisplayName()); + Optional<Gang> optional = GangManager.getInstance().getGang(s); + if (Objects.equals("Gang List", s) || !optional.isPresent()) + return; + + Gang self = GangManager.getInstance().getGangByMember(uuid).orElse(null); + if (self == null) return; + + self.setViewingGang(uuid, optional.get()); + MenuManager.openMenu(player, "gang"); + return; + case REDSTONE: + MenuManager.openMenu(player, "mygang"); + return; + default: + return; + } + case "ammopouch": + switch (item.getType()) { + case REDSTONE: + int slot = e.getSlot(); + int i = 0; + while (slot > 8) { + slot -= 9; + i++; + } + int toDrop = i == 1 ? 50 : i == 2 ? 10 : i == 3 ? 1 : 0; + AmmoType type = AmmoType.getTypes()[slot]; + int ammo = user.getAmmo(type); + if (ammo <= 0) { + player.sendMessage(Lang.AMMO.f("&7You have none of this type of ammo left!")); + return; + } + if (ammo < toDrop) + toDrop = ammo; + ItemStack stack = type.getGameItem().getItem(); + stack.setAmount(toDrop); + user.removeAmmo(type, toDrop); + player.getWorld().dropItemNaturally(Utils.getInFrontOf(player.getLocation()), stack); + player.sendMessage(Lang.AMMO_TAKE.f(toDrop + "&7 " + type.getGameItem().getDisplayName() + "&7!")); + MenuManager.updateMenu(player, "ammopouch"); + return; + default: + return; + } + case "jail": + switch (item.getType()) { + case ARROW: + int page = Integer + .parseInt(ChatColor.stripColor(item.getItemMeta().getLore().get(0)).replace("Page ", "")); + this.setPhoneDefaults(inv); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, + 42}; + List<Player> jailedPlayers = GTMUtils.getJailedPlayers(); + Iterator<Player> it = jailedPlayers.iterator(); + for (int i = 0; i < page * 20; i++) { + if (!it.hasNext()) + break; + Player p = it.next(); + if (i < (page - 1) * 20) + continue; + + GTMUser u = GTM.getUserManager().getLoadedUser(p.getUniqueId()); + if (!u.isArrested()) + continue; + List<String> lore = new ArrayList<>(); + lore.add("&7Time Left: &a&l" + Utils.timeInSecondsToText(u.getJailTimer())); + if (user.getJobMode() == JobMode.COP && Objects.equals(u.getJailCop(), player.getUniqueId())) + lore.add("&7Click to release!"); + inv.setItem(slots[i - (page - 1) * 20], Utils.setSkullOwner( + Utils.createItem(Material.SKULL_ITEM, 3, "&e&l" + p.getName(), lore), p.getName())); + } + if (page > 1) + inv.setItem(48, Utils.createItem(Material.ARROW, "&c&lPrevious Page", "&7Page " + (page - 1))); + inv.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lClose", "&7Click to close this menu!")); + inv.setItem(49, Utils.createItem(Material.IRON_FENCE, "&c&lPrisoner List", "&7Page " + page)); + if (jailedPlayers.size() > (20 * page)) + inv.setItem(50, Utils.createItem(Material.ARROW, "&c&lNext Page", "&7Page " + (page + 1))); + return; + case SKULL_ITEM: + Player p = Bukkit.getPlayer(ChatColor.stripColor(e.getItem().getItemMeta().getDisplayName())); + if (p == null) { + player.sendMessage(Lang.JAIL.f("&7That player is not online!")); + MenuManager.updateMenu(player, "jail"); + return; + } + if (GTM.getUserManager().getLoadedUser(uuid).getJobMode() != JobMode.COP) return; + GTMUser u = GTM.getUserManager().getLoadedUser(p.getUniqueId()); + if (!u.isArrested()) { + player.sendMessage(Lang.JAIL.f("&7That player is not in jail!")); + MenuManager.updateMenu(player, "jail"); + return; + } + if (u.getJailTimer() <= 5) { + player.sendMessage(Lang.JAIL.f("&7That prisoners is already being released!")); + return; + } + if (GTM.getUserManager().getLoadedUser(uuid).getJobMode() != JobMode.COP) { + player.sendMessage(Lang.JAIL.f("&7You must be a cop to release prisoners!")); + return; + } + if (!Objects.equals(u.getJailCop(), player.getUniqueId())) { + player.sendMessage(Lang.JAIL.f("&7You can only release prisoners that you put in jail!")); + return; + } + u.setJailTimer(5); + player.sendMessage(Lang.JAIL.f("&7You released prisoners &e&l" + + Core.getUserManager().getLoadedUser(p.getUniqueId()).getColoredName(p) + "&7!")); + p.sendMessage(Lang.JAIL.f("&7You are being released by &a" + + Core.getUserManager().getLoadedUser(player.getUniqueId()).getColoredName(player) + "&7!")); + MenuManager.updateMenu(player, "jail"); + return; + case REDSTONE: + player.closeInventory(); + return; + default: + return; + } + case "property": + switch (item.getType()) { + case IRON_DOOR: + MenuManager.openMenu(player, "houses"); + return; + case MINECART: + if (GTM.getUserManager().getLoadedUser(uuid).hasPersonalVehicle()) { + MenuManager.openMenu(player, "personalvehicle"); + return; + } + MenuManager.openMenu(player, "vehicles"); + return; + case PAPER: + MenuManager.openMenu(player, "bank"); + return; + case REDSTONE: + MenuManager.openMenu(player, "phone"); + return; + default: + return; + } + case "vehicles": + switch (item.getType()) { + case ARROW: { + int page = Integer + .parseInt(ChatColor.stripColor(item.getItemMeta().getLore().get(0)).replace("Page ", "")); + this.setPhoneDefaults(inv); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + List<PersonalVehicle> vehicles = new ArrayList<>(user.getVehicles()); + if (user.hasPersonalVehicle()) + vehicles.remove(user.getPersonalVehicle()); + Iterator<PersonalVehicle> it = vehicles.iterator(); + for (int i = 0; i < page * 20; i++) { + if (!it.hasNext()) + break; + PersonalVehicle vehicle = it.next(); + if (i < (page - 1) * 20) + continue; + ItemStack stack = vehicle.getVehicleProperties().getItem().clone(); + ItemMeta meta = stack.getItemMeta(); + List<String> lore = new ArrayList<>(meta.getLore()); + lore.add(Utils.f("&7Health: " + vehicle.getFormattedHealth())); + lore.add(Utils.f("&aClick to get this vehicle!")); + lore.add(Utils.f("&7Price: &a$&l200")); + meta.setLore(lore); + stack.setItemMeta(meta); + inv.setItem(slots[i - (page - 1) * 20], stack); + } + if (page > 1) + inv.setItem(48, Utils.createItem(Material.ARROW, "&4&lPrevious Page", "&7Page " + (page - 1))); + inv.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the property page!")); + if (user.hasPersonalVehicle()) { + PersonalVehicle vehicle = user.getPersonalVehicle(); + ItemStack stack = vehicle.getVehicleProperties().getItem().clone(); + ItemMeta meta = stack.getItemMeta(); + List<String> lore = new ArrayList<>(meta.getLore()); + lore.add(Utils.f("&7Health: " + vehicle.getFormattedHealth())); + lore.add(Utils.f("&aClick to view your personal vehicle!")); + meta.setLore(lore); + stack.setItemMeta(meta); + inv.setItem(49, Utils.addGlow(stack)); + + } else + inv.setItem(49, Utils.createItem(Material.MINECART, "&4&lVehicles", "&7Please select your personal vehicle!")); + if (vehicles.size() > (20 * page)) + inv.setItem(50, Utils.createItem(Material.ARROW, "&4&lNext Page", "&7Page " + (page + 1))); + return; + } + case REDSTONE: + MenuManager.openMenu(player, "property"); + return; + default: + if (!item.hasItemMeta() || !item.getItemMeta().hasDisplayName()) return; + GameItem gameItem = GTM.getItemManager().getItemFromDisplayName(item.getItemMeta().getDisplayName()); + if (gameItem == null) return; + PersonalVehicle vehicle = user.getPersonalVehicle(gameItem.getWeaponOrVehicleOrDrug()); + if (vehicle == null) return; + if (Objects.equals(vehicle, user.getPersonalVehicle())) { + MenuManager.openMenu(player, "personalvehicle"); + return; + } + user.setPersonalVehicle(player, Core.getUserManager().getLoadedUser(uuid), vehicle); + player.closeInventory(); + return; + } + + case "vehicleshop": + switch (item.getType()) { + case REDSTONE: + player.closeInventory(); + return; + case SLIME_BALL: { + if (user.hasVehicle(user.getActionVehicle())) { + player.sendMessage(Lang.VEHICLES.f("&7You already own this vehicle!")); + MenuManager.openMenu(player, "vehicles"); + return; + } + MenuManager.openMenu(player, "buyvehicle"); + return; + } + case INK_SACK: { + if (!user.hasVehicle(user.getActionVehicle())) { + player.sendMessage(Lang.VEHICLES.f("&7You don't own this vehicle!")); + MenuManager.openMenu(player, "vehicles"); + return; + } + MenuManager.openMenu(player, "sellvehicle"); + return; + } + default: + return; + } + case "buyvehicle": + switch (item.getType()) { + case STAINED_GLASS_PANE: + switch (item.getDurability()) { + case 5: + Optional<VehicleProperties> opt = GTM.getWastedVehicles().getVehicle(user.getActionVehicle()); + GameItem gameItem = GTM.getItemManager().getItemFromVehicle(user.getActionVehicle()); + if (opt == null || !opt.isPresent() || gameItem == null) { + if (gameItem == null) + Utils.b("GameItem for " + user.getActionVehicle() + " is null"); + player.sendMessage(Lang.VEHICLES.f("&7That vehicle does not exist!")); + return; + } + VehicleProperties vehicle = opt.get(); + double price = gameItem.getSellPrice() * 2; + if (price <= 0) { + player.closeInventory(); + player.sendMessage(Lang.VEHICLES.f("&7You can't buy this vehicle!")); + return; + } + if (user.hasVehicle(vehicle.getIdentifier())) { + player.closeInventory(); + player.sendMessage(Lang.VEHICLES.f("&7You already own this vehicle!")); + return; + } + if (!user.hasMoney(price)) { + player.closeInventory(); + player.sendMessage(Lang.VEHICLES.f("&7You don't have the &c$&l" + Utils.round(price) + "&7 to pay for this vehicle!")); + return; + } + user.setActionVehicle(null); + user.takeMoney(price); + GTMUtils.updateBoard(player, user); + user.giveVehiclePerm(player, vehicle); + player.sendMessage(Lang.VEHICLES.f("&7You bought vehicle " + vehicle.getItem().getItemMeta().getDisplayName() + "&7 for &a$&l" + Utils.round(price) + "&7!")); + MenuManager.openMenu(player, "vehicles"); + return; + case 14: + MenuManager.openMenu(player, "vehicleshop"); + return; + default: + return; + } + + default: + return; + } + case "sellvehicle": + switch (item.getType()) { + case STAINED_GLASS_PANE: + switch (item.getDurability()) { + case 5: + PersonalVehicle vehicle = user.getPersonalVehicle(user.getActionVehicle()); + if (vehicle == null) return; + if (vehicle.onMap()) { + player.sendMessage(Lang.VEHICLES.f("&7Please send the driver to pick up your vehicle first!")); + return; + } + double price = vehicle.getSellPrice(); + if (price <= 0) { + player.closeInventory(); + player.sendMessage(Lang.VEHICLES.f("&7You can't sell this vehicle!")); + return; + } + user.setActionVehicle(null); + user.removeVehiclePerm(player, vehicle.getVehicleProperties()); + user.addMoney(price); + GTMUtils.updateBoard(player, user); + player.sendMessage(Lang.VEHICLES.f("&7You sold vehicle " + vehicle.getDisplayName() + "&7 for &a$&l" + Utils.round(price) + "&7!")); + MenuManager.openMenu(player, "vehicles"); + return; + case 14: + MenuManager.openMenu(player, "personalvehicle"); + return; + default: + return; + } + + default: + return; + } + case "repairvehicle": + switch (item.getType()) { + case STAINED_GLASS_PANE: + switch (item.getDurability()) { + case 5: { + PersonalVehicle vehicle = user.getPersonalVehicle(user.getActionVehicle()); + if (vehicle == null) return; + if (vehicle.onMap()) { + player.sendMessage(Lang.VEHICLES.f("&7Please send the driver to pick up your vehicle first!")); + return; + } + double price = vehicle.getRepairPrice(); + if (price <= 0) { + player.closeInventory(); + player.sendMessage(Lang.VEHICLES.f("&7You can't repair this vehicle!")); + return; + } + if (!user.hasMoney(price)) { + player.sendMessage(Lang.VEHICLES.f("&7You can't afford to pay &c$&l" + price + "&7 to repair this vehicle!")); + return; + } + user.setActionVehicle(null); + user.takeMoney(price); + GTMUtils.updateBoard(player, user); + double health = vehicle.getVehicleProperties().getMaxHealth(); + vehicle.setHealth(health); + vehicle.updateVehicleInDatabase(player, health); + player.sendMessage(Lang.VEHICLES.f("&7You repaired vehicle " + vehicle.getDisplayName() + "&7 for &a$&l" + Utils.round(price) + "&7!")); + MenuManager.openMenu(player, "personalvehicle"); + return; + } + case 14: + MenuManager.openMenu(player, "personalvehicle"); + return; + default: + return; + } + default: + return; + } + case "personalvehicle": + switch (item.getType()) { + case REDSTONE: + MenuManager.openMenu(player, "vehicles"); + return; + case INK_SACK: { + PersonalVehicle vehicle = user.getPersonalVehicle(); + if (vehicle == null) { + MenuManager.openMenu(player, "vehicles"); + return; + } + user.setActionVehicle(vehicle.getVehicle()); + MenuManager.openMenu(player, "sellvehicle"); + return; + } + case ENDER_PEARL: { + PersonalVehicle vehicle = user.getPersonalVehicle(); + if (vehicle == null) { + MenuManager.openMenu(player, "vehicles"); + return; + } + if (vehicle.onMap()) { + vehicle.sendAway(player, Core.getUserManager().getLoadedUser(uuid), user); + } else { + vehicle.call(player, Core.getUserManager().getLoadedUser(uuid), user); + } + return; + } + case WORKBENCH: { + PersonalVehicle vehicle = user.getPersonalVehicle(); + if (vehicle == null) { + MenuManager.openMenu(player, "vehicles"); + return; + } + if (vehicle.getRepairPrice() <= 0) { + player.sendMessage(Lang.VEHICLES.f("&7You can't repair this vehicle!")); + return; + } + user.setActionVehicle(vehicle.getVehicle()); + MenuManager.openMenu(player, "repairvehicle"); + return; + } + default: + PersonalVehicle vehicle = user.getPersonalVehicle(); + if (vehicle == null) { + MenuManager.openMenu(player, "vehicles"); + return; + } + if (!item.hasItemMeta() || !item.getItemMeta().hasDisplayName() || !Objects.equals(item.getItemMeta().getDisplayName(), vehicle.getDisplayName())) + return; + vehicle.call(player, Core.getUserManager().getLoadedUser(uuid), user); + return; + } + case "mechanic": + switch (item.getType()) { + case ARROW: { + int page = Integer + .parseInt(ChatColor.stripColor(item.getItemMeta().getLore().get(0)).replace("Page ", "")); + this.setPhoneDefaults(inv); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + List<PersonalVehicle> vehicles = new ArrayList<>(user.getVehicles()); + new ArrayList<>(vehicles).stream().filter(vehicle -> vehicle.getRepairPrice() <= 0).forEach(vehicles::remove); + Iterator<PersonalVehicle> it = vehicles.iterator(); + for (int i = 0; i < page * 20; i++) { + if (!it.hasNext()) + break; + PersonalVehicle vehicle = it.next(); + if (i < (page - 1) * 20) + continue; + ItemStack stack = vehicle.getVehicleProperties().getItem().clone(); + ItemMeta meta = stack.getItemMeta(); + List<String> lore = new ArrayList<>(meta.getLore()); + lore.add(Utils.f("&7Health: " + vehicle.getFormattedHealth())); + lore.add(Utils.f("&7Repair Price: &a&l$" + NumberFormat.getNumberInstance(Locale.US).format(vehicle.getRepairPrice()))); + lore.add(Utils.f("&aClick to repair this vehicle!")); + meta.setLore(lore); + stack.setItemMeta(meta); + inv.setItem(slots[i - (page - 1) * 20], Objects.equals(vehicle, user.getPersonalVehicle()) ? Utils.addGlow(stack) : stack); + } + if (page > 1) + inv.setItem(48, Utils.createItem(Material.ARROW, "&4&lPrevious Page", "&7Page " + (page - 1))); + inv.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the property page!")); + inv.setItem(49, Utils.createItem(Material.WORKBENCH, "&4&lMechanic", "&7Repair your vehicles!")); + if (vehicles.size() > (20 * page)) + inv.setItem(50, Utils.createItem(Material.ARROW, "&4&lNext Page", "&7Page " + (page + 1))); + return; + } + case REDSTONE: + player.closeInventory(); + return; + default: + if (!item.hasItemMeta() || !item.getItemMeta().hasDisplayName()) return; + GameItem gameItem = GTM.getItemManager().getItemFromDisplayName(item.getItemMeta().getDisplayName()); + if (gameItem == null) return; + PersonalVehicle vehicle = user.getPersonalVehicle(gameItem.getWeaponOrVehicleOrDrug()); + if (vehicle == null) return; + if (vehicle.onMap()) { + player.sendMessage(Lang.VEHICLES.f("&7Please send the driver to pick up your vehicle first!")); + return; + } + double price = vehicle.getRepairPrice(); + if (price <= 0) { + player.closeInventory(); + player.sendMessage(Lang.VEHICLES.f("&7You can't repair this vehicle!")); + return; + } + if (!user.hasMoney(price)) { + player.sendMessage(Lang.VEHICLES.f("&7You can't afford to pay &c$&l" + price + "&7 to repair this vehicle!")); + return; + } + user.setActionVehicle(null); + user.takeMoney(price); + GTMUtils.updateBoard(player, user); + double health = vehicle.getVehicleProperties().getMaxHealth(); + vehicle.setHealth(health); + vehicle.updateVehicleInDatabase(player, health); + player.sendMessage(Lang.VEHICLES.f("&7The Mechanic repaired vehicle " + vehicle.getDisplayName() + "&7 for &a$&l" + Utils.round(price) + "&7!")); + player.closeInventory(); + return; + } + case "heads": { + switch (item.getType()) { + case ARROW: { + int page = Integer + .parseInt(ChatColor.stripColor(item.getItemMeta().getLore().get(0)).replace("Page ", "")); + this.setPhoneDefaults(inv); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + Set<Head> heads = GTM.getShopManager().getNonExpiredHeadsByBid(); + Iterator<Head> it = heads.iterator(); + for (int i = 0; i < page * 20; i++) { + if (!it.hasNext()) + break; + Head head = it.next(); + if (i < (page - 1) * 20) + continue; + List<String> lore = new ArrayList<>(); + lore.add(Utils.f("&7Seller: &a&l" + head.getSellerName())); + if (head.hasBid()) { + lore.add(Utils.f("&7Bidder: &a&l" + head.getBidderName())); + lore.add(Utils.f("&7Bid: &a$&l" + head.getBid())); + } else lore.add(Utils.f("&7Starting Bid: &a$&l10,000")); + lore.add(Utils.f("&7Click to bid!")); + lore.add(Utils.f("&7Time Left: &a&l" + Utils.timeInMillisToText(head.getTimeUntilExpiry()))); + lore.add(Utils.f("&0" + head.getExpiry())); + inv.setItem(slots[i - (page - 1) * 20], new JLibItem.Builder().withType(Material.SKULL_ITEM).withDurability((short) 3).withName(Utils.f("&e&l" + head.getHead())).withLore(lore).withOwner(head.getHead()).build().getItemStack()); + } + inv.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lClose", "&7Click to close this menu!")); + if (page > 1) + inv.setItem(48, Utils.createItem(Material.ARROW, "&e&lPrevious Page", "&7Page " + (page - 1))); + inv.setItem(49, Utils.createItem(Material.SKULL_ITEM, "&e&lHead Auction", "&7Buy and sell your souvenirs!")); + if (heads.size() > 20 * page) + inv.setItem(50, Utils.createItem(Material.ARROW, "&e&lNext Page", "&7Page " + (page + 1))); + inv.setItem(51, Utils.createItem(Material.PAPER, "&e&lAuction Head", "&7Click to auction a player head!")); + return; + } + case REDSTONE: + player.closeInventory(); + return; + case PAPER: + player.closeInventory(); + player.sendMessage(Lang.HEAD_AUCTION.f("&7Click me with the head in your hand to put it up for sale!")); + return; + case SKULL_ITEM: + try { + String owner = ((SkullMeta) item.getItemMeta()).getOwner(); + String s = item.getItemMeta().hasLore() ? ChatColor.stripColor(item.getItemMeta().getLore().get(item.getItemMeta().getLore().size() - 1)) : null; + if (s == null) return; + Long expiry = Long.parseLong(s); + Head head = GTM.getShopManager().getHead(owner, expiry); + if (head == null) return; + user.setBiddingHead(head.getHead()); + user.setCurrentChatAction(ChatAction.BIDDING_HEAD, 0); + user.setBiddingExpiry(head.getExpiry()); + player.sendMessage(Lang.HEAD_AUCTION.f("&7The current bid for &e&l" + head.getHead() + "'s Head&7 is &a$&l" + (head.hasBid() ? head.getBid() : "10,000") + "&7! Type your bid or type &a\"quit\"&7 to cancel bidding.")); + player.closeInventory(); + return; + } catch (NumberFormatException ignored) { + return; + } catch (Exception e1) { + e1.printStackTrace(); + return; + } + default: + return; + } + } + case "auctionhead": + switch (item.getType()) { + case STAINED_GLASS_PANE: + switch (item.getDurability()) { + case 5: { + player.closeInventory(); + GTM.getShopManager().auctionHead(player, GTM.getUserManager().getLoadedUser(uuid)); + return; + } + case 14: + player.closeInventory(); + return; + default: + return; + } + + default: + return; + } + case "armorupgrade": + switch (item.getType()) { + case STAINED_GLASS_PANE: + switch (item.getDurability()) { + case 5: { + player.closeInventory(); + ArmorUpgrade upgrade = user.getBuyingArmorUpgrade(); + if (upgrade == null) { + return; + } + if (!upgrade.canUseUpgrade(user.getRank(), Core.getUserManager().getLoadedUser(player.getUniqueId()).getUserRank())) { + player.sendMessage(Lang.HEY.f("&7You need to rank up to " + upgrade.getGTMRank().getColoredNameBold() + "&7 or donate for " + upgrade.getUserRank().getColoredNameBold() + "&7 at &a&l" + Core.getSettings().getStoreLink() + "&7 to use the &b&l" + upgrade.getDisplayName() + " Armor Upgrade&7!")); + return; + } + ItemStack i = player.getInventory().getItemInMainHand(); + GameItem gameItem = item == null ? null : GTM.getItemManager().getItem(i.getType()); + if (i == null || gameItem == null || !upgrade.canBeUsedOn(gameItem.getName())) { + player.sendMessage(Lang.HEY.f("&7The &b&l" + upgrade.getDisplayName() + " Armor Upgrade&7 can be applied to the following types of items: " + upgrade.getTypesString() + "&7!")); + return; + } + if (ArmorUpgrade.getArmorUpgrades(item).contains(upgrade)) { + player.sendMessage(Lang.ARMOR_UPGRADE.f("&7That piece of armor already has the &b&l" + upgrade.getDisplayName() + " Armor Upgrade&7!")); + return; + } + double price = upgrade.getPrice(); + if (!user.hasMoney(upgrade.getPrice())) { + player.sendMessage(Lang.ARMOR_UPGRADE.f("&7You can't afford the &b&l" + upgrade.getDisplayName() + " Armor Upgrade&7!")); + return; + } + Bukkit.getPluginManager().callEvent(new MoneyEvent(player.getUniqueId(), MoneyEvent.MoneyEventType.TAKE, price)); + player.getInventory().setItemInMainHand(upgrade.getUpgradedItem(gameItem, i)); + player.sendMessage(Lang.ARMOR_UPGRADE.f("&7You applied the &b&l" + upgrade.getDisplayName() + " Armor Upgrade&7 to your " + (i.getItemMeta().hasDisplayName() ? i.getItemMeta().getDisplayName() : i.getType().name()) + "&7 for &a$&l" + price + "&7!")); + return; + } + case 14: + player.closeInventory(); + return; + default: + return; + } + default: + return; + } + case "lottery": { + switch (item.getType()) { + case EMPTY_MAP: + int amnt = Integer.parseInt(ChatColor.stripColor(item.getItemMeta().getDisplayName()) + .replace(" Tickets", "")); + if (!user.hasMoney(amnt * 500)) { + player.sendMessage(Lang.BANK.f("&7You don't have &c$&l" + (amnt * 500) + " &con you!")); + return; + } + user.takeMoney(amnt * 500); + LotteryPlayer p = GTM.getLottery().getLotteryPlayer(uuid); + if (p == null) { + p = new LotteryPlayer(uuid, player.getName()); + GTM.getLottery().addLotteryPlayer(p); + } + p.addTickets(amnt); + GTMUtils.updateBoard(player, user); + player.sendMessage(Lang.LOTTERY.f("&7You bought &e&l" + amnt + " Tickets&7 for &a$&l" + (amnt * 500) + "&7!")); + player.closeInventory(); + return; + case BOOK_AND_QUILL: + user.setCurrentChatAction(ChatAction.BUYING_LOTTERY_TICKETS, 0); + player.closeInventory(); + player.sendMessage(Utils.f(Lang.BANK + + "&7Please type (in chat) the amount of tickets you would like to buy for &a$&l500&7 each, or type&a \"quit\"&7!")); + return; + case REDSTONE: + MenuManager.openMenu(player, "bank"); + return; + default: + break; + } + } + } + + } + + + @EventHandler + public void onMenuClose(MenuCloseEvent e) { + Player player = e.getPlayer(); + UUID uuid = player.getUniqueId(); + Menu menu = e.getMenu(); + switch (menu.getName()) { + case "bountiesplace": + GTMUser user = GTM.getUserManager().getLoadedUser(uuid); + if (user.getCurrentChatAction()==ChatAction.PICKING_BOUNTY || user.getCurrentChatAction()==ChatAction.PICKING_BOUNTY_TARGET) + return; + if (user.getBountyAmount() > 0 || user.getBountyName() != null) + player.sendMessage(Utils.f(Lang.BOUNTIES + "&7You cancelled the bounty.")); + user.setBountyAmount(-1); + user.setBountyName(null); + user.setBountyUUID(null); + return; + default: + break; + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/MobSpawn.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/MobSpawn.java new file mode 100644 index 0000000..954b19e --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/MobSpawn.java @@ -0,0 +1,38 @@ +package net.grandtheftmc.gtm.listeners; + +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.event.entity.EnderDragonChangePhaseEvent; + +import net.grandtheftmc.gtm.GTM; + +/** + * Created by Timothy Lampen on 2017-08-17. + */ +public class MobSpawn implements Listener { + + @EventHandler + public void onSpawn(CreatureSpawnEvent event){ + LivingEntity e = event.getEntity(); + + if (e.getType() == EntityType.ENDER_DRAGON){ + event.setCancelled(true); + } + + if (e.hasMetadata("GTM")) return; + + if(e.getType()==EntityType.RABBIT && !GTM.getHolidayManager().getEaster().isActive()) + event.setCancelled(true); + else if(event.getSpawnReason() != CreatureSpawnEvent.SpawnReason.CUSTOM && event.getEntity().getType() != EntityType.ARMOR_STAND) + event.setCancelled(true); + } + + @EventHandler + public void onEnderDragonChangePhase(EnderDragonChangePhaseEvent event){ + // attempts to stop the enderdragon from changing phases + event.setCancelled(true); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Move.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Move.java new file mode 100644 index 0000000..d4048a2 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Move.java @@ -0,0 +1,77 @@ +package net.grandtheftmc.gtm.listeners; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.drugs.Drug; +import net.grandtheftmc.gtm.drugs.DrugService; +import net.grandtheftmc.gtm.drugs.example.Cocaine; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.users.HouseUser; +import org.bukkit.Location; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.util.Vector; + +import java.util.Optional; + +public class Move implements Listener { + + private int spawnWorldHashcode = -1; + + @EventHandler + public void onMove(PlayerMoveEvent event) { + + + Location to = event.getTo(), from = event.getFrom(); + + if (spawnWorldHashcode == -1 && event.getPlayer().getWorld().getName().equalsIgnoreCase("spawn")) { + //set the hashcode + spawnWorldHashcode = event.getPlayer().getWorld().hashCode(); + } + + if (spawnWorldHashcode == event.getPlayer().getWorld().hashCode()) { + //No need for checks in the spawn world + return; + } + + if (to.getBlockX() == from.getBlockX() && to.getBlockY() == from.getBlockY() && to.getBlockZ() == from.getBlockZ()) { + //Player has not moved block + return; + } + + Player player = event.getPlayer(); + + HouseUser houseUser = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + + if (GTM.getWarpManager().cancelTaxi(player, GTM.getUserManager().getLoadedUser(player.getUniqueId()))) { + player.sendMessage(Lang.TAXI.f("&eYou moved! Teleportation cancelled!")); + return; + } + + if (player.isGliding()) { + if (houseUser.isInsideHouse() || houseUser.isInsidePremiumHouse()) return; + if (!player.isSneaking() || player.getLocation().getY() > 200) return; + double pitch = -event.getTo().getPitch(); + if (pitch < 10 || pitch > 90) return; + Vector vector = player.getLocation().getDirection(); + player.setVelocity(vector.multiply(1.6)); + player.getWorld().playSound(event.getFrom(), Sound.ENTITY_ARROW_SHOOT, 1.0F, 2.0F); + return; + } + + if (!Core.getSettings().isSister()) { + Optional<Drug> cocaine = ((DrugService) GTM.getDrugManager().getService()).getDrug("cocaine"); + + if (cocaine.isPresent()) { + if (((Cocaine) cocaine.get()).cantMove(player.getUniqueId())) { + event.setCancelled(true); + return; + } + } + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/MovementCheat.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/MovementCheat.java new file mode 100644 index 0000000..27cca0e --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/MovementCheat.java @@ -0,0 +1,26 @@ +package net.grandtheftmc.gtm.listeners; + +import net.grandtheftmc.core.anticheat.check.CheatType; +import net.grandtheftmc.core.anticheat.event.MovementCheatEvent; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +/** + * Created by Timothy Lampen on 2/8/2018. + */ +public class MovementCheat implements Listener { + + @EventHandler + public void onMovementCheat(MovementCheatEvent event) { + Player player = event.getPlayerData().getPlayer(); + + if(event.getCheatType().getType()== CheatType.Type.FLIGHT) { + if (player.getInventory().getChestplate() != null && player.getInventory().getChestplate().getType() == Material.ELYTRA) { + if (player.isGliding()) + event.setCancelled(true);//basically cancel the trigger of cheats check if they are gliding using an elytra + } + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/PetListener.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/PetListener.java new file mode 100644 index 0000000..cd78e6e --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/PetListener.java @@ -0,0 +1,29 @@ +package net.grandtheftmc.gtm.listeners; + +/* com.dsh105.echopet.compat.api.event.PetInteractEvent; +import com.dsh105.echopet.compat.api.event.PetTeleportEvent; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.users.GTMUser; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler;*/ +import org.bukkit.event.Listener; + +public class PetListener implements Listener { + + /*@EventHandler + public void onTeleport(PetTeleportEvent e) { + Player player = e.getPet().getOwner(); + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + if (user.isInCombat() || user.isArrested()) + e.setCancelled(true); + } + + @EventHandler + public void onPetInteract(PetInteractEvent e) { + Player player = e.getPet().getOwner(); + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + if (user.isInCombat() || user.isArrested()) + e.setCancelled(true); + }*/ + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Pickup.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Pickup.java new file mode 100644 index 0000000..5a5ec73 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Pickup.java @@ -0,0 +1,86 @@ +package net.grandtheftmc.gtm.listeners; + +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.gtm.items.GameItem; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.GameMode; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerPickupItemEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.items.AmmoType; +import net.grandtheftmc.gtm.users.GTMUser; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class Pickup implements Listener { + + public void m(int i) { + Bukkit.broadcastMessage(String.valueOf(i)); + } + + @EventHandler + public void onPickup(PlayerPickupItemEvent e) { + Player player = e.getPlayer(); + if (player.getGameMode() == GameMode.SPECTATOR) { + e.setCancelled(true); + return; + } + + ItemStack item = e.getItem().getItemStack(); + if (player.isInsideVehicle() || e.getItem().getItemStack().getType() == Material.ARROW) { + e.setCancelled(true); + return; + } + switch (item.getType()) { + case PAPER: + ItemMeta im = item.getItemMeta(); + if (im == null || !im.hasDisplayName()) + return; + String disp = ChatColor.stripColor(item.getItemMeta().getDisplayName()).replace("$", ""); + double amnt; + try { + amnt = Double.parseDouble(disp); + } catch (NumberFormatException ex) { + return; + } + amnt *= item.getAmount(); + + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + user.addMoney(amnt); + player.sendMessage(Utils.f(Lang.MONEY_ADD.toString() + amnt)); + e.getItem().remove(); + e.setCancelled(true); + Utils.kaching(player); + GTMUtils.updateBoard(player, user); + return; + default: + break; + } + AmmoType type = AmmoType.getAmmoType(item.getType(), item.getDurability()); + if (type != null) { + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + if (type.isInInventory()) { + user.updateAmmoLater(); + return; + } + int i = item.getAmount() + e.getRemaining(); + user.addAmmo(type, i); + e.setCancelled(true); + e.getItem().remove(); + player.sendMessage(Lang.AMMO_ADD.f(i + "&7 " + type.getGameItem().getDisplayName())); + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/PortalEnter.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/PortalEnter.java new file mode 100644 index 0000000..70384b3 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/PortalEnter.java @@ -0,0 +1,32 @@ +package net.grandtheftmc.gtm.listeners; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.users.TaxiTarget; +import net.grandtheftmc.gtm.warps.Warp; +import org.bukkit.Sound; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityPortalEnterEvent; + +public class PortalEnter implements Listener { + + @EventHandler + public void playerPortalEvent(EntityPortalEnterEvent event) { + if (event.getEntityType() != EntityType.PLAYER) return; + Player player = (Player) event.getEntity(); + GTMUser gtmUser = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + if (gtmUser.getTaxiTarget() != null) return; + if (event.getLocation().getWorld().getName().equalsIgnoreCase("spawn")) { + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + Warp randomWarp = GTM.getWarpManager().getRandomWarp(); + player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1F, 1F); + GTM.getWarpManager().warp(player, user, GTM.getUserManager().getLoadedUser(player.getUniqueId()), + new TaxiTarget(randomWarp), 0, user.isPremium() ? 1 : 10); + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/PotionSplash.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/PotionSplash.java new file mode 100644 index 0000000..93c6f91 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/PotionSplash.java @@ -0,0 +1,29 @@ +package net.grandtheftmc.gtm.listeners; + +import net.grandtheftmc.gtm.items.ArmorUpgrade; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.PotionSplashEvent; +import org.bukkit.inventory.ItemStack; + +import java.util.HashSet; + +/** + * Created by Timothy Lampen on 7/20/2017. + */ +public class PotionSplash implements Listener { + + @EventHandler + public void onSplashPotion(PotionSplashEvent event){ + for(Entity e : event.getAffectedEntities()){ + if(e instanceof Player){ + Player victim = (Player)e; + if(ArmorUpgrade.playerHasArmorUpgrade(victim, ArmorUpgrade.LEAD_LINED)){ + event.setIntensity(victim, 0); + } + } + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/PrepareItemCraft.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/PrepareItemCraft.java new file mode 100644 index 0000000..0ea1f3f --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/PrepareItemCraft.java @@ -0,0 +1,45 @@ +package net.grandtheftmc.gtm.listeners; + +import net.grandtheftmc.gtm.GTM; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.PrepareItemCraftEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.Recipe; + +import java.util.Arrays; + +/** + * Created by Timothy Lampen on 2017-04-05. + */ +public class PrepareItemCraft implements Listener { + + @EventHandler + public void onPrepareCraft(PrepareItemCraftEvent event){ + /*Recipe recipe = event.getRecipe(); + Bukkit.broadcastMessage("1"); + if(recipe.getResult().equals(GTM.getItemManager().getItem("joint"))){ + Bukkit.broadcastMessage("2"); + if(event.getInventory().getContents()!=null){ + Bukkit.broadcastMessage("4"); + + ItemStack[] contents = event.getInventory().getContents(); + boolean isPossible = true; + for(ItemStack item : contents){ + if(item!=null) { + if (!(item.isSimilar(GTM.getItemManager().getItem("rollingpaper").getItem()) || item.isSimilar(GTM.getItemManager().getItem("groundweed").getItem()))) { + isPossible = false; + } + } + } + if(!isPossible){ + event.getInventory().setResult(new ItemStack(Material.AIR)); + Bukkit.broadcastMessage("3"); + + } + } + }*/ + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/SwapHandItems.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/SwapHandItems.java new file mode 100644 index 0000000..91ab492 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/SwapHandItems.java @@ -0,0 +1,83 @@ +package net.grandtheftmc.gtm.listeners; + +import com.j0ach1mmall3.wastedvehicles.api.events.VehicleEnterEvent; +import com.j0ach1mmall3.wastedvehicles.api.vehicles.WastedVehicle; +import net.grandtheftmc.core.events.PlayerFActionEvent; +import net.grandtheftmc.houses.HouseUtils; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.houses.*; +import net.grandtheftmc.houses.users.HouseUser; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.BlockState; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +import java.util.Set; +import java.util.UUID; + +public class SwapHandItems implements Listener { + + @EventHandler + public void onPlayerFAction(PlayerFActionEvent event) { + Player player = event.getPlayer(); + Block targetBlock; + if (player.getTargetBlock((Set<Material>) null, 1).getType() != Material.AIR) { + targetBlock = player.getTargetBlock((Set<Material>) null, 1); + } else if (player.getTargetBlock((Set<Material>) null, 2).getType() != Material.AIR) { + targetBlock = player.getTargetBlock((Set<Material>) null, 2); + } else { + targetBlock = player.getTargetBlock((Set<Material>) null, 3); + } + player.getWorld().getNearbyEntities(targetBlock.getLocation(), 2, 2, 2).forEach(entity -> { + if (entity.getType() != EntityType.ARMOR_STAND) return; + if (entity.hasMetadata("WastedVehicle")) { + WastedVehicle wastedVehicle = (WastedVehicle) entity.getMetadata("WastedVehicle").get(0).value(); + VehicleEnterEvent vehicleEnterEvent = new VehicleEnterEvent(wastedVehicle, player, (ArmorStand) entity); + Bukkit.getPluginManager().callEvent(vehicleEnterEvent); + if (!vehicleEnterEvent.isCancelled()) wastedVehicle.onRightClick((ArmorStand) entity, player); + } + }); + if (targetBlock.getType() == Material.IRON_DOOR || targetBlock.getType() == Material.IRON_DOOR_BLOCK) { + UUID uuid = player.getUniqueId(); + BlockState state = targetBlock.getState(); + HousesManager hm = Houses.getManager(); + HouseUser houseUser = Houses.getUserManager().getLoadedUser(uuid); + Block underneath = targetBlock.getRelative(BlockFace.DOWN); + if (underneath.getType() == Material.IRON_DOOR_BLOCK) + state = underneath.getState(); + Location loc = state.getLocation(); + Object[] houseAndDoor = hm.getHouseAndDoor(loc); + if (houseAndDoor == null) return; + if (houseAndDoor[0] instanceof PremiumHouse) { + PremiumHouse house = (PremiumHouse) houseAndDoor[0]; + if (houseUser.isTeleporting()) return; + if (!house.hasAccess(player, houseUser) || player.isSneaking()) { + HouseUtils.openPremiumHouseMenu(player, house, houseUser); + return; + } + PremiumHouseDoor door = (PremiumHouseDoor) houseAndDoor[1]; + houseUser.teleportInOrOutPremiumHouse(player, door); + return; + } + House house = (House) houseAndDoor[0]; + if (!houseUser.ownsHouse(house.getId())) { + HouseUtils.openHouseMenu(player, house, houseUser); + return; + } + if (houseUser.isTeleporting()) return; + if (player.isSneaking()) { + HouseUtils.openHouseMenu(player, house, houseUser); + return; + } + HouseDoor door = (HouseDoor) houseAndDoor[1]; + houseUser.teleportInOrOutHouse(player, door); + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Target.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Target.java new file mode 100644 index 0000000..8f2cfbc --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/Target.java @@ -0,0 +1,71 @@ +package net.grandtheftmc.gtm.listeners; + +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.gang.GangManager; +import net.grandtheftmc.gtm.gang.Gang; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.users.JobMode; +import org.bukkit.entity.Player; +import org.bukkit.entity.Tameable; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityTargetEvent; + +import java.util.Objects; +import java.util.UUID; + +public class Target implements Listener { + + @EventHandler + public void onTarget(EntityTargetEvent e) { + if (!(e.getEntity() instanceof Tameable) || !(e.getTarget() instanceof Player)) + return; + Tameable t = (Tameable) e.getEntity(); + if (!(t.getOwner() instanceof Player)) + return; + if ("spawn".equalsIgnoreCase(e.getTarget().getWorld().getName())) { + e.setCancelled(true); + return; + } + Player player = (Player) t.getOwner(); + UUID uuid = player.getUniqueId(); + GTMUser user = GTM.getUserManager().getLoadedUser(uuid); + Player target = (Player) e.getTarget(); + UUID targetUuid = target.getUniqueId(); + GTMUser targetUser = GTM.getUserManager().getLoadedUser(targetUuid); + +// Gang gang = user.getGang(); + Gang gang = GangManager.getInstance().getGangByMember(uuid).orElse(null); + +// Gang targetGang = targetUser.getGang(); + Gang targetGang = GangManager.getInstance().getGangByMember(targetUuid).orElse(null); + + if (targetGang != null && gang != null) { + if (Objects.equals(targetGang, gang)) { + e.setCancelled(true); + return; + } + + if (targetGang.isAllied(gang)) { + e.setCancelled(true); + return; + } + } + + switch (user.getJobMode()) { + case COP: + JobMode mode = targetUser.getJobMode(); + if (user.getJobMode() == JobMode.COP) { + e.setCancelled(true); + break; + } + if (mode == JobMode.CRIMINAL && targetUser.getWantedLevel() == 0) { + e.setCancelled(true); + break; + } + default: + break; + } + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/UpdateListener.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/UpdateListener.java new file mode 100644 index 0000000..ea7364f --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/UpdateListener.java @@ -0,0 +1,466 @@ +package net.grandtheftmc.gtm.listeners; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Random; +import java.util.UUID; +import java.util.stream.Collectors; + +import org.apache.commons.lang.StringUtils; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.events.ChatEvent; +import net.grandtheftmc.core.events.DisplayNameUpdateEvent; +import net.grandtheftmc.core.events.GetPermsEvent; +import net.grandtheftmc.core.events.MoneyEvent; +import net.grandtheftmc.core.events.NametagUpdateEvent; +import net.grandtheftmc.core.events.RewardEvent; +import net.grandtheftmc.core.events.ServerSaveEvent; +import net.grandtheftmc.core.events.TutorialEvent; +import net.grandtheftmc.core.events.UpdateEvent; +import net.grandtheftmc.core.nametags.NametagManager; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserManager; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.voting.Reward; +import net.grandtheftmc.core.voting.Reward.RewardType; +import net.grandtheftmc.core.voting.events.PlayerVoteEvent; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.drugs.Drug; +import net.grandtheftmc.gtm.drugs.DrugService; +import net.grandtheftmc.gtm.drugs.item.DrugItem; +import net.grandtheftmc.gtm.events.TPEvent; +import net.grandtheftmc.gtm.events.WantedLevelChangeEvent; +import net.grandtheftmc.gtm.items.GameItem; +import net.grandtheftmc.gtm.items.Head; +import net.grandtheftmc.gtm.items.ItemManager; +import net.grandtheftmc.gtm.items.Kit; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.users.GTMUserManager; +import net.grandtheftmc.gtm.users.JobMode; +import net.grandtheftmc.gtm.utils.Stats; +import net.grandtheftmc.gtm.weapon.melee.Dildo; +import net.grandtheftmc.gtm.weapon.ranged.special.GoldMinigun; +import net.grandtheftmc.guns.GTMGuns; +import net.grandtheftmc.guns.weapon.Weapon; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.TextComponent; + +public class UpdateListener implements Listener { + private final Map<UUID, Integer> voteCounts = new HashMap<>(); + + @EventHandler + public void voteEvent(PlayerVoteEvent event) { + + // grab event variables + UUID uuid = event.getUUID(); + + // grab the player object + Player player = Bukkit.getPlayer(uuid); + if (player == null){ + return; + } + + // add to vote counter + this.voteCounts.put(uuid, this.voteCounts.getOrDefault(uuid, 0) + 1); + + // grab user objects + GTMUser gtmUser = GTM.getUserManager().getLoadedUser(uuid); + User user = Core.getUserManager().getLoadedUser(uuid); + + Kit kit = GTM.getItemManager().getKit("vote"); + + // currently only 4 active vote sites + if (this.voteCounts.get(uuid) == 4) { + player.sendMessage(Lang.VOTE.f("&7Thank you for voting on all 4 sites! Here is a special vote kit!")); + GTM.getItemManager().giveKitItems(player, gtmUser, kit); + user.addCrowbars(1); + } + } + + @EventHandler + public void tpEvent(TPEvent event) { + if (event.getType() == TPEvent.TPType.HOUSE_ENTER || event.getType() == TPEvent.TPType.PREMIUM_HOUSE_ENTER) { + Player player = event.getPlayer(); + GTMUser gtmUser = GTMUserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + if (gtmUser!= null && gtmUser.isInCombat()) { + event.setCancelled(Utils.f("&7You cannot enter a house while in combat!")); + } + } + } + + @EventHandler + public void serverSaveEvent(ServerSaveEvent event) { + GTM.getShopManager().getHeads().forEach(Head::update); + Collection<GTMUser> gtmUsers = new ArrayList<>(GTMUserManager.getInstance().getUsers()); + gtmUsers.forEach(gtmUser -> { + if (gtmUser == null) + return; + gtmUser.checkAchievements(); + }); + } + + @EventHandler + public void chatEvent(ChatEvent event) { + Player player = event.getSender(); + TextComponent message = event.getTextComponent(); + List<String> hover = Stats.getInstance().getStats(player); + String url = ""; + for (String string : message.getText().split(" ")) { + if (GTMUtils.isValidURL(string)) { + url = string; + break; + } + if (GTMUtils.getUser(player).isRank(UserRank.VIP) && (string.equalsIgnoreCase(":hand:") || string.equalsIgnoreCase(":item:"))) { + if (player.getInventory().getItemInMainHand() == null) + continue; + ItemStack hand = player.getInventory().getItemInMainHand(); + String json = GTMUtils.convertItemStackToJson(hand); + if (json == null) + continue; + if (!hand.hasItemMeta() || !hand.getItemMeta().hasDisplayName()) { + ItemMeta meta = hand.getItemMeta(); + meta.setDisplayName(hand.getType().name().replace("_", " ")); + hand.setItemMeta(meta); + } + message.setText(message.getText().replace(string, hand.getItemMeta().getDisplayName() + message.getColor())); + message.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, new BaseComponent[] { new TextComponent(json) + })); + break; + } + } + if (url.isEmpty()) { + message.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/msg " + player.getName() + ' ')); + } + else { + message.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, url)); + } + if (message.getHoverEvent() == null) { + message.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(StringUtils.join(hover, "\n")).create())); + } + event.setTextComponent(message); + } + + @EventHandler + public void onDisplayNameUpdate(DisplayNameUpdateEvent event) { + + // grab event variables + Player player = event.getPlayer(); + GTMUser gtmUser = GTMUserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + + if (gtmUser != null) { + event.setPrefix(gtmUser.getJobMode() == JobMode.CRIMINAL ? gtmUser.getRank().getColoredNameBold() : gtmUser.getJobMode().getColoredNameBold()); + } + } + + @EventHandler + public void onGetPerms(GetPermsEvent event) { + + // grab event variables + UUID uuid = event.getUUID(); + + GTMUser gtmUser = GTMUserManager.getInstance().getUser(uuid).orElse(null); + if (gtmUser != null && gtmUser.getRank() != null) { + gtmUser.getRank().getAllPerms().forEach(event::addPerm); + } + } + + @EventHandler + public void onNametagChange(NametagUpdateEvent event) { + + // grab event variables + Player player = event.getPlayer(); + if (player == null) { + return; + } + + GTMUser gtmUser = GTMUserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + + if (gtmUser != null) { + + User user = UserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + JobMode mode = gtmUser.getJobMode(); + + if (gtmUser.getWantedLevel() == 0) { + if (mode != JobMode.CRIMINAL) { + event.setSuffix(mode.getColoredNameBold()); + } + else { + if (user.getEquipedTag() != null) { + event.setSuffix(user.getEquipedTag().getBoldName()); + } + else { + event.setSuffix(gtmUser.getRank().getColoredNameBold()); + } + } + } + else { + event.setSuffix(GTMUtils.getWantedLevelStars(gtmUser.getWantedLevel())); + } + } + } + + @EventHandler + public void onTutorialEvent(TutorialEvent e) { + Player player = e.getPlayer(); + switch (e.getType()) { + case PRE_START: + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + if (user.isInCombat()) { + e.setCancelled("&7You can't join tutorials in combat!"); + return; + } + if (user.isArrested()) { + e.setCancelled("&7You can't join tutorials in jail!"); + return; + } + if (!Objects.equals("spawn", player.getWorld().getName())) { + e.setCancelled("&7You can only join tutorials at spawn!"); + return; + } + break; + case START: + GTMUtils.removeBoard(player); + break; + default: + break; + } + + } + + @EventHandler + public void onReward(RewardEvent e) { + + Player player = e.getPlayer(); + Reward reward = e.getReward(); + + if (reward.getCustomType() != null) + switch (reward.getCustomType()) { + case "drug": { + Optional<Drug> drug = ((DrugService) GTM.getDrugManager().getService()).getDrug(reward.getCustomName()); + if (drug.isPresent()) { + DrugItem item = DrugItem.getByDrug(drug.get()); + if (item != null) { + Utils.giveItems(player, item.getItemStack()); + } + else { + player.sendMessage(Lang.GTM + "" + ChatColor.RED + "Unable to give you the drug " + reward.getCustomName() + ", couldn't find it."); + } + } + return; + } + case "item": { + String[] a = reward.getCustomName().split(":"); + GameItem item = GTM.getItemManager().getItem(a[0]); + if (item == null) + return; + ItemStack stack = item.getItem(); + if (a.length > 1) + try { + stack.setAmount(Integer.parseInt(a[1])); + } + catch (NumberFormatException ignored) { + } + if (Utils.giveItems(player, stack)) + player.sendMessage(Utils.f(Lang.VOTE + "&7Your inventory was full so the item was dropped on the ground!")); + e.setSuccessfull(true); + return; + } + case "items": + ItemManager im = GTM.getItemManager(); + boolean successfull = true; + List<ItemStack> items = new ArrayList<>(); + for (String s : reward.getCustomList()) { + String[] a = s.split(":"); + GameItem item = im.getItem(a[0]); + if (item == null) { + successfull = false; + continue; + } + ItemStack stack = item.getItem(); + if (a.length > 1) + try { + stack.setAmount(Integer.parseInt(a[1])); + } + catch (NumberFormatException ignored) { + } + items.add(stack); + } + if (Utils.giveItems(player, Utils.toArray(items))) + player.sendMessage(Utils.f(Lang.VOTE + "&7Your inventory was full so some items were dropped on the ground!")); + e.setSuccessfull(successfull); + return; + case "kit": + Kit kit = GTM.getItemManager().getKit(reward.getCustomName()); + if (kit != null) { + GTM.getItemManager().giveKitItems(player, GTM.getUserManager().getLoadedUser(player.getUniqueId()), kit); + e.setSuccessfull(true); + } + return; + case "permits": + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + user.addPermits((int) reward.getAmount()); + e.setSuccessfull(true); + return; + default: + break; + } + + if (reward.getType() == RewardType.WEAPON) { + + Weapon weapon = GTMGuns.getInstance().getWeaponManager().getWeapon(reward.getName()).orElse(null); + if (weapon != null) { + int stars = reward.getStars(); + WeaponSkin skin = null; + + // clamp bounds + if (stars <= 0) { + stars = 1; + } + if (stars > GTMGuns.MAX_STARS) { + stars = GTMGuns.MAX_STARS; + } + + if (GTMGuns.STAR_SYSTEM) { + Utils.giveItems(player, weapon.createItemStack(stars, skin)); + } + else { + Utils.giveItems(player, weapon.createItemStack()); + } + + e.setSuccessfull(true); + } + } + else if (reward.getType() == RewardType.SKIN) { + Random random = new Random(); + + List<Weapon<?>> weapons = new ArrayList<Weapon<?>>(GTMGuns.getInstance().getWeaponManager().getRegisteredWeapons().stream().filter(weapon -> !(weapon instanceof Dildo) && !(weapon instanceof GoldMinigun)).collect(Collectors.toList())); + + Weapon<?> randomWeapon = weapons.get(random.nextInt(weapons.size())); + WeaponSkin randomSkin = null; + + if (randomWeapon != null && randomWeapon.getWeaponSkins() != null && randomWeapon.getWeaponSkins().length > 1) { + short[] commonSkins = { 5, 7 + }; + + short[] rareSkins = { 2, 6 + }; + +// short[] epicSkins = {}; +// short[] legendarySkins = {}; + + if (reward.getCustomName().equals("weapon_skin_common")) { + randomSkin = GTM.getWeaponSkinManager().getWeaponSkinFromIdentifier(randomWeapon, commonSkins[random.nextInt(commonSkins.length)]); + } + else if (reward.getCustomName().equals("weapon_skin_rare")) { + randomSkin = GTM.getWeaponSkinManager().getWeaponSkinFromIdentifier(randomWeapon, rareSkins[random.nextInt(rareSkins.length)]); + } +// else if (reward.getName().equals("weapon_skin_epic")) { +// randomSkin = GTM.getWeaponSkinManager().getWeaponSkinFromIdentifier(randomWeapon, epicSkins[random.nextInt(rareSkins.length)]); +// } +// else if (reward.getName().equals("weapon_skin_legendary")) { +// randomSkin = GTM.getWeaponSkinManager().getWeaponSkinFromIdentifier(randomWeapon, legendarySkins[random.nextInt(rareSkins.length)]); +// } + + if (randomWeapon == null) { + return; + } + + if (randomSkin == null) { + return; + } + + Utils.giveItems(player, GTM.getWeaponSkinManager().createSkinItem(randomWeapon, randomSkin)); + e.setSuccessfull(true); + } + else { + this.onReward(e); + } + } + } + + @EventHandler + public void onMoneyEvent(MoneyEvent e) { + GTMUser user = GTMUserManager.getInstance().getUser(e.getUUID()).orElse(null); + if (user != null){ + switch (e.getType()) { + case ADD: + user.addMoney(e.getAmount()); + e.setSuccessfull(); + break; + case BALANCE: + e.setBalance(user.getMoney()); + break; + case TAKE: + user.takeMoney(e.getAmount()); + e.setSuccessfull(); + break; + } + } + + GTMUtils.updateBoard(Bukkit.getPlayer(e.getUUID()), user); + } + + @EventHandler + public void onUpdate(UpdateEvent e) { + switch (e.getReason()) { + case BOARD: + case MONEY: + case OTHER: + case RANK: + + GTMUser gtmUser = GTMUserManager.getInstance().getUser(e.getPlayer().getUniqueId()).orElse(null); + if (gtmUser != null){ + GTMUtils.updateBoard(e.getPlayer(), gtmUser); + } + break; + case PREF: + switch (e.getPref()) { + case USE_SCOREBOARD: + gtmUser = GTMUserManager.getInstance().getUser(e.getPlayer().getUniqueId()).orElse(null); + if (gtmUser != null){ + GTMUtils.updateBoard(e.getPlayer(), gtmUser); + } + break; + case TINT_HEALTH: + gtmUser = GTMUserManager.getInstance().getUser(e.getPlayer().getUniqueId()).orElse(null); + if (gtmUser != null){ + User coreUser = UserManager.getInstance().getUser(e.getPlayer().getUniqueId()).orElse(null); + if (coreUser != null){ + gtmUser.updateTintHealth(e.getPlayer(), coreUser); + } + } + break; + default: + break; + } + default: + break; + } + } + + @EventHandler + public void onWantedLevelChange(WantedLevelChangeEvent e) { + GTMUtils.updateBoard(e.getPlayer(), e.getUser()); + NametagManager.updateNametag(e.getPlayer()); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/VehicleUse.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/VehicleUse.java new file mode 100644 index 0000000..8da1bea --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/VehicleUse.java @@ -0,0 +1,248 @@ +package net.grandtheftmc.gtm.listeners; + +import java.util.Objects; +import java.util.Optional; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityToggleGlideEvent; +import org.bukkit.inventory.ItemStack; + +import com.j0ach1mmall3.wastedvehicles.api.events.JetpackFlyEvent; +import com.j0ach1mmall3.wastedvehicles.api.events.VehicleDestroyEvent; +import com.j0ach1mmall3.wastedvehicles.api.events.VehicleEnterEvent; +import com.j0ach1mmall3.wastedvehicles.api.events.VehiclePassengerEnterEvent; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserManager; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.gang.Gang; +import net.grandtheftmc.gtm.gang.GangManager; +import net.grandtheftmc.gtm.users.GTMRank; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.users.GTMUserManager; +import net.grandtheftmc.gtm.users.JobMode; +import net.grandtheftmc.gtm.users.PersonalVehicle; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.users.HouseUser; + +public class VehicleUse implements Listener { + + @EventHandler + public void onVehiclePassengerEnter(VehiclePassengerEnterEvent event) { + if (Bukkit.getPlayer(event.getVehicle().getCreator()) == null) return; + Player passenger = event.getPlayer(); + Player owner = Bukkit.getPlayer(event.getVehicle().getCreator()); + + GTMUser passengerUser = GTMUserManager.getInstance().getUser(passenger.getUniqueId()).orElse(null); + GTMUser ownerUser = GTMUserManager.getInstance().getUser(owner.getUniqueId()).orElse(null); + + Optional<Gang> ownerOpt = GangManager.getInstance().getGangByMember(owner.getUniqueId()), passengerOpt = GangManager.getInstance().getGangByMember(passenger.getUniqueId()); + + if (!ownerOpt.isPresent() || !passengerOpt.isPresent()) { + passenger.sendMessage(Lang.VEHICLES.f("&fYou must be in the same gang as the Vehicle Driver to enter!")); + event.setCancelled(true); + } else { + if (ownerOpt.get() != passengerOpt.get()) { + passenger.sendMessage(Lang.VEHICLES.f("&fYou must be in the same gang as the Vehicle Driver to enter!")); + event.setCancelled(true); + return; + } + + event.setCancelled(false); + } + } + + @EventHandler + public void onVehicleEnter(VehicleEnterEvent e) { + Player player = e.getPlayer(); + if (Objects.equals("spawn", player.getWorld().getName())) { + player.sendMessage(Lang.HEY.f("&7You can't enter vehicles in spawn!")); + e.setCancelled(true); + return; + } + + GTMUser gtmUser = GTMUserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + + if (gtmUser != null){ + if (gtmUser.isArrested()) { + player.sendMessage(Lang.JAIL.f("&7You can't enter vehicles in jail!")); + e.setCancelled(true); + } + } + + if (e.getVehicle().getCreator() == null) return; + Player creator = Bukkit.getPlayer(e.getVehicle().getCreator()); + if (creator != null) { + User u = UserManager.getInstance().getUser(creator.getUniqueId()).orElse(null); + GTMUser user = GTMUserManager.getInstance().getUser(creator.getUniqueId()).orElse(null); + + if (u != null && user != null){ + PersonalVehicle vehicle = user.getPersonalVehicle(); + if (vehicle == null) return; + if (Objects.equals(creator, player)) { + if (!vehicle.isStolen()) return; + vehicle.setStolen(false); + player.sendMessage(Lang.VEHICLES.f("&7You recovered your stolen " + vehicle.getDisplayName() + "&7!")); + return; + } + if (!Objects.equals(e.getArmorStand().getUniqueId(), vehicle.getEntityUUID()) || e.getArmorStand().getPassenger() != null || vehicle.isStolen()) + return; + vehicle.setStolen(true); + vehicle.updateVehicleInDatabase(creator, e.getArmorStand().getHealth()); + creator.sendMessage(Lang.VEHICLES.f("&7Your &c&l" + vehicle.getDisplayName() + "&7 was stolen!")); + player.sendMessage(Lang.VEHICLES.f("&7You stole " + u.getColoredName(creator) + "&7's " + vehicle.getDisplayName() + "&7!")); + } + } + } + + @EventHandler + public void onVehicleDestroy(VehicleDestroyEvent e) { + + // grab event variables + Player creator = Bukkit.getPlayer(e.getVehicle().getCreator()); + + if (creator != null) { + + GTMUser user = GTMUserManager.getInstance().getUser(creator.getUniqueId()).orElse(null); + if (user != null){ + PersonalVehicle vehicle = user.getPersonalVehicle(); + if (vehicle == null || !e.getVehicle().getVehicleProperties().getIdentifier().equalsIgnoreCase(vehicle.getVehicle())) + return; + vehicle.updateVehicleInDatabase(creator, 0); + creator.sendMessage(Lang.VEHICLES.f("&7Your &c&l" + vehicle.getDisplayName() + "&7 was destroyed!")); + } + } + } + + @EventHandler + public void onJetpackFly(JetpackFlyEvent e) { + + // grab event variables + Player p = e.getPlayer(); + GTMUser user = GTMUserManager.getInstance().getUser(p.getUniqueId()).orElse(null); + + if (p.isSprinting() && p.isFlying()) { + p.setSprinting(false); + } + + if (user != null){ + if (user.getJobMode() == JobMode.COP) { + e.setCancelled(true); + + if (p.getInventory().getChestplate() != null){ + ItemStack chestItem = p.getInventory().getChestplate(); + + if (chestItem.getType() == Material.ELYTRA || chestItem.getType() == Material.GOLD_CHESTPLATE) { + Utils.giveItems(p, p.getInventory().getChestplate()); + p.getInventory().setChestplate(null); + } + } + + if (user.getLastJetpackCancel() + 2000 < System.currentTimeMillis()) { + user.setLastJetpackCancel(System.currentTimeMillis()); + e.getPlayer().sendMessage(Lang.VEHICLES.f("&7Jetpacks cannot be used by Cops.")); + e.getPlayer().setAllowFlight(false); + e.getPlayer().setFlying(false); + } + return; + } + if(!user.canUseJetpack()){ + e.setCancelled(true); + if (user.getLastJetpackCancel() + 2000 < System.currentTimeMillis()) { + user.setLastJetpackCancel(System.currentTimeMillis()); + e.getPlayer().sendMessage(Lang.VEHICLES.f("&7Your jetpack was disabled! Please wait &a&l"+Utils.timeInMillisToText(user.getEnableJetpackTime()-System.currentTimeMillis())+"&7 to start flying again.")); + e.getPlayer().setAllowFlight(false); + e.getPlayer().setFlying(false); + } + return; + } + + User coreUser = UserManager.getInstance().getUser(p.getUniqueId()).orElse(null); + if (coreUser != null){ + if (!user.isRank(GTMRank.MOBSTER) && !coreUser.isRank(UserRank.SPONSOR)) { + e.setCancelled(true); + + ItemStack chestPlate = p.getInventory().getChestplate(); + if (chestPlate != null) { + if (chestPlate.getType() == Material.ELYTRA || chestPlate.getType() == Material.GOLD_CHESTPLATE){ + Utils.giveItems(p, p.getInventory().getChestplate()); + p.getInventory().setChestplate(null); + } + } + + if (user.getLastJetpackCancel() + 2000 < System.currentTimeMillis()) { + user.setLastJetpackCancel(System.currentTimeMillis()); + e.getPlayer().sendMessage(Lang.VEHICLES.f("&7You need to rank up to " + GTMRank.MOBSTER.getColoredNameBold() + "&7 or donate for " + UserRank.SPONSOR.getColoredNameBold() + "&7 at &a&l" + Core.getSettings().getStoreLink() + "&7 to use the jetpack!")); + e.getPlayer().setAllowFlight(false); + e.getPlayer().setFlying(false); + } + } + } + } + + // get house user + HouseUser houseUser = Houses.getUserManager().getLoadedUser(p.getUniqueId()); + if (houseUser != null){ + + // are they inside a house + if (houseUser.isInsideHouse()){ + + // if they have the jetpack on, unequip + if (p.getInventory().getChestplate()!=null && p.getInventory().getChestplate().getType() == Material.ELYTRA + || p.getInventory().getChestplate().getType() == Material.GOLD_CHESTPLATE) { + Utils.giveItems(p, p.getInventory().getChestplate()); + p.getInventory().setChestplate(null); + } + + if (user.getLastJetpackCancel() + 2000 < System.currentTimeMillis()) { + user.setLastJetpackCancel(System.currentTimeMillis()); + e.getPlayer().sendMessage(Lang.VEHICLES.f("&fYou cannot use a &4jetpack &fin houses!")); + e.getPlayer().setAllowFlight(false); + e.getPlayer().setFlying(false); + } + } + } + } + + @EventHandler + public void onPlayerFly(EntityToggleGlideEvent event){ + + Entity entity = event.getEntity(); + if (!(entity instanceof Player)){ + return; + } + + Player p = (Player) entity; + GTMUser user = GTMUserManager.getInstance().getUser(p.getUniqueId()).orElse(null); + + if (user != null){ + + if (user.getJobMode() == JobMode.COP) { + event.setCancelled(true); + + if (p.getInventory().getChestplate()!=null && p.getInventory().getChestplate().getType() == Material.ELYTRA + || p.getInventory().getChestplate().getType() == Material.GOLD_CHESTPLATE) { + Utils.giveItems(p, p.getInventory().getChestplate()); + p.getInventory().setChestplate(null); + } + + if (user.getLastJetpackCancel() + 2000 < System.currentTimeMillis()) { + user.setLastJetpackCancel(System.currentTimeMillis()); + p.sendMessage(Lang.VEHICLES.f("&7Wingsuits and/or Jetpacks cannot be used by Cops.")); + p.setAllowFlight(false); + p.setFlying(false); + } + + return; + } + } + } +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/VoteReward.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/VoteReward.java new file mode 100644 index 0000000..4ced82e --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/VoteReward.java @@ -0,0 +1,128 @@ +package net.grandtheftmc.gtm.listeners; + +import java.util.Optional; + +import org.bukkit.Material; +import org.bukkit.entity. Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import com.j0ach1mmall3.wastedvehicles.api.VehicleProperties; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.util.State; +import net.grandtheftmc.core.voting.Reward; +import net.grandtheftmc.core.voting.events.RewardCheckEvent; +import net.grandtheftmc.core.voting.events.RewardGiveEvent; +import net.grandtheftmc.core.voting.events.RewardInfoEvent; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.users.CheatCode; +import net.grandtheftmc.gtm.users.CheatCodeState; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.guns.GTMGuns; +import net.grandtheftmc.guns.weapon.Weapon; + +public class VoteReward implements Listener { + + @EventHandler + public void rewardGiveEvent(RewardGiveEvent event) { + Player player = event.getPlayer(); + GTMUser gtmUser = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + String identifier = event.getIdentifier(); + switch (event.getRewardType()) { + case VEHICLE: { + Optional<VehicleProperties> vehicleOptional = GTM.getWastedVehicles().getVehicle(identifier); + if (!vehicleOptional.isPresent()) return; + gtmUser.giveVehiclePerm(player, vehicleOptional.get()); + player.sendMessage(Lang.REWARDS.f("&4&l" + identifier)); + break; + } + case CHEATCODE: { + CheatCode code = CheatCode.valueOf(identifier.toUpperCase()); + if(gtmUser.getCheatCodeState(code).getState()== State.LOCKED) { + gtmUser.setCheatCodeState(code, new CheatCodeState(code.getDefaultState(), false)); + player.sendMessage(Lang.REWARDS.f("&a&l+ " + code.toString() + " CHEATCODE")); + } + else + player.sendMessage(Lang.REWARDS.f("&cYou recieved the " + identifier + " cheatcode, but you already have it.")); + break; + } + // Note: give event for weapons is handled in UpdateListener + } + + } + + @EventHandler + public void rewardCheckEvent(RewardCheckEvent event) { + GTMUser gtmUser = GTM.getUserManager().getLoadedUser(event.getPlayer().getUniqueId()); + String identifier = event.getIdentifier(); + switch (event.getRewardType()) { + case VEHICLE: + Optional<VehicleProperties> vehicleOptional = GTM.getWastedVehicles().getVehicle(identifier); + if (!vehicleOptional.isPresent()) return; + event.setResult(gtmUser.hasVehicle(identifier)); + break; + case CHEATCODE: + CheatCode code = CheatCode.valueOf(identifier.toUpperCase()); + event.setResult(gtmUser.getCheatCodeState(code).getState()!=State.LOCKED); + break; + } + } + + @EventHandler + public void rewardInfoEvent(RewardInfoEvent event) { + + Reward reward = event.getReward(); + String identifier = event.getIdentifier(); + + switch (event.getRewardType()) { + case VEHICLE: + Optional<VehicleProperties> vehicleOptional = GTM.getWastedVehicles().getVehicle(identifier); + if (!vehicleOptional.isPresent()) return; + event.setDisplayItem(vehicleOptional.get().getItem()); + break; + case CHEATCODE: + CheatCode code = CheatCode.valueOf(identifier.toUpperCase()); + event.setDisplayItem(code.getDisplayItem(null, State.LOCKED)); + break; + case WEAPON: + + Weapon weapon = GTMGuns.getInstance().getWeaponManager().getWeapon(reward.getName()).orElse(null); + + // if reward object is here + if (GTMGuns.STAR_SYSTEM){ + int stars = 1; + if (reward != null){ + stars = reward.getStars(); + } + + event.setDisplayItem(weapon.createItemStack(stars, null)); + } + else{ + event.setDisplayItem(weapon.createItemStack()); + } + break; + case SKIN: + ItemStack stack = new ItemStack(Material.ENCHANTED_BOOK); + ItemMeta meta = stack.getItemMeta(); + + if (event.getIdentifier().equals("weapon_skin_common")) { + meta.setDisplayName(Utils.f("&9&lCommon Weapon Skin")); + } else if (event.getIdentifier().equals("weapon_skin_rare")) { + meta.setDisplayName(Utils.f("&9&lRare Weapon Skin")); + } else if (event.getIdentifier().equals("weapon_skin_epic")) { + meta.setDisplayName(Utils.f("&9&lEpic Weapon Skin")); + } else if (event.getIdentifier().equals("weapon_skin_legendary")) { + meta.setDisplayName(Utils.f("&9&lLegendary Weapon Skin")); + } + + stack.setItemMeta(meta); + event.setDisplayItem(stack); + + break; + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/WeaponShoot.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/WeaponShoot.java new file mode 100644 index 0000000..adf34fa --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/WeaponShoot.java @@ -0,0 +1,42 @@ +package net.grandtheftmc.gtm.listeners; + +import com.j0ach1mmall3.wastedguns.api.events.ranged.RangedWeaponShootEvent; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.guns.weapon.Weapon; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +import java.util.Arrays; +import java.util.List; + +public class WeaponShoot implements Listener { + private final List<String> carGuns = Arrays.asList("Pistol", "CombatPistol", "HeavyPistol", "MarksmanPistol", + "TearGas", "StickyBomb", "Grenade", "MolotovCocktail", "ProximityMine", "MicroSMG", "SMG", "NetLauncher"); + + @EventHandler(ignoreCancelled = true) + public void onRangedWeaponShootEvent(RangedWeaponShootEvent event) { + if (event.getLivingEntity().getType() != EntityType.PLAYER) return; + Weapon weapon = event.getWeapon(); + String weaponName = weapon.getName(); + Player shooter = (Player) event.getLivingEntity(); + boolean inCar = shooter.getVehicle() != null && shooter.getVehicle().hasMetadata("WastedVehiclePassenger"); +// if (weapon.getItemStack().getDurability() != 0) { +// if (weapon.getIdentifier().equalsIgnoreCase("GoldMinigun") +// || weapon.getIdentifier().equalsIgnoreCase("Flamethrower")) return; +// weapon.getItemStack().setDurability((short) 0); +// } + if(inCar && !carGuns.contains(weaponName)) { + shooter.sendMessage(Lang.HEY.f("&7Weapon cannot be used in Car")); + event.setCancelled(true); + return; + } + if (weaponName.contains("NetLauncher")) { + if(shooter.getWorld().getName().equalsIgnoreCase("spawn")) { + shooter.sendMessage(Lang.HEY.f("&7The Net Launcher cannot be used in spawn")); + event.setCancelled(true); + } + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/WeaponUse.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/WeaponUse.java new file mode 100644 index 0000000..f845374 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/listeners/WeaponUse.java @@ -0,0 +1,613 @@ +package net.grandtheftmc.gtm.listeners; + +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import com.j0ach1mmall3.wastedguns.api.events.NetgunHitEvent; +import com.j0ach1mmall3.wastedguns.api.events.WeaponDamageEvent; +import com.j0ach1mmall3.wastedguns.api.events.WeaponRightClickEvent; +import com.j0ach1mmall3.wastedguns.api.events.WeaponSneakEvent; +import com.j0ach1mmall3.wastedguns.api.events.ranged.AmmoUpdateEvent; +import com.j0ach1mmall3.wastedguns.api.events.ranged.RangedWeaponReloadEvent; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserManager; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.gang.Gang; +import net.grandtheftmc.gtm.gang.GangManager; +import net.grandtheftmc.gtm.items.AmmoType; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.users.GTMUserManager; +import net.grandtheftmc.gtm.users.JobMode; +import net.grandtheftmc.gtm.users.LockedWeapon; +import net.grandtheftmc.guns.weapon.Weapon; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.users.HouseUser; + +public class WeaponUse implements Listener { + + private final List<String> spawnBlocked = Arrays.asList("grenade", "molotovcocktail", "teargas", "stickybomb", + "proximitymine", "grenadelauncher", "hominglauncher", "rpg", "netlauncher"); + + private boolean blockedWhileFlyingJetpack(String weapon) { + + // allowed weapons + if (Arrays.asList("baseballbat", "dildo", "katana", "knife", "nightstick", "rake", "pistol", "combatpistol", "heavypistol", "stun gun", "sawed-offshotgun", "microsmg").contains(weapon.toLowerCase())){ + return false; + } + + return true; + } + + private boolean blockedWhileWearingJetpack(String weapon) { + + // allowed weapons + if (Arrays.asList("baseballbat", "dildo", "katana", "knife", "nightstick", "rake", "chainsaw", "pistol", "combatpistol", "heavypistol", "stun gun", "marksmanpistol", "sawed-offshotgun", "microsmg", "smg", "assaultsmg", "combatpdw").contains(weapon.toLowerCase())){ + return false; + } + + return true; + } + + private boolean blockedWhileFlyingWingsuit(String weapon) { + + // allowed weapons + if (Arrays.asList("baseballbat", "dildo", "katana", "knife", "nightstick", "rake", "chainsaw", "pistol", "combatpistol", "heavypistol", "stun gun", "sawed-offshotgun", "microsmg", "smg", "assaultsmg", "combatpdw", "gusenbergsweeper", "assaultrifle", "carbinerifle", "bullpuprifle", "advancedrifle", "specialcarbine").contains(weapon.toLowerCase())){ + return false; + } + + return true; + } + + private boolean blockedWhileWearingWingsuit(String weapon) { + + // allowed weapons + if (Arrays.asList("baseballbat", "dildo", "katana", "knife", "nightstick", "rake", "chainsaw", "pistol", "combatpistol", "heavypistol", "stun gun", "marksmanpistol", "sawed-offshotgun", "microsmg", "smg", "assaultsmg", "combatpdw", "gusenbergsweeper", "sawed-offshotgun", "pumpshotgun", "musket", "assaultshotgun", "heavyshotgun", "assaultrifle", "carbinerifle", "bullpuprifle", "advancedrifle", "specialcarbine").contains(weapon.toLowerCase())){ + return false; + } + + return true; + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onAmmoChange(AmmoUpdateEvent e) { + + // grab event variables + Player p = e.getPlayer(); + + // grab user + GTMUser user = GTMUserManager.getInstance().getUser(p.getUniqueId()).orElse(null); + + if (user != null){ + + for (AmmoType type : AmmoType.getTypes()){ + e.getAmmo().put(type.name(), user.getAmmo(type)); + } + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onReload(RangedWeaponReloadEvent e) { + Weapon weapon = e.getWeapon(); + + // if weapon does not have ammo, or if entity in event is not a player + if (weapon.getAmmoType() == null || !(e.getLivingEntity() instanceof Player)) + return; + + AmmoType type = AmmoType.getAmmoType(weapon.getAmmoType().getType()); + + // if unable to find ammo type + if (type == null) + return; + + // get the player + Player player = (Player) e.getLivingEntity(); + GTMUser user = GTMUserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + + LockedWeapon lockedWeapon = LockedWeapon.getWeapon(weapon.getCompactName()); + + // is this a locked weapon + if (lockedWeapon != null) { + + // get core user + User coreUser = UserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + if (coreUser != null) { + + // if the core rank is not higher than or equal to locked weapon rank + if (!(coreUser.getUserRank() == lockedWeapon.getUserRank() || coreUser.getUserRank().isHigherThan(lockedWeapon.getUserRank()))) { + + if (user != null) { + + // if the gtm rank is not higher than or weapon to locked weapon rank + if (!(user.getRank() == lockedWeapon.getGTMRank() || user.getRank().isHigherThan(lockedWeapon.getGTMRank()))) { + player.sendMessage(Lang.HEY.f("&7You need to rank up to " + lockedWeapon.getGTMRank().getColoredNameBold() + "&7 or donate for " + lockedWeapon.getUserRank().getColoredNameBold() + "&7 at &a&l" + Core.getSettings().getStoreLink() + "&7 to use this weapon!")); + e.setCancelled(true); + return; + } + } + } + } + } + + if (user != null){ + int ammo = user.getAmmo(type); + if (ammo <= 0) { + e.setCancelled(true); + player.sendMessage(Lang.AMMO.f("&7You are out of ammo for this weapon!")); + } else if (ammo < e.getAmmoToReload()) { + e.setAmmoToReload(ammo); + user.removeAmmo(type, ammo); + } else + user.removeAmmo(type, e.getAmmoToReload()); + } + else{ + e.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onWeaponUse(WeaponRightClickEvent e) { + if (!(e.getLivingEntity() instanceof Player)) + return; + + Player player = (Player) e.getLivingEntity(); + Weapon weapon = e.getWeapon(); + if (Objects.equals("spawn", player.getWorld().getName())) { + if (this.spawnBlocked.contains(weapon.getCompactName().toLowerCase())) { + e.setCancelled(true); + return; + } + } + + GTMUser gtmUser = GTMUserManager.getInstance().getUser(player.getUniqueId()).orElse(null); +// LockedWeapon lockedWeapon = LockedWeapon.getWeapon(e.getWeapon().getCompactName().toUpperCase()); +// if(lockedWeapon != null && !lockedWeapon.canUseWeapon(gtmUser.getRank(), Core.getUserManager().getLoadedUser(player.getUniqueId()).getUserRank())) { +// player.sendMessage(Lang.HEY.f("&7You need to rank up to " + lockedWeapon.getGTMRank().getColoredNameBold() + "&7 or donate for " + lockedWeapon.getUserRank().getColoredNameBold() + "&7 at &a&lstore.grandtheftmc.net&7 to use this weapon!")); +// e.setCancelled(true); +// return; +// } + + LockedWeapon lockedWeapon = LockedWeapon.getWeapon(weapon.getCompactName()); + if (lockedWeapon != null) { + //ServerUtil.debug("1 - " + lockedWeapon.name()); + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + //ServerUtil.debug("2 - " + user.getUserRank().name() + " (has:" + (user.getUserRank() == lockedWeapon.getUserRank() || user.getUserRank().isHigherThan(lockedWeapon.getUserRank())) + ")"); + //ServerUtil.debug("3 - " + gtmUser.getRank().name() + " (has:" + (gtmUser.getRank() == lockedWeapon.getGTMRank() || gtmUser.getRank().isHigherThan(lockedWeapon.getGTMRank())) + ")"); + + if (!(user.getUserRank() == lockedWeapon.getUserRank() || user.getUserRank().isHigherThan(lockedWeapon.getUserRank())) + && !(gtmUser.getRank() == lockedWeapon.getGTMRank() || gtmUser.getRank().isHigherThan(lockedWeapon.getGTMRank()))) { + player.sendMessage(Lang.HEY.f("&7You need to rank up to " + lockedWeapon.getGTMRank().getColoredNameBold() + "&7 or donate for " + lockedWeapon.getUserRank().getColoredNameBold() + "&7 at &a&l" + Core.getSettings().getStoreLink() + "&7 to use this weapon!")); + e.setCancelled(true); + //ServerUtil.debug("Blocked."); + return; + } + } + + if (gtmUser != null){ + if (gtmUser.isArrested()) { + player.sendMessage(Lang.JAIL.f("&7You can't use weapons in jail!")); + e.setCancelled(true); + return; + } + + if (gtmUser.hasTeleportProtection()) { + e.setCancelled(true); + player.sendMessage(Lang.COMBATTAG.f("&7Please wait &c&l" + Utils.timeInMillisToText(gtmUser.getTimeUntilTeleportProtectionExpires()) + "&7!")); + return; + } + } + + ItemStack chestPlate = player.getInventory().getChestplate(); + if (chestPlate != null && chestPlate.getType() == Material.ELYTRA) { + if (this.blockedWhileWearingWingsuit(weapon.getCompactName())) { + player.sendMessage(Lang.VEHICLES.f("&7The weapon " + weapon.getCompactName() + " cannot be used while wearing a wingsuit!")); + e.setCancelled(true); + return; + } + if (player.isGliding() && this.blockedWhileFlyingWingsuit(weapon.getCompactName())) { + player.sendMessage(Lang.VEHICLES.f("&7The weapon " + weapon.getCompactName() + " cannot be used while flying a wingsuit!")); + e.setCancelled(true); + return; + } + } + + if (chestPlate != null && chestPlate.getType() == Material.GOLD_CHESTPLATE){ + if (this.blockedWhileWearingJetpack(weapon.getCompactName())) { + player.sendMessage(Lang.VEHICLES.f("&7The weapon " + weapon.getCompactName() + " cannot be used while wearing a jetpack!")); + e.setCancelled(true); + return; + } + if (player.isFlying() && this.blockedWhileFlyingJetpack(weapon.getCompactName())) { + player.sendMessage(Lang.VEHICLES.f("&7The weapon " + weapon.getCompactName() + " cannot be used while flying a jetpack!")); + e.setCancelled(true); + return; + } + } + + HouseUser user = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + if (user.isInsideHouse() || user.isInsidePremiumHouse()){ + e.setCancelled(true); + } + } + + + @EventHandler(priority = EventPriority.HIGHEST) + public void onWeaponUse(WeaponSneakEvent e) { + if (!(e.getLivingEntity() instanceof Player)) + return; + Player player = (Player) e.getLivingEntity(); + Weapon weapon = e.getWeapon(); + if (Objects.equals("spawn", player.getWorld().getName())) { + if (this.spawnBlocked.contains(weapon.getCompactName().toLowerCase())) { + e.setCancelled(true); + return; + } + } + + + GTMUser gtmUser = GTMUserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + + LockedWeapon lockedWeapon = LockedWeapon.getWeapon(weapon.getCompactName()); + if (lockedWeapon != null) { + + User coreUser = UserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + if (coreUser == null){ + e.setCancelled(true); + return; + } + + if (!(coreUser.getUserRank() == lockedWeapon.getUserRank() || coreUser.getUserRank().isHigherThan(lockedWeapon.getUserRank())) + && !(gtmUser.getRank() == lockedWeapon.getGTMRank() || gtmUser.getRank().isHigherThan(lockedWeapon.getGTMRank()))) { + player.sendMessage(Lang.HEY.f("&7You need to rank up to " + lockedWeapon.getGTMRank().getColoredNameBold() + "&7 or donate for " + lockedWeapon.getUserRank().getColoredNameBold() + "&7 at &a&l" + Core.getSettings().getStoreLink() + "&7 to use this weapon!")); + e.setCancelled(true); + return; + } + } + + if (gtmUser != null){ + if (gtmUser.isArrested()) { + player.sendMessage(Lang.JAIL.f("&7You can't use weapons in jail!")); + e.setCancelled(true); + return; + } + if (gtmUser.hasTeleportProtection()) { + e.setCancelled(true); + player.sendMessage(Lang.COMBATTAG.f("&7Please wait &c&l" + Utils.timeInMillisToText(gtmUser.getTimeUntilTeleportProtectionExpires()) + "&7!")); + return; + } + } + + ItemStack chestPlate = player.getInventory().getChestplate(); + + if (chestPlate != null && chestPlate.getType() == Material.GOLD_CHESTPLATE) + if (this.blockedWhileWearingJetpack(weapon.getCompactName())) { + e.setCancelled(true); + return; + } + if (player.isFlying() && this.blockedWhileFlyingJetpack(weapon.getCompactName())) { + e.setCancelled(true); + return; + } + HouseUser user = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + if (user.isInsideHouse() || user.isInsidePremiumHouse()) + e.setCancelled(true); + } + + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void onShoot(WeaponDamageEvent e) { + if (!(e.getLivingEntity() instanceof Player) || !(e.getEntity() instanceof Player) || Objects.equals("spawn", e.getEntity().getWorld().getName())) + return; + + // grab event variables + Weapon weapon = e.getWeapon(); + Player player = (Player) e.getLivingEntity(); + Player victim = (Player) e.getEntity(); + UUID victimUUID = victim.getUniqueId(); + + GTMUser gtmUser = GTMUserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + GTMUser victimGtmUser = GTMUserManager.getInstance().getUser(victimUUID).orElse(null); + + if (victimGtmUser != null && victimGtmUser.hasTeleportProtection()) { + e.setCancelled(true); + player.sendMessage(Lang.COMBATTAG.f("&7That player has teleport protection for &c&l" + Utils.timeInMillisToText(victimGtmUser.getTimeUntilTeleportProtectionExpires()) + "&7!")); + return; + } + + if (gtmUser != null && gtmUser.hasTeleportProtection()) { + e.setCancelled(true); + player.sendMessage(Lang.COMBATTAG.f("&7Please wait &c&l" + Utils.timeInMillisToText(gtmUser.getTimeUntilTeleportProtectionExpires()) + "&7 to damage players!")); + return; + } + + HouseUser victimHouseUser = Houses.getUserManager().getLoadedUser(victimUUID); + HouseUser playerHouseUser = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + if (victimHouseUser.isInsideHouse() || victimHouseUser.isInsidePremiumHouse()) { + e.setCancelled(true); + player.sendMessage(Lang.HOUSES.f("&7You can't hurt players inside a house!")); + return; + } + + if (playerHouseUser.isInsideHouse() || playerHouseUser.isInsidePremiumHouse()) { + e.setCancelled(true); + player.sendMessage(Lang.HOUSES.f("&7You can't hurt players while inside a house!")); + } + + +// Gang victimGang = victimGtmUser.getGang(); +// Gang damagerGang = gtmUser.getGang(); + Gang victimGang = GangManager.getInstance().getGangByMember(victimUUID).orElse(null); + Gang damagerGang = GangManager.getInstance().getGangByMember(player.getUniqueId()).orElse(null); + if (victimGang != null && damagerGang != null && !Objects.equals(victim, player)) { + if (Objects.equals(victimGang, damagerGang)) { + e.setCancelled(true); + player.sendMessage(Lang.GANGS.f("&7You can't hurt players that are in your gang!")); + return; + } + + if (victimGang.isAllied(damagerGang)) { + e.setCancelled(true); + player.sendMessage(Lang.GANGS.f("&7You can't hurt players that are in an allied gang!")); + return; + } + } + + if (weapon.getCompactName().equalsIgnoreCase("flamethrower")) { + victim.setFireTicks(victim.getFireTicks() + 20); + victim.getNearbyEntities(5, 0, 5).forEach(entity -> { + if (entity == victim || entity.getType() != EntityType.PLAYER) return; + Player target = (Player) entity; + if (target.getGameMode() != GameMode.ADVENTURE) return; + target.setFireTicks(target.getFireTicks() + 10); + }); + return; + } + + // grab the player jetpack + ItemStack chestPlate = player.getInventory().getChestplate(); + + // if player is wearing a chestplate of some sort + if (chestPlate != null){ + + // if source player is wearing a jetpack + if (chestPlate.getType().equals(Material.GOLD_CHESTPLATE)){ + if (blockedWhileWearingJetpack(weapon.getCompactName())){ + e.setCancelled(true); + player.sendMessage(Lang.VEHICLES.f("&7The weapon " + weapon.getCompactName() + " cannot be used while wearing a jetpack!")); + return; + } + } + + // if source player is wearing a wingsuit + if (chestPlate.getType().equals(Material.ELYTRA)){ + if (blockedWhileWearingWingsuit(weapon.getCompactName())){ + e.setCancelled(true); + player.sendMessage(Lang.VEHICLES.f("&7The weapon " + weapon.getCompactName() + " cannot be used while wearing a wingsuit!")); + return; + } + } + } + + if (weapon.getCompactName().equalsIgnoreCase("stungun") && victim.getInventory().getChestplate() != null && victim.getInventory().getChestplate().getType().equals(Material.GOLD_CHESTPLATE)) { + victimGtmUser.disableJetpack(); + victim.setFlying(false); + } + + if (gtmUser != null && gtmUser.getJobMode() != JobMode.COP) return; + if (victimGtmUser != null && victimGtmUser.getJobMode() == JobMode.COP) { + e.setCancelled(true); + player.sendMessage(Utils.f(Lang.HEY + "&cYou can't kill cops!")); + return; + } + + if (victimGtmUser != null && victimGtmUser.getJobMode() == JobMode.CRIMINAL && victimGtmUser.getWantedLevel() == 0) { + player.sendMessage(Lang.HEY.f("&7You can't damage citizens that are not wanted!")); + e.setCancelled(true); + return; + } + + if (gtmUser != null && gtmUser.getJobMode() == JobMode.COP) { + if (weapon.getCompactName().equalsIgnoreCase("nightstick")) { + victim.addPotionEffect(new PotionEffect(PotionEffectType.CONFUSION, 80, 1)); + victim.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 50, 1)); + } + } + + if (!"stungun".equalsIgnoreCase(weapon.getCompactName()) || victimGtmUser.getJobMode() != JobMode.CRIMINAL || victimGtmUser.getWantedLevel() == 0) + return; + + if (victim.getLastDamageCause() == null || victim.getLastDamageCause().getCause() != EntityDamageEvent.DamageCause.DRAGON_BREATH) + return; + + if ((chestPlate != null && (chestPlate.getType() == Material.GOLD_CHESTPLATE || chestPlate.getType() == Material.ELYTRA) && player.getLocation().getBlock().getRelative(BlockFace.DOWN).getType() == Material.AIR) || player.isFlying() || player.isGliding()) { + player.sendMessage(Lang.COP_MODE.f("&fYou may not arrest criminals during flight!")); + return; + } + + if (player.getVehicle() != null) { + player.sendMessage(Lang.COP_MODE.f("&fYou may not arrest criminals while in a Vehicle!")); + return; + } + + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + User victimUser = Core.getUserManager().getLoadedUser(victimUUID); + int wantedLevel = victimGtmUser.getWantedLevel(); + int timeInJail = GTMUtils.getTimeInJail(wantedLevel); + victimGtmUser.jail(timeInJail, player); + player.sendMessage(Lang.COP_MODE.f("&7You arrested &a" + victimUser.getColoredName(victim) + + "&7! He will go to jail for &a" + Utils.timeInSecondsToText(timeInJail) + "&7!")); + Utils.broadcastExcept(player, Lang.COP_MODE.f("&a" + victimUser.getColoredName(victim) + "&7 was arrested by &a" + + user.getColoredName(player) + "&7!")); + victimGtmUser.addDeaths(1); + victimGtmUser.setLastTag(-1); + victimGtmUser.setKillCounter(0); + victimGtmUser.setKillStreak(0); + victimGtmUser.unsetCompassTarget(victim, victimUser); + if (GTM.getWarpManager().cancelTaxi(victim, victimGtmUser)) + victim.sendMessage(Utils.f(Lang.TAXI + "&eThe taxi was cancelled!")); + victim.setHealth(victim.getMaxHealth()); + victim.spigot().respawn(); + victim.setFireTicks(0); + victim.setGameMode(GameMode.SPECTATOR); + victim.setFlying(true); + victim.getActivePotionEffects().clear(); + victim.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 180, 0), false); + victim.setFoodLevel(20); + victim.playSound(victim.getLocation(), Sound.ENTITY_WITHER_SPAWN, 1, 0.5F); + victim.setFlySpeed(0); + GTMUtils.removeBoard(victim); + double lostMoney = Utils.round(victimGtmUser.getMoney() / 2); + new BukkitRunnable() { + @Override + public void run() { + Player victim = Bukkit.getPlayer(victimUUID); + if (victim == null) + return; + + User victimUser = Core.getUserManager().getLoadedUser(victim.getUniqueId()); + GTMUser victimGameUser = GTM.getUserManager().getLoadedUser(victim.getUniqueId()); + victim.sendMessage(Lang.JAIL.f("&7You were arrested and have to stay in jail for &a" + + Utils.timeInSecondsToText(timeInJail) + "&7!")); + if (lostMoney > 0) + victim.sendMessage(Lang.MONEY_TAKE.f(String.valueOf(lostMoney))); + victim.teleport(GTM.getWarpManager().getJail().getLocation()); + victim.setGameMode(GameMode.ADVENTURE); + victim.getActivePotionEffects().clear(); + victim.setFoodLevel(20); + victim.setFlying(false); + victim.setFlySpeed(0.1F); + GTMUtils.giveGameItems(victim); + GTMUtils.updateBoard(victim, victimGameUser); + } + }.runTaskLater(GTM.getInstance(), 150); + ItemStack[] contents = victim.getInventory().getContents(); + victim.getInventory().clear(); + Location loc = victim.getLocation(); + for (ItemStack item : contents) + if (item != null && item.getType() != Material.WATCH && item.getType() != Material.COMPASS + && item.getType() != Material.CHEST) + loc.getWorld().dropItemNaturally(loc, item); + if (lostMoney > 0) { + victimGtmUser.takeMoney(lostMoney); + gtmUser.addMoney(lostMoney); + player.sendMessage(Lang.MONEY.f("&7You confiscated &a$&l" + lostMoney + "&7 of &a" + + victimUser.getColoredName(victim) + "&7's money!")); + } + int copMoney = GTMUtils.getCopMoney(wantedLevel); + gtmUser.addMoney(copMoney); + player.sendMessage(Lang.COP_MODE.f("&7You were rewarded &a$&l" + copMoney + "&7 for arresting a player with &e" + + GTMUtils.getWantedLevelStars(wantedLevel) + " (" + wantedLevel + ")&7!")); + Utils.sendTitle(victim, "&c&lBUSTED", "&7Arrested by " + player.getName(), 80, 50, 20); + GTMUtils.updateBoard(player, user, gtmUser); + GTMUtils.arrestPlayer(e, weapon, player, victim); + } + + /** + * Listens in on netgun hit events. + * <p> + * This is fired when a netgun hits a target, and we listen + * on low priority so other events can mutate this for + * permission and changes later. + * <p> + * + * @param event - the event + */ + @EventHandler (priority = EventPriority.LOW) + public void onNetgunHitLow(NetgunHitEvent event){ + + // grab event variables + Entity shooter = event.getShooter(); + Entity target = event.getTarget().orElse(null); + Location loc = event.getLocation(); + int duration = event.getDuration(); + + // if target is alive and not dead + if (target != null && !target.isDead() && target instanceof LivingEntity){ + + // grab target chestplate + LivingEntity livingTarget = (LivingEntity) target; + ItemStack chestPlate = livingTarget.getEquipment().getChestplate(); + + if (chestPlate != null){ + + // if wearing wingsuit + if (chestPlate.getType() == Material.ELYTRA){ + duration = (int) (duration * 3.0); + } + // if wearing jetpack + else if (chestPlate.getType() == Material.GOLD_CHESTPLATE){ + duration = (int) (duration * 2.0); + } + } + } + + // mutate duration for listeners of event + event.setDuration(duration); + } + + /** + * Listens in on netgun hit events. + * <p> + * This is fired when a netgun hits a target, and we listen + * on high priority as it's after a permission check + * + * Note: If event is cancelled already, skip this code. + * <p> + * + * @param event - the event + */ + @EventHandler (priority = EventPriority.HIGH, ignoreCancelled = true) + public void onNetgunHitHigh(NetgunHitEvent event){ + + // grab event variables + Entity shooter = event.getShooter(); + Entity target = event.getTarget().orElse(null); + Location loc = event.getLocation(); + int duration = event.getDuration(); + + // if target is valid + if (target != null && !target.isDead()){ + if (target instanceof Player){ + + // grab player + Player targetPlayer = (Player) target; + GTMUser gtmUser = GTMUserManager.getInstance().getUser(targetPlayer.getUniqueId()).orElse(null); + if (gtmUser != null){ + + // disable jetpack for a quarter length of stun + int disableTicks = (int) (duration / 4.0); + // convert from ticks to milliseconds + gtmUser.setEnableJetpackTime(System.currentTimeMillis() + (disableTicks * 50)); + + // disable fly + targetPlayer.setFlying(false); + } + } + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/lootcrates/CrateManager.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/lootcrates/CrateManager.java new file mode 100644 index 0000000..f828ed9 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/lootcrates/CrateManager.java @@ -0,0 +1,182 @@ +package net.grandtheftmc.gtm.lootcrates; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.scheduler.BukkitRunnable; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.drugs.DrugService; +import net.grandtheftmc.gtm.drugs.item.DrugItem; +import net.grandtheftmc.gtm.items.GameItem; +import net.grandtheftmc.guns.GTMGuns; + +public class CrateManager { + + public CrateManager() { + this.loadCrates(); + this.startSchedule(); + } + + private List<LootItem> items = new ArrayList<>(); + private List<LootCrate> crates = new ArrayList<>(); + private int cooldown = 30; // in MINUTES + + private int taskId = -1; + + public List<LootItem> getItems() { + return this.items; + } + + public List<LootCrate> getCrates() { + return this.crates; + } + + + public void loadCrates() { + YamlConfiguration c = GTM.getSettings().getLootConfig(); + this.items = new ArrayList<>(); + for (String identifier : c.getKeys(false)) { + + // get the game item id, if one exists, otherwise default to this identifier + String gameItemID = c.getString(identifier + ".gameitem", identifier); + String type = c.getString(identifier + ".type"); + + try { + GameItem item = GTM.getItemManager().getItem(gameItemID); + if (item == null && (type == null || !type.equals("SKIN"))) { + Core.error("Error loading game item identifier='" + identifier + "', gameItemID='" + gameItemID + "' for Loot Crates!"); + continue; + } + + double chance = 100; + if (c.getString(identifier + ".chance") != null) + chance = c.getDouble(identifier + ".chance"); + int min = 1; + if (c.getString(identifier + ".min") != null) + min = c.getInt(identifier + ".min"); + int max = 64; + if (c.getString(identifier + ".max") != null) + max = c.getInt(identifier + ".max"); + + // rarity rating for weapon + int stars = 1; + if (c.getString(identifier + ".stars") != null) + stars = c.getInt(identifier + ".stars"); + + // clamp bounds + if (stars < 1){ + stars = 1; + } + if (stars > GTMGuns.MAX_STARS){ + stars = GTMGuns.MAX_STARS; + } + + LootItem lootItem = new LootItem(identifier, gameItemID, chance, min, max, stars, false); + this.items.add(lootItem); + } catch (Exception e) { + Core.error("Error loading loot item identifier='" + identifier + "', gameItemID='" + gameItemID + "' for Loot Crates!"); + } + } + + if (!Core.getSettings().isSister()) { + for (DrugItem drugItem : ((DrugService) GTM.getInstance().getDrugManager().getService()).getAllDrugItems()) { + this.items.add(new LootItem(drugItem.drug().getName(), drugItem.drug().getName(), 8, 1, 5, 0, true)); + } + } + + c = GTM.getSettings().getLootCratesConfig(); + this.crates = new ArrayList<>(); + if (c.get("lootcrates") != null) + this.crates.addAll(c.getStringList("lootcrates").stream().map(s -> new LootCrate(Utils.blockLocationFromString(s))).collect(Collectors.toList())); + this.cooldown = c.getInt("cooldown"); + } + + public void saveCrates() { + YamlConfiguration c = GTM.getSettings().getLootConfig(); + for (String s : c.getKeys(false)) { + if (c.contains(s + ".type")) continue; + c.set(s, null); + } + for (LootItem item : this.items) { + if (item.getIdentifier().contains("skin")) continue; + + if(!item.isDrug()) { + String identifier = item.getIdentifier(); + + // legacy compatibility + if (identifier == null){ + identifier = item.getItemName(); + } + + c.set(identifier + ".gameitem", item.getItemName()); + c.set(identifier + ".chance", item.getChance()); + c.set(identifier + ".min", item.getMin()); + c.set(identifier + ".max", item.getMax()); + c.set(identifier + ".stars", item.getStars()); + } + } + Utils.saveConfig(c, "loot"); + + c = GTM.getSettings().getLootCratesConfig(); + List<String> list = this.crates.stream().map(crate -> Utils.blockLocationToString(crate.getLocation())).collect(Collectors.toList()); + c.set("lootcrates", list); + c.set("cooldown", this.cooldown); + Utils.saveConfig(c, "lootcrates"); + } + + public void startSchedule() { + if (this.taskId != -1) Bukkit.getScheduler().cancelTask(this.taskId); + this.taskId = new BukkitRunnable() { + @Override + public void run() { + GTM.getCrateManager().getCrates().forEach(LootCrate::tick); + } + }.runTaskTimer(GTM.getInstance(), 20, 20).getTaskId(); + } + + public LootCrate getCrate(Location location) { + return this.crates.stream().filter(crate -> Objects.equals(crate.getLocation(), location)).findFirst().orElse(null); + } + + public void addCrate(Location location) { + if (this.getCrate(location) == null) + this.crates.add(new LootCrate(location)); + } + + public void removeCrate(Location location) { + LootCrate crate = this.getCrate(location); + if (crate != null) { + crate.removeHologram(); + this.crates.remove(crate); + } + } + + public int getCooldown() { + return this.cooldown; + } + + public void setCooldown(int i) { + this.cooldown = i; + } + + public void addItem(LootItem lootItem) { + this.items.add(lootItem); + } + + public LootItem getItem(GameItem gameItem) { + return this.items.stream().filter(item -> Objects.equals(item.getGameItem(), gameItem)).findFirst().orElse(null); + } + + public void removeItem(LootItem lootItem) { + this.items.remove(lootItem); + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/lootcrates/LootCrate.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/lootcrates/LootCrate.java new file mode 100644 index 0000000..2e94b1b --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/lootcrates/LootCrate.java @@ -0,0 +1,201 @@ +package net.grandtheftmc.gtm.lootcrates; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.block.Chest; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import com.gmail.filoghost.holographicdisplays.api.Hologram; +import com.gmail.filoghost.holographicdisplays.api.HologramsAPI; +import com.gmail.filoghost.holographicdisplays.api.VisibilityManager; +import com.gmail.filoghost.holographicdisplays.api.line.TextLine; +import com.j0ach1mmall3.jlib.methods.Random; + +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.guns.GTMGuns; +import net.grandtheftmc.guns.weapon.Weapon; +import net.grandtheftmc.guns.weapon.WeaponSkin; + +public class LootCrate { + + private Location location; + private long timer; + private Hologram hologram; + private final List<TextLine> textLines = new ArrayList<>(); + + public LootCrate(Location location) { + this.location = location; + this.timer = 60; + } + + public Location getLocation() { + return this.location; + } + + public void setLocation(Location location) { + this.location = location; + } + + public long getTimer() { + return this.timer; + } + + public void resetTimer() { + this.timer = GTM.getCrateManager().getCooldown() * 60L; + } + + public void tick() { + if (this.timer > 0) { + if(!this.location.getChunk().isLoaded()) { + this.timer--; + return; + } + +// if(Stream.of(this.location.getChunk().getEntities()) +// .filter(entity -> entity instanceof Player && entity.getLocation().distanceSquared(this.location) < 225) +// .count() <= 0) { +// this.timer--; +// return; +// } + + /* if(Bukkit.getOnlinePlayers().stream() + .filter(player -> player.getLocation().getWorld().getName().equals(location.getWorld().getName()) + && player.getLocation().distanceSquared(location) <= 200) + .count() <= 0) { + this.timer--; + return; + }*/ + + this.updateHologram("&7Restocks in &a" + Utils.timeInSecondsToText(this.timer) + "&7!"); + this.timer--; + this.updateVisibility(); + } else if (this.timer == 0) { + this.closeOutViewers(); //Close out inventory viewers before restocking. + this.restock(); + this.updateVisibility(); + timer = -1; + } + else{ + this.updateVisibility(); + } + } + + public void restock() { + BlockState state = this.location.getBlock().getState(); + if (!(state instanceof Chest)) { + GTM.log("Loot Chest at location " + Utils.blockLocationToString(this.location) + " is not a Chest!"); + this.updateHologram("&c&lERROR: Please contact an admin!"); + this.timer = -1; + return; + } + Chest chest = (Chest) state; + chest.setCustomName(Utils.f("&e&lLoot Crate")); + +// CraftChest craftChest = (CraftChest) chest; +// TileEntityChest tileEntityChest = craftChest.getTileEntity(); +// tileEntityChest.setCustomName(Utils.f("&e&lLoot Crate")); + + Inventory inv = chest.getBlockInventory(); + inv.clear(); + GTM.getCrateManager().getItems().stream().filter(item -> Utils.calculateChance(item.getChance())).forEach(item -> { + + // attempt to get weapon, if it is one + Optional<Weapon<?>> weaponOpt = GTMGuns.getInstance().getWeaponManager().getWeapon(item.getGameItem().getName()); + + if (weaponOpt.isPresent()){ + ItemStack stack = weaponOpt.get().createItemStack(item.getStars(), null); + stack.setAmount(Utils.randomNumber(item.getMin(), item.getMax())); + Utils.putItemInInventoryRandomly(inv, stack); + } + else { + /** + * TODO: Different weapon skin rarities + */ + if (item.getItemName().startsWith("weapon_skin_")) { + this.restockWeaponSkin(inv, item); + } else { + ItemStack stack = item.getGameItem().getItem(); + stack.setAmount(Utils.randomNumber(item.getMin(), item.getMax())); + Utils.putItemInInventoryRandomly(inv, stack); + } + } + }); + this.updateHologram("&7Restocked!"); + this.timer = -1; + } + + private void restockWeaponSkin(Inventory inv, LootItem item) { + List<Weapon<?>> weapons = new ArrayList<Weapon<?>>(GTMGuns.getInstance().getWeaponManager().getRegisteredWeapons()); + Weapon<?> randomWeapon = weapons.get(Random.getInt(weapons.size())); + WeaponSkin randomSkin = null; + + if (randomWeapon == null || randomWeapon.getWeaponSkins() == null || randomWeapon.getWeaponSkins().length <= 1) { + this.restockWeaponSkin(inv, item); + } + + short[] commonSkins = { + 5, 7 + }; + + short[] rareSkins = { + 2, 6 + }; + + if (item.getItemName().endsWith("common")) { + randomSkin = GTM.getWeaponSkinManager().getWeaponSkinFromIdentifier(randomWeapon, commonSkins[Random.getInt(0, commonSkins.length)]); + } else if (item.getItemName().endsWith("rare")) { + randomSkin = GTM.getWeaponSkinManager().getWeaponSkinFromIdentifier(randomWeapon, rareSkins[Random.getInt(0, rareSkins.length)]); + } + + Utils.putItemInInventoryRandomly(inv, GTM.getWeaponSkinManager().createSkinItem(randomWeapon, randomSkin)); + } + + private void updateHologram(String text) { + if (this.hologram == null) { + this.hologram = HologramsAPI.createHologram(GTM.getInstance(), this.location.clone().add(0.5, 2, 0.5)); + this.textLines.add(this.hologram.appendTextLine(Utils.f("&e&lLoot Crate"))); + this.textLines.add(this.hologram.appendTextLine(Utils.f(text))); + this.hologram.getVisibilityManager().setVisibleByDefault(false); + } else + this.textLines.get(1).setText(Utils.f(text)); + + } + + private void updateVisibility() { + VisibilityManager v = this.hologram.getVisibilityManager(); + for (Player player : Bukkit.getOnlinePlayers()) { + if (Objects.equals(player.getWorld(), this.location.getWorld()) && player.getLocation().distanceSquared(this.location) < 200) { + if (!v.isVisibleTo(player)) + v.showTo(player); + } else if (v.isVisibleTo(player)) + v.hideTo(player); + } + } + + public void removeHologram() { + this.hologram.delete(); + this.hologram = null; + this.textLines.clear(); + + } + + private void closeOutViewers() { + if (this.location == null) return; + Block block = this.location.getBlock(); + if (block.getType() != Material.CHEST) return; + Chest chest = (Chest) block.getState(); + chest.getInventory().getViewers().forEach(HumanEntity::closeInventory); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/lootcrates/LootCrateCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/lootcrates/LootCrateCommand.java new file mode 100644 index 0000000..e916dd7 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/lootcrates/LootCrateCommand.java @@ -0,0 +1,194 @@ +package net.grandtheftmc.gtm.lootcrates; + +import java.util.Iterator; +import java.util.List; +import java.util.UUID; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.items.GameItem; +import net.grandtheftmc.gtm.users.GTMUser; + +public class LootCrateCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + Player player = (Player) s; + if (!player.hasPermission("lootcrate.admin")) { + player.sendMessage(Lang.NOPERM.s()); + return true; + } + UUID uuid = player.getUniqueId(); + GTMUser user = GTM.getUserManager().getLoadedUser(uuid); + if (args.length == 0) { + s.sendMessage(Utils.f("&c/lootcrates add")); + s.sendMessage(Utils.f("&c/lootcrates remove")); + s.sendMessage(Utils.f("&c/lootcrates cooldown <minutes> ")); + s.sendMessage(Utils.f("&c/lootcrates check")); + s.sendMessage(Utils.f("&c/lootcrates restock")); + s.sendMessage(Utils.f("&c/lootcrates list [page]")); + + s.sendMessage(Utils.f("&c/lootcrates item <itemName> <chance> <min> <max>")); + s.sendMessage(Utils.f("&c/lootcrates removeitem <itemName>")); + s.sendMessage(Utils.f("&c/lootcrates load")); + s.sendMessage(Utils.f("&c/lootcrates save")); + return true; + } + switch (args[0].toLowerCase()) { + case "add": + s.sendMessage(Lang.LOOTCRATES.f("&7Right click on the chest you want to turn in to a Loot Crate. Make sure the chest has display name &e&lLoot Crate&7!")); + user.setAddingLootCrate(true); + return true; + case "remove": + s.sendMessage(Lang.LOOTCRATES.f("&7Right click on the chest you would like to remove as a Loot Crate.")); + user.setRemovingLootCrate(true); + return true; + case "cooldown": + if (args.length != 2) { + s.sendMessage(Utils.f("&c/lootcrate cooldown <minutes> ")); + return true; + } + try { + GTM.getCrateManager().setCooldown(Integer.parseInt(args[1])); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f("&cThe cooldown must be a number measured in minutes!")); + return true; + } + s.sendMessage(Lang.LOOTCRATES.f("&7The cooldown on Loot Crates was set to &a" + + GTM.getCrateManager().getCooldown() + " minutes&7!")); + return true; + case "check": + s.sendMessage(Lang.LOOTCRATES + .f("&7Right click on the Loot Crate of which you would like to check the cooldown;")); + user.setCheckingLootCrate(true); + return true; + case "restock": + s.sendMessage(Lang.LOOTCRATES.f("&7Right click the Loot Crate which you want to restock.")); + user.setRestockingLootCrate(true); + return true; + case "removeitem": { + if (args.length != 2) { + s.sendMessage(Utils.f("&c/lootcrate removeitem <itemName>")); + return true; + } + GameItem item = GTM.getItemManager().getItem(args[1]); + if (item == null) { + s.sendMessage(Lang.LOOTCRATES.f("&7That GameItem does not exist!")); + return true; + } + LootItem lootItem = GTM.getCrateManager().getItem(item); + if (lootItem == null) { + s.sendMessage(Lang.LOOTCRATES.f("&7That GameItem is not added to Loot Crates!")); + return true; + } + GTM.getCrateManager().removeItem(lootItem); + s.sendMessage(Lang.LOOTCRATES.f("&7GameItem &a" + item.getName() + "&7 was removed from LootCrates!")); + return true; + } + case "item": + if (args.length < 5) { + s.sendMessage(Utils.f("&c/lootcrate item <id> <itemName> <chance> <stars> [min] [max]")); + return true; + } + + String identifier = args[1]; + + GameItem item = GTM.getItemManager().getItem(args[2]); + if (item == null) { + s.sendMessage(Lang.LOOTCRATES.f("&7That GameItem does not exist!")); + return true; + } + + double chance; + int stars = 1; + int min; + int max; + try { + chance = Double.parseDouble(args[3]); + stars = Integer.parseInt(args[4]); + min = args.length > 4 ? Integer.parseInt(args[5]) : 1; + max = args.length > 5 ? Integer.parseInt(args[6]) : min; + } catch (NumberFormatException e) { + s.sendMessage(Lang.LOOTCRATES.f("&7The chance must be a double, min and max must be integers!")); + return true; + } + if (min > max) { + s.sendMessage(Lang.LOOTCRATES.f("&7The maximum must be greater than or equal to the minimum!")); + return true; + } + LootItem lootItem = GTM.getCrateManager().getItem(item); + if (lootItem == null) + GTM.getCrateManager().addItem(new LootItem(identifier, item.getName(), chance, min, max, stars, false)); + else { + lootItem.setChance(chance); + lootItem.setMin(min); + lootItem.setMax(max); + } + s.sendMessage(Lang.LOOTCRATES + .f("&7You added GameItem &a" + item.getName() + "&7 to LootCrates with a chance of &a" + chance + + "&7, a min of &a" + min + "&7 and a max of &a" + max + "&7!")); + return true; + case "list": + List<LootCrate> crates = GTM.getCrateManager().getCrates(); + int page = 1; + if (args.length > 1) { + try { + page = Integer.parseInt(args[1]); + } catch (NumberFormatException e) { + s.sendMessage(Lang.LOOTCRATES.f("&cThe page must be a number!")); + return true; + } + } + if (page < 1) { + s.sendMessage(Lang.LOOTCRATES.f("&7The page must be a positive number!")); + return true; + } + int pages = crates.size() / 6 + 1; + s.sendMessage(Utils.f(" &7&m---------------&7[&e&l Loot Crates List &7Page &e" + page + "&7/&e" + pages + + " &7&m]---------------")); + Iterator<LootCrate> it = crates.iterator(); + for (int i = 0; i < page * 6; i++) { + if (!it.hasNext()) + return true; + LootCrate cr = it.next(); + if (i < page * 6 - 6) + continue; + s.sendMessage(Utils.f("&e" + Utils.blockLocationToString(cr.getLocation()))); + } + return true; + case "load": + GTM.getSettings().setLootCratesConfig(Utils.loadConfig("lootcrates")); + GTM.getSettings().setLootConfig(Utils.loadConfig("loot")); + GTM.getCrateManager().loadCrates(); + s.sendMessage(Lang.LOOTCRATES.f("&7Loaded LootCrates!")); + return true; + case "save": + GTM.getCrateManager().saveCrates(); + s.sendMessage(Lang.LOOTCRATES.f("&7Saved LootCrates!")); + return true; + default: + s.sendMessage(Utils.f("&c/lootcrates add")); + s.sendMessage(Utils.f("&c/lootcrates remove")); + s.sendMessage(Utils.f("&c/lootcrates cooldown <minutes> ")); + s.sendMessage(Utils.f("&c/lootcrates check")); + s.sendMessage(Utils.f("&c/lootcrates restock")); + s.sendMessage(Utils.f("&c/lootcrates list [page]")); + s.sendMessage(Utils.f("&c/lootcrates item <itemName> <chance> <min> <max>")); + s.sendMessage(Utils.f("&c/lootcrates removeitem <itemName>")); + s.sendMessage(Utils.f("&c/lootcrates load")); + s.sendMessage(Utils.f("&c/lootcrates save")); + return true; + } + } + +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/lootcrates/LootItem.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/lootcrates/LootItem.java new file mode 100644 index 0000000..ec498ea --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/lootcrates/LootItem.java @@ -0,0 +1,126 @@ +package net.grandtheftmc.gtm.lootcrates; + +import java.util.Optional; + +import org.bukkit.inventory.ItemStack; + +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.drugs.Drug; +import net.grandtheftmc.gtm.drugs.DrugService; +import net.grandtheftmc.gtm.drugs.item.DrugItem; +import net.grandtheftmc.gtm.items.GameItem; + +public class LootItem { + + /** The identifier for this loot item */ + private String identifier; + /** The name of the item to drop, usually the game item */ + private String itemName; + private double chance; + private int min; + private int max; + /** Star rating for weapons */ + private int stars; + private boolean isDrug; + + public LootItem(String identifier, String itemName, double chance, int min, int max, int stars, boolean isDrug) { + this.identifier = identifier; + this.itemName = itemName; + this.chance = chance; + this.min = min; + this.max = max; + this.stars = stars; + this.isDrug = isDrug; + } + + /** + * Get the identifier for this loot item. + * <p> + * This is what the id is for the yml. + * </p> + * + * @return The identifier for this loot item. + */ + public String getIdentifier() { + return identifier; + } + + /** + * Set the identifier for this loot item. + * <p> + * This is what the id is for the yml. + * </p> + * @param identifier - the new identifier + */ + public void setIdentifier(String identifier) { + this.identifier = identifier; + } + + public String getItemName() { + return this.itemName; + } + + public void setItemName(String itemName) { + this.itemName = itemName; + } + + public GameItem getGameItem() { + if(!isDrug){ + return GTM.getItemManager().getItem(this.itemName); + } else { + Optional<Drug> drug = ((DrugService) GTM.getInstance().getDrugManager().getService()).getDrug(itemName); + if (!drug.isPresent()) { + return null; + } + DrugItem itema = DrugItem.getByDrug(drug.get()); + ItemStack is = itema.getItemStack(); + return new GameItem(itemName, is, is.getItemMeta().getDisplayName()); + } + } + + public boolean isDrug(){ + return isDrug; + } + + public double getChance() { + return this.chance; + } + + public void setChance(double chance) { + this.chance = chance; + } + + public int getMin() { + return this.min; + } + + public void setMin(int min) { + this.min = min; + } + + public int getMax() { + return this.max; + } + + public void setMax(int max) { + this.max = max; + } + + /** + * Get the stars/rarity associated with this loot item. + * + * @return The stars/rarity associated with this loot item. + */ + public int getStars() { + return stars; + } + + /** + * Set the stars/rarity associated with this loot item. + * + * @param stars - the new stars + */ + public void setStars(int stars) { + this.stars = stars; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/tasks/GlassesTask.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/tasks/GlassesTask.java new file mode 100644 index 0000000..a21af5a --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/tasks/GlassesTask.java @@ -0,0 +1,36 @@ +package net.grandtheftmc.gtm.tasks; + +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +public class GlassesTask extends BukkitRunnable { + private Long ct; + + @Override + public void run() { + this.ct = System.currentTimeMillis(); + Bukkit.getOnlinePlayers().forEach(player -> checkGlasses(player)); + } + + public void checkGlasses(Player player) { + if(player.getInventory().getHelmet() == null) return; + if(player.getInventory().getHelmet().getType() != Material.CHAINMAIL_HELMET) return; + player.getNearbyEntities(30, 30, 30).forEach(entity -> { + if(entity.getType() != EntityType.PLAYER) return; + Player target = (Player)entity; + new BukkitRunnable() { + @Override + public void run() { + GTMUtils.sendGlow(player, target, 12); + } + }.runTaskAsynchronously(GTM.getInstance()); + }); + player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 20, 20); + } +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/tasks/Lottery.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/tasks/Lottery.java new file mode 100644 index 0000000..dd161ea --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/tasks/Lottery.java @@ -0,0 +1,295 @@ +package net.grandtheftmc.gtm.tasks; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import com.gmail.filoghost.holographicdisplays.api.Hologram; +import com.gmail.filoghost.holographicdisplays.api.HologramsAPI; +import com.gmail.filoghost.holographicdisplays.api.line.TextLine; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.utils.WeightedRandomCollection; + +/** + * Created by Liam on 11/01/2017. + */ +public class Lottery { + + private final List<TextLine> textLines = new ArrayList<>(); + private final List<LotteryPlayer> lotteryPlayers = new ArrayList<>(); + private LocalDateTime end; + private Location hologramLocation; + private Hologram hologram; + private List<LotteryPlayer> winners = new ArrayList<>(3); + + public Lottery() { + this.loadConfig(); + this.startScheduler(); + } + + public static void test() { + WeightedRandomCollection<String> collection = new WeightedRandomCollection<>(); + collection.add(50, "Top Guy"); + collection.add(5, "Medium Guy"); + collection.add(3, "Mediocre Guy"); + collection.add(2, "Peasant1"); + collection.add(2, "Peasant2"); + collection.add(2, "Peasant3"); + collection.add(2, "Peasant4"); + collection.add(2, "Peasant5"); + collection.add(1, "Slave1"); + collection.add(1, "Slave2"); + collection.add(1, "Slave3"); + collection.add(1, "Slave4"); + collection.add(1, "Slave5"); + List<String> names = new ArrayList<>(); + Bukkit.broadcastMessage("--- " + collection.values().size()); + for (int i = 0; i < 13; i++) + if (!names.contains(collection.next())) + names.add(collection.last()); + + names.forEach(Bukkit::broadcastMessage); + } + + public void loadConfig() { + YamlConfiguration c = GTM.getSettings().getLotteryConfig(); + this.hologramLocation = Utils.teleportLocationFromString(c.getString("hologramLocation")); + this.end = c.get("end") == null ? LocalDateTime.now(ZoneId.of("UTC")).plusDays(1) + : LocalDateTime.of(c.getInt("end.year"), c.getInt("end.month"), c.getInt("end.day"), c.getInt("end.hour"), c.getInt("end.minute")); + this.winners.clear(); + if (c.get("winners") != null) + for (String s : c.getConfigurationSection("winners").getKeys(false)) { + try { + UUID uuid = UUID.fromString(c.getString("winners." + s + ".uuid")); + String name = c.getString("winners." + s + ".name"); + double amnt = c.getDouble("winners." + s + ".amount"); + boolean paid = c.getBoolean("winners." + s + ".paid"); + LotteryPlayer player = new LotteryPlayer(uuid, name); + player.setAmount(amnt); + player.setPaid(paid); + this.winners.add(player); + } catch (Exception e) { + Core.log("Error while loading lottery winner " + s); + e.printStackTrace(); + } + } + this.lotteryPlayers.clear(); + if (c.get("players") != null) + for (String s : c.getConfigurationSection("players").getKeys(false)) + try { + UUID uuid = UUID.fromString(s); + LotteryPlayer player = new LotteryPlayer(uuid, c.getString("players." + uuid + ".name")); + player.setTickets(c.getInt("players." + uuid + ".tickets")); + this.lotteryPlayers.add(player); + } catch (Exception e) { + Core.log("Error while loading lottery player " + s); + e.printStackTrace(); + } + } + + public void saveConfig() { + YamlConfiguration c = GTM.getSettings().getLotteryConfig(); + for (String s : c.getKeys(false)) + c.set(s, null); + c.set("hologramLocation", Utils.teleportLocationToString(this.hologramLocation)); + c.set("end.year", this.end.getYear()); + c.set("end.month", this.end.getMonthValue()); + c.set("end.day", this.end.getDayOfMonth()); + c.set("end.hour", this.end.getHour()); + c.set("end.minute", this.end.getMinute()); + for (int i = 0; i < 3; i++) { + LotteryPlayer player = this.getWinner(i); + if (player == null) continue; + c.set("winners." + i + ".uuid", player.getUUID().toString()); + c.set("winners." + i + ".name", player.getName()); + c.set("winners." + i + ".amount", player.getAmount()); + c.set("winners." + i + ".paid", player.isPaid()); + } + for (LotteryPlayer player : this.lotteryPlayers) { + c.set("players." + player.getUUID() + ".name", player.getName()); + c.set("players." + player.getUUID() + ".tickets", player.getTickets()); + } + Utils.saveConfig(c, "lottery"); + } + + private void startScheduler() { + new BukkitRunnable() { + @Override + public void run() { + if (Lottery.this.end != null && Lottery.this.end.isBefore(LocalDateTime.now(ZoneId.of("UTC")))) + Lottery.this.end(); + Lottery.this.updateHologram(); + } + }.runTaskTimer(GTM.getInstance(), 20, 20); + + } + + public void end() { + this.end = LocalDateTime.now(ZoneId.of("UTC")).plusDays(1); + WeightedRandomCollection<LotteryPlayer> players = new WeightedRandomCollection<>(); + for (LotteryPlayer player : this.lotteryPlayers) { + if(player.getTickets() <= 0) continue; + players.add(player.getTickets(), player); + } + this.winners = players.getUniqueElements(3); + double value = this.getPotValue(); + LotteryPlayer winner1 = this.getWinner(0); + LotteryPlayer winner2 = this.getWinner(1); + LotteryPlayer winner3 = this.getWinner(2); + if (winner1 != null) winner1.addAmount(0.5 * value); + if (winner2 != null) winner2.addAmount(0.2 * value); + if (winner3 != null) winner3.addAmount(0.1 * value); + GTMUtils.log("lottery", winner1.getName() + " has won the lottery prize of " + 0.5 * value + "(50% of the pot)"); + GTMUtils.log("lottery", winner2.getName() + " has won the lottery prize of " + 0.2 * value + "(20% of the pot)"); + GTMUtils.log("lottery", winner3.getName() + " has won the lottery prize of " + 0.1 * value + "(10% of the pot)"); + this.lotteryPlayers.clear(); + for (Player p : Bukkit.getOnlinePlayers()) + p.sendMessage(new String[]{"", Utils.f(GTMUtils.HEADER), "", + Utils.fc("&e&lLottery Results"), "", + Utils.fc("&7For a total pot of &a&l" + Utils.formatMoney(value)), + Utils.fc("&a#&l1&7: &r" + winner1 + " &a&l" + Utils.formatMoney(0.5 * value) + "&7 (&a50%&7 of the pot)"), + Utils.fc("&a#&l2&7: &r" + winner2 + " &a&l" + Utils.formatMoney(0.2 * value) + "&7 (&a20%&7 of the pot)"), + Utils.fc("&a#&l3&7: &r" + winner3 + " &a&l" + Utils.formatMoney(0.1 * value) + "&7 (&a10%&7 of the pot)"), + "", Utils.fc("&e&lCongratulations to the winners!"), + "", Utils.f(GTMUtils.FOOTER), ""}); + + for (int i = 0; i < 3 && i < this.winners.size(); i++) { + LotteryPlayer winner = this.winners.get(i); + if (winner != null && !winner.isPaid()) { + Player player = Bukkit.getPlayer(winner.getUUID()); + if (player == null) continue; + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + user.addBank(winner.getAmount()); + winner.setPaid(true); + player.sendMessage(Lang.LOTTERY.f("&7You've won the lottery, coming in " + (i == 0 ? "1st" : i == 1 ? "2nd" : i == 2 ? "3rd" : "error") + "! &a" + Utils.formatMoney(winner.getAmount()) + "&7 was added to your bank account.")); + GTMUtils.updateBoard(player, user); + } + } + + } + + + public void updateHologram() { + if (this.hologramLocation == null) return; + LotteryPlayer winner1 = this.winners.isEmpty() ? null : this.winners.get(0); + LotteryPlayer winner2 = this.winners.size() > 1 ? this.winners.get(1) : null; + LotteryPlayer winner3 = this.winners.size() > 2 ? this.winners.get(2) : null; + if (this.hologram == null) { + this.hologram = HologramsAPI.createHologram(GTM.getInstance(), this.hologramLocation.clone().add(0.5, 4, 0.5)); + this.textLines.add(this.hologram.appendTextLine(Utils.f("&e&lLottery"))); + this.textLines.add(this.hologram.appendTextLine(Utils.f("&7&oGo big or go home!"))); + this.textLines.add(this.hologram.appendTextLine("")); + this.textLines.add(this.hologram.appendTextLine(Utils.f("&7Pot value:"))); + this.textLines.add(this.hologram.appendTextLine(Utils.f("&a&l" + Utils.formatMoney(this.getPotValue())))); + this.textLines.add(this.hologram.appendTextLine("")); + this.textLines.add(this.hologram.appendTextLine(Utils.f("&7Time until jackpot:"))); + this.textLines.add(this.hologram.appendTextLine(Utils.f("&a&l" + this.timeToEnd()))); + this.textLines.add(this.hologram.appendTextLine("")); + this.textLines.add(this.hologram.appendTextLine(Utils.f("&7Last week's winners:"))); + this.textLines.add(this.hologram.appendTextLine(Utils.f(winner1 == null ? "" : ("&a#&l1&7: &r" + winner1 + " &a" + Utils.formatMoney(winner1.getAmount()) + "&7 (&a50%&7 of the pot)")))); + this.textLines.add(this.hologram.appendTextLine(Utils.f(winner2 == null ? "" : ("&a#&l2&7: &r" + winner2 + " &a" + Utils.formatMoney(winner2.getAmount()) + "&7 (&a20%&7 of the pot)")))); + this.textLines.add(this.hologram.appendTextLine(Utils.f(winner3 == null ? "" : ("&a#&l3&7: &r" + winner3 + " &a" + Utils.formatMoney(winner3.getAmount()) + "&7 (&a10%&7 of the pot)")))); + } else { + this.textLines.get(4).setText(Utils.f("&a&l" + Utils.formatMoney(this.getPotValue()))); + this.textLines.get(7).setText(Utils.f("&a&l" + this.timeToEnd())); + this.textLines.get(10).setText(Utils.f("&a#&l1&7: &r" + (winner1 == null ? "" : (winner1 + " &a" + Utils.formatMoney(winner1.getAmount()) + "&7 (&a50%&7 of the pot)")))); + this.textLines.get(11).setText(Utils.f("&a#&l2&7: &r" + (winner2 == null ? "" : (winner2 + " &a" + Utils.formatMoney(winner2.getAmount()) + "&7 (&a20%&7 of the pot)")))); + this.textLines.get(12).setText(Utils.f("&a#&l2&7: &r" + (winner3 == null ? "" : (winner3 + " &a" + Utils.formatMoney(winner3.getAmount()) + "&7 (&a10%&7 of the pot)")))); + + } + } + + public String timeToEnd() { + if (this.end == null) this.end = LocalDateTime.now(ZoneId.of("UTC")).plusDays(1); + return Utils.timeInSecondsToText(ChronoUnit.SECONDS.between(LocalDateTime.now(ZoneId.of("UTC")), this.end)); + } + + public List<LotteryPlayer> getTickets() { + return this.lotteryPlayers; + } + + public LotteryPlayer getLotteryPlayer(UUID uuid) { + return this.lotteryPlayers.stream().filter(player -> Objects.equals(player.getUUID(), uuid)).findFirst().orElse(null); + } + + public LotteryPlayer getLotteryPlayer(String name) { + return this.lotteryPlayers.stream().filter(player -> Objects.equals(player.getName(), name)).findFirst().orElse(null); + } + + public LotteryPlayer getWinner(UUID uuid) { + return this.winners.stream().filter(player -> Objects.equals(player.getUUID(), uuid)).findFirst().orElse(null); + } + + + public LotteryPlayer getWinner(int i) { + return this.winners.size() > i ? this.winners.get(i) : null; + } + + public double getPotValue() { + return 500 * this.lotteryPlayers.stream().mapToInt(LotteryPlayer::getTickets).sum(); + } + + public void joinCheck(Player player, User user, GTMUser gtmUser) { + for (int i = 0; i < 3 && i < this.winners.size(); i++) { + LotteryPlayer winner = this.winners.get(i); + if (winner != null && !winner.isPaid() && Objects.equals(winner.getUUID(), player.getUniqueId())) { + gtmUser.addBank(winner.getAmount()); + winner.setPaid(true); + player.sendMessage(Lang.LOTTERY.f("&7You won the lottery, coming in " + (i == 0 ? "1st" : i == 1 ? "2nd" : i == 2 ? "3rd" : "error") + "! &a&l" + Utils.formatMoney(winner.getAmount()) + "&7 was added to your bank account.")); + } + } + if (user.isSpecial()) { + LotteryPlayer p = this.getLotteryPlayer(player.getUniqueId()); + if (p != null) return; + p = new LotteryPlayer(player.getUniqueId(), player.getName()); + this.lotteryPlayers.add(p); + p.addTickets(GTMUtils.getFreeLotteryTickets(user.getUserRank())); + player.sendMessage(Lang.LOTTERY.f("&7Thank you for supporting " + Core.getSettings().getServer_GTM_shortName() + "! You have been given &a&l" + p.getTickets() + "&7 free lottery tickets for today's draw.")); + } + } + + public List<LotteryPlayer> getLastWinners() { + return this.winners; + } + + public void addLotteryPlayer(LotteryPlayer p) { + this.lotteryPlayers.add(p); + } + + public Location getHologramLocation() { + return this.hologramLocation; + } + + public void setHologramLocation(Location hologramLocation) { + this.hologramLocation = hologramLocation; + } + + public LocalDateTime getEnd() { + return this.end; + } + + public void setEnd(LocalDateTime end) { + this.end = end; + } + + public List<LotteryPlayer> getLotteryPlayers() { + return new ArrayList<>(this.lotteryPlayers); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/tasks/LotteryPlayer.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/tasks/LotteryPlayer.java new file mode 100644 index 0000000..053a2e2 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/tasks/LotteryPlayer.java @@ -0,0 +1,64 @@ +package net.grandtheftmc.gtm.tasks; + +import java.util.UUID; + +public class LotteryPlayer { + private final UUID uuid; + private String name = "Presidentx"; + private int tickets; + + private double amount; + private boolean paid; + + public LotteryPlayer(UUID uuid, String name) { + this.uuid = uuid; + this.name = name; + } + + public UUID getUUID() { + return this.uuid; + } + + public String getName() { + return this.name; + } + + public int getTickets() { + return this.tickets; + } + + public void setTickets(int tickets) { + this.tickets = tickets; + } + + public void addTickets(int tickets) { + this.tickets += tickets; + } + + public void setAmount(double amount) { + this.amount = amount; + } + + public void addAmount(double amount) { + this.amount += amount; + } + + public double getAmount() { + return this.amount; + } + + public void setPaid(boolean b) { + this.paid = b; + } + + public boolean isPaid() { + return this.paid; + } + + @Override + public String toString() { + return this.name; + } + + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/tasks/PlayerTask.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/tasks/PlayerTask.java new file mode 100644 index 0000000..69342a8 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/tasks/PlayerTask.java @@ -0,0 +1,173 @@ +package net.grandtheftmc.gtm.tasks; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ThreadLocalRandom; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.users.CompassTarget; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.users.GTMUserManager; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.users.HouseUser; + +public class PlayerTask extends BukkitRunnable { + public static List<Block> fireBlocks = new ArrayList<>(); + private Long ct; + + @Override + public void run() { + this.ct = System.currentTimeMillis(); + if (!fireBlocks.isEmpty()) checkFire(); + for (Player player : Bukkit.getOnlinePlayers()) { + + GTMUser gtmUser = GTMUserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + if (gtmUser != null){ + this.checkCombatTagExpiration(player, gtmUser); + this.checkCompassRefresh(player, gtmUser); + this.checkTpaRequestExpiration(player, gtmUser); + this.checkJailRelease(player, gtmUser); + this.checkDualWield(player); + this.checkElytra(player); + this.checkHouses(player); + gtmUser.checkBackupExpiration(player); + } + } + } + + private void checkHouses(Player player) { + if (player.getInventory().getChestplate() == null) return; + HouseUser houseUser = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + if (houseUser.isInsidePremiumHouse() || houseUser.isInsideHouse()) { + if (player.getInventory().getChestplate().getType() == Material.ELYTRA + || player.getInventory().getChestplate().getType() == Material.GOLD_CHESTPLATE) { + Utils.giveItems(player, player.getInventory().getChestplate()); + player.getInventory().setChestplate(null); + player.sendMessage(Lang.HOUSES.f("&7You cannot equip this gear while in a house!")); + } + } + } + + private void checkFire() { + Block block = fireBlocks.get(ThreadLocalRandom.current().nextInt(fireBlocks.size())); + if (block.getChunk().isLoaded()) block.setType(Material.AIR); + fireBlocks.remove(block); + } + + private void checkElytra(Player player) { + if (player.isGliding()) { + if (player.getInventory().contains(Material.COAL)) { + if (player.isSneaking()) { + ItemStack fuel = player.getInventory().getItem(player.getInventory().first(Material.COAL)); + if (fuel.getAmount() <= 1 || fuel.getAmount() - 5 < 1) { + player.getInventory().remove(fuel); + } else { + fuel.setAmount(fuel.getAmount() - 5); + } + player.getWorld().playSound(player.getLocation(), Sound.ENTITY_ITEM_PICKUP, 1.0F, 1.0F); + player.getInventory().getChestplate().setDurability((short) 0); + } + } else { + player.sendMessage(Lang.VEHICLES.f("&7Elytra requires (jetpack) fuel to fly!")); + player.setGliding(false); + if (player.getInventory().firstEmpty() == -1) { + player.getWorld().dropItem(player.getLocation(), player.getInventory().getChestplate()); + } else { + player.getInventory().addItem(player.getInventory().getChestplate()); + } + player.getInventory().setChestplate(null); + player.setFallDistance(-50); + } + } + } + + private void checkDualWield(Player player) { + if (player.getInventory().getItemInOffHand() != null && player.getInventory().firstEmpty() != -1) { + if (player.getInventory().getItemInOffHand().getType() == Material.SHIELD) return; + player.getInventory().addItem(player.getInventory().getItemInOffHand()); + } + player.getInventory().setItemInOffHand(null); + } + + private void checkJailRelease(Player player, GTMUser gtmUser) { + int timer = gtmUser.getJailTimer(); + if (!gtmUser.isArrested() || timer < 0) + return; + if (timer == 600 || timer == 300 || timer == 180 || timer == 120 || timer == 60 || timer == 30 + || timer == 15 || timer == 10 || (timer <= 5 && timer > 0)) { + player.sendMessage( + Lang.JAIL.f("&7You will be released in &a" + Utils.timeInSecondsToText(timer) + "&7!")); + if (timer == 1) { + player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 50, 0)); + player.playSound(player.getLocation(), Sound.BLOCK_LAVA_EXTINGUISH, 0.5F, 1); + } else + player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 4.0F / timer, 2); + } + if (timer == 0) { + gtmUser.resetJail(); + player.teleport(GTM.getWarpManager().getSpawn().getLocation()); + player.sendMessage(Lang.JAIL.f("&7You were released from jail!")); + player.removePotionEffect(PotionEffectType.SLOW); + player.getActivePotionEffects().clear(); + return; + } + gtmUser.setJailTimer(timer - 1); + } + + + private void checkCombatTagExpiration(Player player, GTMUser user) { + if (user.isInCombat() || user.getLastTag() == -1) + return; + user.setLastTag(-1); + player.sendMessage(Utils.f(Lang.COMBATTAG + "&7You are no longer in combat. You may log out safely.")); + } + + private void checkCompassRefresh(Player player, GTMUser gtmUser) { + if (gtmUser.hasCompassTarget() && gtmUser.getLastCompassRefresh() + 60000 < this.ct) + gtmUser.refreshCompassTarget(player, Core.getUserManager().getLoadedUser(player.getUniqueId())); + ItemStack item = player.getInventory().getItemInMainHand(); + if (item == null || item.getType() != Material.COMPASS || !gtmUser.hasCompassTarget()) return; + CompassTarget target = gtmUser.getCompassTarget(); + if(target.getTargetPlayer()==null && target.getType()== CompassTarget.TargetType.PLAYER) { + player.sendMessage(Lang.GTM.f("&7The player that you were tracking has logged off or died, resetting your tracker.")); + gtmUser.unsetCompassTarget(player, Core.getUserManager().getLoadedUser(player.getUniqueId())); + return; + } + double i = Utils.getAngleBetweenVectors(player, player.getCompassTarget()); + boolean negative = i < 0; + i = Math.abs(i); + String s = target.getType() == CompassTarget.TargetType.PLAYER ? Utils.f("&c&l" + target.getTargetPlayer().getName()) : ""; + if (i < 30) + Utils.sendActionBar(player, "^ " + s + " ^"); + else if (i < 60) + Utils.sendActionBar(player, negative ? "&e< " + s : s + " &e>"); + else if (i < 90) + Utils.sendActionBar(player, negative ? "&e<< " + s : s + " &e>>"); + else if (i < 120) + Utils.sendActionBar(player, negative ? "&c<&e< " + s : s + " &e>&c>"); + else if (i < 150) + Utils.sendActionBar(player, negative ? "&c<&e<< " + s : s + " &e>>&c>"); + else + Utils.sendActionBar(player, negative ? "&c<<< " + s : s + " &c>>>"); + // TODO make fancier and cooler and stuff + } + + private void checkTpaRequestExpiration(Player player, GTMUser gtmUser) { + if (gtmUser.getLastTpaRequest() > 0 && gtmUser.getLastTpaRequest() + 60000 < this.ct) { + gtmUser.unsetTpaRequests(); + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/tasks/TaskManager.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/tasks/TaskManager.java new file mode 100644 index 0000000..8b419e5 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/tasks/TaskManager.java @@ -0,0 +1,24 @@ +package net.grandtheftmc.gtm.tasks; + +import net.grandtheftmc.gtm.GTM; + +public class TaskManager { + private PlayerTask playerTask; + private GlassesTask glassesTask; + + public TaskManager() { + this.startTasks(); + } + + private void startTasks() { + this.playerTask = new PlayerTask(); + this.playerTask.runTaskTimer(GTM.getInstance(), 20, 20); + this.glassesTask = new GlassesTask(); + this.glassesTask.runTaskTimer(GTM.getInstance(), 100, 100); + } + + public PlayerTask getPlayerTask() { + return this.playerTask; + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/trashcan/TrashCanManager.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/trashcan/TrashCanManager.java new file mode 100644 index 0000000..b00d1ec --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/trashcan/TrashCanManager.java @@ -0,0 +1,322 @@ +package net.grandtheftmc.gtm.trashcan; + +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import org.apache.commons.lang3.StringUtils; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.block.BlockState; +import org.bukkit.block.Dropper; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitRunnable; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.items.GameItem; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.users.GTMUserManager; + +public class TrashCanManager implements Listener { + + public static void openTrashCan(Player player) { + + GTMUser gtmUser = GTMUserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + + if (gtmUser == null){ + player.sendMessage(Lang.TRASH_CAN.f("&7Error opening trash can! Please rejoin!")); + return; + } + + if (gtmUser.isArrested()) { + player.sendMessage(Lang.JAIL.f("&7You can't sell items in jail!")); + return; + } + + Inventory inv = Bukkit.createInventory(null, 54, Utils.f("&8&lTrash Can")); + int[] paneSlots = new int[] { 9, 10, 11, 12, 13, 14, 15, 16, 17, 27, 28, 29, 30, 31, 32, 33, 34, 35, 45, 46, 47, + 48, 49, 50, 51, 52 }; + for (int i : paneSlots) + inv.setItem(i, Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a")); + // inv.setItem(52, Utils.createItem(Material.DIAMOND, "&6&lSell Entire Inventory", "&7Total Value: &a$&l" + getTotalInvPrice(player))); + inv.setItem(53, Utils.createItem(Material.PAPER, "&a&lConfirm", "&7Total Reward: &a$&l0")); + inv.setItem(44, Utils.createItem(Material.REDSTONE, "&c&lCancel", "&7Return all items!")); + player.openInventory(inv); + } + + private void m(int i) { + this.m(String.valueOf(i)); + } + + private void m(String s) { + Bukkit.broadcastMessage(s); + } + + @EventHandler + public void onInteract(PlayerInteractEvent e) { + if (e.getAction() != Action.RIGHT_CLICK_BLOCK) return; + BlockState block = e.getClickedBlock().getState(); + if (block.getType() != Material.DROPPER) return; + if (!e.getPlayer().getWorld().getName().equalsIgnoreCase("spawn")) { + e.setCancelled(false); + return; + } + + if (e.getPlayer().isSneaking()) return; + Dropper dropper = (Dropper) block; + e.setCancelled(true); + + if (Objects.equals("Trash Can", ChatColor.stripColor(dropper.getInventory().getTitle()))) + openTrashCan(e.getPlayer()); + } + + @EventHandler + public void onClick(InventoryClickEvent e) { + Player player = (Player) e.getWhoClicked(); + Inventory inv = e.getView().getTopInventory(); + if (inv == null || e.getClickedInventory() == null || inv.getType() != InventoryType.CHEST + || !"Trash Can".equalsIgnoreCase(ChatColor.stripColor(inv.getTitle()))) + return; + + ItemStack c = e.getCurrentItem(); + if (c != null) { + switch (c.getType()) { + case PAPER: + e.setCancelled(true); + player.closeInventory(); + return; + + case DIAMOND: + case REDSTONE: + e.setCancelled(true); + List<ItemStack> items = itemSlots.stream().mapToInt(i -> i).mapToObj(inv::getItem).filter(Objects::nonNull).collect(Collectors.toList()); + + for (int i : itemSlots) { + inv.setItem(i, null); + inv.setItem(i + 9, Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a")); + } + + player.closeInventory(); + Utils.giveItems(player, items.toArray(new ItemStack[items.size()])); + + if (c.getType() == Material.REDSTONE) + player.sendMessage(Utils.f(Lang.TRASH_CAN + "&7The items have been added back to your inventory.")); + + if (c.getType() == Material.DIAMOND) + player.sendMessage(Utils.f(" &c&lERROR&8&l> &cThis feature is currently disabled, try again soon!")); + + return; + + /* + case DIAMOND://TODO, Fix sell-all, It causes alot of lag! + e.setCancelled(true); +// double price = getTotalInvPrice(player); +// if (price == 0) return; + player.closeInventory(); +// GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); +// user.setSellInvConfirmAmt(price); +// MenuManager.openMenu(player, "sellinvconfirm"); + + //TODO, Remove message after fixing lag. + player.sendMessage(Utils.f(" &c&lERROR&8&l> &cThis feature is currently disabled, try again soon!")); + return; + */ + + default: + break; + } + } + + if (Objects.equals(e.getClickedInventory(), inv) && !itemSlots.contains(e.getSlot())) { + e.setCancelled(true); + player.updateInventory(); + return; + } + UUID uuid = player.getUniqueId(); + new BukkitRunnable() { + @Override + public void run() { + Player p = Bukkit.getPlayer(uuid); + if (p == null) + return; + Inventory inv = p.getOpenInventory().getTopInventory(); + if (inv != null && Objects.equals("Trash Can", ChatColor.stripColor(inv.getTitle()))) { + TrashCanManager.this.updateTrashCan(inv); + } + + } + }.runTaskLater(GTM.getInstance(), 1); + } + + + private double calculateItem(Inventory inv, int slot, boolean updateInventory) { + ItemStack item = inv.getItem(slot); + if (item == null) { + if(updateInventory) + inv.setItem(slot + 9, Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a")); + return 0; + } + if(item.getType() == Material.SKULL_ITEM) { + return 0; + } + GameItem gameItem = GTMUtils.isArmor(item.getType()) ? GTM.getItemManager().getSellableItem(item, true) : GTM.getItemManager().getSellableItem(item); + + if (gameItem == null) { + gameItem = GTM.getItemManager().getSellableItem(item, 8); + if (gameItem == null) { + if(updateInventory) + inv.setItem(slot + 9, Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a")); + return 0; + } + } + + if (gameItem.getType() == GameItem.ItemType.DRUG || gameItem.getType() == GameItem.ItemType.VEHICLE) { + if(updateInventory) + inv.setItem(slot + 9, Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a")); + return 0; + } + + if(!gameItem.canSell()) { + if(updateInventory) + inv.setItem(slot + 9, Utils.createItem(Material.STAINED_GLASS_PANE, 14, "&c&lReward: &c$&l0")); + return 0; + } + + double price = gameItem.getSellPrice(); + if(GTMUtils.isArmor(item.getType())) { + price *= (double)(item.getType().getMaxDurability() - item.getDurability()) / item.getType().getMaxDurability(); + } + + price *= item.getAmount(); + DecimalFormat df = new DecimalFormat("#.##"); + if(updateInventory) + inv.setItem(slot + 9, Utils.createItem(Material.STAINED_GLASS_PANE, 13,"&a&lReward: &a$&l" + df.format(price))); + return price; + } + + private double updateTrashCan(Inventory inv) { + Optional<HumanEntity> viewer = inv.getViewers().stream().findFirst(); + Player player = (Player) viewer.get(); + List<Integer> itemSlots = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 18, 19, 20, 21, 22, 23, 24, 25, 26, 36, 37, 38, 39, 40, 41, 42, 43); + double totalPrice = itemSlots.stream().mapToDouble(i -> this.calculateItem(inv, i, true)).sum(); + //inv.setItem(52, Utils.createItem(Material.DIAMOND, "&6&lSell Entire Inventory", "&7Total Value: &a$&l" + getTotalInvPrice(player))); + DecimalFormat df = new DecimalFormat("#.##"); + + inv.setItem(53, Utils.createItem(Material.PAPER, "&a&lConfirm", "&7Total Reward: &a$&l" + df.format(totalPrice))); + inv.setItem(44, Utils.createItem(Material.REDSTONE, "&c&lCancel", "&7Return all items!")); + return totalPrice; + } + + public double getTotalInvPrice(Player player) { + double invPrice = IntStream.range(0, 36).mapToDouble(i -> this.calculateItem(player.getInventory(), i, false)).sum(); + for(int i =9; i<36; i++){ + ItemStack is = player.getInventory().getItem(i); + if(is==null || is.getType()==Material.AIR) + continue; + GameItem item = GTM.getItemManager().getSellableItem(is); + if(item==null || item.getType()== GameItem.ItemType.DRUG) + continue; + invPrice += item.getSellPrice() * is.getAmount() ; + } + return invPrice; + } + + private final List<Integer> itemSlots = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 18, 19, 20, 21, 22, 23, 24, 25, 26, 36, 37, 38, 39, 40, 41, 42, 43); + public Collection<GameItem> getSellableItems(Inventory inv) { + Collection<GameItem> items = new ArrayList<>(); + + for (int slot : itemSlots) { + if (inv.getItem(slot) != null) { + ItemStack itemStack = inv.getItem(slot); + GameItem gameItem = GTM.getItemManager().getSellableItem(itemStack, GTMUtils.isArmor(itemStack.getType())); + if (gameItem == null || gameItem.getType()== GameItem.ItemType.DRUG) continue; + gameItem.getItem().setAmount(itemStack.getAmount()); + items.add(gameItem); + } + } + + //I think this causes selling problems. +// itemSlots.stream().forEachOrdered(i -> { +// if (inv.getItem(i) != null) { +// ItemStack itemStack = inv.getItem(i); +// GameItem gameItem = GTM.getItemManager().getSellableItem(itemStack, GTMUtils.isArmor(itemStack.getType())); +// if (gameItem == null || gameItem.getType()== GameItem.ItemType.DRUG) return; +// gameItem.getItem().setAmount(itemStack.getAmount()); +// items.add(gameItem); +// } +// }); + + return items; + } + + @EventHandler + public void onClose(InventoryCloseEvent e) { + + // grab event variables + Player player = (Player) e.getPlayer(); + Inventory inv = e.getInventory(); + + // skip improper menu/inventories + if (e.getInventory().getType() != InventoryType.CHEST || !"Trash Can".equalsIgnoreCase(ChatColor.stripColor(inv.getTitle()))){ + return; + } + + GTMUser user = GTMUserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + if (user == null){ + player.sendMessage(Lang.TRASH_CAN.f("&7Error selling contents in trash can! Please rejoin!")); + return; + } + + Collection<GameItem> sellableItems = getSellableItems(inv); + double totalPrice = this.updateTrashCan(inv); + + if (!sellableItems.isEmpty()) { + Collection<String> items = new ArrayList<>(); + sellableItems.forEach(gameItem -> items.add(gameItem.getName())); + + String itemsSold = StringUtils.join(items, ", "); + + GTMUtils.log("trashcan", player.getName() + " sold the following for $" + totalPrice + + ": " + itemsSold); + } + + /*for (ItemStack itemStack : inv.getStorageContents()) { + if (itemStack == null) continue; + if (!itemStack.hasItemMeta()) continue; + if (itemStack.getItemMeta().getDisplayName() == null) continue; + Optional<DrugItem> drugItem = ((DrugService) GTM.getDrugManager().getService()).getDrugItem(itemStack.getItemMeta().getDisplayName()); + if (drugItem.isPresent()) { + Optional<DrugDealerItem> drugDealerItem = DrugDealerItem.byDrugItem(drugItem.get()); + if (!drugDealerItem.isPresent()) continue; + drugDealerItem.get().setStockRemaining(drugDealerItem.get().getStockRemaining() + 1); + } + }*/ + + if (totalPrice > 0) { + user.addMoney(totalPrice); + GTMUtils.updateBoard(player, user); + player.sendMessage(Utils.f(Lang.MONEY_ADD.toString() + Math.round(totalPrice))); + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/ChatAction.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/ChatAction.java new file mode 100644 index 0000000..93f7fe4 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/ChatAction.java @@ -0,0 +1,19 @@ +package net.grandtheftmc.gtm.users; + +/** + * Created by Timothy Lampen on 2017-10-18. + */ +public enum ChatAction { + BRIBING, + BIDDING_HEAD, + PICKING_BOUNTY, + PICKING_BOUNTY_TARGET, + BANK_DEPOSITING, + BANK_WITHDRAWING, + BANK_TRANSFERRING, + BUYING_LOTTERY_TICKETS, + GANG_CHAT_ACTION, + SANTA_NAUGHTY_LIST, + CONFIRM_TRANSFER, + CONFIRM_TRANSFER_2 +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/CheatCode.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/CheatCode.java new file mode 100644 index 0000000..f253c04 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/CheatCode.java @@ -0,0 +1,235 @@ +package net.grandtheftmc.gtm.users; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Optional; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.State; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.items.ItemManager; + +/** + * Created by Timothy Lampen on 8/21/2017. + */ +public enum CheatCode { + + KATANA(UserRank.ADMIN, Utils.createItem(Material.DIAMOND_SWORD, (short)421, "KATANA", "&7Chop off heads with this masterful weapon!", "&7Delay: &e&l3 days."), true, false, "katana_cc", null), + SNEAKY(UserRank.ADMIN, Utils.createItem(Material.GLASS_BOTTLE, "SNEAKY", "&7Gain invisibility for the duration of your teleport protection "), true, true, null, null), + FEED(UserRank.SPONSOR, Utils.createItem(Material.COOKED_BEEF, "FEED", "&7Have access to the feed command."), true, false, null, null), + FUCKME(UserRank.ADMIN, Utils.createItem(Material.SAPLING, 1, "FUCKME", "&7Gives a dildo so you can go fuck yourself.", "&7Delay: &e&l3 days."), true, false, "fuckme_cc", null), + WINGSUIT(UserRank.ADMIN, Utils.createItem(Material.ELYTRA, "WINGSUIT", "&7Recieve a single wingsuit and 5 stacks of jetpack fuel.", "&7Delay: &e&l3 days."), true, false, "wingsuit_cc", null), + FIXHAND(UserRank.VIP, Utils.createItem(Material.ANVIL, "FIXHAND", "&7Gain access to the /fix hand command."), true, false, null, null), + FIXALL(UserRank.SUPREME, Utils.createItem(Material.CHEST, "FIXALL", "&7Have the ability to do /fix all."), true, false, null, null), + STACK(UserRank.SUPREME, Utils.createItem(Material.GOLD_INGOT, "STACK", "&7Be able to do the /stack command."), true, false, null, "&7This cheatcode comes with the " + UserRank.SUPREME.getColoredNameBold() + "&7 rank."), + DRUGS(UserRank.ADMIN, Utils.createItem(Material.FLINT_AND_STEEL, 5, "DRUGS", "&7Recieve the drugs kit.", "&7Delay: &e&l3 days&7."), true, false, "drugs_cc", null), + QUICKSELL(UserRank.SUPREME, Utils.createItem(Material.DISPENSER, "QUICK SELL", "&7Have the ability to sell items", "&7without having to travel back", "&7to spawn!"), true, false, null, "&7To unlock this cheatcode, purchase the &c&lSUPREME&7 rank or the &2&lQUICKSELL&7 cheatcode at &a&lstore.grandtheftmc.net&7!"), + ; + + private final ItemStack displayItem; + private final boolean toggleable, defaultToggle; + private final UserRank rank; + private String cooldownID, lockedLore; + + CheatCode(UserRank rank, ItemStack displayItem, boolean defaultToggle, boolean toggleable, String cooldownID, String lockedLore) { + ItemMeta im = displayItem.getItemMeta(); + im.setUnbreakable(true); + im.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE); + displayItem.setItemMeta(im); + this.defaultToggle = defaultToggle; + this.lockedLore = Utils.f(lockedLore == null ? "&7You can purchase this cheatcode at &a&l" + Core.getSettings().getStoreLink() + "&7!" : lockedLore); + this.displayItem = displayItem; + this.toggleable = toggleable; + this.rank = rank; + this.cooldownID = cooldownID; + } + + public UserRank getMinmumRank() { + return rank; + } + + public State getDefaultState() { + return this.defaultToggle ? State.ON : State.OFF; + } + + public String getLockedLore() { + return this.lockedLore; + } + + public boolean isToggleable() { + return toggleable; + } + + public ItemStack getDisplayItem(User user, State state) { + ItemStack is = displayItem.clone(); + ItemMeta im = is.getItemMeta(); + im.setUnbreakable(true); + im.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE); + if (state == State.LOCKED) { + ArrayList<String> lore = new ArrayList<>(im.getLore()); + lore.add(" "); + lore.add(Utils.f("&4&lLOCKED")); + if (this.rank.isHigherThan(UserRank.DEFAULT) && !this.rank.isHigherThan(UserRank.YOUTUBER)) { + lore.add(Utils.f("&4&lUnlocked with rank: " + rank.getColoredNameBold())); + } + im.setDisplayName(Utils.f(getStateColor(state) + im.getDisplayName())); + im.setLore(lore); + is.setItemMeta(im); + return is; + } + + if (user != null && this.cooldownID != null) { + boolean stillOnCooldown = user.isOnCooldown(this.cooldownID); + state = stillOnCooldown ? State.OFF : State.ON; + List<String> lore = new ArrayList<>(im.getLore()); + if (stillOnCooldown) + lore.set(1, Utils.f("&7Delay: &e&l" + Utils.timeInSecondsToText(user.getCooldownTimeLeft(this.cooldownID), C.RED, C.RED, C.GRAY) + "&7.")); + } + im.setDisplayName(Utils.f(getStateColor(state) + im.getDisplayName())); + is.setItemMeta(im); + return is; + } + + public static String seralizeCheatCodes(HashMap<CheatCode, CheatCodeState> codes) { + StringBuilder sb = new StringBuilder(); + codes.forEach((codea, statea) -> sb.append(codea.toString()).append("#").append(statea.getState()).append("#").append(statea.isPurchased()).append("-")); + sb.deleteCharAt(sb.length() - 1); + return sb.toString(); + } + + public void activate(User coreUser, GTMUser user, Player player, CheatCodeState cState) { + if (user.isArrested()) { + player.sendMessage(Lang.CHEAT_CODES.f("&7You cannot use this cheat code while you are arrested!")); + return; + } + if (cState.getState() == State.LOCKED) { + player.sendMessage(Lang.CHEAT_CODES.f("&7You haven't unlocked this cheat code yet!")); + return; + } + if (!this.isToggleable()) {//the non-toggleables + if (coreUser.isOnCooldown(this.cooldownID)) { +// player.sendMessage(Lang.CHEAT_CODES.f("&7You must wait &a" + coreUser.getFormattedCooldown(this.cooldownID, true) + " &7before using this cheatcode again!")); + player.sendMessage(Lang.CHEAT_CODES.f("&7You must wait &a" + Utils.timeInSecondsToText(coreUser.getCooldownTimeLeft(this.cooldownID), C.RED, C.RED, C.GRAY) + " &7before using this cheatcode again!")); + return; + } + switch (this) { + case KATANA: + + if (!GTM.getSettings().isGlobalCheatcodes()){ + player.sendMessage(ChatColor.RED + "Cheatcodes are temporarily disabled."); + return; + } + + if (Utils.giveItems(player, GTM.getItemManager().getItem("katana").getItem())) { + player.sendMessage(Utils.f(Lang.CHEAT_CODES + "&cYour inventory was full so some items were dropped on the ground!")); + } + coreUser.addCooldown(this.cooldownID, 60 * 60 * 24 * 3, true, true); + player.sendMessage(Lang.CHEAT_CODES.f("&7You have used your katana cheat code!")); + break; + case FUCKME: + + if (!GTM.getSettings().isGlobalCheatcodes()){ + player.sendMessage(ChatColor.RED + "Cheatcodes are temporarily disabled."); + return; + } + + if (Utils.giveItems(player, GTM.getItemManager().getItem("dildo").getItem())) { + player.sendMessage(Utils.f(Lang.CHEAT_CODES + "&cYour inventory was full so some items were dropped on the ground!")); + } + coreUser.addCooldown(this.cooldownID, 60 * 60 * 24 * 3, true, true); + player.sendMessage(Lang.CHEAT_CODES.f("&7You have used your fuck me cheat code!")); + break; + case WINGSUIT: { + + if (!GTM.getSettings().isGlobalCheatcodes()){ + player.sendMessage(ChatColor.RED + "Cheatcodes are temporarily disabled."); + return; + } + + ItemStack[] items = new ItemStack[]{GTM.getItemManager().getItem("wingsuit").getItem(), GTM.getItemManager().getItem("jetpackfuel").getItem(64), GTM.getItemManager().getItem("jetpackfuel").getItem(64), GTM.getItemManager().getItem("jetpackfuel").getItem(64), GTM.getItemManager().getItem("jetpackfuel").getItem(64), GTM.getItemManager().getItem("jetpackfuel").getItem(64)}; + if (Utils.giveItems(player, items)) { + player.sendMessage(Utils.f(Lang.CHEAT_CODES + "&cYour inventory was full so some items were dropped on the ground!")); + } + coreUser.addCooldown(this.cooldownID, 60 * 60 * 24 * 3, true, true); + player.sendMessage(Lang.CHEAT_CODES.f("&7You have used your wingsuit cheat code!")); + break; + } + case DRUGS: + + if (!GTM.getSettings().isGlobalCheatcodes()){ + player.sendMessage(ChatColor.RED + "Cheatcodes are temporarily disabled."); + return; + } + + ItemManager im = GTM.getItemManager(); + if (im.giveKit(player, coreUser, user, "drugs")) { + coreUser.addCooldown(this.cooldownID, 60 * 60 * 24 * 3, true, true); + player.sendMessage(Lang.CHEAT_CODES.f("&7You have used your drugs cheat code!")); + } + break; + case STACK: + + if (!GTM.getSettings().isGlobalCheatcodes()){ + player.sendMessage(ChatColor.RED + "Cheatcodes are temporarily disabled."); + return; + } + + player.chat("/stack"); + break; + case FIXALL: + player.chat("/fix all"); + break; + case FIXHAND: + player.chat("/fix hand"); + break; + case FEED: + player.chat("/feed"); + break; + case QUICKSELL: + player.closeInventory(); + player.chat("/qsell"); + break; + } + } else { + player.sendMessage(Lang.CHEAT_CODES.f("&7You turned " + (cState.getState() == State.OFF ? "&a&lon &7" : "&c&loff &7") + (this.toString().toLowerCase().replace("_", " ")))); + } + user.setCheatCodeState(this, new CheatCodeState(cState.getState() == State.ON && this.isToggleable() ? State.OFF : State.ON, cState.isPurchased())); + } + + private String getStateColor(State state) { + switch (state) { + case ON: + return "&a&l"; + case OFF: + return "&c&l"; + case LOCKED: + return "&4&l"; + } + return null; + } + + public static Optional<CheatCode> getCheatCodeFromItemStack(ItemStack stack) { + if (stack == null) + return Optional.empty(); + return Arrays.stream(CheatCode.getCodes()).filter(code -> code.getDisplayItem(null, State.ON).getType() == stack.getType() && code.getDisplayItem(null, State.ON).getDurability() == stack.getDurability()).findFirst(); + } + + private static CheatCode[] sisterCodes = new CheatCode[]{CheatCode.KATANA, CheatCode.SNEAKY, CheatCode.FEED, CheatCode.WINGSUIT, CheatCode.FIXHAND, CheatCode.FIXALL, CheatCode.STACK, CheatCode.QUICKSELL}; + public static CheatCode[] getCodes() { + return Core.getSettings().isSister() ? sisterCodes : values(); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/CheatCodeState.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/CheatCodeState.java new file mode 100644 index 0000000..9855e6e --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/CheatCodeState.java @@ -0,0 +1,26 @@ +package net.grandtheftmc.gtm.users; + + +import net.grandtheftmc.core.util.State; + +/** + * Created by Timothy Lampen on 2017-08-26. + */ +public class CheatCodeState { + + private final State state; + private final boolean purchased; + + public CheatCodeState(State state, boolean purchased) { + this.state = state; + this.purchased = purchased; + } + + public State getState() { + return state; + } + + public boolean isPurchased() { + return purchased; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/CompassTarget.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/CompassTarget.java new file mode 100644 index 0000000..8981b8b --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/CompassTarget.java @@ -0,0 +1,152 @@ +package net.grandtheftmc.gtm.users; + +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.gtm.GTMUtils; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +import java.util.Objects; +import java.util.Random; +import java.util.UUID; + +public class CompassTarget { + + private TargetType type; + + private UUID targetPlayer; + private UUID targetEntity; + private Location location; + + public CompassTarget() { + this.type = TargetType.NONE; + } + + public CompassTarget(Player player) { + this.type = TargetType.PLAYER; + this.targetPlayer = player.getUniqueId(); + } + + public CompassTarget(Entity entity) { + this.type = TargetType.ENTITY; + this.targetEntity = entity.getUniqueId(); + } + + public CompassTarget(Location position) { + this.type = TargetType.LOCATION; + this.location = position; + } + + public CompassTarget(PersonalVehicle vehicle) { + this.type = TargetType.VEHICLE; + this.targetEntity = vehicle.getEntityUUID(); + } + + public TargetType getType() { + return this.type; + } + + public void setType(TargetType type) { + this.type = type; + } + + public UUID getTargetPlayerUUID() { + return this.targetPlayer; + } + + public Player getTargetPlayer() { + if (this.targetPlayer == null) + return null; + return Bukkit.getPlayer(this.targetPlayer); + } + + public void setTargetPlayer(UUID targetPlayer) { + this.targetPlayer = targetPlayer; + this.type = TargetType.PLAYER; + } + + public UUID getTargetEntityUUID() { + return this.targetEntity; + } + + public Entity getTargetEntity() { + if (this.targetEntity == null) + return null; + for (World w : Bukkit.getWorlds()) + for (Entity e : w.getEntities()) + if (Objects.equals(e.getUniqueId(), this.targetEntity)) + return e; + this.targetEntity = null; + return null; + } + + public void setTargetEntity(UUID targetEntity) { + this.targetEntity = targetEntity; + this.type = TargetType.ENTITY; + } + + public void setTargetEntity(Entity targetEntity) { + this.targetEntity = targetEntity == null ? null : targetEntity.getUniqueId(); + this.type = TargetType.ENTITY; + } + + public Location getLocation() { + return this.location; + } + + public void setLocation(Location location) { + this.location = location; + } + + public Location getExactLocation(Player player) { + Location loc = null; + switch (this.type) { + case LOCATION: + loc = this.location; + break; + case ENTITY: + Entity entity = this.getTargetEntity(); + if (entity != null) + loc = entity.getLocation(); + break; + case PLAYER: + Player targetPlayer = this.getTargetPlayer(); + if (targetPlayer != null) + loc = targetPlayer.getLocation(); + break; + case VEHICLE: + Entity vehicle = this.getTargetEntity(); + if (vehicle != null) + loc = vehicle.getLocation(); + break; + default: + break; + } + if (loc == null || !Objects.equals(player.getLocation().getWorld(), loc.getWorld())) { + return player.getLocation(); + } + return loc; + } + + public Location getApproximateLocation(Player player, int radius) { + Random rand = Utils.getRandom(); + return this.getExactLocation(player).add(rand.nextInt(radius << 1) - radius, 0, rand.nextInt(radius << 1) - radius); + } + + public Location getApproximateLocation(Player player, User u) { + return this.getApproximateLocation(player, GTMUtils.getCompassRadius(u.getUserRank())); + } + + + public enum TargetType { + NONE, + PLAYER, + ENTITY, + LOCATION, + VEHICLE + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/GTMRank.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/GTMRank.java new file mode 100644 index 0000000..6497835 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/GTMRank.java @@ -0,0 +1,157 @@ +package net.grandtheftmc.gtm.users; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +import org.bukkit.ChatColor; +import org.bukkit.Material; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.Utils; + +public enum GTMRank { + + HOBO(0, 0, 0, 0, Material.CHEST), + CRIMINAL(10000, 0, 0, 5.0, Material.WOOD_SWORD), + HOMIE(25000, 0, 0, 10.0, Material.LEATHER_HELMET), + THUG(50000, 1, 0, 15.0, Material.WOOD_HOE), + GANGSTER(75000, 1, 2, 20.0, Material.IRON_HELMET), + MUGGER(100000, 2, 3, 25.0, Material.WOOD_SWORD), + HUNTER(250000, 2, 5, 30.0, Material.WOOD_AXE), + DEALER(500000, 2, 5, 35.0, Material.SUGAR), + PIMP(1000000, 2, 10, 40.0, Material.IRON_SWORD), + MOBSTER(2000000, 3, 10, 45.0, Material.IRON_SPADE), + GODFATHER(5000000, 3, 20, 50.0, Material.DIAMOND_CHESTPLATE); + + private final int price; + private final List<String> perms; + private final Material material; + private final int houses; + private final int gangMembers; + /** The additional tax applied to this rank */ + private final double serverTax; + + GTMRank(int price, int houses, int gangMembers, double serverTax, Material material, String... perms) { + this.price = price; + this.perms = Arrays.asList(perms); + this.houses = houses; + this.material = material; + this.gangMembers = gangMembers; + this.serverTax = serverTax; + } + + public List<String> getAllPerms() { + List<String> permissions = new ArrayList<>(); + for (GTMRank uc : getGTMRanks()) { + permissions.addAll(uc.perms); + if (uc == this) + return permissions; + } + return permissions; + } + + private List<String> getPerms() { + return this.perms; + } + + public int getPrice() { + return this.price; + } + + public String getName() { + if (Core.getSettings().isSister()) { + if (this == DEALER) + return "HUSTLER"; + if (this == PIMP) + return "UNDERBOSS"; + } + return this.toString(); + } + + public ChatColor getColor() { + return this == GTMRank.HOBO ? ChatColor.GRAY : ChatColor.YELLOW; + } + + public String getColoredName() { + return Utils.f(this.getColor() + this.getName() + "&r"); + } + + public String getColoredNameBold() { + return Utils.f(this.getColor() + "&l" + this.getName() + "&r"); + } + + public GTMRank getNext() { + String rankName = this.getName(); + if ("GODFATHER".equalsIgnoreCase(rankName)) + return null; + int go = 0; + + GTMRank rank = null; + for (GTMRank r : getGTMRanks()) + if (go == 0) { + if (Objects.equals(r.getName(), rankName)) { + go = 1; + } + } + else if (go == 1) { + rank = r; + break; + } + return rank; + } + + public static GTMRank[] getGTMRanks() { + return GTMRank.class.getEnumConstants(); + } + + public static GTMRank fromString(String string) { + return Arrays.stream(GTMRank.getGTMRanks()).filter(uc -> uc.getName().equalsIgnoreCase(string) || uc.name().equalsIgnoreCase(string)).findFirst().orElse(GTMRank.HOBO); + } + + public Material getMaterial() { + return this.material; + } + + public static GTMRank getRankOrNull(String name) { + if (name == null) + return null; + return Arrays.stream(getGTMRanks()).filter(r -> r.getName().equalsIgnoreCase(name) || r.name().equalsIgnoreCase(name)).findFirst().orElse(null); + } + + public boolean isHigherThan(GTMRank rank) { + if (rank == null) + return false; + for (GTMRank r : getGTMRanks()) + if (r == this) + return false; + else if (r == rank) + return true; + return false; + } + + public int getHouses() { + return this.houses; + } + + public int getGangMembers() { + return this.gangMembers; + } + + /** + * Get the additional server tax applied for this GTMRank. + * <p> + * If this player dies, some of their money drops, which can be picked up. + * This variable increases or decreases the amount of money they drop. + * + * Note: 5.0 represents 5% increase. + * </p> + * + * @return The additional server tax applied for this GTMRank. + */ + public double getServerTax() { + return serverTax; + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/GTMTag.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/GTMTag.java new file mode 100644 index 0000000..0b56bfd --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/GTMTag.java @@ -0,0 +1,21 @@ +package net.grandtheftmc.gtm.users; + +import org.bukkit.ChatColor; + +/** + * Created by Timothy Lampen on 2017-12-16. + * + * @deprecated - unused due to net.grandtheftmc.core.users.eventtag.EventTag. + */ +public enum GTMTag { + FESTIVE("&b&lFestive"), + XMAS("&2&lXMAS"), + SNOWMAN("&r&lSnowman"), + SANTA("&c&lSanta"), + HOHOHO("&c&lH&2&lo&c&lH&2&lo&c&lH&2&lo"); + + private final String disp; + GTMTag(String disp) { + this.disp = ChatColor.translateAlternateColorCodes('&', disp); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/GTMUser.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/GTMUser.java new file mode 100644 index 0000000..3cdc332 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/GTMUser.java @@ -0,0 +1,1832 @@ +package net.grandtheftmc.gtm.users; + +import java.sql.Blob; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; +import java.util.logging.Level; +import java.util.stream.Collectors; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitRunnable; + +import com.j0ach1mmall3.wastedguns.api.events.ranged.AmmoUpdateEvent; +import com.j0ach1mmall3.wastedvehicles.api.VehicleProperties; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.achivements.Achievement; +import net.grandtheftmc.core.currency.Currency; +import net.grandtheftmc.core.currency.Purse; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.database.dao.CurrencyDAO; +import net.grandtheftmc.core.database.mutex.Mutexable; +import net.grandtheftmc.core.nametags.NametagManager; +import net.grandtheftmc.core.users.Pref; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserDAO; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.NMSUtil; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.State; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.util.debug.Log; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.database.dao.AmmoDAO; +import net.grandtheftmc.gtm.events.WantedLevelChangeEvent; +import net.grandtheftmc.gtm.gang.member.GangMember; +import net.grandtheftmc.gtm.gang.member.GangRole; +import net.grandtheftmc.gtm.items.AmmoType; +import net.grandtheftmc.gtm.items.ArmorUpgrade; +import net.grandtheftmc.gtm.items.GameItem; +import net.grandtheftmc.gtm.items.Head; +import net.grandtheftmc.gtm.items.Kit; +import net.grandtheftmc.gtm.utils.Stats; +import net.grandtheftmc.gtm.weapon.skins.WeaponSkinDAO; +import net.grandtheftmc.guns.weapon.Weapon; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; + +public class GTMUser extends Mutexable { + + /** The uuid of the user */ + private final UUID uuid; + /** The name of the user */ + private final String name; + private final Map<AmmoType, Integer> ammo = new HashMap<>(); + private final List<PersonalVehicle> vehicles = new ArrayList<>(); + private double sellInvConfirmAmt = 0; + private ChatAction currentChatAction = null; + private Object currentChatValue = null; + private final int[] wantedLevels = new int[] { 0, 1, 2, 4, 10, 25 }; + private GTMRank rank; + private int kills; + private boolean dead = false; + private int transferID = -1; + private int deaths; + // private double money; + private double bank; + private final HashMap<CheatCode, CheatCodeState> cheatCodes = new HashMap<>(); + private int killCounter; + private int killStreak; + // private int permits; + private JobMode jobMode = JobMode.CRIMINAL; + private long lastJobMode = -1; + private ItemStack[] backpackContents; + private HashMap<String, Long> kitExpiries = new HashMap<>(); + private String gang; + private GangRole gangRole; + private Long playtime; + private Long jointime; + private CompassTarget compassTarget; + private long lastCompassRefresh; + private PersonalVehicle personalVehicle; + private int vehicleTaskId = -1; + private int vehicleTimer; + private PersonalVehicle nextVehicle; + private boolean sendAway; + private String actionVehicle; + private int taxiTaskId = -1; + private TaxiTarget taxiTarget; + private int taxiPrice; + private int taxiTimer; + private UUID tpaRequestUUID; + private UUID tpaRequestSentUUID; + private boolean tpaHere; + private long lastTpaRequest = -1; + private long lastTeleport = -1; + private UUID bountyUUID; + private String bountyName; + private int bountyAmount = -1; + private List<String> gangInvites = new ArrayList<>(); + private String viewingGang; + private GangMember viewingGangMember; + private boolean gangChat; + private boolean addingLootCrate; + private boolean removingLootCrate; + private boolean checkingLootCrate; + private boolean restockingLootCrate; + private int jailTimer; + private UUID jailCop; + private String jailCopName; + private double bribe; + private long lastBackupRequest; + private ArmorUpgrade buyingArmorUpgrade; + private boolean kicked; + private long lastCopSpawn; + private long lastTag = -1; + private long lastJetpackCancel; + private long enableJetpackTime; + private String biddingHead; + private long biddingExpiry; + private boolean backpackOpen; + private Map<Short, List<Short>> unlockedWeaponSkins = new HashMap<>(); + private Map<Short, Short> equippedWeaponSkins = new HashMap<>(); + + // TODO test remove for debugging + public Map<String, Integer> methodCallCounter = new HashMap<>(); + + /** + * Holds currencies + */ + private Purse purse; + + /** + * Construct a new GTMUser. + * + * @param uuid - the uuid of the user + * @param name - the name of the user + */ + public GTMUser(UUID uuid, String name) { + this.uuid = uuid; + this.name = name; + this.purse = new Purse(); + + // initialize all currencies in purse + for (Currency curr : Currency.values()) { + purse.registerCurrency(curr); + } + + // initialize all ammo types + for (AmmoType type : AmmoType.getTypes()) { + if (!type.isInInventory()) { + this.ammo.put(type, 0); + } + } + + // TODO debug remove + // seeing how many method calls are being invoked per player + methodCallCounter.put("saveBackpackContents", 0); + methodCallCounter.put("saveBackpackContentsSync", 0); + methodCallCounter.put("setRank", 0); + methodCallCounter.put("setKills", 0); + methodCallCounter.put("addKills", 0); + methodCallCounter.put("setDeaths", 0); + methodCallCounter.put("addDeaths", 0); + // methodCallCounter.put("setMoney", 0); + // methodCallCounter.put("addMoney", 0); + // methodCallCounter.put("takeMoney", 0); + methodCallCounter.put("setBank", 0); + methodCallCounter.put("addBank", 0); + methodCallCounter.put("takeBank", 0); + methodCallCounter.put("depositToBank", 0); + methodCallCounter.put("withdrawFromBank", 0); + methodCallCounter.put("setPlaytime", 0); + // methodCallCounter.put("setKillCounter", 0); + // methodCallCounter.put("addKillCounter", 0); + // methodCallCounter.put("takeKillCounter", 0); + // methodCallCounter.put("setKillStreak", 0); + // methodCallCounter.put("addKillStreak", 0); + // methodCallCounter.put("takeKillStreak", 0); + // methodCallCounter.put("addPermits", 0); + // methodCallCounter.put("takePermits", 0); + // methodCallCounter.put("setPermits", 0); + // methodCallCounter.put("setJobMode", 0); + // methodCallCounter.put("setLastJobMode", 0); + // methodCallCounter.put("setAmmo", 0); + // methodCallCounter.put("addAmmo", 0); + // methodCallCounter.put("resetJail", 0); + // methodCallCounter.put("giveVehiclePerm", 0); + // methodCallCounter.put("removeVehiclePerm", 0); + // methodCallCounter.put("setCheatCodeState", 0); + } + + /** + * Called when we need to load data pertaining to the user. + * + * @param conn - the database connection thread + * + * @return {@code true} if the data was loaded, {@code false} otherwise. + */ + public boolean onLoad(Connection conn) { + + // TODO test remove + long start = System.currentTimeMillis(); + + String query = "SELECT * FROM " + Core.name() + " WHERE uuid=UNHEX(?) LIMIT 1;"; + + try (PreparedStatement statement = conn.prepareStatement(query)) { + statement.setString(1, getUUID().toString().replaceAll("-", "")); + + try (ResultSet result = statement.executeQuery()) { + if (result.next()) { + this.rank = GTMRank.fromString(result.getString("rank")); + this.kills = result.getInt("kills"); + this.deaths = result.getInt("deaths"); + this.bank = result.getDouble("bank"); + this.killCounter = result.getInt("killCounter"); + this.killStreak = result.getInt("killStreak"); + this.jobMode = JobMode.getMode(result.getString("jobMode")); + this.lastJobMode = result.getLong("lastJobMode"); + this.backpackContents = GTMUtils.fromBase64(result.getString("backpackContents")); + this.kitExpiries = new HashMap<>(); + this.jailTimer = result.getInt("jailTimer"); + try { + this.jailCop = result.getString("jailCop") == null ? null : UUID.fromString(result.getString("jailCop")); + } + catch (Exception ignored) { + } + this.playtime = (long) result.getInt("playtime"); + this.jailCopName = result.getString("jailCopName"); + String s = result.getString("kitExpiries"); + this.kitExpiries = new HashMap<>(); + if (s != null) { + try { + String[] expiries = s.split(","); + for (String e : expiries) { + String[] a = e.split(":"); + String kit = a[0]; + Kit k = GTM.getItemManager().getKit(kit); + if (kit == null || a.length < 2) + continue; + long expiry; + try { + expiry = Long.parseLong(a[1]); + } + catch (NumberFormatException ex) { + continue; + } + if (expiry > System.currentTimeMillis()) + this.kitExpiries.put(k.getName().toLowerCase(), expiry); + } + + } + catch (Exception e) { + GTM.getInstance().getLogger().log(Level.ALL, "Error while loading kitExpiries for player " + result.getString("name")); + e.printStackTrace(); + } + } + + for (VehicleProperties properties : GTM.getWastedVehicles().getBabies().getVehicleProperties()) { + if (result.getBoolean(properties.getIdentifier().toLowerCase())) { + PersonalVehicle v = new PersonalVehicle(properties.getIdentifier()); + this.vehicles.add(v); + String st = result.getString(properties.getIdentifier().toLowerCase() + ":info"); + if (st == null) + continue; + String[] a = st.split(":"); + if (a == null | a.length == 0) + continue; + v.setHealth(Double.parseDouble(a[0])); + } + } + + this.loadCheatCodes(conn, result); + } + } + } + catch (SQLException e) { + e.printStackTrace(); + } + + // load skins + this.unlockedWeaponSkins = WeaponSkinDAO.getUnlockedSkins(conn, this.uuid); + this.equippedWeaponSkins = WeaponSkinDAO.getEquippedSkins(conn, this.uuid); + + for (Currency curr : Currency.values()){ + switch(curr){ + case MONEY: + case PERMIT: + + // grab currency based off serverKey + int amount = CurrencyDAO.getCurrency(conn, curr.getServerKey(), getUUID(), curr); + // set in the purse + getPurse().set(curr, amount); + + // TODO remove debug messages + Core.log("[GTMUser] uuid=" + uuid.toString() + ", curr=" + curr.getId() + ", amount=" + getPurse().getBalance(curr)); + break; + } + } + + // load ammo + Map<AmmoType, Integer> ammoMap = AmmoDAO.getAllAmmo(conn, getUUID(), Core.name().toUpperCase()); + + // populate local variable + // as each k/v is init to 0 + ammoMap.forEach((k, v) -> { + // TODO remove + Core.log("[GTMUser][AmmoTest] uuid=" + uuid.toString() + "Type=" + k + " was found, amt=" + v); + ammo.put(k, v); + }); + + // TODO test remove + Log.info("[GTMUser][TEST]", "Finished onLoad() for " + getName() + " in " + (System.currentTimeMillis() - start) + " msecs."); + + return true; + } + + /** + * Call when we need to save data pertaining to the user. + * + * @param conn - the database connection thread + * + * @return {@code true} if the data was saved, {@code false} otherwise. + */ + public boolean onSave(Connection conn) { + + // save all the currencies + for (Currency curr : getPurse().getCurrencies().keySet()) { + + // only save + switch(curr){ + case MONEY: + case PERMIT: + int balance = getPurse().getBalance(curr); + + // TODO test remove + Core.log("[GTMUser][CurrencyTest] Saving user uuid=" + getUUID().toString() + ", currency=: " + curr.getId() + ", amt=" + balance); + CurrencyDAO.saveCurrency(conn, curr.getServerKey(), getUUID(), curr, balance); + break; + } + } + + // save all the ammo in user_ammo + AmmoDAO.saveAllAmmo(conn, getUUID(), Core.name().toUpperCase(), getAmmo()); + + // TODO debug statements please remove + StringBuilder builder = new StringBuilder(); + for (AmmoType at : ammo.keySet()) { + builder.append(at.name().toLowerCase() + "="); + builder.append(ammo.get(at) + ","); + } + Core.log("[GTMUser][AmmoTest] Saving user ammo of: " + builder.toString()); + + // TODO debug statements please remove + StringBuilder methodBuilder = new StringBuilder(); + methodCallCounter.forEach((k, v) -> { + methodBuilder.append(k + "=" + v + ", "); + }); + Core.log("[GTMUser][MethodCounter] User " + uuid.toString() + " call counter: " + methodBuilder.toString()); + + return true; + } + + public void dataCheck() { + + // TODO remove + Log.info("[GTMUser][TEST]", "Core name=" + getUUID().toString().replaceAll("-", "")); + + // TODO note: inline queries like this are subject to SQL injection + BaseDatabase.runCustomQuery("INSERT INTO " + Core.name() + "(`uuid`,`name`,`bank`) VALUES(UNHEX('" + getUUID().toString().replaceAll("-", "") + "'),'" + name + "','5000') ON DUPLICATE KEY UPDATE `name`='" + name + "';"); + + // TODO this shouldn't be how we set duplicate names + + // TODO note: inline queries like this are subject to SQL injection + BaseDatabase.runCustomQuery("UPDATE " + Core.name() + " SET `name`='ERROR' WHERE `name`='" + name + "' AND uuid != UNHEX('" + getUUID().toString().replaceAll("-", "") + "');"); + } + + /** + * Get the UUID of the user. + * + * @return The UUID of the user. + */ + public UUID getUUID() { + return this.uuid; + } + + /** + * Get the name of the user. + * + * @return The name of the user. + */ + public String getName() { + return this.name; + } + + public HashMap<CheatCode, CheatCodeState> getCheatCodes() { + return cheatCodes; + } + + private void loadCheatCodes(Connection conn, ResultSet rs) throws SQLException { + + if (rs.getBlob("cheatcodes") != null) { + Blob b = rs.getBlob("cheatcodes"); + String cheatCodesBlob = new String(b.getBytes(1, (int) b.length())); + for (String serializedCheatCode : cheatCodesBlob.split("-")) { + String[] split = serializedCheatCode.split("#"); + try { + this.cheatCodes.put(CheatCode.valueOf(split[0]), new CheatCodeState(State.valueOf(split[1]), Boolean.valueOf(split[2]))); + } + catch (Exception e) { + } + } + } + + // we get rank this way b/c user might not be loaded in container yet + UserRank highestRank = UserDAO.getHighestRank(conn, getUUID()); + + // TOOD user might not be loaded yet + for (CheatCode code : CheatCode.getCodes()) { + if (highestRank == code.getMinmumRank() || highestRank.isHigherThan(code.getMinmumRank())) { + if (!this.cheatCodes.containsKey(code) || this.cheatCodes.get(code).getState() == State.LOCKED) { + this.cheatCodes.put(code, new CheatCodeState(code.getDefaultState(), false)); + } + } + else { + if (this.cheatCodes.containsKey(code) && !this.cheatCodes.get(code).isPurchased()) { + this.cheatCodes.put(code, new CheatCodeState(State.LOCKED, false)); + } + } + } + + for (CheatCode code : CheatCode.getCodes()) + if (!this.cheatCodes.containsKey(code)) + this.cheatCodes.put(code, new CheatCodeState(State.LOCKED, false)); + + if (Core.getPermsManager().hasPerm(this.uuid, "kit.drugs")) { + this.cheatCodes.put(CheatCode.DRUGS, new CheatCodeState(CheatCode.DRUGS.getDefaultState(), true)); + Core.getPermsManager().removePerm(this.uuid, "kits.drugs"); + } + } + + public void saveBackpackContents() { + Bukkit.getScheduler().runTaskAsynchronously(GTM.getInstance(), () -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `backpackContents`=? WHERE `uuid`=UNHEX(?);")) { + statement.setString(1, this.backpackContents == null ? null : GTMUtils.toBase64(this.backpackContents)); + statement.setString(2, getUUID().toString().replaceAll("-", "")); + statement.execute(); + } + } + catch (SQLException e) { + e.printStackTrace(); + } + + }); + + // TODO remove test counter + methodCallCounter.put("saveBackpackContents", methodCallCounter.get("saveBackpackContents") + 1); + } + + public void saveBackpackContentsSync(Connection connection) { +// try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `backpackContents`=? WHERE `uuid`=UNHEX(?);")) { + statement.setString(1, this.backpackContents == null ? null : GTMUtils.toBase64(this.backpackContents)); + statement.setString(2, getUUID().toString().replaceAll("-", "")); + statement.execute(); + } + catch (SQLException e) { + e.printStackTrace(); + } + + // TODO remove test counter + methodCallCounter.put("saveBackpackContentsSync", methodCallCounter.get("saveBackpackContentsSync") + 1); + } + + public GTMRank getRank() { + return this.rank; + } + + public boolean isRank(GTMRank rank) { + if (rank == null || this.rank == null) + return false; + return this.rank == rank || this.rank.isHigherThan(rank); + } + + public void setTransferID(int transferID) { + this.transferID = transferID; + } + + public int getTransferID() { + return transferID; + } + + public void setRank(GTMRank r, Player player, User u) { + this.rank = r; + + ServerUtil.runTaskAsync(() -> GTMUserDAO.setRank(this.uuid, r)); + + NametagManager.updateNametag(Bukkit.getPlayer(this.uuid)); + u.setPerms(player); + + // TODO remove test counter + methodCallCounter.put("setRank", methodCallCounter.get("setRank") + 1); + } + + public void rankup(Player player, User u) { + GTMRank nextRank = this.rank.getNext(); + if (nextRank == null) { + player.sendMessage(Utils.f(Lang.RANKUP + "&7You can't rank up any more!")); + return; + } + int price = nextRank.getPrice(); + if (!this.hasMoney(price)) { + player.sendMessage(Utils.f(Lang.RANKUP + "&7You don't have the &c$&l" + price + "&7 required to rank up!")); + return; + } + this.takeMoney(price); + this.setRank(nextRank, player, u); + GTMUtils.updateBoard(player, u, this); + Utils.broadcastExcept(player, Lang.RANKUP + "&7" + u.getColoredName(player) + "&7 ranked up to " + nextRank.getColoredNameBold() + "&7!"); + player.sendMessage(Lang.MONEY_TAKE.toString() + price); + player.sendMessage(Utils.f(Lang.RANKUP + "&7You ranked up to " + nextRank.getColoredNameBold() + "&7!")); + } + + public int getKills() { + return this.kills; + } + + public void setKills(int i) { + this.kills = i; + + ServerUtil.runTaskAsync(() -> GTMUserDAO.setKills(this.uuid, this.kills)); + + // TODO remove test counter + methodCallCounter.put("setKills", methodCallCounter.get("setKills") + 1); + } + + public void addKills(int i) { + this.kills += i; + + ServerUtil.runTaskAsync(() -> GTMUserDAO.setKills(this.uuid, this.kills)); + + // TODO remove test counter + methodCallCounter.put("addKills", methodCallCounter.get("addKills") + 1); + } + + public int getDeaths() { + return this.deaths; + } + + public void setDeaths(int i) { + this.deaths = i; + + ServerUtil.runTaskAsync(() -> GTMUserDAO.setDeaths(this.uuid, this.deaths)); + + // TODO remove test counter + methodCallCounter.put("setDeaths", methodCallCounter.get("setDeaths") + 1); + } + + public void addDeaths(int i) { + this.deaths += i; + + ServerUtil.runTaskAsync(() -> GTMUserDAO.setDeaths(this.uuid, this.deaths)); + + // TODO remove test counter + methodCallCounter.put("addDeaths", methodCallCounter.get("addDeaths") + 1); + } + + /** + * Get the purse that holds the currency for this player. + * + * @return The purse that holds the currency for this player. + */ + public Purse getPurse() { + return purse; + } + + public double getMoney() { + if (getPurse().getBalance(Currency.MONEY) < 0) { + getPurse().set(Currency.MONEY, 0); + } + + return getPurse().getBalance(Currency.MONEY); + } + + public void setMoney(double amount) { + getPurse().set(Currency.MONEY, (int) amount); + + GTMUtils.updateBoard(Bukkit.getPlayer(this.uuid), this); + } + + public void addMoney(double amount) { + if (amount < 0) + return; + + getPurse().set(Currency.MONEY, getPurse().getBalance(Currency.MONEY) + (int) amount); + } + + public void takeMoney(double amount) { + getPurse().set(Currency.MONEY, getPurse().getBalance(Currency.MONEY) - (int) amount); + } + + public boolean hasMoney(double amount) { + return getPurse().getBalance(Currency.MONEY) >= amount; + } + + public double getBank() { + if (this.bank < 0) + this.setBank(0); + return this.bank; + } + + public void setBank(double amount) { + double old = this.bank; + this.bank = amount; + + ServerUtil.runTaskAsync(() -> { + GTMUserDAO.setBank(this.uuid, this.bank); + String name = Bukkit.getPlayer(this.uuid) == null ? "ERROR" : Bukkit.getPlayer(this.uuid).getName(); + Utils.insertLog(this.uuid, name, "BANK", "SET", old + " -> " + this.bank, amount, 0); + }); + + // TODO remove test counter + methodCallCounter.put("setBank", methodCallCounter.get("setBank") + 1); + } + + public void addBank(double amount) { + double old = this.bank; + this.bank += amount; + + ServerUtil.runTaskAsync(() -> { + GTMUserDAO.setBank(this.uuid, this.bank); + String name = Bukkit.getPlayer(this.uuid) == null ? "ERROR" : Bukkit.getPlayer(this.uuid).getName(); + Utils.insertLog(this.uuid, name, "BANK", "ADD", old + " -> " + this.bank, amount, 0); + }); + + // TODO remove test counter + methodCallCounter.put("addBank", methodCallCounter.get("addBank") + 1); + } + + public void takeBank(double amount) { + double old = this.bank; + this.bank -= amount; + + ServerUtil.runTaskAsync(() -> { + GTMUserDAO.setBank(this.uuid, this.bank); + String name = Bukkit.getPlayer(this.uuid) == null ? "ERROR" : Bukkit.getPlayer(this.uuid).getName(); + Utils.insertLog(this.uuid, name, "BANK", "TAKE", old + " -> " + this.bank, amount, 0); + }); + + // TODO remove test counter + methodCallCounter.put("takeBank", methodCallCounter.get("takeBank") + 1); + } + + public void depositToBank(double amount) { + double old = this.bank; + this.bank += amount; + + getPurse().set(Currency.MONEY, getPurse().getBalance(Currency.MONEY) - (int) amount); + // TODO stephen + ServerUtil.runTaskAsync(() -> { + try (Connection conn = BaseDatabase.getInstance().getConnection()) { + CurrencyDAO.saveCurrency(conn, Currency.MONEY.getServerKey(), this.uuid, Currency.MONEY, getPurse().getBalance(Currency.MONEY)); + } + catch (Exception e) { + e.printStackTrace(); + } + }); + + ServerUtil.runTaskAsync(() -> { + GTMUserDAO.setBank(this.uuid, this.bank); + String name = Bukkit.getPlayer(this.uuid) == null ? "ERROR" : Bukkit.getPlayer(this.uuid).getName(); + Utils.insertLog(this.uuid, name, "BANK", "DEPOSIT", old + " -> " + this.bank, amount, 0); + }); + + // TODO remove test counter + methodCallCounter.put("depositToBank", methodCallCounter.get("depositToBank") + 1); + } + + public void withdrawFromBank(double amount) { + double old = this.bank; + this.bank -= amount; + + getPurse().set(Currency.MONEY, getPurse().getBalance(Currency.MONEY) + (int) amount); + // TODO stephen + ServerUtil.runTaskAsync(() -> { + try (Connection conn = BaseDatabase.getInstance().getConnection()) { + CurrencyDAO.saveCurrency(conn, Currency.MONEY.getServerKey(), this.uuid, Currency.MONEY, getPurse().getBalance(Currency.MONEY)); + } + catch (Exception e) { + e.printStackTrace(); + } + }); + + ServerUtil.runTaskAsync(() -> { + GTMUserDAO.setBank(this.uuid, this.bank); + String name = Bukkit.getPlayer(this.uuid) == null ? "ERROR" : Bukkit.getPlayer(this.uuid).getName(); + Utils.insertLog(this.uuid, name, "BANK", "WITHDRAW", old + " -> " + this.bank, amount, 0); + }); + + // TODO remove test counter + methodCallCounter.put("withdrawFromBank", methodCallCounter.get("withdrawFromBank") + 1); + } + + public boolean hasBank(double i) { + return this.bank >= i; + } + + public int getWantedLevel() { + int wantedLevel = 0; + for (int i = 0; i < this.wantedLevels.length; i++) + if (this.killCounter >= this.wantedLevels[i]) + wantedLevel = i; + return wantedLevel; + } + + public Long getPlaytime() { + return this.playtime; + } + + public void setPlaytime(Long playtime) { + this.playtime = playtime; + + ServerUtil.runTaskAsync(() -> GTMUserDAO.setPlaytime(this.uuid, this.playtime)); + + // TODO remove test counter + methodCallCounter.put("setPlaytime", methodCallCounter.get("setPlaytime") + 1); + } + + public Long getJoinTime() { + return this.jointime; + } + + public void setJointime(Long jointime) { + this.jointime = jointime; + } + + public int getKillCounter() { + return this.killCounter; + } + + public void setKillCounter(int i) { + int wantedLevel = this.getWantedLevel(); + this.killCounter = i; + + ServerUtil.runTaskAsync(() -> GTMUserDAO.setKillCounter(this.uuid, this.killCounter)); + + Player player = Bukkit.getPlayer(this.uuid); + int wantedLevelAfter = this.getWantedLevel(); + if (wantedLevel != wantedLevelAfter) + Bukkit.getPluginManager().callEvent(new WantedLevelChangeEvent(player, this, wantedLevelAfter)); + } + + public void addKillCounter(int i) { + int wantedLevel = this.getWantedLevel(); + this.killCounter += i; + + ServerUtil.runTaskAsync(() -> GTMUserDAO.setKillCounter(this.uuid, this.killCounter)); + + Player player = Bukkit.getPlayer(this.uuid); + int wantedLevelAfter = this.getWantedLevel(); + if (wantedLevel != wantedLevelAfter) + Bukkit.getPluginManager().callEvent(new WantedLevelChangeEvent(player, this, wantedLevelAfter)); + } + + public void takeKillCounter(int i) { + int wantedLevel = this.getWantedLevel(); + this.killCounter -= i; + + ServerUtil.runTaskAsync(() -> GTMUserDAO.setKillCounter(this.uuid, this.killCounter)); + + Player player = Bukkit.getPlayer(this.uuid); + int wantedLevelAfter = this.getWantedLevel(); + if (wantedLevel != wantedLevelAfter) + Bukkit.getPluginManager().callEvent(new WantedLevelChangeEvent(player, this, wantedLevelAfter)); + } + + public int getKillStreak() { + return this.killStreak; + } + + public void setKillStreak(int i) { + this.killStreak = i; + ServerUtil.runTaskAsync(() -> GTMUserDAO.setKillstreak(this.uuid, this.killStreak)); + } + + public void addKillStreak(int i) { + this.killStreak += i; + ServerUtil.runTaskAsync(() -> GTMUserDAO.setKillstreak(this.uuid, this.killStreak)); + } + + public void takeKillStreak(int i) { + this.killStreak -= i; + ServerUtil.runTaskAsync(() -> GTMUserDAO.setKillstreak(this.uuid, this.killStreak)); + } + + public void addPermits(int amount) { + getPurse().set(Currency.PERMIT, getPurse().getBalance(Currency.PERMIT) + amount); + } + + public void takePermits(int amount) { + getPurse().set(Currency.PERMIT, getPurse().getBalance(Currency.PERMIT) - amount); + } + + public int getPermits() { + return getPurse().getBalance(Currency.PERMIT); + } + + public void setPermits(int amount) { + getPurse().set(Currency.PERMIT, amount); + } + + public boolean hasPermits(int amount) { + return getPurse().getBalance(Currency.PERMIT) >= amount; + } + + public JobMode getJobMode() { + return this.jobMode == null ? JobMode.CRIMINAL : this.jobMode; + } + + public void setJobMode(JobMode jobMode) { + if (jobMode == null || JobMode.CRIMINAL != jobMode) { + User u = Core.getUserManager().getLoadedUser(this.uuid); + u.setEquipedTag(null); + } + + this.jobMode = jobMode; + this.lastJobMode = System.currentTimeMillis(); +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set jobMode='" + this.jobMode + "', lastJobMode=" + this.lastJobMode + " where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + Core.name() + " set jobMode='" + this.jobMode + "', lastJobMode=" + this.lastJobMode + " where uuid=UNHEX('" + getUUID().toString().replaceAll("-", "") + "');")); + + if (Bukkit.getPlayer(this.uuid) != null) { + Player player = Bukkit.getPlayer(this.uuid); + player.setAllowFlight(false); + player.setFlying(false); + } + } + + public boolean canSwitchJobMode(UserRank rank) { + return this.lastJobMode <= 0 || this.lastJobMode + (GTMUtils.getJobModeDelay(rank) * 1000) < System.currentTimeMillis(); + } + + public long getTimeUntilJobModeSwitch(UserRank rank) { + return this.lastJobMode + (GTMUtils.getJobModeDelay(rank) * 1000L) - System.currentTimeMillis(); + } + + public long getLastJobMode() { + return this.lastJobMode; + } + + public void setLastJobMode(int lastJobMode) { + this.lastJobMode = lastJobMode; +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set jobMode='" + this.jobMode + "', lastJobMode=" + this.lastJobMode + " where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + Core.name() + " set jobMode='" + this.jobMode + "', lastJobMode=" + this.lastJobMode + " where uuid=UNHEX('" + getUUID().toString().replaceAll("-", "") + "');")); + } + + public boolean isInCombat() { + return (this.lastTag + 20000) > System.currentTimeMillis(); + } + + public Long getLastTag() { + return this.lastTag; + } + + public void setLastTag(long i) { + this.lastTag = i; + } + + public CompassTarget getCompassTarget() { + return this.compassTarget; + } + + public boolean hasCompassTarget() { + return this.compassTarget != null; + } + + public void setCompassTarget(Player player, User u, CompassTarget compassTarget) { + this.compassTarget = compassTarget; + this.refreshCompassTarget(player, u); + } + + public void unsetCompassTarget(Player player, User u) { + this.compassTarget = null; + player.setCompassTarget(player.getLocation()); + } + + public boolean refreshCompassTarget(Player player, User u) { + if (this.compassTarget == null) + return false; + if (this.getCompassTarget().getExactLocation(player).equals(player.getLocation())) { + this.unsetCompassTarget(player, Core.getUserManager().getLoadedUser(uuid)); + player.sendMessage(Utils.f(Lang.GPS + "&7Your GPS target was unset as you are in a different worlds compared to your target.")); + return false; + } + this.lastCompassRefresh = System.currentTimeMillis(); + player.setCompassTarget(this.compassTarget.getApproximateLocation(player, u)); + return true; + } + + public Long getLastCompassRefresh() { + return this.lastCompassRefresh; + } + + public void setLastCompassRefresh(Long lastCompassRefresh) { + this.lastCompassRefresh = lastCompassRefresh; + } + + public boolean isUsingTaxi() { + return this.taxiTarget != null; + } + + public TaxiTarget getTaxiTarget() { + return this.taxiTarget; + } + + public void setTaxiTarget(TaxiTarget t) { + this.taxiTarget = t; + } + + public void unsetTaxiTarget() { + this.taxiTarget = null; + this.taxiTaskId = -1; + this.taxiPrice = 0; + this.taxiTimer = 0; + } + + public int getTaxiPrice() { + return this.taxiPrice; + } + + public void setTaxiPrice(int i) { + this.taxiPrice = i; + } + + public int getTaxiTimer() { + return this.taxiTimer; + } + + public void setTaxiTimer(int i) { + this.taxiTimer = i; + } + + public UUID getTpaRequestUUID() { + return this.tpaRequestUUID; + } + + public void setTpaRequestUUID(UUID tpaRequestUUID) { + this.tpaRequestUUID = tpaRequestUUID; + this.lastTpaRequest = tpaRequestUUID == null ? -1 : System.currentTimeMillis(); + } + + public UUID getTpaRequestSentUUID() { + return this.tpaRequestSentUUID; + } + + public void setTpaRequestSentUUID(UUID uuid) { + this.tpaRequestSentUUID = uuid; + } + + public Long getLastTpaRequest() { + return this.lastTpaRequest; + } + + public void setLastTpaRequest(Long lastTpaRequest) { + this.lastTpaRequest = lastTpaRequest; + } + + public boolean hasTpaRequest() { + return !(this.lastTpaRequest > 0 && this.lastTpaRequest + 60000 < System.currentTimeMillis()); + } + + public boolean isTpaHere() { + return this.tpaHere; + } + + public void setTpaHere(boolean b) { + this.tpaHere = b; + } + + public void unsetTpaRequests() { + this.lastTpaRequest = -1L; + this.tpaRequestSentUUID = null; + this.tpaRequestUUID = null; + this.tpaHere = false; + } + + public UUID getBountyUUID() { + return this.bountyUUID; + } + + public void setBountyUUID(UUID bountyUUID) { + this.bountyUUID = bountyUUID; + } + + public String getBountyName() { + return this.bountyName; + } + + public void setBountyName(String bountyName) { + this.bountyName = bountyName; + } + + public ItemStack[] getBackpackContents() { + return this.backpackContents; + } + + public void setBackpackContents(ItemStack[] backpackContents) { + this.backpackContents = backpackContents; + this.saveBackpackContents(); + } + + public boolean canUseKit(String name) { + return !(this.kitExpiries.containsKey(name.toLowerCase()) && this.kitExpiries.get(name.toLowerCase()) > System.currentTimeMillis()); + } + + public long getKitExpiry(String name) { + return this.kitExpiries.containsKey(name.toLowerCase()) ? this.kitExpiries.get(name.toLowerCase()) : -1; + } + + public void setKitExpiry(String name, int delay) { // delay is IN SECONDS + this.kitExpiries.put(name.toLowerCase(), System.currentTimeMillis() + (delay * 1000)); + this.updateExpiries(); + } + + public Map<String, Long> getKitExpiries() { + return this.kitExpiries; + } + + public String getKitExpiriesString() { + String expiries = ""; + for (Map.Entry<String, Long> entry : this.kitExpiries.entrySet()) { + Long l = entry.getValue(); + if (l > System.currentTimeMillis()) + expiries += entry.getKey() + ':' + l + ','; + } + return expiries.endsWith(",") ? expiries.substring(0, expiries.length() - 1) : expiries; + } + + public void updateExpiries() { +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set kitExpiries='" + this.getKitExpiriesString() + "' where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + Core.name() + " set kitExpiries='" + this.getKitExpiriesString() + "' where uuid=UNHEX('" + getUUID().toString().replaceAll("-", "") + "');")); + } + + public long getLastCopSpawn() { + return this.lastCopSpawn; + } + + public void setLastCopSpawn(long lastCopSpawn) { + this.lastCopSpawn = lastCopSpawn; + } + + public double getKDR() { + return Utils.round(this.deaths == 0 ? this.kills : this.kills / (double) this.deaths); + } + + public boolean isAddingLootCrate() { + return this.addingLootCrate; + } + + public void setAddingLootCrate(boolean addingLootCrate) { + this.addingLootCrate = addingLootCrate; + } + + public boolean isRemovingLootCrate() { + return this.removingLootCrate; + } + + public void setRemovingLootCrate(boolean removingLootCrate) { + this.removingLootCrate = removingLootCrate; + } + + public boolean isCheckingLootCrate() { + return this.checkingLootCrate; + } + + public void setCheckingLootCrate(boolean checkingLootCrate) { + this.checkingLootCrate = checkingLootCrate; + } + + public boolean isRestockingLootCrate() { + return this.restockingLootCrate; + } + + public void setRestockingLootCrate(boolean restockingLootCrate) { + this.restockingLootCrate = restockingLootCrate; + } + + public Map<AmmoType, Integer> getAmmo() { + return this.ammo; + } + + public int getAmmoInInventory(Player player, AmmoType type) { + GameItem gameItem = type.getGameItem(); + if (gameItem == null || player == null) + return 0; + return Arrays.stream(player.getInventory().getContents()).filter(item -> item != null && item.isSimilar(gameItem.getItem())).mapToInt(ItemStack::getAmount).sum(); + } + + public int getAmmo(AmmoType type) { + if (type.isInInventory()) + return this.getAmmoInInventory(Bukkit.getPlayer(this.uuid), type); + else + return this.ammo.containsKey(type) ? this.ammo.get(type) : 0; + } + + public void setAmmoInInventory(Player player, AmmoType type, int amount) { + int ammo = this.getAmmoInInventory(Bukkit.getPlayer(this.uuid), type); + if (ammo > amount) + this.removeAmmoFromInventory(player, type, ammo - amount); + else if (ammo < amount) + this.addAmmoToInventory(player, type, amount - ammo); + this.updateAmmo(); + } + + public void setAmmo(AmmoType type, int amount) { + if (type.isInInventory()) { + this.setAmmoInInventory(Bukkit.getPlayer(this.uuid), type, amount); + return; + } + this.ammo.put(type, amount); + +// Core.sql.updateAsyncLater("update " + Core.name() + " set " + type.name() + '=' + i + " where uuid='" + this.uuid + "';"); +// ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + Core.name() + " set " + type.name() + '=' + amount + " where uuid='" + this.uuid + "';")); + + this.updateAmmo(); + } + + public void addAmmoToInventory(Player player, AmmoType type, int amount) { + GameItem gameItem = type.getGameItem(); + if (gameItem == null) + return; + ItemStack item = gameItem.getItem(); + item.setAmount(amount); + Utils.giveItems(player, item); + this.updateAmmo(); + } + + public void addAmmo(AmmoType type, int amount) { + if (type.isInInventory()) { + this.addAmmoToInventory(Bukkit.getPlayer(this.uuid), type, amount); + return; + } + this.ammo.put(type, this.ammo.get(type) + amount); + +// Core.sql.updateAsyncLater("update " + Core.name() + " set " + type.name() + '=' + type.name() + '+' + i +// + " where uuid='" + this.uuid + "';"); +// ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + Core.name() + " set " + type.name() + '=' + type.name() + '+' + amount + " where uuid='" + this.uuid + "';")); + + this.updateAmmo(); + } + + public void removeAmmoFromInventory(Player player, AmmoType type, int toRemove) { + GameItem gameItem = type.getGameItem(); + if (gameItem == null) + return; + Utils.takeItems(player, toRemove, gameItem.getItem()); + this.updateAmmo(); + } + + public void removeAmmo(AmmoType type, int toRemove) { + if (type.isInInventory()) { + this.removeAmmoFromInventory(Bukkit.getPlayer(this.uuid), type, toRemove); + return; + } + + this.ammo.put(type, this.ammo.get(type) >= toRemove ? this.ammo.get(type) - toRemove : 0); + + // NOTE: THIS IS CALLED EVERY RELOAD WHICH IS BAD! +// Core.sql.updateAsyncLater("update " + Core.name() + " set " + type.name() + '=' + type.name() + '-' + i +// + " where uuid='" + this.uuid + "';"); + // ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + + // Core.name() + " set " + type.name() + '=' + type.name() + '-' + i + " + // where uuid='" + this.uuid + "';")); + + this.updateAmmo(); + } + + public boolean hasAmmoInInventory(Player player, AmmoType type, int amount) { + return this.getAmmoInInventory(player, type) >= amount; + } + + public boolean hasAmmo(AmmoType type, int amount) { + if (type.isInInventory()) + return this.hasAmmoInInventory(Bukkit.getPlayer(this.uuid), type, amount); + return this.ammo.get(type) >= amount; + } + + public void updateAmmo() { + Bukkit.getPluginManager().callEvent(new AmmoUpdateEvent(Bukkit.getPlayer(this.uuid))); + } + + public void updateAmmoLater() { + new BukkitRunnable() { + @Override + public void run() { + Bukkit.getPluginManager().callEvent(new AmmoUpdateEvent(Bukkit.getPlayer(GTMUser.this.uuid))); + } + }.runTaskLater(GTM.getInstance(), 1); + + } + + public boolean isKicked() { + return this.kicked; + } + + public void setKicked(boolean kicked) { + this.kicked = kicked; + } + + public void jail(int jailTimer, Player cop) { + this.jailTimer = jailTimer; + this.jailCop = cop.getUniqueId(); + this.jailCopName = cop.getName(); + +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set jailTimer=" + this.jailTimer + ", jailCop='" + this.jailCop + "', jailCopName='" + this.jailCopName + "' where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + Core.name() + " set jailTimer=" + this.jailTimer + ", jailCop='" + this.jailCop + "', jailCopName='" + this.jailCopName + "' where uuid=UNHEX('" + getUUID().toString().replaceAll("-", "") + "');")); + } + + public boolean isArrested() { + return this.jailTimer >= 0; + } + + public int getJailTimer() { + return this.jailTimer; + } + + public void setJailTimer(int jailTimer) { + this.jailTimer = jailTimer; +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set jailTimer=" + jailTimer + " where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + Core.name() + " set jailTimer=" + jailTimer + " where uuid=UNHEX('" + getUUID().toString().replaceAll("-", "") + "');")); + } + + public UUID getJailCop() { + return this.jailCop; + } + + public void resetJail() { + this.jailTimer = -1; + this.jailCop = null; + this.jailCopName = null; + this.bribe = 0; +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set jailTimer=-1, jailCop=NULL, jailCopName=NULL where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + Core.name() + " set jailTimer=-1, jailCop=NULL, jailCopName=NULL where uuid=UNHEX('" + getUUID().toString().replaceAll("-", "") + "');")); + } + + public String getJailCopName() { + return this.jailCopName; + } + + public void updateTintHealth(Player player, User user) { + if (!user.getPref(Pref.TINT_HEALTH) || player.getHealth() >= player.getMaxHealth()) { +// new JLibPlayer(player).setWorldborderTint(0); + NMSUtil.setWorldBoarderTint(player, 0); + return; + } + UUID uuid = player.getUniqueId(); + new BukkitRunnable() { + @Override + public void run() { + Player player = Bukkit.getPlayer(uuid); + if (player != null) { + NMSUtil.setWorldBoarderTint(player, (int) ((player.getHealth() * 100) / player.getMaxHealth())); +// new JLibPlayer(player).setWorldborderTint(100 - (int) (player.getHealth() * 100 / player.getMaxHealth())); + } + } + }.runTaskLater(GTM.getInstance(), 1); + } + + public PersonalVehicle getPersonalVehicle() { + return this.personalVehicle; + } + + public void setPersonalVehicle(PersonalVehicle personalVehicle) { + this.personalVehicle = personalVehicle; + } + + public boolean hasPersonalVehicle() { + return this.personalVehicle != null; + } + + public List<PersonalVehicle> getVehicles() { + return this.vehicles; + } + + public boolean isDead() { + return dead; + } + + public void setDead(boolean dead) { + this.dead = dead; + } + + public List<VehicleProperties> getVehicleProperties() { + return this.vehicles.stream().filter(v -> v.getVehicleProperties() != null).map(PersonalVehicle::getVehicleProperties).collect(Collectors.toList()); + } + + public boolean hasVehicle(String vehicle) { + return this.vehicles.stream().anyMatch(v -> v.getVehicle().equalsIgnoreCase(vehicle)); + } + + public void giveVehiclePerm(Player player, VehicleProperties vehicle) { +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set `" + vehicle.getIdentifier().toLowerCase() + "`=true where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + Core.name() + " set `" + vehicle.getIdentifier().toLowerCase() + "`=true where uuid=UNHEX('" + getUUID().toString().replaceAll("-", "") + "');")); + + if (!this.hasVehicle(vehicle.getIdentifier())) + this.vehicles.add(new PersonalVehicle(vehicle.getIdentifier())); + } + + public void removeVehiclePerm(Player player, VehicleProperties vehicle) { +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set `" + vehicle.getIdentifier().toLowerCase() + "`=false where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + Core.name() + " set `" + vehicle.getIdentifier().toLowerCase() + "`=false where uuid=UNHEX('" + getUUID().toString().replaceAll("-", "") + "');")); + + if (this.personalVehicle != null && this.personalVehicle.getVehicle().equalsIgnoreCase(vehicle.getIdentifier())) + this.personalVehicle = null; + new ArrayList<>(this.vehicles).stream().filter(v -> v.getVehicle().equalsIgnoreCase(vehicle.getIdentifier())).forEach(this.vehicles::remove); + } + + public PersonalVehicle getPersonalVehicle(String s) { + if (this.personalVehicle != null && this.personalVehicle.getVehicle().equalsIgnoreCase(s)) + return this.personalVehicle; + return this.vehicles.stream().filter(v -> v.getVehicle().equalsIgnoreCase(s)).findFirst().orElse(null); + } + + public void setPersonalVehicle(Player player, User user, PersonalVehicle vehicle) { + if (this.personalVehicle != null && this.personalVehicle.onMap()) { + this.nextVehicle = vehicle; + this.personalVehicle.teleport(player, user, this, true); + return; + } + if (!this.vehicles.contains(vehicle)) { + player.sendMessage(Lang.VEHICLES.f("&7You do not own that vehicle!")); + return; + } + this.personalVehicle = vehicle; + this.nextVehicle = null; + player.sendMessage(Lang.VEHICLES.f("&7You set " + vehicle.getDisplayName() + "&7 as your personal vehicle!")); + this.personalVehicle.call(player, user, this); + } + + public boolean cancelVehicleTeleport() { + if (this.vehicleTaskId == -1) + return false; + Bukkit.getScheduler().cancelTask(this.vehicleTaskId); + this.nextVehicle = null; + this.sendAway = false; + this.vehicleTimer = -1; + return true; + } + + public int getVehicleTaskId() { + return this.vehicleTaskId; + } + + public void setVehicleTaskId(int vehicleTaskId) { + this.vehicleTaskId = vehicleTaskId; + } + + public int getVehicleTimer() { + return this.vehicleTimer; + } + + public void setVehicleTimer(int vehicleTimer) { + this.vehicleTimer = vehicleTimer; + } + + public PersonalVehicle getNextVehicle() { + return this.nextVehicle; + } + + public void setNextVehicle(PersonalVehicle nextVehicle) { + this.nextVehicle = nextVehicle; + } + + public boolean isSendAway() { + return this.sendAway; + } + + public void setSendAway(boolean sendAway) { + this.sendAway = sendAway; + } + + public String getActionVehicle() { + return this.actionVehicle; + } + + public void setActionVehicle(String actionVehicle) { + this.actionVehicle = actionVehicle; + } + + public long getLastTeleport() { + return this.lastTeleport; + } + + public void setLastTeleport(long lastTeleport) { + this.lastTeleport = lastTeleport; + } + + public void setLastTeleport() { + this.lastTeleport = System.currentTimeMillis(); + } + + public boolean hasTeleportProtection() { + return this.lastTeleport + 10000 > System.currentTimeMillis(); + } + + public long getTimeUntilTeleportProtectionExpires() { + return this.lastTeleport + 10000 - System.currentTimeMillis(); + } + + public ChatAction getCurrentChatAction() { + return this.currentChatAction; + } + + public long getBiddingExpiry() { + return this.biddingExpiry; + } + + public void setBiddingExpiry(long biddingExpiry) { + this.biddingExpiry = biddingExpiry; + } + + public Head getBiddingHead() { + Head head = GTM.getShopManager().getHead(this.biddingHead, this.biddingExpiry); + if (head == null) { + this.biddingHead = null; + this.biddingExpiry = -1; + } + return head; + } + + public CheatCodeState getCheatCodeState(CheatCode code) { + if (this.cheatCodes.containsKey(code)) + return this.cheatCodes.get(code); + this.cheatCodes.put(code, new CheatCodeState(State.LOCKED, false)); + return new CheatCodeState(State.LOCKED, false); + } + + public void setBribe(double bribe) { + this.bribe = bribe; + } + + public void setBountyAmount(int bountyAmount) { + this.bountyAmount = bountyAmount; + } + + public int getBountyAmount() { + return bountyAmount; + } + + public double getBribe() { + return this.bribe; + } + + /** + * @param code the enum cheatcode that you are setting + * @param state the state of the cheatcode (which can be gotten from new + * CheatCodeState) + * @apiNote this method immediately updates ALL the cheatcodes to the MySQL + * server. + */ + public void setCheatCodeState(CheatCode code, CheatCodeState state) { + this.cheatCodes.put(code, state); +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set cheatcodes='" + CheatCode.seralizeCheatCodes(this.cheatCodes) + "' where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + Core.name() + " set cheatcodes='" + CheatCode.seralizeCheatCodes(this.cheatCodes) + "' where uuid=UNHEX('" + getUUID().toString().replaceAll("-", "") + "');")); + } + + public void setBiddingHead(String biddingHead) { + this.biddingHead = biddingHead; + } + + public long getLastJetpackCancel() { + return this.lastJetpackCancel; + } + + public void setLastJetpackCancel(long lastJetpackCancel) { + this.lastJetpackCancel = lastJetpackCancel; + } + + public long getEnableJetpackTime() { + return enableJetpackTime; + } + + public void setEnableJetpackTime(long enableJetpackTime) { + this.enableJetpackTime = enableJetpackTime; + } + + public boolean canUseJetpack(){ + return System.currentTimeMillis()>this.enableJetpackTime; + } + + public void disableJetpack(){ + if(System.currentTimeMillis() + 10000 > this.enableJetpackTime)this.enableJetpackTime=System.currentTimeMillis() + 10000; + } + + public ArmorUpgrade getBuyingArmorUpgrade() { + return this.buyingArmorUpgrade; + } + + public void setBuyingArmorUpgrade(ArmorUpgrade buyingArmorUpgrade) { + this.buyingArmorUpgrade = buyingArmorUpgrade; + } + + public boolean getBackpackOpen() { + return this.backpackOpen; + } + + public void setBackpackOpen(boolean backpackOpen) { + this.backpackOpen = backpackOpen; + } + + public boolean hasRequestedBackup() { + Player player = Bukkit.getPlayer(uuid); + return this.lastBackupRequest + 60000 > System.currentTimeMillis(); + } + + public long getTimeUntilBackupRequestExpires() { + return 60000 + this.lastBackupRequest - System.currentTimeMillis(); + } + + public void checkBackupExpiration(Player player) { + if (this.lastBackupRequest > 0) { + if (this.lastBackupRequest + 60000 < System.currentTimeMillis()) { + this.lastBackupRequest = -1; + player.spigot().sendMessage(new ComponentBuilder(Lang.COP_MODE.s()).append("Your backup request has expired! Click to extend it: ").color(net.md_5.bungee.api.ChatColor.GRAY).append(" [ACCEPT] ").color(net.md_5.bungee.api.ChatColor.GREEN).bold(true).event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/backup")).create()); + } + + } + } + + public void setLastBackupRequest(long l) { + this.lastBackupRequest = l; + } + + public void checkAchievements() { + User user = Core.getUserManager().getLoadedUser(getUUID()); + Player player = Bukkit.getPlayer(this.uuid); + if (!user.getUnlockedAchievements().contains(Achievement.Hobo)) + user.addAchievement(Achievement.Hobo); + if (!user.getUnlockedAchievements().contains(Achievement.CRIMINAL) && isRank(GTMRank.CRIMINAL)) + user.addAchievement(Achievement.CRIMINAL); + if (!user.getUnlockedAchievements().contains(Achievement.HOMIE) && isRank(GTMRank.HOMIE)) + user.addAchievement(Achievement.HOMIE); + if (!user.getUnlockedAchievements().contains(Achievement.THUG) && isRank(GTMRank.THUG)) + user.addAchievement(Achievement.THUG); + if (!user.getUnlockedAchievements().contains(Achievement.GANGSTER) && isRank(GTMRank.GANGSTER)) + user.addAchievement(Achievement.GANGSTER); + if (!user.getUnlockedAchievements().contains(Achievement.MUGGER) && isRank(GTMRank.MUGGER)) + user.addAchievement(Achievement.MUGGER); + if (!user.getUnlockedAchievements().contains(Achievement.HUNTER) && isRank(GTMRank.HUNTER)) + user.addAchievement(Achievement.HUNTER); + if (!user.getUnlockedAchievements().contains(Achievement.DEALER) && isRank(GTMRank.DEALER)) + user.addAchievement(Achievement.DEALER); + if (!user.getUnlockedAchievements().contains(Achievement.PIMP) && isRank(GTMRank.PIMP)) + user.addAchievement(Achievement.PIMP); + if (!user.getUnlockedAchievements().contains(Achievement.MOBSTER) && isRank(GTMRank.MOBSTER)) + user.addAchievement(Achievement.MOBSTER); + if (!user.getUnlockedAchievements().contains(Achievement.GODFATHER) && isRank(GTMRank.GODFATHER)) + user.addAchievement(Achievement.GODFATHER); + if (!user.getUnlockedAchievements().contains(Achievement.Psychopath) && getKills() >= 10000) + user.addAchievement(Achievement.Psychopath); + if (!user.getUnlockedAchievements().contains(Achievement.GTM_God) && Stats.getInstance().getHoursPlayedRaw(Bukkit.getPlayer(user.getUUID())) > 1000) + user.addAchievement(Achievement.GTM_God); + user.updateNameTag(Bukkit.getPlayer(user.getUUID())); + if (!user.getUnlockedAchievements().contains(Achievement.Witness)) { + Bukkit.getOnlinePlayers().forEach(target -> { + if (target.getUniqueId().toString().equals("0e4a6028-3d9a-4a2e-9797-eb1ddcb0aca9")) { + user.addAchievement(Achievement.Witness); + } + }); + } + } + + private int chatActionExpireRunnable = -1; + + /** + * @param action the ChatAction that the next thing the player says will be + * registered with. + * @param value if there is a 'second-level' the 'first-level' value should + * be inserted here. For exmaple if a player chose an amount to + * pay a player, then was asked to say the name of the player + * they were sending the money to, 'first-level' would be the + * amount, which would then run setCurrentChatAction(action, + * amount) where the amount is the amount that was chosen by the + * player. Then this amount would be passed to the 'second-level' + * where the player is paid. + */ + public void setCurrentChatAction(ChatAction action, Object value) { + Player player = Bukkit.getPlayer(this.uuid); + if (this.chatActionExpireRunnable != -1) + Bukkit.getScheduler().cancelTask(chatActionExpireRunnable); + + this.currentChatValue = value; + this.currentChatAction = action; + this.chatActionExpireRunnable = new BukkitRunnable() { + @Override + public void run() { + if (currentChatAction != null) { + if (player.isOnline()) + player.sendMessage(Lang.GTM.f("&7Your chat response for &a" + (action.toString().toLowerCase().replace("_", " ") + "&7 has &4expired&7."))); + clearCurrentChatAction(); + } + } + }.runTaskLater(GTM.getInstance(), 20 * 20).getTaskId(); + } + + /** + * @param value the value to reset the timer with. Using example from above + * if you were exiting out of the second-level because the string + * inputted wasn't a player, you would do + * resetCurrentChatActionTimer(amount) where amount is from the + * first-level so that value isn't erased. + * @apiNote this method basically gives the player another 20 seconds to + * answer the prompt before it expires. + */ + public void resetCurrentChatActionTimer(Object value) { + if (this.chatActionExpireRunnable != -1) { + Bukkit.getScheduler().cancelTask(chatActionExpireRunnable); + this.currentChatValue = value; + } + } + + /** + * @apiNote clears and resets the chat action + */ + public void clearCurrentChatAction() { + switch (this.currentChatAction) { + case BIDDING_HEAD: + biddingExpiry = -1; + biddingHead = null; + } + currentChatAction = null; + currentChatValue = null; + if (chatActionExpireRunnable != -1) + Bukkit.getScheduler().cancelTask(chatActionExpireRunnable); + } + + public Object getCurrentChatValue() { + return this.currentChatValue; + } + + public double getSellInvConfirmAmt() { + return sellInvConfirmAmt; + } + + public void setSellInvConfirmAmt(double sellInvConfirmAmt) { + this.sellInvConfirmAmt = sellInvConfirmAmt; + } + + /* + * public void figureOutSpawn() { Player player = Bukkit.getPlayer(uuid); + * String s = (String) + * Core.getUserManager().getLoadedUser(uuid).getPref(Pref.SPAWN_LOCATION); + * if(!Core.getUserManager().getLoadedUser(uuid).isRank(UserRank.PREMIUM) && + * !s.equals("spawn")){ + * Core.getUserManager().getLoadedUser(uuid).setPref(player, + * Pref.SPAWN_LOCATION, "spawn"); + * player.teleport(GTM.getWarpManager().getSpawn().getLocation()); return; } + * if (!s.equals("spawn")) { if (s.contains("warp")) { String name = + * s.split(":")[1]; if (GTM.getWarpManager().getWarp(name) == null) { + * player.sendMessage(Lang.PREFS.f( + * "&7Tried to teleport you to the warp with name: " + name + + * " but couldn't find the warp.")); } else + * player.teleport(GTM.getWarpManager().getWarp(name).getLocation()); } else + * if (Utils.isInteger(s.split(":")[1])) { int id = + * Integer.parseInt(s.split(":")[1]); if (s.contains("houseId")) { HouseUser + * houseUser = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + * if (!houseUser.ownsHouse(id)) { player.sendMessage(Lang.PREFS.f( + * "&7Tried to teleport you to your house with id " + id + + * " but it seems you do not own it.")); + * player.teleport(GTM.getWarpManager().getSpawn().getLocation()); } else { + * houseUser.teleportInOrOutHouse(player, + * Houses.getHousesManager().getHouse(id)); } } else if + * (s.contains("premiumHouseId")) { HouseUser houseUser = + * Houses.getUserManager().getLoadedUser(player.getUniqueId()); if + * (houseUser.getPremiumHouse(id) == null) { + * player.sendMessage(Lang.PREFS.f( + * "&7Tried to teleport you to your premium house with id " + id + + * " but it seems you do not own it.")); + * player.teleport(GTM.getWarpManager().getSpawn().getLocation()); } else { + * houseUser.teleportInOrOutPremiumHouse(player, + * houseUser.getPremiumHouse(id)); } } } } else { + * player.teleport(GTM.getWarpManager().getSpawn().getLocation()); } } + */ + + public void lockWeaponSkin(Weapon<?> weapon, WeaponSkin skin) { + if (this.unlockedWeaponSkins.get(weapon.getUniqueIdentifier()) != null) { + this.unlockedWeaponSkins.get(weapon.getUniqueIdentifier()).remove((Object) (short) (skin.getIdentifier() - weapon.getWeaponIdentifier())); + + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + WeaponSkinDAO.lockSkin(connection, this.uuid, weapon, skin); + } + catch (SQLException e) { + e.printStackTrace(); + } + }); + } + } + + public void unlockWeaponSkin(Weapon<?> weapon, WeaponSkin skin) { + if (this.unlockedWeaponSkins.get(weapon.getUniqueIdentifier()) == null) { + this.unlockedWeaponSkins.put(weapon.getUniqueIdentifier(), new ArrayList<Short>()); + } + + if (!this.hasSkinUnlocked(weapon, skin)) { + this.unlockedWeaponSkins.get(weapon.getUniqueIdentifier()).add((short) (skin.getIdentifier() - weapon.getWeaponIdentifier())); + + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + WeaponSkinDAO.unlockSkin(connection, this.uuid, weapon, skin); + } + catch (SQLException e) { + e.printStackTrace(); + } + }); + } + } + + public void equipWeaponSkin(Weapon<?> weapon, WeaponSkin skin) { + short currentSkin = this.equippedWeaponSkins.containsKey(weapon.getUniqueIdentifier()) ? this.equippedWeaponSkins.get(weapon.getUniqueIdentifier()) : 0; + + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + if (currentSkin != weapon.getWeaponIdentifier()) { + WeaponSkinDAO.disableSkin(connection, this.uuid, weapon, currentSkin); + } + + if (skin.getIdentifier() != weapon.getWeaponIdentifier()) { + WeaponSkinDAO.enableSkin(connection, this.uuid, weapon, (short) (skin.getIdentifier() - weapon.getWeaponIdentifier())); + } + } + catch (SQLException e) { + e.printStackTrace(); + } + }); + + this.equippedWeaponSkins.put(weapon.getUniqueIdentifier(), (short) (skin.getIdentifier() - weapon.getWeaponIdentifier())); + } + + public boolean hasSkinUnlocked(Weapon<?> weapon, WeaponSkin skin) { + if (this.getUnlockedWeaponSkins(weapon) != null) { + for (short skinID : this.getUnlockedWeaponSkins(weapon)) { + if (skinID == (short) (skin.getIdentifier() - weapon.getWeaponIdentifier())) { + return true; + } + } + } + + return false; + } + + public List<Short> getUnlockedWeaponSkins(Weapon<?> weapon) { + return this.unlockedWeaponSkins.get(weapon.getUniqueIdentifier()); + } + + public Map<Short, List<WeaponSkin>> getUnlockedWeaponSkins() { + Map<Short, List<WeaponSkin>> skins = new HashMap<Short, List<WeaponSkin>>(); + + for (short weaponID : this.unlockedWeaponSkins.keySet()) { + Optional<Weapon<?>> weaponOpt = GTM.getWastedGuns().getWeaponManager().getWeaponFromUniqueIdentifier(weaponID); + + if (weaponOpt.isPresent()) { + Weapon<?> weapon = weaponOpt.get(); + List<WeaponSkin> skinSubArray = new ArrayList<WeaponSkin>(); + + for (short skinID : this.unlockedWeaponSkins.get(weaponID)) { + skinSubArray.add(GTM.getWeaponSkinManager().getWeaponSkinFromIdentifier(weapon, skinID)); + } + + skins.put(weaponID, skinSubArray); + } + } + + return skins; + } + + public Map<Short, List<Short>> getRawUnlockedWeaponSkins() { + return this.unlockedWeaponSkins; + } + + public WeaponSkin getEquippedWeaponSkin(Weapon<?> weapon) { + if (equippedWeaponSkins != null) { + if (equippedWeaponSkins.containsKey(weapon.getUniqueIdentifier())) { + short weaponUnique = equippedWeaponSkins.get(weapon.getUniqueIdentifier()); + + return GTM.getWeaponSkinManager().getWeaponSkinFromIdentifier(weapon, weaponUnique); + } + } + + if (weapon.getWeaponSkins() != null) { + return weapon.getWeaponSkins()[0]; + } + + return null; + } + + public Map<Short, WeaponSkin> getEquippedWeaponSkins() { + Map<Short, WeaponSkin> skins = new HashMap<Short, WeaponSkin>(); + + for (short weaponID : this.equippedWeaponSkins.values()) { + Optional<Weapon<?>> weaponOpt = GTM.getWastedGuns().getWeaponManager().getWeaponFromUniqueIdentifier(weaponID); + + if (weaponOpt.isPresent()) { + skins.put(weaponID, GTM.getWeaponSkinManager().getWeaponSkinFromIdentifier(weaponOpt.get(), this.equippedWeaponSkins.get(weaponID))); + } + } + + return skins; + } +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/GTMUserDAO.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/GTMUserDAO.java new file mode 100644 index 0000000..b34341e --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/GTMUserDAO.java @@ -0,0 +1,331 @@ +package net.grandtheftmc.gtm.users; + +import java.sql.Blob; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.UUID; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.currency.Currency; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.database.dao.CurrencyDAO; +import net.grandtheftmc.core.users.UserDAO; + +public class GTMUserDAO { + + /** + * @param uuid the player's uuid that is transfering. The player should be kicked before doing this, also should be done with a delay. + * @param server the gtm server number that the player is transfering to. + */ + public static boolean transferData(UUID uuid, int server){ + String query = "SELECT * FROM " + Core.name() + " WHERE uuid = UNHEX(?)"; + String targetServerQuery = "INSERT INTO gtm" + server + " (uuid,name,rank,backpackContents,cheatcodes,bank) VALUES(UNHEX(?),?,?,?,?,?) ON DUPLICATE KEY UPDATE `name`=?, `rank`=?, `backpackContents`=?, `cheatcodes`=?, `bank`=?";; + String originServerQuery = "DELETE FROM " + Core.name() + " WHERE `uuid` = UNHEX('" + uuid.toString().replaceAll("-", "") +"')"; + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + double bank; + GTMRank rank; + String backpack; + Blob cheatcodes; + String name; + int money = CurrencyDAO.getCurrency(connection, Currency.MONEY.getServerKey(), uuid, Currency.MONEY); + int permits = CurrencyDAO.getCurrency(connection, Currency.PERMIT.getServerKey(), uuid, Currency.PERMIT); + try (PreparedStatement statement = connection.prepareStatement(query)) { + + statement.setString(1, uuid.toString().replaceAll("-", "")); + try (ResultSet set = statement.executeQuery()){ + + set.next(); + + bank = set.getDouble("bank"); + rank = GTMRank.fromString(set.getString("rank")); + backpack = set.getString("backpackContents");; + cheatcodes = set.getBlob("cheatcodes"); + name = set.getString("name"); + Core.log("[TransferCommand] [uuid=" + uuid.toString() + "] Got " + bank + " / " + rank + " / " + backpack + " / " + cheatcodes + " / " + name + ". Transfering data to GTM" + server); + } + catch (SQLException e){ + e.printStackTrace(); + return false; + } + } + + /** + * delete the entire record of the current player. + */ + connection.prepareStatement(originServerQuery).execute(); + Core.log("[TransferCommand] [uuid=" + uuid + "] Deleted player's record from original server."); + CurrencyDAO.saveCurrency(connection, Core.name().toUpperCase(), uuid, Currency.MONEY, 0); + CurrencyDAO.saveCurrency(connection, Core.name().toUpperCase(), uuid, Currency.PERMIT, 0); + + /** + * Transfer values over to the new server. + */ + try (PreparedStatement statement = connection.prepareStatement(targetServerQuery)){ + statement.setString(1, uuid.toString().replaceAll("-", "")); + statement.setString(2, name); + statement.setString(3, rank.toString()); + statement.setString(4, backpack); + statement.setBlob(5, cheatcodes); + statement.setDouble(6, bank); + + statement.setString(7, name); + statement.setString(8, rank.toString()); + statement.setString(9, backpack); + statement.setBlob(10, cheatcodes); + statement.setDouble(11, bank); + + Core.log("[TransferCommand] [uuid=" + uuid.toString() + "] Sent information to target server with following statement: " + statement.toString()); + + statement.execute(); + } + CurrencyDAO.saveCurrency(connection, "GTM"+server, uuid, Currency.MONEY, money); + CurrencyDAO.saveCurrency(connection, "GTM"+server, uuid, Currency.PERMIT, permits); + Core.log("[TransferCommand] [uuid=" + uuid + "] Updated player's currencies money=" + money + ", permits=" + permits); + + + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + + return true; + } + + public static boolean setRank(String name, GTMRank rank) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `rank`=? WHERE `name`=?;")) { + statement.setString(1, rank.getName()); + statement.setString(2, name); + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean setRank(UUID uuid, GTMRank rank) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `rank`=? WHERE `uuid`=UNHEX(?);")) { + statement.setString(1, rank.getName()); + statement.setString(2, uuid.toString().replaceAll("-", "")); + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean setKills(String name, int value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `kills`=? WHERE `name`=?;")) { + statement.setInt(1, value); + statement.setString(2, name); + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean setKills(UUID uuid, int value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `kills`=? WHERE `uuid`=UNHEX(?);")) { + statement.setInt(1, value); + statement.setString(2, uuid.toString().replaceAll("-", "")); + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean setDeaths(String name, int value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `deaths`=? WHERE `name`=?;")) { + statement.setInt(1, value); + statement.setString(2, name); + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean setDeaths(UUID uuid, int value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `deaths`=? WHERE `uuid`=UNHEX(?);")) { + statement.setInt(1, value); + statement.setString(2, uuid.toString().replaceAll("-", "")); + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + /** + * Hard sets the value of the money currency in the user_currency table, + * using another DAO to help. + * + * @deprecated - Please see CurrencyDAO for how to use this global currency. + */ + @Deprecated + public static boolean setMoney(String name, double value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + UUID uuid = UserDAO.getUuidByName(name); + if (uuid != null){ + return CurrencyDAO.saveCurrency(connection, Currency.MONEY.getServerKey(), uuid, Currency.MONEY, (int) value); + } + } catch (SQLException e) { + e.printStackTrace(); + } + + return false; + } + + /** + * Hard sets the value of the money currency in the user_currency table, + * using another DAO to help. + * + * @deprecated - Please see CurrencyDAO for how to use this global currency. + */ + @Deprecated + public static boolean setMoney(UUID uuid, double value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + return CurrencyDAO.saveCurrency(connection, Currency.MONEY.getServerKey(), uuid, Currency.MONEY, (int) value); + } catch (SQLException e) { + e.printStackTrace(); + } + + return false; + } + + public static boolean setBank(String name, double value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `bank`=? WHERE `name`=?;")) { + statement.setDouble(1, value); + statement.setString(2, name); + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean setBank(UUID uuid, double value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `bank`=? WHERE `uuid`=UNHEX(?);")) { + statement.setDouble(1, value); + statement.setString(2, uuid.toString().replaceAll("-", "")); + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean addBank(UUID uuid, double value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET bank = bank + ? WHERE uuid = UNHEX(?);")) { + statement.setDouble(1, value); + statement.setString(2, uuid.toString().replaceAll("-", "")); + statement.executeUpdate(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean setPlaytime(UUID uuid, long value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `playtime`=? WHERE `uuid`=UNHEX(?);")) { + statement.setLong(1, value); + statement.setString(2, uuid.toString().replaceAll("-", "")); + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean setKillCounter(UUID uuid, int value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `killCounter`=? WHERE `uuid`=UNHEX(?);")) { + statement.setInt(1, value); + statement.setString(2, uuid.toString().replaceAll("-", "")); + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean setKillstreak(UUID uuid, int value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `killStreak`=? WHERE `uuid`=UNHEX(?);")) { + statement.setInt(1, value); + statement.setString(2, uuid.toString().replaceAll("-", "")); + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + /** + * Hard sets the value of the permit currency in the user_currency table, + * using another DAO to help. + * + * @deprecated - Please see CurrencyDAO for how to use this global currency. + */ + @Deprecated + public static boolean setPermits(UUID uuid, int value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + return CurrencyDAO.saveCurrency(connection, Currency.PERMIT.getServerKey(), uuid, Currency.PERMIT, value); + } catch (SQLException e) { + e.printStackTrace(); + } + + return false; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/GTMUserManager.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/GTMUserManager.java new file mode 100644 index 0000000..ecd55a1 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/GTMUserManager.java @@ -0,0 +1,190 @@ +package net.grandtheftmc.gtm.users; + +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +public class GTMUserManager { + + /** Singleton of this class */ + private static GTMUserManager instance; + /** Mapping of uuid to gtm user objects */ + private Map<UUID, GTMUser> users = new ConcurrentHashMap<>(); + + /** + * Private constructor since singletons cannot be initialized + */ + private GTMUserManager() { + } + + /** + * Gets the instance of the singleton. + * + * @return The singleton of this class. + */ + public static GTMUserManager getInstance() { + if (instance == null) { + instance = new GTMUserManager(); + } + + return instance; + } + + /** + * Add a new gtm user to the container. + * + * @param user - the gtm user to add + * + * @return {@code true} if the gtm user was successfully added, + * {@code false} if the user already exists. + */ + public boolean addUser(GTMUser user) { + if (!users.containsKey(user.getUUID())) { + users.put(user.getUUID(), user); + return true; + } + + return false; + } + + /** + * Get whether or not the container has a gtm user with the specified uuid. + * + * @param uuid - the uuid to lookup + * + * @return {@code true} if the gtm user exists already in the container, + * {@code false} otherwise. + */ + public boolean hasUser(UUID uuid) { + if (users.containsKey(uuid)) { + return true; + } + + return false; + } + + /** + * Get whether or not the container has a gtm user with the specified name. + * + * @param name - the name to lookup + * + * @return {@code true} if the gtm user exists already in the container, + * {@code false} otherwise. + */ + public boolean hasUser(String name) { + + for (GTMUser user : users.values()) { + if (user.getName().equalsIgnoreCase(name)) { + return true; + } + } + + return false; + } + + /** + * Get the gtm user with the specified uuid from the container. + * + * @param uuid - the uuid to lookup + * + * @return The gtm user with the specified uuid, if one exists, otherwise + * empty. + */ + public Optional<GTMUser> getUser(UUID uuid) { + if (users.containsKey(uuid)) { + return Optional.of(users.get(uuid)); + } + + return Optional.empty(); + } + + /** + * Get the gtm user with the specified name from the container. + * + * @param name - the name to lookup + * + * @return The gtm user with the specified name, if one exists, otherwise + * empty. + */ + public Optional<GTMUser> getUser(String name) { + for (GTMUser user : users.values()) { + if (user.getName().equalsIgnoreCase(name)) { + return Optional.of(user); + } + } + + return Optional.empty(); + } + + /** + * Removes the gtm user with the specified uuid. + * + * @param uuid - the uuid of the gtm user to remove + * + * @return The gtm user that was removed, if one was found, otherwise empty. + */ + public Optional<GTMUser> removeUser(UUID uuid) { + if (users.containsKey(uuid)) { + return Optional.of(users.remove(uuid)); + } + + return Optional.empty(); + } + + /** + * Removes the gtm user with the specified name. + * + * @param name - the name of the gtm user to remove + * + * @return The gtm user that was removed, if one was found, otherwise empty. + */ + public Optional<GTMUser> removeUser(String name) { + + // lookup user + GTMUser user = getUser(name).orElse(null); + + if (user != null) { + if (users.containsKey(user.getUUID())) { + return Optional.of(users.remove(user.getUUID())); + } + } + + return Optional.empty(); + } + + /** + * Get all gtm users in this container. + * + * @return {@link Collection} of {@link GTMUser}s inside this container. + */ + public Collection<GTMUser> getUsers() { + return Collections.unmodifiableCollection(users.values()); + } + + /** + * A wrapper around {@link Map#size()}. + * + * @return The size of the collection that contains the gtm users. + */ + public int size() { + return users.size(); + } + + /** + * Get the gtm user from this manager. + * + * @param uuid - the uuid of the user to lookup + * + * @return The gtm user from this manager, if one is found. + * + * @deprecated - Please use {@link #getUser(UUID)}} instead as the result + * can be {@code null} + */ + @Deprecated + public GTMUser getLoadedUser(UUID uuid) { + return getUser(uuid).orElse(null); + } +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/JobMode.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/JobMode.java new file mode 100644 index 0000000..287594c --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/JobMode.java @@ -0,0 +1,86 @@ +package net.grandtheftmc.gtm.users; + +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.UserRank; +import org.bukkit.Material; + +import java.util.Arrays; + +public enum JobMode { + + CRIMINAL("e"), + COP("3", GTMRank.GANGSTER, UserRank.PREMIUM), + HITMAN("8", GTMRank.HUNTER, UserRank.ELITE), + ; + + private final String color; + private final GTMRank rank; + private final UserRank userRank; + + JobMode(String color) { + this.color = color; + this.rank = null; + this.userRank = null; + } + + JobMode(String color, GTMRank rank, UserRank userRank) { + this.color = color; + this.rank = rank; + this.userRank = userRank; + } + + public boolean canUse(GTMRank rank, UserRank userRank) { + return (this.userRank == null && this.rank == null) || rank == this.rank || rank.isHigherThan(this.rank) || userRank == this.userRank || userRank.isHigherThan(this.userRank); + } + + public String getName() { + return this.toString(); + } + + public static JobMode getMode(String string) { + return Arrays.stream(getJobModes()).filter(mode -> mode.toString().equalsIgnoreCase(string)).findFirst().orElse(JobMode.CRIMINAL); + } + + public static JobMode getModeOrNull(String string) { + return Arrays.stream(getJobModes()).filter(mode -> mode.getName().equalsIgnoreCase(string)).findFirst().orElse(null); + } + + public static JobMode[] getJobModes() { + return JobMode.class.getEnumConstants(); + } + + public String getColoredName() { + return Utils.f('&' + this.color + this.getName()); + } + + public String getColoredNameBold() { + return Utils.f('&' + this.color + "&l" + this.getName()); + } + + public String getColor() { + return '&' + this.color; + } + + public Material getMaterial() { + switch (this) { + case COP: + return Material.LEATHER_CHESTPLATE; + case HITMAN: + return Material.SKULL_ITEM; + default: + return Material.WOOD_SWORD; + } + } + + public String getColorChar() { + return this.color; + } + + public GTMRank getRank() { + return this.rank; + } + + public UserRank getUserRank() { + return this.userRank; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/LockedWeapon.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/LockedWeapon.java new file mode 100644 index 0000000..47a3e3f --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/LockedWeapon.java @@ -0,0 +1,54 @@ +package net.grandtheftmc.gtm.users; + +import net.grandtheftmc.core.users.UserRank; + +import java.util.Arrays; + +public enum LockedWeapon { + + MARKSMANPISTOL(GTMRank.HOMIE, UserRank.VIP), + HEAVYSHOTGUN(GTMRank.THUG, UserRank.VIP), + CHAINSAW(GTMRank.GANGSTER, UserRank.PREMIUM), + GUSENBERGSWEEPER(GTMRank.GANGSTER, UserRank.PREMIUM), + RPG(GTMRank.MUGGER, UserRank.PREMIUM), + HEAVYSNIPER(GTMRank.HUNTER, UserRank.ELITE), + SPECIALCARBINE(GTMRank.DEALER, UserRank.ELITE), + GRENADELAUNCHER(GTMRank.PIMP, UserRank.SPONSOR), + COMBATMG(GTMRank.MOBSTER, UserRank.SPONSOR), + HOMINGLAUNCHER(GTMRank.GODFATHER, UserRank.SUPREME), + MINIGUN(GTMRank.GODFATHER, UserRank.SUPREME); + + private final GTMRank rank; + private final UserRank userRank; + + LockedWeapon(GTMRank rank, UserRank userRank) { + this.rank = rank; + this.userRank = userRank; + } + + public static boolean canUseWeapon(String identifier, GTMRank rank, UserRank userRank) { + LockedWeapon w = getWeapon(identifier); + return w == null || w.canUseWeapon(rank, userRank); + } + + public static LockedWeapon getWeapon(String identifier) { + return Arrays.stream(LockedWeapon.values()).filter(w -> w.toString().equalsIgnoreCase(identifier)).findFirst().orElse(null); + } + + public GTMRank getGTMRank() { + return this.rank; + } + + public UserRank getUserRank() { + return this.userRank; + } + +// public boolean canUseWeapon(GTMRank rank, UserRank userRank) { +// return this.rank == rank || rank.isHigherThan(this.rank) || this.userRank == userRank || userRank.isHigherThan(this.userRank); +// } + + public boolean canUseWeapon(GTMRank rank, UserRank userRank) { + if(rank == null || userRank == null) return false; + return this.rank == rank || rank.isHigherThan(this.rank) || this.userRank == userRank || userRank.isHigherThan(this.userRank); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/PersonalVehicle.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/PersonalVehicle.java new file mode 100644 index 0000000..8814462 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/PersonalVehicle.java @@ -0,0 +1,368 @@ +package net.grandtheftmc.gtm.users; + +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import com.j0ach1mmall3.jlib.methods.Random; +import com.j0ach1mmall3.wastedvehicles.api.VehicleProperties; +import com.j0ach1mmall3.wastedvehicles.api.vehicles.WastedVehicle; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.events.TPEvent; +import net.grandtheftmc.gtm.items.GameItem; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.users.HouseUser; + +/** + * Created by Liam on 24/09/2016. + */ +public class PersonalVehicle { + + private String vehicle; + private double health = -1; + private UUID entityUUID; + private boolean stolen; + + public PersonalVehicle(String vehicle) { + this.vehicle = vehicle; + } + + public String getVehicle() { + return this.vehicle; + } + + public void setVehicle(String vehicle) { + this.vehicle = vehicle; + } + + public String getDisplayName() { + VehicleProperties p = this.getVehicleProperties(); + return p == null ? "Error" : p.getItem().getItemMeta().getDisplayName(); + } + + public VehicleProperties getVehicleProperties() { + Optional<VehicleProperties> opt = GTM.getWastedVehicles().getVehicle(this.vehicle); + return opt.isPresent() ? opt.get() : null; + } + + public String getFormattedHealth() { + if (this.isDestroyed()) return "&c&lDestroyed"; + return GTM.getWastedVehicles().formatHealth(this.getHealth(), this.getVehicleProperties().getMaxHealth()); + } + + public double getHealth() { + return this.health < 0 ? this.getVehicleProperties().getMaxHealth() : this.health; + } + + public boolean isStolen() { + if (this.getEntity() == null) this.stolen = false; + return this.stolen; + } + + public double getPrice() { + GameItem item = GTM.getItemManager().getItemFromVehicle(this.vehicle); + return item == null ? -1 : item.getSellPrice() * 2; + } + + public double getSellPrice() { + return this.getPrice() / 2 - this.getRepairPrice(); + } + + public double getRepairPrice() { + if(!this.isDestroyed()) return 0; + return this.getPrice() / 100; + } + + public void setStolen(boolean b) { + this.stolen = b; + } + + public void setHealth(double health) { + this.health = health; + } + + public UUID getEntityUUID() { + return this.entityUUID; + } + + public void setEntityUUID(UUID entityUUID) { + this.entityUUID = entityUUID; + } + + public ArmorStand getEntity() { + if (this.entityUUID == null) return null; + for (World world : Bukkit.getWorlds()) + for (ArmorStand e : world.getEntitiesByClass(ArmorStand.class)) + if (Objects.equals(e.getUniqueId(), this.entityUUID)) { + this.health = e.getHealth(); + return e; + } + this.entityUUID = null; + return null; + } + + public boolean isDestroyed() { + return this.getHealth() <= 1; + } + + public void updateVehicleInDatabase(Player player, double health) { + VehicleProperties v = this.getVehicleProperties(); + this.health = health; + if (v != null) { +// Core.sql.updateAsyncLater("update " + Core.name() + " set `" + v.getIdentifier().toLowerCase() + ":info`='" + (this.isStolen() ? 0 : this.health) + "' where uuid='" + player.getUniqueId() + "';"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + Core.name() + " set `" + v.getIdentifier().toLowerCase() + ":info`='" + (this.isStolen() ? 0 : this.health) + "' where uuid=UNHEX('" + player.getUniqueId().toString().replaceAll("-", "") + "');")); + } + } + + public boolean onMap() { + return this.getEntity() != null; + } + + public void call(Player player, User user, GTMUser gtmUser) { + this.teleport(player, user, gtmUser, false); + } + + public void sendAway(Player player, User user, GTMUser gtmUser) { + this.teleport(player, user, gtmUser, true); + } + + public void teleport(Player player, User user, GTMUser gtmUser, boolean sendAway) { + GTMUtils.giveGameItems(player); + UUID uuid = player.getUniqueId(); + if (gtmUser.getVehicleTaskId() != -1) + Bukkit.getScheduler().cancelTask(gtmUser.getVehicleTaskId()); + if (gtmUser.isInCombat()) { + player.sendMessage(Lang.COMBATTAG.f("&7You can't " + (sendAway ? "send away" : "call") + " your vehicle in combat!")); + return; + } + if (user.isInTutorial()) return; + if (!sendAway && Objects.equals("spawn", player.getWorld().getName())) { + player.sendMessage(Lang.VEHICLES.f("&7You can't call vehicles to spawn!")); + return; + } + if (gtmUser.isArrested()) { + player.sendMessage(Lang.JAIL.f("&7You can't " + (sendAway ? "send away" : "call") + " your vehicle in jail!")); + return; + } + if (this.isDestroyed()) { + player.sendMessage(Lang.VEHICLES.f("&7Your " + this.getDisplayName() + "&7 was destroyed, call the mechanic to fix it first!")); + return; + } + if (sendAway && !this.onMap()) { + player.sendMessage(Lang.VEHICLES.f("&7Your vehicle can not be sent away!")); + return; + } + if (this.stolen) { + player.sendMessage(Lang.VEHICLES.f("&7Your " + this.getDisplayName() + "&7 was stolen!")); + return; + } + if (!gtmUser.hasMoney(200)) { + player.sendMessage(Lang.VEHICLES.f("&7You can't afford to pay &c$&l200&7 for driver!")); + return; + } + player.sendMessage(Lang.VEHICLES.f("&7A driver is coming to " + (sendAway ? "pick up" : "drop off") + " your " + this.getDisplayName() + "&7!")); + gtmUser.setVehicleTimer(GTMUtils.getWarpDelay(user.getUserRank())); + gtmUser.setSendAway(sendAway); + gtmUser.setVehicleTaskId(new BukkitRunnable() { + @Override + public void run() { + Player player = Bukkit.getPlayer(uuid); + if (player == null) { + this.cancel(); + return; + } + GTMUser gtmUser = GTM.getUserManager().getLoadedUser(uuid); + int timer = gtmUser.getVehicleTimer(); + boolean sendAway = gtmUser.isSendAway(); + PersonalVehicle vehicle = gtmUser.getPersonalVehicle(); + + if (timer == 15 || timer == 10 || (timer <= 5 && timer > 0)) { + player.sendMessage(Lang.VEHICLES.f("&7Your vehicle is " + (sendAway ? "being picked up" : "arriving") + " in " + timer + " &7second" + + (timer == 1 ? "" : "s") + '!')); + if (timer == 1) + player.playSound(player.getLocation(), Sound.BLOCK_LAVA_EXTINGUISH, 0.5F, 1); + else + player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 4.0F / timer, 2); + } + if (timer == 0) { + if (vehicle == null) { + gtmUser.cancelVehicleTeleport(); + player.sendMessage(Lang.VEHICLES.f("&7You have no vehicle to teleport!")); + return; + } + if (gtmUser.isInCombat()) { + gtmUser.cancelVehicleTeleport(); + player.sendMessage(Lang.COMBATTAG.f("&7You can't " + (sendAway ? "send away" : "call") + " your vehicle in combat!")); + return; + } + if (user.isInTutorial()) return; + if (gtmUser.isArrested()) { + gtmUser.cancelVehicleTeleport(); + player.sendMessage(Lang.JAIL.f("&7You can't " + (sendAway ? "send away" : "call") + " your vehicle in jail!")); + return; + } + if(Objects.equals("spawn", player.getWorld().getName())) { + gtmUser.cancelVehicleTeleport(); + player.sendMessage(Lang.JAIL.f("&7You can't " + (sendAway ? "send away" : "call") + " your vehicle in spawn!")); + return; + } + if (vehicle.isDestroyed()) { + gtmUser.cancelVehicleTeleport(); + player.sendMessage(Lang.VEHICLES.f("&7Your " + vehicle.getDisplayName() + "&7 was destroyed, call the mechanic to fix it first!")); + return; + } + if (sendAway && !vehicle.onMap()) { + gtmUser.cancelVehicleTeleport(); + player.sendMessage(Lang.VEHICLES.f("&7Your vehicle can not be sent away!")); + return; + } + if (vehicle.stolen) { + gtmUser.cancelVehicleTeleport(); + player.sendMessage(Lang.VEHICLES.f("&7Your " + vehicle.getDisplayName() + "&7 was stolen!")); + return; + } + if (!gtmUser.hasMoney(200)) { + gtmUser.cancelVehicleTeleport(); + player.sendMessage(Lang.VEHICLES.f("&7You can't afford to pay &c$&l200&7 for driver!")); + return; + } + TPEvent e = new TPEvent(player, player, + sendAway ? TPEvent.TPType.VEHICLE_SEND_AWAY : TPEvent.TPType.VEHICLE_CALL).call(); + if (e.isCancelled()) { + gtmUser.cancelVehicleTeleport(); + player.sendMessage(Lang.VEHICLES.f(e.getCancelMessage())); + return; + } + PersonalVehicle next = gtmUser.getNextVehicle(); + gtmUser.cancelVehicleTeleport(); + if (sendAway) { + if (!vehicle.sendAway(player, true)) return; + } else if (!vehicle.teleport(player, true)) return; + gtmUser.takeMoney(200); + player.sendMessage(Lang.MONEY_TAKE.f("200")); + GTMUtils.updateBoard(player, Core.getUserManager().getLoadedUser(player.getUniqueId()), gtmUser); + if (sendAway && next != null) { + gtmUser.setPersonalVehicle(null); + gtmUser.setNextVehicle(null); + gtmUser.setPersonalVehicle(player, Core.getUserManager().getLoadedUser(uuid), next); + } + MenuManager.updateMenu(player, "vehicles"); + MenuManager.updateMenu(player, "personalvehicle"); + return; + } + gtmUser.setVehicleTimer(timer - 1); + } + }.runTaskTimer(GTM.getInstance(), 20, 20).getTaskId()); + } + + private Location getLocationAround(Player player) { + VehicleProperties prop = this.getVehicleProperties(); + for (int i = 0; i < 50; i++) { + Location l = player.getLocation().add(Random.getInt(-7, 7), 0, Random.getInt(-7, 7)); + Material m = l.getBlock().getRelative(BlockFace.DOWN).getType(); + if (m == Material.AIR) + m = l.getBlock().getRelative(BlockFace.DOWN).getRelative(BlockFace.DOWN).getType(); + if (prop.getAllowedBlocks().contains(m.toString())) return l; + } + return null; + } + + private boolean teleport(Player player) { + return this.teleport(player, false); + } + + private boolean teleport(Player player, boolean sendMessage) { + ArmorStand e = this.getEntity(); + HouseUser houseUser = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + if (houseUser.isInsideHouse() || houseUser.isInsidePremiumHouse()) { + player.sendMessage(Lang.VEHICLES.f("&7You can't call your vehicle inside a house!")); + return false; + } + if (e == null) { + VehicleProperties v = this.getVehicleProperties(); + if (v == null) { + if (sendMessage) + player.sendMessage(Lang.VEHICLES.f("&7That vehicle does not exist!")); + return false; + } + Location loc = this.getLocationAround(player); + if (loc == null) { + player.sendMessage(Lang.VEHICLES.f("&7Your vehicle can not be placed near you!")); + return false; + } + ArmorStand wv = GTM.getWastedVehicles().spawnVehicle(v, loc, player, (this.health > v.getMaxHealth() || this.health < 0) ? v.getMaxHealth() : this.health); + this.entityUUID = wv.getUniqueId(); + if (sendMessage) + player.sendMessage(Lang.VEHICLES.f("&7The driver dropped off your vehicle" + (houseUser.isInsideHouse() || houseUser.isInsidePremiumHouse() ? " at your door" : "") + '!')); + return true; + } + if (this.stolen) { + if (sendMessage) + player.sendMessage(Lang.VEHICLES.f("&7Your " + this.getDisplayName() + "&7 was stolen!")); + return false; + } + Location loc = this.getLocationAround(player); + if (loc == null) { + player.sendMessage(Lang.VEHICLES.f("&7Your vehicle can not be placed near you!")); + return false; + } + e.teleport(loc); + if (sendMessage) + player.sendMessage(Lang.VEHICLES.f("&7The driver dropped off your vehicle" + (houseUser.isInsideHouse() || houseUser.isInsidePremiumHouse() ? " at your door" : "") + '!')); + return true; + } + + private boolean sendAway(Player player) { + return this.sendAway(player, false); + } + + private boolean sendAway(Player player, boolean sendMessage) { + ArmorStand e = this.getEntity(); + if (this.isDestroyed()) { + if (sendMessage) + player.sendMessage(Lang.VEHICLES.f("&7Your " + this.getDisplayName() + "&7 is destroyed!")); + return false; + } + if (e == null) { + if (sendMessage) + player.sendMessage(Lang.VEHICLES.f("&7You can't send away your vehicle!")); + return false; + } + if (e.getPassenger() != null) { + if (sendMessage) + player.sendMessage(Lang.VEHICLES.f("&7Your vehicle is not empty!")); + return false; + } + ((WastedVehicle) e.getMetadata("WastedVehicle").get(0).value()).onDismount(e); + ((WastedVehicle) e.getMetadata("WastedVehicle").get(0).value()).getPassengers().forEach(passenger -> { + passenger.eject(); + passenger.remove(); + }); + GTM.getWastedVehicles().getEntityQueue().remove(e); + e.remove(); + this.entityUUID = null; + if (sendMessage) + player.sendMessage(Lang.VEHICLES.f("&7The driver picked up your vehicle!")); + return true; + } + + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/TaxiTarget.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/TaxiTarget.java new file mode 100644 index 0000000..214760d --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/TaxiTarget.java @@ -0,0 +1,134 @@ +package net.grandtheftmc.gtm.users; + +import net.grandtheftmc.gtm.warps.Warp; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +import java.util.Objects; +import java.util.UUID; + +public class TaxiTarget { + private TargetType type; + + private UUID targetPlayer; + private UUID targetEntity; + private Location location; + private Warp warp; + + public TaxiTarget() { + this.type = TargetType.NONE; + } + + public TaxiTarget(Player player) { + this.type = TargetType.PLAYER; + this.targetPlayer = player.getUniqueId(); + } + + public TaxiTarget(Entity entity) { + this.type = TargetType.ENTITY; + this.targetEntity = entity.getUniqueId(); + } + + public TaxiTarget(Location position) { + this.type = TargetType.LOCATION; + this.location = position; + } + + public TaxiTarget(Warp warp) { + this.type = TargetType.WARP; + this.warp = warp; + } + + public TargetType getType() { + return this.type; + } + + public void setType(TargetType type) { + this.type = type; + } + + public UUID getTargetPlayerUUID() { + return this.targetPlayer; + } + + public Player getTargetPlayer() { + if (this.targetPlayer == null) + return null; + return Bukkit.getPlayer(this.targetPlayer); + } + + public void setTargetPlayer(UUID targetPlayer) { + this.targetPlayer = targetPlayer; + this.type = TargetType.PLAYER; + } + + public UUID getTargetEntityUUID() { + return this.targetEntity; + } + + public Entity getTargetEntity() { + if (this.targetEntity == null) + return null; + for (World w : Bukkit.getWorlds()) + for (Entity e : w.getEntities()) + if (Objects.equals(e.getUniqueId(), this.targetEntity)) + return e; + this.targetEntity = null; + return null; + } + + public void setTargetEntity(UUID targetEntity) { + this.targetEntity = targetEntity; + this.type = TargetType.ENTITY; + } + + public void setTargetEntity(Entity targetEntity) { + this.targetEntity = targetEntity == null ? null : targetEntity.getUniqueId(); + this.type = TargetType.ENTITY; + } + + public Location getLocation() { + return this.location; + } + + public void setLocation(Location location) { + this.location = location; + } + + public Warp getWarp() { + return this.warp; + } + + public void setWarp(Warp w) { + this.warp = w; + } + + public Location getExactLocation() { + switch (this.type) { + case LOCATION: + return this.location; + case ENTITY: + Entity e = this.getTargetEntity(); + return e == null ? null : e.getLocation(); + case PLAYER: + Player p = this.getTargetPlayer(); + return p == null ? null : p.getLocation(); + case WARP: + return this.warp == null ? null : this.warp.getLocation(); + default: + return null; + } + } + + public enum TargetType { + NONE, + PLAYER, + ENTITY, + LOCATION, + WARP + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/ArmorNPC.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/ArmorNPC.java new file mode 100644 index 0000000..3b1f503 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/ArmorNPC.java @@ -0,0 +1,109 @@ +package net.grandtheftmc.gtm.users.npcs; + +import java.util.Collections; + +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import net.citizensnpcs.api.event.NPCCollisionEvent; +import net.citizensnpcs.api.event.NPCLeftClickEvent; +import net.citizensnpcs.api.event.NPCPushEvent; +import net.citizensnpcs.api.event.NPCRightClickEvent; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.inventory.CoreMenu; +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import net.grandtheftmc.core.inventory.button.ClickableItem; +import net.grandtheftmc.core.npc.CoreNPC; +import net.grandtheftmc.core.npc.interfaces.ClickableNPC; +import net.grandtheftmc.core.npc.interfaces.CollideableNPC; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.items.GameItem; +import net.grandtheftmc.gtm.users.GTMUser; + +/** + * Created by Timothy Lampen on 1/14/2018. + */ +public class ArmorNPC extends CoreNPC implements ClickableNPC, CollideableNPC { + private static final String[] ARMOR_GAMEITEMS = new String[]{"shirt", "kevlarvest", "ceramicvest", "titaniumvest", "jetpackfuel10", "jetpack", "jetpackfuel100", "nikes", "pants", "baseballcap", "tacticalmask","titaniumhelmet"}; + public ArmorNPC(Location loc) { + super(loc, EntityType.PLAYER, "&c&lFrank Sheathson", "&7&oBuy armor and clothes here!"); + } + + @Override + protected void generateNewNPC() { + setLookClose(true); + setSkin("eyJ0aW1lc3RhbXAiOjE1MTU5ODM2NDk2NjgsInByb2ZpbGVJZCI6IjdjZjc2MTFkYmY2YjQxOWRiNjlkMmQzY2Q4NzUxZjRjIiwicHJvZmlsZU5hbWUiOiJrYXJldGg5OTkiLCJzaWduYXR1cmVSZXF1aXJlZCI6dHJ1ZSwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzI4Y2RkZmQxM2Y1NmI3YzJjNGYxZjNkNmI4MjY5Y2UxOTgxYjJjYTlhOWFmMjEzODVhNDQ2YTUzMTEifX19", "f2GaPKFyc2hG+I8+7CnIbDZcxU56RG+gbYZzKt58n2PWifyjoR7USPSsQEV9eDM8EnJuay5vhbSuFODX8O2w1Fkz0M9MyjDg41J3ERwOVD8B7VnAS3P24gISwpAmKSL5QQ8Va8gUZvx4Cgc07XJflfw60YdZ4DpinW4XQh2b1rEMTdHBFilmFj4GVbejcMSRGp9aOY60TXX4+aD4Uww/CVuAaAE7tAcX0V1NkmP/sUBGtKtZLTxzVnUWYsMEjvOTlgy4gd4OsK+pCegG092k2KNoI5q93TG1oMNGRQtpD5Yd4jwA8uO5vUaHBw1tIxe+pn85j3qS3KIB0QDMHIM2NNi+tHKEkLO0+ScILD7Ud2vqfXxI0oO2j8olcVBGivScssKp+8k7p1tHL2kQxYt/K6y+Xiw76H0aYoabWOnwkw7ZobDMHKoWMSBxbxqDjJ4n8itTtIO1Qn5UQZ9zAbEojGwwBZ82fqZmZkKBPX1b2/9yJ2jkVCKmEV3sSUBgovjPtm44ZyONFqf0HkmI1r19cCgzzY1xy13sueokOgevYn0trkLJsitpJEt6Z3pbnZ99k3aqjtsi+FMUqxqHHe8U8Kp7AKxW/BNnZOBFcFArXjy/C9ia8g8QajUWBt+YRr+RiDhEpCDON1WPYGhyq95FWIJf9Uz3/z59mMTNhUZAA9c="); + setCollideable(true); + } + + @Override + public void onRightClick(NPCRightClickEvent event) { + Player player = event.getClicker(); + + if (!GTM.getSettings().canBuy()){ + player.sendMessage(ChatColor.RED + "Buying things is currently disabled."); + return; + } + + new ArmorMenu().openInventory(player); + } + + @Override + public void onLeftClick(NPCLeftClickEvent npcLeftClickEvent) { + + } + + @Override + public void onCollide(NPCCollisionEvent event) { + + } + + @Override + public void onPush(NPCPushEvent event) { + + } + + private class ArmorMenu extends CoreMenu { + private final int[] ARMOR_SPOTS = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42, 47, 48, 49, 50, 51}; + public ArmorMenu() { + super(6, Utils.f("&8&lArmor Seller"), CoreMenuFlag.PHONE_LAYOUT); + + int counter = 0; + for(String armor : ARMOR_GAMEITEMS) { + GameItem item = armor.contains("jetpackfuel") ? GTM.getItemManager().getItem("jetpackfuel") : GTM.getItemManager().getItem(armor); + if(!item.canBuy()) + continue; + int amt = 1; + if(armor.contains("jetpackfuel")) { + amt = Integer.parseInt(armor.replace("jetpackfuel", "")); + } + double price = item.getBuyPrice()*amt; + ItemStack is = item.getItem(); + ItemMeta im = is.getItemMeta(); + im.setDisplayName(Utils.f("&6&l" + amt+ "x " + im.getDisplayName())); + im.setLore(Collections.singletonList(Utils.f("&6&lPrice: $&a" + (price)))); + is.setItemMeta(im); + + int finalAmt = amt; + addItem(new ClickableItem(ARMOR_SPOTS[counter], is, ((player, clickType) -> { + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + if(!user.hasMoney(price)){ + player.sendMessage(Lang.SHOP.f("&cYou do not have enough money for this item!")); + return; + } + user.takeMoney(price); + GTMUtils.updateBoard(player, GTM.getUserManager().getLoadedUser(player.getUniqueId())); + Utils.giveItems(player, item.getItem(finalAmt)); + }), false)); + counter++; + + } + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/BankTellerNPC.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/BankTellerNPC.java new file mode 100644 index 0000000..8e5a3e9 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/BankTellerNPC.java @@ -0,0 +1,51 @@ +package net.grandtheftmc.gtm.users.npcs; + +import net.citizensnpcs.api.event.NPCCollisionEvent; +import net.citizensnpcs.api.event.NPCLeftClickEvent; +import net.citizensnpcs.api.event.NPCPushEvent; +import net.citizensnpcs.api.event.NPCRightClickEvent; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.npc.CoreNPC; +import net.grandtheftmc.core.npc.interfaces.ClickableNPC; +import net.grandtheftmc.core.npc.interfaces.CollideableNPC; + +import org.bukkit.Location; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; + +/** + * Created by Timothy Lampen on 1/14/2018. + */ +public class BankTellerNPC extends CoreNPC implements ClickableNPC, CollideableNPC { + public BankTellerNPC(Location loc) { + super(loc, EntityType.PLAYER, "&a&lSacha Goldman", "&7&oAccess your bank here!"); + } + + @Override + protected void generateNewNPC() { + setLookClose(true); + setSkin("eyJ0aW1lc3RhbXAiOjE1MTU5ODIyMzkzMTUsInByb2ZpbGVJZCI6IjcwOTU2NDU0NTJkOTRiYTI5YzcwZDFmYTY3YjhkYTQyIiwicHJvZmlsZU5hbWUiOiJIaWRkdXMiLCJzaWduYXR1cmVSZXF1aXJlZCI6dHJ1ZSwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzNmZjM3ZjdiYTBlYzlmMDczYWJhM2VlYTk0OGI3NDMzYzg3YmVmZWNkNzNmYjdjOWQyNjExYWZhMmVlNzY2In19fQ==", "d1UU+O/OvjxxspCnb7gRPXVW0RxpfpcG2ygVWiCZeBC9Mz5ztKRgsska9jqk3bOlupJR+ApefO88DgWrhHIsT0SZyG5e+kqg1r0pYWvE2LpYKmFyL4kgWs9om+KKXP1NGHXVJT9yJ+SdCHwAsqjosuLpg0IGs6e9V+2Tw9Lw3Fhq7GvQuufZjnvpWOKXsMnMRzil8bX3AlLkAvRnYXwOAmWeK/L6BGtT7olb+ewOjZwoKIbLH13kXJJ6BTEoOoFLlczTU+bCYx/Lc5tEkTqJoiTZtxV6oWZaLK7Q8YxdOsegP1yo7ZLGyH6IuKPPmtTVOC9C09PqBA9sWkBJUIKP5iA+gfNnPxkApo4ooY/gMEenzaPihHPt+USvpLvgvB/GtNkjSmtSXuYygyRAg6ukejM9PC+3waecH0rGtYuNZ2gKzdAboPMIlL7Z066A3b7+xrqbicYVtmKRrtdJZ3nuztNcFFhD6sBkl2fY6i2Xf8bYbE45LiNSrKB8a+DrgFRCuhlgtagesFALik5a9zBSSVIARMFlDgZqrJimQIbsTwprIAuqoUN2MDMTlmKIFzDheOZHyo8IGp+JyXztttzWz35RfPP68stJWJ0+2t5X2HFw6ERBTLpXeg/2RZ/CgHWNKJxBhOGKZONFZUOwPGy6BDQq9TX+ZQG6T3Eyhbg0zFM="); + setCollideable(true); + } + + @Override + public void onRightClick(NPCRightClickEvent event) { + Player player = event.getClicker(); + MenuManager.openMenu(player, "bank"); + } + + @Override + public void onLeftClick(NPCLeftClickEvent event) { + + } + + @Override + public void onCollide(NPCCollisionEvent event) { + + } + + @Override + public void onPush(NPCPushEvent event) { + + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/CarNPC.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/CarNPC.java new file mode 100644 index 0000000..eef80fc --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/CarNPC.java @@ -0,0 +1,96 @@ +package net.grandtheftmc.gtm.users.npcs; + +import java.util.List; + +import org.bukkit.Location; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import net.citizensnpcs.api.event.NPCCollisionEvent; +import net.citizensnpcs.api.event.NPCLeftClickEvent; +import net.citizensnpcs.api.event.NPCPushEvent; +import net.citizensnpcs.api.event.NPCRightClickEvent; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.inventory.CoreMenu; +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import net.grandtheftmc.core.inventory.button.ClickableItem; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.npc.CoreNPC; +import net.grandtheftmc.core.npc.interfaces.ClickableNPC; +import net.grandtheftmc.core.npc.interfaces.CollideableNPC; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.items.GameItem; +import net.grandtheftmc.gtm.users.GTMUser; + +/** + * Created by Timothy Lampen on 1/14/2018. + */ +public class CarNPC extends CoreNPC implements ClickableNPC, CollideableNPC { + + public CarNPC(Location loc) { + super(loc, EntityType.PLAYER, "&d&lSlimy Patrick", "&7&oBest vehicles in the world!"); + } + + @Override + protected void generateNewNPC() { + setLookClose(true); + setSkin("eyJ0aW1lc3RhbXAiOjE1MTU5ODM1NDI2ODAsInByb2ZpbGVJZCI6IjNlMjZiMDk3MWFjZDRjNmQ5MzVjNmFkYjE1YjYyMDNhIiwicHJvZmlsZU5hbWUiOiJOYWhlbGUiLCJzaWduYXR1cmVSZXF1aXJlZCI6dHJ1ZSwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzdiYmUxMjdlMmFiYjQxNTNkMmVlZDQ0M2M3OGM0ZmVlNmQzOWVjNjZjMTA4MDkyNTBlYmIwNzQyZjYyMWVmNSJ9fX0=", "Reqe3QaLLd+i19gsDZZv8RrFgeOHb0sNvX/aqw/fEcp65YNV4rMCJWP0aDb60rt53mAedi3h4CR9BKIEgBEk1R2zbFJNwGQnHi5CH0yggiaSdjFzc90oAY/QPvsqya9Il/WQ+YutVQXTG3iMG62jfAm5xsX9I098eHkEqoWGhY4MNjFkTuX5u6XTi5knXj2dkWP8bD+6wwFRpyou5arwyZS3cVjMsvBUwZv34kLL7asUfEg+Ud3k1RNjJrwz92+YW2DqRH2R2ZFwhofSvawi3a2uPf8wpefARIkzM1AZ1MW3mj9CplUw1FHCz8tiu0eM2O4fyrqgVIfNsJoCpYqEDvSByMQo8svwhXLZr/JaQjYneYqTueJ2QGwhbVwKq8862VQLJRaRMMYgKRdPaBTpmvYOHN/LMhWBLVYsMqT7RE5jYybAcXR1Ad9/wtR66/BtXPgd0/0t7GAAA8KY2xw80k7XXfdSJCS6snVMPxuzvc0mGmGPq+FG8kb6/NQcGTtTyUVP5HA/qW0b+yQ2qlYRe/F6D//LVWM/1+Qo8U9z9eqHM+G7c/i+bQPa8NxYR8H2B4Hf/dQMnpMIgiclCuX6OcqPQr8ikDpJ8AQCmA1FR8S9uqxE92je5hFMy1+84jMfGLUKecs/wxFy+uUYHYbs2FH0eALMsP/XkbYfyOJmidc="); + setCollideable(true); + } + + @Override + public void onRightClick(NPCRightClickEvent event) { + Player player = event.getClicker(); + new CarMenu(player).openInventory(player); + } + + @Override + public void onLeftClick(NPCLeftClickEvent event) { + + } + + @Override + public void onCollide(NPCCollisionEvent event) { + + } + + @Override + public void onPush(NPCPushEvent event) { + + } + + private class CarMenu extends CoreMenu{ + + private final String[] CARS = new String[]{"zentorno", "entity_xf", "9f", "armoredkuruma", "primo", "attackmaverick", "maverick", "bmx", "dinghy", "hydra", "rhino"}; + private final int[] CAR_SPOTS = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42, 47, 48, 49, 50, 51}; + public CarMenu(Player p) { + super(6, Utils.f("&d&lPurchase Cars"), CoreMenuFlag.PHONE_LAYOUT); + int counter = 0; + GTMUser user = GTM.getUserManager().getLoadedUser(p.getUniqueId()); + for(String s : CARS){ + GameItem item = GTM.getItemManager().getItem(s); + if(item==null){ + Core.error("[CarMenu] Unable to load car: " + s + " from game item."); + continue; + } + ItemStack is = item.getItem(); + if(user.hasVehicle(s)){ + ItemMeta im = is.getItemMeta(); + List<String> lore = im.getLore(); + lore.add(Utils.f("&a&lPurchased")); + im.setLore(lore); + is.setItemMeta(im); + } + addItem(new ClickableItem(CAR_SPOTS[counter], is, (player, clickType) -> { + user.setActionVehicle(s); + player.closeInventory(); + MenuManager.openMenu(player, "vehicleshop"); + }, false)); + counter++; + } + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/CasinoNPC.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/CasinoNPC.java new file mode 100644 index 0000000..7f2f523 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/CasinoNPC.java @@ -0,0 +1,36 @@ +package net.grandtheftmc.gtm.users.npcs; + +import net.citizensnpcs.api.event.NPCLeftClickEvent; +import net.citizensnpcs.api.event.NPCRightClickEvent; +import net.grandtheftmc.core.casino.coins.VendorMenu; +import net.grandtheftmc.core.npc.CoreNPC; +import net.grandtheftmc.core.npc.interfaces.ClickableNPC; +import org.bukkit.Location; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; + +/** + * Created by Timothy Lampen on 3/23/2018. + */ +public class CasinoNPC extends CoreNPC implements ClickableNPC { + public CasinoNPC(Location loc) { + super(loc, EntityType.PLAYER, "&eMr. Goldman", "&7&oGet you're casino chips here!"); + } + + @Override + protected void generateNewNPC() { + setLookClose(true); + setSkin("eyJ0aW1lc3RhbXAiOjE1MjE4NTQyNjM3OTgsInByb2ZpbGVJZCI6IjkxOGEwMjk1NTlkZDRjZTZiMTZmN2E1ZDUzZWZiNDEyIiwicHJvZmlsZU5hbWUiOiJCZWV2ZWxvcGVyIiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9mYTRjNThlNTFjZDY1MjJhMTdlNWY3MGE5YzUzMDJkMTVjNzU4MThhNzY1NGNiNGM4ZTM2Zjk5Njk2NTg5OTkifX19", "EwjF5VIfbHDAaAp+UEE9ctxqoD3IpyboYOMBIMtGZWikS4FAa5Ju56Ip5cuCW9vZj2Oo4ZvGrK6Jzm0BkMz+uXlzNYjUVOFgfatVa2Ibr+CGn4KdbMFAXb0vK4moVWVurapYeXkDs9wih5evf3CI/9g2deoyRNul/iGdG8hbIUq910Cc2m0JHFMeRVyRivnyw7l7SWhcL54m/+goiRtklpYnKcqiQSaHhfi5rPBNldvRF0T6f1raJzTrh3hGriiRRz2et5zP8ZBphWGUzij07kUZLuVSXm9FMltQGrOzFrePejSrGE9tjIefHphVqScM0+tqbCyC7b7TtZ0aYCFpv2DLDlYt/wCrbyxpi7l1hDvB4xK3aLfm8HRD4HK8lgpiqcD17WNCg0P2+m43jbuIIMK/AWDr74LAL0mblp66vqaR3fr2ifp7bbgXXiV7hoykkJ5B+ozxGV73J4u58fEPgZRGVUQaALeRyQsNLaeLGgkvsu3FFnqvHf0CBA9tEjElHt+7XleHoKkvVKmaVTkq/APiItowHbDDgeWGcAHi+6jPnfz5d7k0P/KcePYCCcRMPK+1/UP/StXJ80Dj+tFyiUVg82nLiLvq0Uv2thrqZQvNxL0YvkFuRjYIKspu4jXJvCfEPNVjczdmYNFxtO56P9oEPL+6byvzPPbXW/Q4L0Q="); + } + + @Override + public void onRightClick(NPCRightClickEvent event) { + Player player = event.getClicker(); + new VendorMenu().openInventory(player); + } + + @Override + public void onLeftClick(NPCLeftClickEvent npcLeftClickEvent) { + + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/CriminalNPC.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/CriminalNPC.java new file mode 100644 index 0000000..15fec24 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/CriminalNPC.java @@ -0,0 +1,59 @@ +package net.grandtheftmc.gtm.users.npcs; + +import net.citizensnpcs.api.event.NPCCollisionEvent; +import net.citizensnpcs.api.event.NPCLeftClickEvent; +import net.citizensnpcs.api.event.NPCPushEvent; +import net.citizensnpcs.api.event.NPCRightClickEvent; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.npc.CoreNPC; +import net.grandtheftmc.core.npc.interfaces.ClickableNPC; +import net.grandtheftmc.core.npc.interfaces.CollideableNPC; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.users.JobMode; +import org.bukkit.Location; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; + +public class CriminalNPC extends CoreNPC implements ClickableNPC, CollideableNPC { + + public CriminalNPC(Location loc) { + super(loc, EntityType.PLAYER, "&3&lCriminal", "&o&7Back to simple criminal lifestyle.."); + } + + @Override + protected void generateNewNPC() { + setLookClose(true); + setSkin("eyJ0aW1lc3RhbXAiOjE1MjEyMjg4MDMyNjgsInByb2ZpbGVJZCI6IjExODAxYzEzMGNiYzQ5MGY4YmEzM2E0MTMxMTZiNzk1IiwicHJvZmlsZU5hbWUiOiIweDE5ZCIsInNpZ25hdHVyZVJlcXVpcmVkIjp0cnVlLCJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNGQ2ZjlhY2NiN2JhMjM1ZWY3ODZmNzFkOWFkNjUzOTE5NjIyYjZhYWE1MjE5NDk5ODA1N2U2Y2JiMDczYSJ9fX0=", + "XkAbsDP7YR1guq32Xh/FZRQx4nmHK5JnR7FMonif3ynlRD07eLEacxob3PhUpilqPb3+/UNsho+dTSt7rqiTcEXHI971bSi+v/rtOW7nsjMnNnCB0Wi30by6kIw0qd231VVD17046hkVUis+N9HptnN1QqtMV1J9+HTldC+OmepoyNV6Ir0Usyl1d/oqNZWRCVebCMCEX9y0PuV6HQx5wdl4MtEKl78HMf5epdGOcgUaP0qF/RdNQ88dizlgMNHYa5+eq3N2npYlwR+DevSzIJEnokcJkG0wb0Kz9x/3UNLtNR+9/K6T2UVCCPZqV6iWZ+ryL3tExFBByaJYL4Gd8PcjfYVdA0jovN55db7OSZtfix7Uj9k5mqiw4Egj2WfilQ2HLebOm5+jkwWDIchoOWsl15xy+1INrwFi2uRMeV3/ajy0SFXg2WlkAc6XmOPNfYpYNYzd2+fUp4X0RzOyXeqx+BV2moGcUHoJVghK2ddPoIU70H4OxMjwio+A/bOshWrJlDfrnuWlzWRaiIeNIgP2O+P/ojb9jnjWywbRzMy5386Ng6U0GteWQaxxw+RD5iv7ryaziVr4j8oMj20z57StqfgXGZXoC7vMU7lDd55fm5br8cnpKTwCok5E5F2bZFPvx+IenMaVZsGBFpH2EJalOHT6lnQ9K80xlLTLDVc="); + } + + @Override + public void onRightClick(NPCRightClickEvent event) { + Player player = event.getClicker(); + + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (Core.getSettings().isUseEditMode() && user.hasEditMode()) + return; + + JobMode mode = JobMode.getModeOrNull("CRIMINAL"); + if (mode == null) return; + GTMUtils.chooseJobMode(player, user, GTM.getUserManager().getLoadedUser(player.getUniqueId()), mode); + } + + @Override + public void onLeftClick(NPCLeftClickEvent event) { + + } + + @Override + public void onCollide(NPCCollisionEvent event) { + + } + + @Override + public void onPush(NPCPushEvent event) { + + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/FoodNPC.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/FoodNPC.java new file mode 100644 index 0000000..376f110 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/FoodNPC.java @@ -0,0 +1,104 @@ +package net.grandtheftmc.gtm.users.npcs; + +import java.util.Collections; + +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import net.citizensnpcs.api.event.NPCCollisionEvent; +import net.citizensnpcs.api.event.NPCLeftClickEvent; +import net.citizensnpcs.api.event.NPCPushEvent; +import net.citizensnpcs.api.event.NPCRightClickEvent; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.inventory.CoreMenu; +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import net.grandtheftmc.core.inventory.button.ClickableItem; +import net.grandtheftmc.core.npc.CoreNPC; +import net.grandtheftmc.core.npc.interfaces.ClickableNPC; +import net.grandtheftmc.core.npc.interfaces.CollideableNPC; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.items.GameItem; +import net.grandtheftmc.gtm.users.GTMUser; + +/** + * Created by Timothy Lampen on 1/14/2018. + */ +public class FoodNPC extends CoreNPC implements ClickableNPC, CollideableNPC { + + private static final String[] FOOD_GAMEITEMS = new String[]{"burrito", "burger", "chocolatechipcookie", "friedchicken", "carrot", "chickensoup", "pie"}; + + public FoodNPC(Location loc) { + super(loc, EntityType.PLAYER, "&c&lBenjamin Baker", "&7&oBuy different food here!"); + } + + @Override + protected void generateNewNPC() { + setLookClose(true); + setSkin("eyJ0aW1lc3RhbXAiOjE1MTU5ODM3MDczNjMsInByb2ZpbGVJZCI6ImUzYjQ0NWM4NDdmNTQ4ZmI4YzhmYTNmMWY3ZWZiYThlIiwicHJvZmlsZU5hbWUiOiJNaW5pRGlnZ2VyVGVzdCIsInNpZ25hdHVyZVJlcXVpcmVkIjp0cnVlLCJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvODIzNzI3MTZmMDczMTYxOTJjZTg5MTk3YWY5MjQzMjY4MzZiZGQ0OWI1NWE0YmMyMTFiNjczNjg2NjFhMzU2NyJ9fX0=", "BwAEZYJEJRpiipEyWGUiWbWOfRYCxd1B1JDDwfJfXFKjLB7DzT9wAgXVr+WBA1fr6eU8sU8lSHZ9TL8NWRZVoqbyQjX04d18pz2XaBXH8yu02qOK8od3VhAihVId4pLh1W3zwApGGlP5iHQI1xZ3PZsqJxmuGEugHfg+9E1031lls0alA4WLImuocZx0Xjt/gHphAtQgw0K2WLm1U+78kZ2mBl7B+mSgWMz19b1UfkgLoYeusUxPbNXhEwX/A0H1wQS20TZuYabHBxp5yG4jYt8UZoetTtNQ5u927AhoiYbTtd8mWHRxOqc15EsPw91dO8Vy7ZFEQbALX2kFp6ghYo5D6sLoPPk41GXSi/Z0m0md1nKcqH2QRWmaX0KfssHZz1iVPlQtBBDWTVX6/xmUaMnUH2/fyVIDVf2d1zw2JxucSQ3X9k7s6Gm9BekKyMVtX8qwveemGf1/fVH6aTztYXrNoPC0GEcYu0fmQ4UnDuwFeqIAtLOtAwB3jAXxss04Xc4AnH09Q5CdE+OpK2pd949jj65Y84wjbj3Vkelur5xc8WcRBg6uoO/Xx8nQr9vNY9MUvFpIhATS/GHb3gP+U8hGUNYIwG7ff/neD4pSqZqBcTq4Vf7qC4eTsoepWXdGFLyT2qm2EY6XSkndyIuSMWMEI3aKoLKrjOBC8U8OhDY="); + setCollideable(true); + } + + @Override + public void onRightClick(NPCRightClickEvent event) { + Player player = event.getClicker(); + + if (!GTM.getSettings().canBuy()){ + player.sendMessage(ChatColor.RED + "Buying things is currently disabled."); + return; + } + + new FoodMenu().openInventory(player); + } + + @Override + public void onLeftClick(NPCLeftClickEvent npcLeftClickEvent) { + + } + + @Override + public void onCollide(NPCCollisionEvent event) { + + } + + @Override + public void onPush(NPCPushEvent event) { + + } + + private class FoodMenu extends CoreMenu { + private final int[] FOOD_SPOTS = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42, 47, 48, 49, 50, 51}; + public FoodMenu() { + super(6, Utils.f("&c&lFood Seller"), CoreMenuFlag.PHONE_LAYOUT); + + int counter = 0; + for(String food : FOOD_GAMEITEMS) { + GameItem item = GTM.getItemManager().getItem(food); + if(!item.canSell()) + continue; + double price = item.getSellPrice()*8; + ItemStack is = item.getItem(); + ItemMeta im = is.getItemMeta(); + im.setDisplayName(Utils.f("&6&l8x " + im.getDisplayName())); + im.setLore(Collections.singletonList(Utils.f("&6&lPrice: $&a" + price))); + is.setItemMeta(im); + + addItem(new ClickableItem(FOOD_SPOTS[counter], is, ((player, clickType) -> { + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + if(!user.hasMoney(price)){ + player.sendMessage(Lang.SHOP.f("&cYou do not have enough money for this item!")); + return; + } + user.takeMoney(price); + Utils.giveItems(player, item.getItem(8)); + }), false)); + counter++; + + } + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/HeadSellerNPC.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/HeadSellerNPC.java new file mode 100644 index 0000000..c2fe8df --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/HeadSellerNPC.java @@ -0,0 +1,55 @@ +package net.grandtheftmc.gtm.users.npcs; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import net.citizensnpcs.api.event.NPCCollisionEvent; +import net.citizensnpcs.api.event.NPCLeftClickEvent; +import net.citizensnpcs.api.event.NPCPushEvent; +import net.citizensnpcs.api.event.NPCRightClickEvent; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.npc.CoreNPC; +import net.grandtheftmc.core.npc.interfaces.ClickableNPC; +import net.grandtheftmc.core.npc.interfaces.CollideableNPC; + +/** + * Created by Timothy Lampen on 1/14/2018. + */ +public class HeadSellerNPC extends CoreNPC implements ClickableNPC, CollideableNPC { + public HeadSellerNPC(Location loc) { + super(loc, EntityType.PLAYER, "&a&lHead Seller", "&7&oSell your heads here!"); + } + + @Override + protected void generateNewNPC() { + setLookClose(true); + setSkin("eyJ0aW1lc3RhbXAiOjE1MTU5ODIyMzkzMTUsInByb2ZpbGVJZCI6IjcwOTU2NDU0NTJkOTRiYTI5YzcwZDFmYTY3YjhkYTQyIiwicHJvZmlsZU5hbWUiOiJIaWRkdXMiLCJzaWduYXR1cmVSZXF1aXJlZCI6dHJ1ZSwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzNmZjM3ZjdiYTBlYzlmMDczYWJhM2VlYTk0OGI3NDMzYzg3YmVmZWNkNzNmYjdjOWQyNjExYWZhMmVlNzY2In19fQ==", "d1UU+O/OvjxxspCnb7gRPXVW0RxpfpcG2ygVWiCZeBC9Mz5ztKRgsska9jqk3bOlupJR+ApefO88DgWrhHIsT0SZyG5e+kqg1r0pYWvE2LpYKmFyL4kgWs9om+KKXP1NGHXVJT9yJ+SdCHwAsqjosuLpg0IGs6e9V+2Tw9Lw3Fhq7GvQuufZjnvpWOKXsMnMRzil8bX3AlLkAvRnYXwOAmWeK/L6BGtT7olb+ewOjZwoKIbLH13kXJJ6BTEoOoFLlczTU+bCYx/Lc5tEkTqJoiTZtxV6oWZaLK7Q8YxdOsegP1yo7ZLGyH6IuKPPmtTVOC9C09PqBA9sWkBJUIKP5iA+gfNnPxkApo4ooY/gMEenzaPihHPt+USvpLvgvB/GtNkjSmtSXuYygyRAg6ukejM9PC+3waecH0rGtYuNZ2gKzdAboPMIlL7Z066A3b7+xrqbicYVtmKRrtdJZ3nuztNcFFhD6sBkl2fY6i2Xf8bYbE45LiNSrKB8a+DrgFRCuhlgtagesFALik5a9zBSSVIARMFlDgZqrJimQIbsTwprIAuqoUN2MDMTlmKIFzDheOZHyo8IGp+JyXztttzWz35RfPP68stJWJ0+2t5X2HFw6ERBTLpXeg/2RZ/CgHWNKJxBhOGKZONFZUOwPGy6BDQq9TX+ZQG6T3Eyhbg0zFM="); + setCollideable(true); + } + + @Override + public void onRightClick(NPCRightClickEvent event) { + Player player = event.getClicker(); + //MenuManager.openMenu(player, "heads"); + ItemStack item = player.getInventory().getItemInMainHand(); + MenuManager.openMenu(player, item != null && item.getType() == Material.SKULL_ITEM ? "auctionhead" : "heads"); + } + + @Override + public void onLeftClick(NPCLeftClickEvent event) { + + } + + @Override + public void onCollide(NPCCollisionEvent event) { + + } + + @Override + public void onPush(NPCPushEvent event) { + + } +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/HitmanNPC.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/HitmanNPC.java new file mode 100644 index 0000000..743c9bd --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/HitmanNPC.java @@ -0,0 +1,59 @@ +package net.grandtheftmc.gtm.users.npcs; + +import net.citizensnpcs.api.event.NPCCollisionEvent; +import net.citizensnpcs.api.event.NPCLeftClickEvent; +import net.citizensnpcs.api.event.NPCPushEvent; +import net.citizensnpcs.api.event.NPCRightClickEvent; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.npc.CoreNPC; +import net.grandtheftmc.core.npc.interfaces.ClickableNPC; +import net.grandtheftmc.core.npc.interfaces.CollideableNPC; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.users.JobMode; +import org.bukkit.Location; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; + +public class HitmanNPC extends CoreNPC implements ClickableNPC, CollideableNPC { + + public HitmanNPC(Location loc) { + super(loc, EntityType.PLAYER, "&3&lHitman", "&o&7Seek down bounties for money."); + } + + @Override + protected void generateNewNPC() { + setLookClose(true); + setSkin("eyJ0aW1lc3RhbXAiOjE1MjEyMjg5MTkxMTYsInByb2ZpbGVJZCI6IjExODAxYzEzMGNiYzQ5MGY4YmEzM2E0MTMxMTZiNzk1IiwicHJvZmlsZU5hbWUiOiIweDE5ZCIsInNpZ25hdHVyZVJlcXVpcmVkIjp0cnVlLCJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZjM3MDEwYzRiNjZkZjQwNzcyZDY0NDU0YTZlZGI5N2MzYjFkYTNhNzM3ZDY1YjVmYjViOGFmZTk3ZTcwNjIifX19", + "qPMTqj42MLzHgymB8piUecAgQyGR+kjS7euyOZV0mLoVAfmJXfSWX2GWOmykBuQ8B2jy66AAT/EzGFFMJFdNsilXsGgdYamEV2hLXUfk36yOzKcqGDS3KNoRy352vIlbeVvZVooVhcTsB7sE5uZYx5Qkaqj1+1D3lyruC7ZffbZLFhRXeNlqsGCds9pG8Fp2jUjrYSDNN6aXEZ9p28AKL6PG0NjxuIav0MfITC8HizND1PuN36P2F2qqnxAU4VfIBYaCSLFXicCp/S6A87RclHEQLrXUDzDcJFrkXtcvp0RQsHhmLNAryaVbFwmDRzJ4jyPTc3aFS+66aVf/SbDkGylPl+sDRVltg0q8sbLc7k4y3exhdGUQRs2N55gzwcUBFcZ6ple/B640xy1uoTHNZs3xqUJhQK8jM9odgIxeLIQ/fktQ1OXnQmgrm1S7owJ9t3vy5/yR2mSix/b+2WCARIS/4A73YKKyFkt2X020ElFaQHB0d3D+RHJE9j4cLNNEps/vWgX8FN8G2JFXXV0lDq7an7vE8hJTqdqNBp3Lb3Ly2poasFNQn/gIasp6U008k8mhWvb0BYhL4eLhN9BwSVtdZ6uYxKyH4NCdhkYFVydSCIYvvNDiSGN5DmfiGHM0DUCvCSjr+rvAoulaXQT7Axby+XaO7937LskIjYsVC7k="); + } + + @Override + public void onRightClick(NPCRightClickEvent event) { + Player player = event.getClicker(); + + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (Core.getSettings().isUseEditMode() && user.hasEditMode()) + return; + + JobMode mode = JobMode.getModeOrNull("HITMAN"); + if (mode == null) return; + GTMUtils.chooseJobMode(player, user, GTM.getUserManager().getLoadedUser(player.getUniqueId()), mode); + } + + @Override + public void onLeftClick(NPCLeftClickEvent event) { + + } + + @Override + public void onCollide(NPCCollisionEvent event) { + + } + + @Override + public void onPush(NPCPushEvent event) { + + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/MechanicNPC.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/MechanicNPC.java new file mode 100644 index 0000000..097135b --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/MechanicNPC.java @@ -0,0 +1,52 @@ +package net.grandtheftmc.gtm.users.npcs; + +import org.bukkit.Location; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; + +import net.citizensnpcs.api.event.NPCCollisionEvent; +import net.citizensnpcs.api.event.NPCLeftClickEvent; +import net.citizensnpcs.api.event.NPCPushEvent; +import net.citizensnpcs.api.event.NPCRightClickEvent; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.npc.CoreNPC; +import net.grandtheftmc.core.npc.interfaces.ClickableNPC; +import net.grandtheftmc.core.npc.interfaces.CollideableNPC; + +/** + * Created by Timothy Lampen on 1/14/2018. + */ +public class MechanicNPC extends CoreNPC implements ClickableNPC, CollideableNPC { + public MechanicNPC(Location loc) { + super(loc, EntityType.PLAYER, "&a&lMechanic Gary", "&7&oRepair your vehicles here!"); + } + + @Override + protected void generateNewNPC() { + setLookClose(true); + setSkin("eyJ0aW1lc3RhbXAiOjE1MTU5ODIyMzkzMTUsInByb2ZpbGVJZCI6IjcwOTU2NDU0NTJkOTRiYTI5YzcwZDFmYTY3YjhkYTQyIiwicHJvZmlsZU5hbWUiOiJIaWRkdXMiLCJzaWduYXR1cmVSZXF1aXJlZCI6dHJ1ZSwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzNmZjM3ZjdiYTBlYzlmMDczYWJhM2VlYTk0OGI3NDMzYzg3YmVmZWNkNzNmYjdjOWQyNjExYWZhMmVlNzY2In19fQ==", "d1UU+O/OvjxxspCnb7gRPXVW0RxpfpcG2ygVWiCZeBC9Mz5ztKRgsska9jqk3bOlupJR+ApefO88DgWrhHIsT0SZyG5e+kqg1r0pYWvE2LpYKmFyL4kgWs9om+KKXP1NGHXVJT9yJ+SdCHwAsqjosuLpg0IGs6e9V+2Tw9Lw3Fhq7GvQuufZjnvpWOKXsMnMRzil8bX3AlLkAvRnYXwOAmWeK/L6BGtT7olb+ewOjZwoKIbLH13kXJJ6BTEoOoFLlczTU+bCYx/Lc5tEkTqJoiTZtxV6oWZaLK7Q8YxdOsegP1yo7ZLGyH6IuKPPmtTVOC9C09PqBA9sWkBJUIKP5iA+gfNnPxkApo4ooY/gMEenzaPihHPt+USvpLvgvB/GtNkjSmtSXuYygyRAg6ukejM9PC+3waecH0rGtYuNZ2gKzdAboPMIlL7Z066A3b7+xrqbicYVtmKRrtdJZ3nuztNcFFhD6sBkl2fY6i2Xf8bYbE45LiNSrKB8a+DrgFRCuhlgtagesFALik5a9zBSSVIARMFlDgZqrJimQIbsTwprIAuqoUN2MDMTlmKIFzDheOZHyo8IGp+JyXztttzWz35RfPP68stJWJ0+2t5X2HFw6ERBTLpXeg/2RZ/CgHWNKJxBhOGKZONFZUOwPGy6BDQq9TX+ZQG6T3Eyhbg0zFM="); + setCollideable(true); + } + + @Override + public void onRightClick(NPCRightClickEvent event) { + Player player = event.getClicker(); + //MenuManager.openMenu(player, "vehicles"); + MenuManager.openMenu(player, "mechanic"); + } + + @Override + public void onLeftClick(NPCLeftClickEvent event) { + + } + + @Override + public void onCollide(NPCCollisionEvent event) { + + } + + @Override + public void onPush(NPCPushEvent event) { + + } +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/PoliceNPC.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/PoliceNPC.java new file mode 100644 index 0000000..ddc62a0 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/PoliceNPC.java @@ -0,0 +1,61 @@ +package net.grandtheftmc.gtm.users.npcs; + +import net.citizensnpcs.api.event.NPCCollisionEvent; +import net.citizensnpcs.api.event.NPCLeftClickEvent; +import net.citizensnpcs.api.event.NPCPushEvent; +import net.citizensnpcs.api.event.NPCRightClickEvent; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.npc.CoreNPC; +import net.grandtheftmc.core.npc.interfaces.ClickableNPC; +import net.grandtheftmc.core.npc.interfaces.CollideableNPC; + +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.users.JobMode; +import org.bukkit.Location; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; + +public class PoliceNPC extends CoreNPC implements ClickableNPC, CollideableNPC { + + public PoliceNPC(Location loc) { + super(loc, EntityType.PLAYER, "&3&lCop", "&o&7Become a Cop and fight crime!"); + } + + @Override + protected void generateNewNPC() { + setLookClose(true); + setSkin("eyJ0aW1lc3RhbXAiOjE1MjEyMjg2NTk5NjEsInByb2ZpbGVJZCI6IjExODAxYzEzMGNiYzQ5MGY4YmEzM2E0MTMxMTZiNzk1IiwicHJvZmlsZU5hbWUiOiIweDE5ZCIsInNpZ25hdHVyZVJlcXVpcmVkIjp0cnVlLCJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMTU5MGFmOGIzNTNiZjk4MzRiMTlhMjk0ZWZhNTUzYmM3NjM5OTEzOTkzNjRlYTRlY2Y4YzBjNjNkOTNhYTU3In19fQ==", + "LlCVPj90DakqMhenHks4mEwK2sHPYf/H3Np4F6dgtkDeUDAVmG7ZJiAewEPtjTXeLcD9RdF1NmZJoLT+FOy4ZVDYTuIMCYis8IHRUCm5zPwV6kqvHFO6ZWBpj4SQEdRE/QeaUVyBpFMHVUx4uknti4gw42pSXnBuik/xMv3Jhf8Qe80YG6CLMB+0mIjb9l1ImlT1O5BGtAlC2gk+mnk1R4sNaW4oy+C4RT7K//T/S+v7YUzjwHQf/0065Cx7EoyhfBXcldnOYdxWDqpYo8JLmq0utuR9g3CDZBwTznu4TLByDmJnFutPNVVXSU1cAYUEPXfAnm5Zkgj1WwnytAh4xG+zn0psk567Po+2ouT7zEiYEfK1jAAU3VkjmrSAgCTu2hisXAZibMzKgBubcnquIipfQin4lGQ9Kp4s51u5tOvl33zsINsTNZi+bSks9j9pN7fqYQmzu3DWIBKKxFwW+LaMY5uGlzaeaYSmSlFEpcreMDsbxTKnJ7oNWOGOwmX6vwJw74is1MmI54g3y6HxCsBCGXvg6LhEjKF7lgwgvV1PLP0B0AgFZkc8H+mF/uU9fNaE95TC0zq7KetNE8/93tnF7G2UyJv6IdM/ZYDEMP1Bi/41T6FTIFRuW2tviri2JwyAF7QnoXmB39M2n8lzqWhFYnfb5w/yQQEbp1v1AWc="); + } + + @Override + public void onRightClick(NPCRightClickEvent event) { + Player player = event.getClicker(); + + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (Core.getSettings().isUseEditMode() && user.hasEditMode()) + return; + + JobMode mode = JobMode.getModeOrNull("COP"); + if (mode == null) return; + GTMUtils.chooseJobMode(player, user, GTM.getUserManager().getLoadedUser(player.getUniqueId()), mode); + } + + @Override + public void onLeftClick(NPCLeftClickEvent event) { + + } + + @Override + public void onCollide(NPCCollisionEvent event) { + + } + + @Override + public void onPush(NPCPushEvent event) { + + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/RewardsNPC.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/RewardsNPC.java new file mode 100644 index 0000000..8386c73 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/RewardsNPC.java @@ -0,0 +1,52 @@ +package net.grandtheftmc.gtm.users.npcs; + +import net.citizensnpcs.api.event.NPCCollisionEvent; +import net.citizensnpcs.api.event.NPCLeftClickEvent; +import net.citizensnpcs.api.event.NPCPushEvent; +import net.citizensnpcs.api.event.NPCRightClickEvent; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.npc.CoreNPC; +import net.grandtheftmc.core.npc.interfaces.ClickableNPC; +import net.grandtheftmc.core.npc.interfaces.CollideableNPC; + +import org.bukkit.Location; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; + +/** + * Created by Timothy Lampen on 1/14/2018. + */ +public class RewardsNPC extends CoreNPC implements ClickableNPC, CollideableNPC { + + public RewardsNPC(Location loc) { + super(loc, EntityType.PLAYER, "&2&lFree Tony", "&7&oClaim rewards and vote here!"); + } + + @Override + protected void generateNewNPC() { + setLookClose(true); + setSkin("eyJ0aW1lc3RhbXAiOjE1MTU5ODM4MzE4NDYsInByb2ZpbGVJZCI6IjdkYTJhYjNhOTNjYTQ4ZWU4MzA0OGFmYzNiODBlNjhlIiwicHJvZmlsZU5hbWUiOiJHb2xkYXBmZWwiLCJzaWduYXR1cmVSZXF1aXJlZCI6dHJ1ZSwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2I1ZGMyNmUzMjZhNTY5ODUxOTgyM2FiYWFlZWQyODM1YTk3YzY5Yzk4Y2JhMTNhMmYxNDdkMTI5MWU1ZTgifX19", "UonaJdHIdT7paVOCZ5sNTrrV2tMT6lIdGOC/AG5oleC0m1QXuPkoEiWlf26IOzHMV9KfZuTCZPcc35f9+X8ySG+8cMSMXvhAzM6sCxbidB8XoQ8MgfAt/eUBQzyhRU/f02pRpefTaYfNVmjucrpI+GK5Hrq6PfmqxFRyiFVaFcWxL6ZQ23j5REy7lHvbhcqIFy10VRJqzIy4TeNCh9X3aBRoNK/nosUHR+M0qQiTYrAM8eRFFTu/d55ofAZx0dgs7XM4Mp/UswGa1yUdgIwtJSKsVVxgiwQ5/Gj1iWY6SAmcBF9ueySiqSLtopC8NSUzzD8HxiuBvq0yQPSsnxzGljBFcwKUzzCu+c03b8XfcppwV5WXa3uXGDNRHL/MzE9Sdp7vi4Pg2e44kNnakuGA/w0jEMNu4EPz+lgBHL9QIzL1mLZiXc9xGquvDtNVR1QePYY8uRbqVTahXDJmHe/1D0wisrLjiaKQPHhjHsRqk6H6D/Zr+3U1/wH+XHdHqVWhAh4dqznOD3gLCmXmaegRLvkNi0LHhnnurdP1y/CY4UCL/VdC86Q2LANeKCxqx3BSnXctRyMXiL/ZUwK41flbdeiOv3zvR7QwBilqAufQ+zXZCeMUTBU0RDeXeXDUV3LY3LkKIpmO1LqK0PK7uOEDTvW8fX/s/cxXxBcUO15b1mQ="); + setCollideable(true); + } + + @Override + public void onRightClick(NPCRightClickEvent event) { + Player player = event.getClicker(); + MenuManager.openMenu(player, "rewards"); + } + + @Override + public void onLeftClick(NPCLeftClickEvent event) { + + } + + @Override + public void onCollide(NPCCollisionEvent event) { + + } + + @Override + public void onPush(NPCPushEvent event) { + + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/ShopNPC.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/ShopNPC.java new file mode 100644 index 0000000..147d86c --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/ShopNPC.java @@ -0,0 +1,275 @@ +package net.grandtheftmc.gtm.users.npcs; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; + +import net.citizensnpcs.api.event.NPCCollisionEvent; +import net.citizensnpcs.api.event.NPCLeftClickEvent; +import net.citizensnpcs.api.event.NPCPushEvent; +import net.citizensnpcs.api.event.NPCRightClickEvent; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.inventory.CoreMenu; +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import net.grandtheftmc.core.inventory.button.ClickableItem; +import net.grandtheftmc.core.npc.CoreNPC; +import net.grandtheftmc.core.npc.interfaces.ClickableNPC; +import net.grandtheftmc.core.npc.interfaces.CollideableNPC; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.items.GameItem; +import net.grandtheftmc.gtm.trashcan.TrashCanManager; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.guns.WeaponManager; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.Weapon; +import net.grandtheftmc.guns.weapon.WeaponType; + +/** + * Created by Timothy Lampen on 1/14/2018. + */ +public class ShopNPC extends CoreNPC implements ClickableNPC, CollideableNPC { + + private static final Set<String> DISABLED = new HashSet<>(Arrays.asList("clausinator")); + private static final HashMap<AmmoType, Integer> AMMO_MULTIPLIERS = new HashMap<>(); + private final WeaponManager weaponManager; + + static { + AMMO_MULTIPLIERS.put(AmmoType.ASSAULT_RIFLE, 50); + AMMO_MULTIPLIERS.put(AmmoType.GRENADE, 5); + AMMO_MULTIPLIERS.put(AmmoType.ROCKET, 1); + AMMO_MULTIPLIERS.put(AmmoType.LAUNCHER, 1); + AMMO_MULTIPLIERS.put(AmmoType.MINIGUN, 600); + AMMO_MULTIPLIERS.put(AmmoType.PISTOL, 20); + AMMO_MULTIPLIERS.put(AmmoType.SMG, 60); + AMMO_MULTIPLIERS.put(AmmoType.LMG, 40); + AMMO_MULTIPLIERS.put(AmmoType.SHOTGUN, 12); + AMMO_MULTIPLIERS.put(AmmoType.SNIPER, 10); + AMMO_MULTIPLIERS.put(AmmoType.FUEL, 64); + } + + public ShopNPC(WeaponManager weaponManager, Location loc) { + super(loc, EntityType.PLAYER, "&9&lGary McNaggins", "&7&oBuy the best guns and ammo here!"); + this.weaponManager = weaponManager; + } + + @Override + protected void generateNewNPC() { + setLookClose(true); + setSkin("eyJ0aW1lc3RhbXAiOjE1MDc2MTM5NzI2NDUsInByb2ZpbGVJZCI6ImUzYjQ0NWM4NDdmNTQ4ZmI4YzhmYTNmMWY3ZWZiYThlIiwicHJvZmlsZU5hbWUiOiJNaW5pRGlnZ2VyVGVzdCIsInNpZ25hdHVyZVJlcXVpcmVkIjp0cnVlLCJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZGUyYjUwYzI4NDQ1YmQyOWE2OGRmZTIyM2M0YzlmZDYyZTYyOWNkNWU1ZDdjMTc3NzIwNmU4YjRkNjMxIn19fQ==", "gza3eHED3BMmxRjZmDDUQQliH10Q4e8U5uKNv0RaGfOKdPOxMToH2rqSpyNeS+odXQvAq6cDZulKk5LZgcs89kpv+Jkb3sfWdUb6HnJvqkeA+4iTw3n9BxRZpoC0lyBmiJSQPlSwywgjmd9cybGPtgX3+WpbExRDYy90X8ii3iN9dlFlNWFiInNZjBUUjslcqnD8VEkItonJwNbPbXkgvHu0qmiBon6bWmnI81cO0DekrxOGAbQQynNosnGVbV7oGTAtN87G9zM7McNvMXK+1BJqAxdqad3U2Jfnu3PHDZ1pDCJIA+5yQiiTblQPzYx9Fp73E2NpS51239/P5B0bWOa8MWGK2fKCznxRy/lZTd/3Ewojxu9guWann0ALLeYyvXA/FDY1vY6clRF50JyhgBR6Tf58lOF8kkq964gdpYlhtldI1ZWf8jn/inK//b3rNmqu046oKQLuhYjxVNoV4lrzzb+pzjjKx2/iBXqzxnWTjrTLZv6n6jLS9aFghryaLbUXc4IETj+MsZ5Z9WdPCG02V3f3Z+5aFZfMg2zkj1qQxDVhrdJr/87lE23ZupYDV1szocx39JF1gtwbKhTugVKlDV4UQZHokFdcFRtMLSpX7zJwNLiVK/+aMN1YbGQzdwII9CFXN2DtgawzTnQQafEBwNiyp3GAcPTE9VqffFY="); + setCollideable(true); + } + + @Override + public void onRightClick(NPCRightClickEvent event) { + Player player = event.getClicker(); + + if (!GTM.getSettings().canBuy()){ + player.sendMessage(ChatColor.RED + "Buying things is currently disabled."); + return; + } + + new CategoryMenu().openInventory(player); + } + + @Override + public void onLeftClick(NPCLeftClickEvent npcLeftClickEvent) { + + } + + @Override + public void onCollide(NPCCollisionEvent event) { + + } + + @Override + public void onPush(NPCPushEvent event) { + + } + + private class CategoryMenu extends CoreMenu { + private final int[] CATEGORY_SLOTS = new int[]{20, 21, 22, 23, 24, 29, 30, 31, 32, 33}; + private int counter = 0; + + protected CategoryMenu() { + super(6, Utils.f("&c&lChoose Category"), CoreMenuFlag.PHONE_LAYOUT); + addItem(getCategoryPlaceholder(WeaponType.THROWABLE, Utils.f("&7&oRemember: Don't miss!"))); + addItem(getCategoryPlaceholder(WeaponType.MELEE, Utils.f("&7&oFor when you need to get close and personal."))); + addItem(getCategoryPlaceholder(WeaponType.PISTOL, Utils.f("&7&oA basic gun; point, shoot, kill."))); + addItem(getCategoryPlaceholder(WeaponType.LMG, Utils.f("&7&oSlow and steady wins the race... so do a lot of bullets."))); + addItem(getCategoryPlaceholder(WeaponType.SMG, Utils.f("&7&oFor when you need to get close and personal."))); + addItem(getCategoryPlaceholder(WeaponType.SHOTGUN, Utils.f("&7&oDamage? Check! Spread? Check!"), Utils.f("&7&oOverall coolness factor? What more could you want!?"))); + addItem(getCategoryPlaceholder(WeaponType.ASSAULT, Utils.f("&7&oNow we're talking!"))); + addItem(getCategoryPlaceholder(WeaponType.LAUNCHER, Utils.f("&7&oWhen you're too lazy to throw..."))); + addItem(getCategoryPlaceholder(WeaponType.SNIPER, Utils.f("&7&oNot all battles are fought at close range."))); + addItem(getCategoryPlaceholder(WeaponType.SPECIAL, Utils.f("&7&oRespect comes in many forms..."), Utils.f("&7&oespecially that of a giant death machine!"))); + + addItem(getSellWeaponsButton()); + } + + private ClickableItem getCategoryPlaceholder(WeaponType type, String... lore) { + Optional<Weapon<?>> optWeapon = type == WeaponType.SPECIAL ? weaponManager.getWeapon("minigun") : weaponManager.getRegisteredWeapons().stream().filter(w -> w.getWeaponType() == type && GTM.getItemManager().getItemFromWeapon(w.getCompactName()) != null && GTM.getItemManager().getItemFromWeapon(w.getCompactName()).canBuy()).findFirst(); + if (!optWeapon.isPresent()) { + return new ClickableItem(CATEGORY_SLOTS[counter++], new ItemStack(Material.STONE), ((player, clickType) -> { + new ShopMenu(type).openInventory(player); + }), false); + } + + ItemStack is = optWeapon.get().getBaseItemStack().clone(); + ItemMeta im = is.getItemMeta(); + im.setDisplayName(Utils.f("&a&l" + type.toString())); + im.setLore(Arrays.asList(lore)); + im.setUnbreakable(true); + im.setUnbreakable(true); + im.addItemFlags(ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ATTRIBUTES); + is.setItemMeta(im); + return new ClickableItem(CATEGORY_SLOTS[counter++], is, ((player, clickType) -> { + new ShopMenu(type).openInventory(player); + }), false); + } + + private ClickableItem getSellWeaponsButton() { + ItemStack is = new ItemStack(Material.PAPER); + ItemMeta im = is.getItemMeta(); + im.setDisplayName(Utils.f("&a&lSell Weapons")); + is.setItemMeta(im); + + return new ClickableItem(49, is, ((player, clickType) -> { + player.closeInventory(); + TrashCanManager.openTrashCan(player); + })); + } + } + + private class ShopMenu extends CoreMenu { + + private final int[] WEAPON_SPOTS = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + + /** + * PAGE LEGEND + * 1 - GRENADES + * 2 - MELEE + * 3 - PISTOLS + * 4 - SMGS + * 5 - LMGS + * 6 - SHOTGUNS + * 7 - ASSAULT + * 8 - LAUNCHER + * 9 - SPECIAL + */ + protected ShopMenu(WeaponType type) { + super(6, Utils.f("&9&lPurchase " + type.toString()), CoreMenuFlag.PHONE_LAYOUT); + addItem(getBackwardSelector()); + + int counter = 0; + Set<Weapon<?>> filtered = weaponManager.getRegisteredWeapons().stream().filter(w -> { + if (w == null) + return false; + if (DISABLED.contains(w.getName().toLowerCase())) + return false; + return w.getWeaponType() == type || (type == WeaponType.SPECIAL && (w.getWeaponType() != WeaponType.MELEE && w.getWeaponType() != WeaponType.ASSAULT && w.getWeaponType() != WeaponType.LAUNCHER && w.getWeaponType() != WeaponType.THROWABLE && w.getWeaponType() != WeaponType.SMG && w.getWeaponType() != WeaponType.LMG && w.getWeaponType() != WeaponType.SHOTGUN && w.getWeaponType() != WeaponType.PISTOL && w.getWeaponType() != WeaponType.SNIPER)); + }).collect(Collectors.toSet()); + + for (Weapon<?> w : filtered) { + GameItem item = GTM.getItemManager().getItemFromWeapon(w.getCompactName()); + if (item == null) { + Core.error("[ShopNPC] Unable to load gameitem from weapon: " + w.getCompactName()); + continue; + } + if (!item.canBuy()) { + ServerUtil.debug("[ShopNPC] Unable to find buy price for weapon: " + w.getCompactName() + " is it suppose to be like that?"); + continue; + } + ItemStack is = item.getItem(); + ItemMeta im = is.getItemMeta(); + im.setDisplayName(Utils.f("&6" + w.getName())); + List<String> lore = new ArrayList<>(); + lore.add(Utils.f("&6&lBuy Weapon &8(&6Left Click&8)&6: $&a" + item.getBuyPrice())); + + GameItem ammoItem = null; + if (type != WeaponType.THROWABLE && type != WeaponType.MELEE && w.getAmmoType() != AmmoType.NONE) { + if (type == WeaponType.LMG) + ammoItem = net.grandtheftmc.gtm.items.AmmoType.MG.getGameItem();//because of how the naming of the wastedguns / gtmguns is :( + else + ammoItem = net.grandtheftmc.gtm.items.AmmoType.getAmmoType(w.getAmmoType().toString()).getGameItem(); + if (ammoItem == null) { + Core.error("[ShopNPC] Unable to load ammo from string: " + w.getAmmoType() + " for weapon: " + w.getName()); + return; + } + + lore.add(Utils.f("&6&lBuy x&b&l" + AMMO_MULTIPLIERS.get(w.getAmmoType()) + "&6&l Ammo &8(&6Right Click&8)&6: $&a" + (ammoItem.getBuyPrice() * AMMO_MULTIPLIERS.get(w.getAmmoType())))); + } + im.setLore(lore); + is.setItemMeta(im); + + final GameItem finalAmmoItem = ammoItem; + + addItem(new ClickableItem(WEAPON_SPOTS[counter], is, (player, clickType) -> { + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + switch (clickType) { + case LEFT: + case SHIFT_LEFT: + if (!user.hasMoney(item.getBuyPrice())) { + player.sendMessage(Lang.SHOP.f("&cYou do not have enough money for this item!")); + return; + } + user.takeMoney(item.getBuyPrice()); + Utils.giveItems(player, item.getItem()); + break; + case RIGHT: + case SHIFT_RIGHT: + + if (finalAmmoItem == null) + return; + if (!user.hasMoney(finalAmmoItem.getBuyPrice() * AMMO_MULTIPLIERS.get(w.getAmmoType()))) { + player.sendMessage(Lang.SHOP.f("&cYou do not have enough money for this item!")); + return; + } + + net.grandtheftmc.gtm.items.AmmoType ammoType = net.grandtheftmc.gtm.items.AmmoType.getAmmoType(w.getAmmoType().getType()); + + // for some reason this can be null + if (ammoType == null){ + return; + } + + user.takeMoney(finalAmmoItem.getBuyPrice() * AMMO_MULTIPLIERS.get(w.getAmmoType())); + user.addAmmo(ammoType, AMMO_MULTIPLIERS.get(w.getAmmoType())); + player.sendMessage(Lang.AMMO_ADD.f(AMMO_MULTIPLIERS.get(w.getAmmoType()) + "&7 " + w.getAmmoType().toString())); + break; + } + }, false)); + counter++; + } + } + + + private ClickableItem getBackwardSelector() { + ItemStack is = new ItemStack(Material.SKULL_ITEM, 1, (short) 3); + SkullMeta im = (SkullMeta) is.getItemMeta(); + im.setOwner("MHF_ArrowLeft"); + im.setDisplayName(Utils.f("&cBack")); + is.setItemMeta(im); + return new ClickableItem(47, is, ((player, clickType) -> { + new CategoryMenu().openInventory(player); + })); + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/SkinsNPC.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/SkinsNPC.java new file mode 100644 index 0000000..6d76901 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/SkinsNPC.java @@ -0,0 +1,47 @@ +package net.grandtheftmc.gtm.users.npcs; + +import org.bukkit.Location; +import org.bukkit.entity.EntityType; + +import net.citizensnpcs.api.event.NPCCollisionEvent; +import net.citizensnpcs.api.event.NPCLeftClickEvent; +import net.citizensnpcs.api.event.NPCPushEvent; +import net.citizensnpcs.api.event.NPCRightClickEvent; +import net.grandtheftmc.core.npc.CoreNPC; +import net.grandtheftmc.core.npc.interfaces.ClickableNPC; +import net.grandtheftmc.core.npc.interfaces.CollideableNPC; +import net.grandtheftmc.gtm.weapon.skins.menu.MainMenu; + +public class SkinsNPC extends CoreNPC implements ClickableNPC, CollideableNPC { + public SkinsNPC(Location location) { + super(location, EntityType.PLAYER, "&9&lMr Skinner", "&7&oManage and view your weapon skins here!"); + } + + @Override + protected void generateNewNPC() { + setLookClose(true); + setSkin("eyJ0aW1lc3RhbXAiOjE1MTg1NjMxNzk3MDEsInByb2ZpbGVJZCI6Ijc2MTJhZWU1YTk5YjQxZWRiYTg3Nzg4MGMyMjZiMzM2IiwicHJvZmlsZU5hbWUiOiJGbG91cmVrIiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS8yNjE0ODNmMGIxNjc2OWQ2NGFlMTI5Yjg5ZDYyY2M3N2M1Mzk0OGRlZTVmYzQ2MmFlNTQ1OTQyZWYwNDdjNzliIn19fQ==", + "svzvIYm7x02JAMpjnW+oKQAM48jpzTNvKtLVSPGuL7DjWjZOuH+fjrw6tqGWKAHZYbR7QaIfNiHKk/uKbF8gGij9jxphAZuD47p53ALODYwbopir2lSdmMl+flPggTS7dWYmPfQsnSa4t13O1yLZMmdtFUTzyJQYZqFeU+Ss7CAiU0Xxvi5SNqlrLlm+utDaQQoobfkHeuHBe1/bFDNrTx7iYGYuPqn3Y5T8YtqgyRVaQsoDyeAmONNJE5R/o8MVOEFKtqE/MqL5ONpAFkkM1iDlajj+C3lhJ/3ORnpA6HTTyAGvLLZJNXBNM2+nl4x7hyEMw6kQJ5JCh3uFGbJamXvpi/pFQS2rBI1OZVzhZbYIE9/dfqxK6MH7A9Z1XlCPYQPFmQzh0unJH8y4OTBxfUsEjaIgB8AG61SjuyJqFo5oeJ2DJ1kO8ua72tLl13ron/fk+AfGeW16LuwxIy1XaUki4UC5MRcE0wj7ou68ME1gR/XmjpQDuaPaJj7yf+epFHc9lDARtb21yqOkYJXAKiN6ec8HU7uhIXW142K+bhzFGTfUZ6jxnL54TQ6qWojwpM/VEM8ewsMaL4Xf3Kh5hPzuXeylca4qPZzhsJ2I9Bf09i1TknDVTnW8qgmz4WZynyBNMdWZ60w25q/afM1DB9QuzUo2Qa+y2z7MSDALMCw="); + setCollideable(true); + } + + @Override + public void onRightClick(NPCRightClickEvent event) { + new MainMenu(event.getClicker()).open(); + } + + @Override + public void onLeftClick(NPCLeftClickEvent npcLeftClickEvent) { + + } + + @Override + public void onCollide(NPCCollisionEvent event) { + + } + + @Override + public void onPush(NPCPushEvent event) { + + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/TaxiNPC.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/TaxiNPC.java new file mode 100644 index 0000000..f1650f1 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/users/npcs/TaxiNPC.java @@ -0,0 +1,112 @@ +package net.grandtheftmc.gtm.users.npcs; + +import net.citizensnpcs.api.event.NPCCollisionEvent; +import net.citizensnpcs.api.event.NPCLeftClickEvent; +import net.citizensnpcs.api.event.NPCPushEvent; +import net.citizensnpcs.api.event.NPCRightClickEvent; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.npc.CoreNPC; +import net.grandtheftmc.core.npc.interfaces.ClickableNPC; +import net.grandtheftmc.core.npc.interfaces.CollideableNPC; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.users.GTMRank; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.users.TaxiTarget; +import org.bukkit.ChatColor; +import org.bukkit.Color; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +/** + * Created by Timothy Lampen on 1/14/2018. + */ +public class TaxiNPC extends CoreNPC implements ClickableNPC, CollideableNPC { + + public TaxiNPC(Location loc) { + super(loc, EntityType.PLAYER, "&e&lGerald Hackney", "&7&oGo to the game world!"); + } + + @Override + protected void generateNewNPC() { + setSkin("eyJ0aW1lc3RhbXAiOjE1MTU5NzAzNjYzNDUsInByb2ZpbGVJZCI6ImFkMWM2Yjk1YTA5ODRmNTE4MWJhOTgyMzY0OTllM2JkIiwicHJvZmlsZU5hbWUiOiJGdXJrYW5iejAwIiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9jYzUzZWQyMzJlYWQyNmU4Y2I0NzJiMGFmOGIyMDQyYjdhZjljZDMyOGRlM2M0YTZlNGQzNjNiNDNiZDlmNDUifX19", "hLKOkCuejv8K7bwWS/SKY6jrxJXNojg4eiv1/TPkKJ/1Hc+njUE99IPLCuexppJASlUEMe2815FfDwS4PTzMzgxBeLPdcB/xJR8BZw4FuvodIXfLubmVkxme245u0hRHfVlPLk31l4dyPFEwRMhbSmHacVroB8pebEov6+164p3fUnctqlM48bf6lNfpsbhY46nvqPVRVtv9ljTL6FwBPDvnZL97zTSsUqjKjLUJMTtuHIaAj26Q9+M9y4rP1VMInDWrgfXpEuwz32xy/2HiHHQrGMrNxU9MmshDX1BTJ4UAxmipmj+pJENRSon3GrIgLE7t/yP0Z1ZCcfHFqZtzLHKPXzt+u4jW5hl9bFUU9d9HSUEV0qt+nD68a1yNiWPE2rB0l549v+AZ5D8bktSpvdLy574/uBLLXbM8JJk8g1iFgyeEpQS8TJuHfnyV62KU6lML5+MTt7/zBXlRh2+Vz89Ti0fbZs1g6NdcJWQisCTtVPMBiws9yoitmSsqKk+8/8WYQX7EYXLGilL7gavoBZhlIyP0P8ltTc4oHfcwoOtoZvPivauUv8lHZu18tZpOE1kq28lNuBdytLTWTuJckDzeRwbB8pHCQKB628nRLt2Xp1N57CNnc9XW/3sWY+rKTRHRNw7BvVqoaCAXP4tNo+c7frELxv+CgWMxRcE2g5E="); + setLookClose(true); + setCollideable(true); + setGlowing(ChatColor.GREEN); + + new BukkitRunnable() { + @Override + public void run() { + if (!getNPC().isSpawned()) { + this.cancel(); + } else { + getStartingLoc().getWorld().spawnParticle(Particle.VILLAGER_HAPPY, getStartingLoc(), 25, 1.2, 1, 1.2); + +// LivingEntity entity = (LivingEntity) TaxiNPC.this.getNPC().getEntity(); +// if (entity.hasPotionEffect(PotionEffectType.GLOWING)) +// entity.removePotionEffect(PotionEffectType.GLOWING); +// +// entity.addPotionEffect(new PotionEffect(PotionEffectType.GLOWING, 20, 0, false, false, colors[i[0]])); + } + } + }.runTaskTimer(GTM.getInstance(), 20, 20); + } + + @Override + public void onRightClick(NPCRightClickEvent event) { + Player player = event.getClicker(); + + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + if (player.isSneaking() || user.getRank() == GTMRank.HOBO) { + GTM.getWarpManager().warp( + player, + Core.getUserManager().getLoadedUser(player.getUniqueId()), + user, + new TaxiTarget(GTM.getWarpManager().getRandomWarp()), + 0, + Core.getUserManager().getLoadedUser(player.getUniqueId()).isPremium() ? 1 : 10 + ); + + return; + } + + MenuManager.openMenu(player, "taxi"); + } + + @Override + public void onLeftClick(NPCLeftClickEvent event) { + Player player = event.getClicker(); + + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + if (player.isSneaking() || user.getRank() == GTMRank.HOBO) { + GTM.getWarpManager().warp( + player, + Core.getUserManager().getLoadedUser(player.getUniqueId()), + user, + new TaxiTarget(GTM.getWarpManager().getRandomWarp()), + 0, + Core.getUserManager().getLoadedUser(player.getUniqueId()).isPremium() ? 1 : 10 + ); + + return; + } + + MenuManager.openMenu(player, "taxi"); + } + + @Override + public void onCollide(NPCCollisionEvent event) { + + } + + @Override + public void onPush(NPCPushEvent event) { + + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/utils/ItemStackUtil.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/utils/ItemStackUtil.java new file mode 100644 index 0000000..77527bf --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/utils/ItemStackUtil.java @@ -0,0 +1,82 @@ +package net.grandtheftmc.gtm.utils; + +import net.grandtheftmc.core.util.ItemStackManager; +import net.minecraft.server.v1_12_R1.NBTTagCompound; +import net.minecraft.server.v1_12_R1.NBTTagInt; +import net.minecraft.server.v1_12_R1.NBTTagString; +import org.bukkit.Material; +import org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack; +import org.bukkit.inventory.ItemStack; + +/** + * Created by Luke Bingham on 06/08/2017. + */ +public class ItemStackUtil { + + public static ItemStack makeStackable(org.bukkit.inventory.ItemStack itemStack, int stacksize) { + if(itemStack == null || itemStack.getType() == Material.AIR) return itemStack; + + ItemStackManager.STACKABLES.put(itemStack.getType(), stacksize); + + net.minecraft.server.v1_12_R1.ItemStack stack = org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack.asNMSCopy(itemStack); + stack.getItem().d(stacksize); + itemStack = org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack.asBukkitCopy(stack); + + return itemStack; + } + + public static ItemStack removeStackable(org.bukkit.inventory.ItemStack itemStack) { + if(itemStack == null || itemStack.getType() == Material.AIR) return itemStack; + + net.minecraft.server.v1_12_R1.ItemStack stack = org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack.asNMSCopy(itemStack); + stack.getItem().d(1); + itemStack = org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack.asBukkitCopy(stack); + + return itemStack; + } + + public static ItemStack addTag(ItemStack itemStack, String key, int value) { + net.minecraft.server.v1_12_R1.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + NBTTagCompound compound = nmsItem.hasTag() ? nmsItem.getTag() : new NBTTagCompound(); + if (compound == null) compound = new NBTTagCompound(); + + compound.set(key, new NBTTagInt(value)); + nmsItem.setTag(compound); + nmsItem.save(compound); + + return CraftItemStack.asBukkitCopy(nmsItem); + } + + public static ItemStack addTag(ItemStack itemStack, String key, String value) { + net.minecraft.server.v1_12_R1.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + NBTTagCompound compound = nmsItem.hasTag() ? nmsItem.getTag() : new NBTTagCompound(); + if (compound == null) compound = new NBTTagCompound(); + + compound.set(key, new NBTTagString(value)); + nmsItem.setTag(compound); + nmsItem.save(compound); + + return CraftItemStack.asBukkitCopy(nmsItem); + } + + public static boolean hasTag(ItemStack itemStack, String key) { + net.minecraft.server.v1_12_R1.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + return nmsItem.hasTag() && nmsItem.getTag() != null && nmsItem.getTag().hasKey(key); + } + + private static boolean hasTag(net.minecraft.server.v1_12_R1.ItemStack nmsItem, String key) { + return nmsItem.hasTag() && nmsItem.getTag() != null && nmsItem.getTag().hasKey(key); + } + + public static int getIntTag(ItemStack itemStack, String key) { + net.minecraft.server.v1_12_R1.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + NBTTagCompound tag = nmsItem.getTag(); + return Integer.parseInt(tag.get(key).toString()); + } + + public static Object getTag(ItemStack itemStack, String key) { + net.minecraft.server.v1_12_R1.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + NBTTagCompound tag = nmsItem.getTag(); + return tag.get(key).toString(); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/utils/ParticleColor.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/utils/ParticleColor.java new file mode 100644 index 0000000..6a5aba2 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/utils/ParticleColor.java @@ -0,0 +1,206 @@ +package net.grandtheftmc.gtm.utils; + + import java.util.Arrays; + import java.util.List; + +/** + * Represents a particle color + */ +@SuppressWarnings("WeakerAccess") +public class ParticleColor { + // Standard Minecraft Chat Colors + public static final ParticleColor BLACK = new ParticleColor(0, 0, 0); // 0x000000 + public static final ParticleColor DARK_BLUE = new ParticleColor(0, 0, 170); // 0x0000AA + public static final ParticleColor DARK_GREEN = new ParticleColor(0, 170, 0); // 0x00AA00 + public static final ParticleColor DARK_AQUA = new ParticleColor(0, 170, 170); // 0x00AAAA + public static final ParticleColor DARK_RED = new ParticleColor(170, 0, 0); // 0xAA0000 + public static final ParticleColor DARK_PURPLE = new ParticleColor(170, 0, 170); // 0xAA00AA + public static final ParticleColor GOLD = new ParticleColor(255, 170, 0); // 0xFFAA00 + public static final ParticleColor GRAY = new ParticleColor(170, 170, 170); // 0xAAAAAA + public static final ParticleColor DARK_GRAY = new ParticleColor(85, 85, 85); // 0x555555 + public static final ParticleColor BLUE = new ParticleColor(85, 85, 255); // 0x5555FF + public static final ParticleColor GREEN = new ParticleColor(85, 255, 85); // 0x55FF55 + public static final ParticleColor AQUA = new ParticleColor(85, 255, 255); // 0x55FFFF + public static final ParticleColor RED = new ParticleColor(255, 85, 85); // 0xFF5555 + public static final ParticleColor LIGHT_PURPLE = new ParticleColor(255, 85, 255); // 0xFF55FF + public static final ParticleColor YELLOW = new ParticleColor(255, 255, 85); // 0xFFFF55 + public static final ParticleColor WHITE = new ParticleColor(255, 255, 255); // 0xFFFFFF + + /** + * List of all pre-named colors + */ + public static final List<String> names = Arrays.asList( + "black", + "dark-blue", + "dark-green", + "dark-aqua", + "dark-red", + "dark-purple", + "gold", + "gray", + "dark-gray", + "blue", + "green", + "aqua", + "red", + "light-purple", + "yellow", + "white" + ); + + private final float red; + private final float green; + private final float blue; + + /** + * Creates a new particle color from RGB values 0 - 255 + * + * @param red Red value + * @param green Green value + * @param blue Blue value + */ + public ParticleColor(int red, int green, int blue) { + // values of 0 are changed to 0.0001 for black + // due to the way the particle packet works + this.red = (red == 0 ? 0.0001F : red) / 255; + this.green = (green == 0 ? 0.0001F : green) / 255; + this.blue = (blue == 0 ? 0.0001F : blue) / 255; + } + + /** + * Get the red value + * <p> + * The values 0.0 - 1.0 represent 0 - 255 + * + * @return Red value + */ + public float getRed() { + return red; + } + + /** + * Get the green value + * <p> + * The values 0.0 - 1.0 represent 0 - 255 + * + * @return Green value + */ + public float getGreen() { + return green; + } + + /** + * Get the blue value + * <p> + * The values 0.0 - 1.0 represent 0 - 255 + * + * @return Blue value + */ + public float getBlue() { + return blue; + } + + /** + * Get the hexadecimal color code for this color + * + * @return Hexadecimal color code + */ + public String getHex() { + return String.format("#%02x%02x%02x", (int) (red * 255), (int) (green * 255), (int) (blue * 255)).toUpperCase(); + } + + /** + * Get color by name or hex code + * <p> + * Invalid colors will default to RED + * + * @param color Color name or hex code + * @return ParticleColor + */ + public static ParticleColor getColor(String color) { + ParticleColor actual = getColorExact(color); + return actual == null ? RED : actual; + } + + /** + * Get color by name or hex code + * <p> + * Invalid colors return NULL + * + * @param color Color name or hex code + * @return ParticleColor + */ + public static ParticleColor getColorExact(String color) { + switch (color.toUpperCase()) { + case "BLACK": + return BLACK; + case "DARK_BLUE": + return DARK_BLUE; + case "DARK_GREEN": + return DARK_GREEN; + case "DARK_AQUA": + return DARK_AQUA; + case "DARK_RED": + return DARK_RED; + case "DARK_PURPLE": + return DARK_PURPLE; + case "GOLD": + return GOLD; + case "GRAY": + return GRAY; + case "DARK_GRAY": + return DARK_GRAY; + case "BLUE": + return BLUE; + case "GREEN": + return GREEN; + case "AQUA": + return AQUA; + case "RED": + return RED; + case "LIGHT_PURPLE": + return LIGHT_PURPLE; + case "YELLOW": + return YELLOW; + case "WHITE": + return WHITE; + } + + if (color.startsWith("#")) { + color = color.substring(1); // remove # sign if present + } + + ParticleColor particleColor = null; + + if (color.length() < 6) { + return null; + } + + try { + particleColor = new ParticleColor( + Integer.valueOf(color.substring(0, 2), 16), + Integer.valueOf(color.substring(2, 4), 16), + Integer.valueOf(color.substring(4, 6), 16) + ); + } catch (Exception ignore) { + } + + return particleColor; + } + + /** + * Get a human readable String representation of this color + * + * @return Human readable String representation of color + */ + @Override + public String toString() { + return "ParticleColor[red:[" + + red + + "], green:[" + + green + + "], blue:[" + + blue + + "]]"; + } +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/utils/RandomUtil.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/utils/RandomUtil.java new file mode 100644 index 0000000..25d00cc --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/utils/RandomUtil.java @@ -0,0 +1,7 @@ +package net.grandtheftmc.gtm.utils; + +import java.util.Random; + +public class RandomUtil { + public static final Random RANDOM = new Random(); +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/utils/ReflectionUtil.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/utils/ReflectionUtil.java new file mode 100644 index 0000000..3024cb5 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/utils/ReflectionUtil.java @@ -0,0 +1,210 @@ +package net.grandtheftmc.gtm.utils; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +public final class ReflectionUtil { + + /* + * The server version string to location NMS & OBC classes + */ + private static String versionString; + + /* + * Cache of NMS classes that we've searched for + */ + private static final Map<String, Class<?>> LOADED_NMS_CLASSES = new HashMap<>(); + + /* + * Cache of OBS classes that we've searched for + */ + private static final Map<String, Class<?>> LOADED_OBC_CLASSES = new HashMap<>(); + + /* + * Cache of methods that we've found in particular classes + */ + private static final Map<Class<?>, Map<String, Method>> LOADED_METHODS; + + static { + LOADED_METHODS = new HashMap<>(); + } + + /* + * Cache of fields that we've found in particular classes + */ + private static final Map<Class<?>, Map<String, Field>> LOADED_FIELDS = new HashMap<>(); + + private ReflectionUtil() { + } + + /** + * Gets the version string for NMS & OBC class paths + * + * @return The version string of OBC and NMS packages + */ + public static String getVersion() { + if (versionString == null) { + String name = Bukkit.getServer().getClass().getPackage().getName(); + versionString = name.substring(name.lastIndexOf('.') + 1) + '.'; + } + + return versionString; + } + + /** + * Get an NMS Class + * + * @param nmsClassName The name of the class + * @return The class + */ + public static Class<?> getNMSClass(String nmsClassName) { + if (LOADED_NMS_CLASSES.containsKey(nmsClassName)) { + return LOADED_NMS_CLASSES.get(nmsClassName); + } + + String clazzName = "net.minecraft.server." + getVersion() + nmsClassName; + Class<?> clazz; + + try { + clazz = Class.forName(clazzName); + } catch (Throwable t) { + t.printStackTrace(); + return LOADED_NMS_CLASSES.put(nmsClassName, null); + } + + LOADED_NMS_CLASSES.put(nmsClassName, clazz); + return clazz; + } + + /** + * Get a class from the org.bukkit.craftbukkit package + * + * @param obcClassName the path to the class + * @return the found class at the specified path + */ + public static synchronized Class<?> getOBCClass(String obcClassName) { + if (LOADED_OBC_CLASSES.containsKey(obcClassName)) { + return LOADED_OBC_CLASSES.get(obcClassName); + } + + String clazzName = "org.bukkit.craftbukkit." + getVersion() + obcClassName; + Class<?> clazz; + + try { + clazz = Class.forName(clazzName); + } catch (Throwable t) { + t.printStackTrace(); + LOADED_OBC_CLASSES.put(obcClassName, null); + return null; + } + + LOADED_OBC_CLASSES.put(obcClassName, clazz); + return clazz; + } + + /** + * Get a Bukkit {@link Player} players NMS playerConnection object + * + * @param player The player + * @return The players connection + */ + public static Object getConnection(Player player) { + Method getHandleMethod = getMethod(player.getClass(), "getHandle"); + + if (getHandleMethod != null) { + try { + Object nmsPlayer = getHandleMethod.invoke(player); + Field playerConField = getField(nmsPlayer.getClass(), "playerConnection"); + return playerConField.get(nmsPlayer); + } catch (Exception e) { + e.printStackTrace(); + } + } + + return null; + } + + /** + * Get a classes constructor + * + * @param clazz The constructor class + * @param params The parameters in the constructor + * @return The constructor object + */ + public static Constructor<?> getConstructor(Class<?> clazz, Class<?>... params) { + try { + return clazz.getConstructor(params); + } catch (NoSuchMethodException e) { + return null; + } + } + + /** + * Get a method from a class that has the specific paramaters + * + * @param clazz The class we are searching + * @param methodName The name of the method + * @param params Any parameters that the method has + * @return The method with appropriate paramaters + */ + public static Method getMethod(Class<?> clazz, String methodName, Class<?>... params) { + if (!LOADED_METHODS.containsKey(clazz)) { + LOADED_METHODS.put(clazz, new HashMap<>()); + } + + Map<String, Method> methods = LOADED_METHODS.get(clazz); + + if (methods.containsKey(methodName)) { + return methods.get(methodName); + } + + try { + Method method = clazz.getMethod(methodName, params); + methods.put(methodName, method); + LOADED_METHODS.put(clazz, methods); + return method; + } catch (Exception e) { + e.printStackTrace(); + methods.put(methodName, null); + LOADED_METHODS.put(clazz, methods); + return null; + } + } + + /** + * Get a field with a particular name from a class + * + * @param clazz The class + * @param fieldName The name of the field + * @return The field object + */ + public static Field getField(Class<?> clazz, String fieldName) { + if (!LOADED_FIELDS.containsKey(clazz)) { + LOADED_FIELDS.put(clazz, new HashMap<>()); + } + + Map<String, Field> fields = LOADED_FIELDS.get(clazz); + + if (fields.containsKey(fieldName)) { + return fields.get(fieldName); + } + + try { + Field field = clazz.getField(fieldName); + fields.put(fieldName, field); + LOADED_FIELDS.put(clazz, fields); + return field; + } catch (Exception e) { + e.printStackTrace(); + fields.put(fieldName, null); + LOADED_FIELDS.put(clazz, fields); + return null; + } + } +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/utils/Stats.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/utils/Stats.java new file mode 100644 index 0000000..2dd98f4 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/utils/Stats.java @@ -0,0 +1,111 @@ +package net.grandtheftmc.gtm.utils; + +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.util.TimeFormatter; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.gang.Gang; +import net.grandtheftmc.gtm.gang.GangManager; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.users.JobMode; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.users.HouseUser; +import org.bukkit.ChatColor; +import org.bukkit.Statistic; +import org.bukkit.entity.Player; + +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +public class Stats { + private static Stats stats; + + public static Stats getInstance() { + if (stats == null) stats = new Stats(); + return stats; + } + + public List<String> getStats(Player target) { + List<String> stats = new ArrayList<>(); + GTMUser user = GTM.getUserManager().getLoadedUser(target.getUniqueId()); + HouseUser houseUser = Houses.getUserManager().getLoadedUser(target.getUniqueId()); + stats.add(Utils.f(target.getDisplayName())); + stats.add(this.format("Playtime", this.getHoursPlayed(target))); + stats.add(this.format("Money", '$' + this.numberFormat(user.getMoney()))); + stats.add(this.format("Bank", '$' + this.numberFormat(user.getBank()))); + + Gang gang = GangManager.getInstance().getGangByMember(target.getUniqueId()).orElse(null); + if (gang != null) { + stats.add(this.format("Gang", gang.getName())); + } + + if (user.getJobMode() == JobMode.CRIMINAL && user.getWantedLevel() > 0) { + stats.add(this.format("Wanted Level", ChatColor.WHITE + GTMUtils.getWantedLevelStars(user.getWantedLevel()))); + } + else if (user.getJobMode() != JobMode.CRIMINAL) { + stats.add(this.format("Job", user.getJobMode().getColoredNameBold())); + } + + if (!houseUser.getPremiumHouses().isEmpty()) { + stats.add(this.format("Premium Houses", String.valueOf(houseUser.getPremiumHouses().size()))); + } + + if (!houseUser.getHouses().isEmpty()) { + stats.add(this.format("Houses", String.valueOf(houseUser.getHouses().size()))); + } + + stats.add(this.format("Kills", this.getKillAmount(target))); + stats.add(this.format("Deaths", this.getDeathAmount(target))); + stats.add(this.format("K/D", this.getKDRatio(target))); + return stats; + } + + public String getKDRatio(Player player) { + int kills = player.getStatistic(Statistic.PLAYER_KILLS); + int deaths = player.getStatistic(Statistic.DEATHS); + if (kills == 0 && deaths == 0) { + return "0.0"; + } + double kd = (double) kills / deaths; + return String.valueOf(kd).substring(0, 3); + } + + public String getDeathAmount(Player player) { + int deaths = player.getStatistic(Statistic.DEATHS); + return this.numberFormat(deaths); + } + + public String getKillAmount(Player player) { + int kills = player.getStatistic(Statistic.PLAYER_KILLS); + return this.numberFormat(kills); + } + + public long getHoursPlayedRaw(Player player) { + if (player == null) return 0; + int ticks = player.getStatistic(Statistic.PLAY_ONE_TICK); + long minutes = ticks / 20 / 60; + TimeFormatter tf = Utils.timeFormatter(TimeUnit.MINUTES, minutes); + return tf.getHours(); + } + + public String getHoursPlayed(Player player) { + int ticks = player.getStatistic(Statistic.PLAY_ONE_TICK); + long minutes = ticks / 20 / 60; + TimeFormatter tf = Utils.timeFormatter(TimeUnit.MINUTES, minutes); + return tf.getDays() + "d " + tf.getHours() + "h " + tf.getMinutes() + "m"; + } + + public String numberFormat(int num) { + return NumberFormat.getInstance().format(num); + } + + public String numberFormat(double num) { + return NumberFormat.getInstance().format(num); + } + + public String format(String key, String value) { + return ChatColor.GRAY + key + ": " + ChatColor.GREEN + value; + } +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/utils/WeightedRandomCollection.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/utils/WeightedRandomCollection.java new file mode 100644 index 0000000..6a341b4 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/utils/WeightedRandomCollection.java @@ -0,0 +1,91 @@ +package net.grandtheftmc.gtm.utils; +/* + * Copyright (C) 2013-Current Carter Gale (Ktar5) <buildfresh@gmail.com> + * + * This file is part of gtm. + * + * gtm can not be copied and/or distributed without the express + * permission of the aforementioned owner. + */ + +import com.google.common.collect.Lists; + +import java.util.*; +import java.util.concurrent.ThreadLocalRandom; + +/** + * A utility collection created in order to simplify the selection of a random + * element based on its corresponding relative weight + * <p> + * "Relative weight" means that, for example, each "weight" is a lottery ticket thrown + * into the "total weight". We pick a random ticket, and then return that element. Thus, + * the higher the weight, the higher the chance it will be picked. + * + * @param <E> the type of element to be placed into this collection + */ +public class WeightedRandomCollection<E> { + private final NavigableMap<Double, E> map = new TreeMap<>(); + private E last; + private double total; + + /** + * Add an item to the random collection with the + * specified weight + * + * @param weight the weight (relative to the others) + * @param result the item that corresponds to this weight + */ + public WeightedRandomCollection<E> add(double weight, E result) { + if (weight <= 0) throw new NumberFormatException("Weights cannot be less than zero. Idiot."); + this.total += weight; + this.map.put(this.total, result); + this.last = result; + return this; + } + + public E last() { + return this.last; + } + + /** + * Return a set of all the values + * + * @return a set of all the values + */ + public Set<E> values() { + return new HashSet<>(this.map.values()); + } + + /** + * Returns #amount of unique elements chosen randomly for a lottery-type system + * + * @param amount the max amount of unique elements you want returned + * @return a list containing maximum #amount unique elements, unless there are + * less than that many elements in the collection + */ + public List<E> getUniqueElements(int amount) { + if (this.map.size() <= amount) { + return Lists.newArrayList(this.map.values()); + } + List<E> uniqueElements = new ArrayList<>(amount); + while (uniqueElements.size() < amount && uniqueElements.size() < this.map.size()) { + if (!uniqueElements.contains(this.next())) { + uniqueElements.add(this.last()); + } + } + return uniqueElements; + } + + /** + * Select a random item from the list based on the chance + * Uses a ThreadLocalRandom because Random sucks shit + * ThreadLocalRandom is faster + * + * @return a random element from the collection, selected based on its relative weight + */ + public E next() { + double value = ThreadLocalRandom.current().nextDouble() * this.total; + this.last = this.map.ceilingEntry(value).getValue(); + return this.last; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/warps/SpawnCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/warps/SpawnCommand.java new file mode 100644 index 0000000..40a0b16 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/warps/SpawnCommand.java @@ -0,0 +1,53 @@ +package net.grandtheftmc.gtm.warps; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.users.TaxiTarget; + +public class SpawnCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + WarpManager wm = GTM.getWarpManager(); + Player player = (Player) s; + if (args.length == 0) { + wm.warp(player, Core.getUserManager().getLoadedUser(player.getUniqueId()), + GTM.getUserManager().getLoadedUser(player.getUniqueId()), new TaxiTarget(wm.getSpawn()), 0, -1); + return true; + } + if (!s.hasPermission("warps.admin")) { + s.sendMessage(Lang.NOPERM.s()); + return true; + } + switch (args[0].toLowerCase()) { + case "setspawn": + wm.setSpawn(player.getLocation()); + s.sendMessage(Utils.f("&aYou set the spawn!")); + return true; + case "settutorialspawn": + wm.setTutorialSpawn(player.getLocation()); + s.sendMessage(Utils.f("&aYou set the tutorial spawn!")); + return true; + case "setjail": + wm.setJail(player.getLocation()); + s.sendMessage(Utils.f("&aYou set the jail spawn!")); + return true; + default: + s.sendMessage(Utils.f("&c/spawn")); + s.sendMessage(Utils.f("&c/spawn setspawn")); + s.sendMessage(Utils.f("&c/spawn settutorialspawn")); + return true; + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/warps/TpaCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/warps/TpaCommand.java new file mode 100644 index 0000000..dd7d29e --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/warps/TpaCommand.java @@ -0,0 +1,59 @@ +package net.grandtheftmc.gtm.warps; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.users.GTMUser; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.UUID; + +public class TpaCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Utils.f(Lang.TAXI + "&eYou are not a player!")); + return true; + } + WarpManager wm = GTM.getWarpManager(); + Player player = (Player) s; + UUID uuid = player.getUniqueId(); + User user = Core.getUserManager().getLoadedUser(uuid); + GTMUser gtmUser = GTM.getUserManager().getLoadedUser(uuid); + switch (lbl) { + case "tpa": + if (args.length != 1) { + s.sendMessage(Utils.f("&c/tpa <player>")); + return true; + } + wm.tpa(player, user, gtmUser, Bukkit.getPlayer(args[0])); + return true; + case "tpahere": + if (args.length != 1) { + s.sendMessage(Utils.f("&c/tpahere <player>")); + return true; + } + wm.tpaHere(player, user, gtmUser, Bukkit.getPlayer(args[0])); + return true; + case "tpdeny": + case "tpno": + wm.tpDeny(player, user, gtmUser); + return true; + default: + if (args.length != 0) { + s.sendMessage(Utils.f("&c/" + lbl)); + return true; + } + wm.tpAccept(player, user, gtmUser); + return true; + } + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/warps/Warp.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/warps/Warp.java new file mode 100644 index 0000000..74a6a09 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/warps/Warp.java @@ -0,0 +1,31 @@ +package net.grandtheftmc.gtm.warps; + +import org.bukkit.Location; + +public class Warp { + + private String name; + private Location location; + + public Warp(String name, Location location) { + this.name = name; + this.location = location; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public Location getLocation() { + return this.location; + } + + public void setLocation(Location location) { + this.location = location; + } + +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/warps/WarpCache.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/warps/WarpCache.java new file mode 100644 index 0000000..6b4b066 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/warps/WarpCache.java @@ -0,0 +1,46 @@ +package net.grandtheftmc.gtm.warps; + +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.users.TaxiTarget; + +import java.util.UUID; + +/** + * Created by Luke Bingham on 13/08/2017. + */ +public class WarpCache { + + private final User user; + private final GTMUser gtmUser; + private final TaxiTarget target; + private final int price, delay; + + public WarpCache(User user, GTMUser gtmUser, TaxiTarget target, int price, int delay) { + this.user = user; + this.gtmUser = gtmUser; + this.target = target; + this.price = price; + this.delay = delay; + } + + public User getUser() { + return user; + } + + public GTMUser getGtmUser() { + return gtmUser; + } + + public TaxiTarget getTarget() { + return target; + } + + public int getPrice() { + return price; + } + + public int getDelay() { + return delay; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/warps/WarpCommand.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/warps/WarpCommand.java new file mode 100644 index 0000000..79dbfac --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/warps/WarpCommand.java @@ -0,0 +1,138 @@ +package net.grandtheftmc.gtm.warps; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.users.TaxiTarget; +import org.bukkit.Location; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.List; + +public class WarpCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command cmd, String label, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + WarpManager wm = GTM.getWarpManager(); + Player player = (Player) s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (args.length == 0) { + if (!s.hasPermission("warps.admin")) { + GTM.getWarpManager().warp(player, user, GTM.getUserManager().getLoadedUser(player.getUniqueId()), + new TaxiTarget(GTM.getWarpManager().getRandomWarp()), 0, user.isPremium() ? 1 : 10); + return true; + } + s.sendMessage(Utils.f("&c/warp list")); + s.sendMessage(Utils.f("&c/warp set <name>")); + s.sendMessage(Utils.f("&c/warp delete <name>")); + s.sendMessage(Utils.f("&c/warp <warp>")); + s.sendMessage(Utils.f("&c/warp load")); + s.sendMessage(Utils.f("&c/warp save")); + return true; + } + if (!s.hasPermission("warps.admin")) return true; + switch (args[0].toLowerCase()) { + case "list": + List<Warp> list = wm.getWarps(); + s.sendMessage(Utils.f("&aWarps&7: (&a" + list.size() + "&7)")); + if (list.isEmpty()) { + s.sendMessage(Utils.f("&cNone!")); + return true; + } + String msg = "&a" + list.get(0).getName(); + for (int i = 1; i < wm.getWarps().size(); i++) + msg = msg + "&7, &a" + list.get(i).getName(); + s.sendMessage(Utils.f(msg)); + return true; + case "set": { + if (args.length != 2) { + s.sendMessage(Utils.f("&c/warp set <name>")); + return true; + } + + String warpName = args[1]; + switch (warpName.toLowerCase()) { + case "spawn": + wm.setSpawn(player.getLocation()); + s.sendMessage(Utils.f("&aYou set the spawn!")); + return true; + case "tutorialspawn": + wm.setTutorialSpawn(player.getLocation()); + s.sendMessage(Utils.f("&aYou set the tutorial spawn!")); + return true; + case "jail": + wm.setJail(player.getLocation()); + s.sendMessage(Utils.f("&aYou set the jail spawn!")); + return true; + default: + break; + } + Warp warp = wm.getWarp(warpName); + if (warp != null) { + warp.setLocation(player.getLocation()); + warp.setName(warpName); + s.sendMessage(Utils.f("&7Warp &a" + warpName + "&7 was set to your current location!")); + return true; + } + warp = new Warp(warpName, player.getLocation()); + wm.addWarp(warp); + s.sendMessage(Utils.f("&7A new warp with the name &a" + warpName + "&7 was set to your current location!")); + return true; + } + case "delete": { + if (args.length != 2) { + s.sendMessage(Utils.f("&c/warp delete <name>")); + return true; + } + String warpName = args[1]; + Warp warp = wm.getWarp(warpName); + if (warp == null) { + s.sendMessage(Utils.f("&cThat warp does not exist!")); + return true; + } + Location loc = warp.getLocation(); + wm.removeWarp(warp); + s.sendMessage(Utils.f("&cWarp &a" + warpName + "&c at &a" + loc.getX() + "&c," + loc.getY() + "&c," + + loc.getZ() + "&c was removed.")); + return true; + } + case "load": + GTM.getSettings().setWarpsConfig(Utils.loadConfig("warps")); + GTM.getWarpManager().loadWarps(); + s.sendMessage(Lang.WARP.f("&7Loaded Warps!")); + return true; + case "save": + GTM.getWarpManager().saveWarps(); + s.sendMessage(Lang.WARP.f("&7Saved Warps!")); + return true; + default: + if (args.length != 1) { + s.sendMessage(Utils.f("&c/warp list")); + s.sendMessage(Utils.f("&c/warp set <name>")); + s.sendMessage(Utils.f("&c/warp delete <name>")); + s.sendMessage(Utils.f("&c/warp <warp>")); + s.sendMessage(Utils.f("&c/warp load")); + s.sendMessage(Utils.f("&c/warp save")); + return true; + } + String warpName = args[0]; + Warp warp = wm.getWarp(warpName); + if (warp == null) { + s.sendMessage(Utils.f("&cThat warp does not exist!")); + return true; + } + s.sendMessage(Utils.f("&7Warping to warp &a" + warp.getName() + "&7!")); + player.teleport(warp.getLocation()); + return true; + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/warps/WarpManager.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/warps/WarpManager.java new file mode 100644 index 0000000..263a102 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/warps/WarpManager.java @@ -0,0 +1,601 @@ +package net.grandtheftmc.gtm.warps; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.stream.Collectors; + +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.BlockFace; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.Pref; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.State; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.events.TPEvent; +import net.grandtheftmc.gtm.events.TPEvent.TPType; +import net.grandtheftmc.gtm.users.CheatCode; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.users.JobMode; +import net.grandtheftmc.gtm.users.TaxiTarget; +import net.grandtheftmc.gtm.users.TaxiTarget.TargetType; + +public class WarpManager { + + private Warp tutorialSpawn; + private Warp spawn; + private Warp jail; + private List<Warp> warps = new ArrayList<>(); + private Map<Location, String> warpPads = new HashMap<>(); + private final HashMap<UUID, WarpCache> warpCache = Maps.newHashMap(); + private final HashSet<UUID> toRemove = Sets.newHashSet(); + + public WarpManager() { + this.loadWarps(); + + new BukkitRunnable() { + @Override public void run() { + if(!warpCache.isEmpty()) { + + // for each player + for (UUID uuid : warpCache.keySet()) { + + try{ + Player player = Bukkit.getPlayer(uuid); + if (player == null || !player.isOnline()) { + toRemove.add(uuid); + continue; + } + + WarpCache cache = warpCache.get(uuid); + if (cache == null) { + toRemove.add(uuid); + continue; + } + + int timer = cache.getGtmUser().getTaxiTimer(); + if (cache.getGtmUser().isInCombat()) { + player.sendMessage(Utils.f(Lang.COMBATTAG + "&7You can't call a cab while in combat!")); + cache.getGtmUser().unsetTaxiTarget(); + toRemove.add(uuid); + continue; + } + + if (timer == 15 || timer == 10 || (timer <= 5 && timer > 0)) { + player.sendMessage(Utils.f(Lang.TAXI + "&eYour taxi is arriving in &a" + timer + " &esecond" + + (timer == 1 ? "" : "s") + '!')); + if (timer == 1) { + player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 50, 0)); + player.playSound(player.getLocation(), Sound.BLOCK_LAVA_EXTINGUISH, 0.5F, 1); + } else + player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 4.0F / timer, 2); + } + + if (timer == 0) { + if (!cache.getUser().isRank(UserRank.ELITE)) { + if (!cache.getGtmUser().hasMoney(cache.getGtmUser().getTaxiPrice())) { + if (cache.getGtmUser().hasBank(cache.getGtmUser().getTaxiPrice())) { + cache.getGtmUser().withdrawFromBank(cache.getGtmUser().getTaxiPrice()); + } else { + player.sendMessage(Utils.f(Lang.TAXI + "&eYou can't afford to pay &a$&l" + + cache.getGtmUser().getTaxiPrice() + "&e for the ride! Taxi cancelled.")); + toRemove.add(uuid); + continue; + } + } + } + + TaxiTarget target = cache.getGtmUser().getTaxiTarget(); + if (target == null) { + cache.getGtmUser().unsetTaxiTarget(); + player.sendMessage(Lang.TAXI.f("&eYour target could not be reached!")); + toRemove.add(uuid); + continue; + } + + Location tpLoc = target.getExactLocation(); + TPEvent e = new TPEvent(player, target.getTargetPlayer(), + target.getType() == TargetType.PLAYER ? TPType.TP_COMPLETE : TPType.WARP).call(); + if (e.isCancelled()) { + cache.getGtmUser().unsetTaxiTarget(); + toRemove.add(uuid); + player.sendMessage(Lang.TAXI.f(e.getCancelMessage())); + continue; + } + + if (e.targetLocationIsChanged()) + tpLoc = e.getTargetLocation(); + + // if warping an entity or player + if (target.getType() == TargetType.ENTITY || target.getType() == TargetType.PLAYER){ + + // if they are tping to air + if (tpLoc != null && tpLoc.getBlock().getRelative(BlockFace.DOWN).getType() == Material.AIR){ + tpLoc = tpLoc.getWorld().getHighestBlockAt(tpLoc).getLocation(); + } + } + + if (tpLoc == null) { + cache.getGtmUser().unsetTaxiTarget(); + toRemove.add(uuid); + player.sendMessage(Lang.TAXI.f("&eYour destination could not be reached!")); + continue; + } + + player.teleport(tpLoc); + cache.getGtmUser().setLastTeleport(); + if(cache.getGtmUser().getCheatCodeState(CheatCode.SNEAKY).getState()== State.ON) { + player.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, 20*10, 0)); + } + int price = cache.getGtmUser().getTaxiPrice(); + cache.getGtmUser().unsetTaxiTarget(); + player.sendMessage(Utils.f(Lang.TAXI + "&eThe taxi dropped you off at your destination" + (target.getWarp() != null ? " (" + target.getWarp().getName() + ")" : "."))); + if (price > 0 && !cache.getUser().isRank(UserRank.ELITE)) { + + // If user has money on hand, take it. + if (cache.getGtmUser().hasMoney(price)) + cache.getGtmUser().takeMoney(price); + + // If user has money in bank, take it. + else if (cache.getGtmUser().hasBank(price)) + cache.getGtmUser().takeBank(price); + + GTMUtils.updateBoard(player, Core.getUserManager().getLoadedUser(player.getUniqueId()), cache.getGtmUser()); + Lang.MONEY_TAKE.f(String.valueOf(price)); + } + + toRemove.add(uuid); + continue; + } + + cache.getGtmUser().setTaxiTimer(timer - 1); + } + catch(Exception e){ + // if we get here there's a null pointer somewhere + // stops bug affecting multiple users + e.printStackTrace(); + toRemove.add(uuid); + } + } + } + + if(toRemove.isEmpty()) return; + for(UUID uuid : toRemove) warpCache.remove(uuid); + toRemove.clear(); + } + }.runTaskTimer(GTM.getInstance(), 20L, 20L); + } + + public Warp getTutorialSpawn() { + return this.tutorialSpawn; + } + + public void setTutorialSpawn(Location location) { + this.tutorialSpawn = new Warp("tutorialSpawn", location); + } + + public Warp getSpawn() { + return this.spawn; + } + + public void setSpawn(Location location) { + this.spawn = new Warp("spawn", location); + } + + public Warp getJail() { + return this.jail; + } + + public void setJail(Location location) { + this.jail = new Warp("jail", location); + } + + public List<Warp> getWarps() { + return this.warps; + } + + public Warp getRandomWarp() { + if (this.warps.isEmpty()) + return null; + return this.warps.get(Utils.getRandom().nextInt(this.warps.size())); + } + + public Warp getWarp(String warpName) { + return this.warps.stream().filter(warp -> warp.getName().equalsIgnoreCase(warpName)).findFirst().orElse(null); + } + + public void addWarp(Warp warp) { + this.warps.add(warp); + } + + public void removeWarp(Warp warp) { + this.warps.remove(warp); + } + + public boolean cancelTaxi(Player player, GTMUser gtmUser) { +// if (gtmUser.getTaxiTaskId() == -1) +// return false; +// Bukkit.getScheduler().cancelTask(gtmUser.getTaxiTaskId()); + if(player == null || gtmUser == null) return false; + if(!warpCache.containsKey(player.getUniqueId())) return false; + + gtmUser.unsetTaxiTarget(); + warpCache.remove(player.getUniqueId()); + + return true; + } + + public void warp(Player player, User user, GTMUser gtmUser, TaxiTarget target) { + this.warp(player, user, gtmUser, target, 0, -1, null); + } + + public void warp(Player player, User user, GTMUser gtmUser, TaxiTarget target, int price) { + this.warp(player, user, gtmUser, target, price, -1, null); + } + + public void warp(Player player, User user, GTMUser gtmUser, TaxiTarget target, int price, int delay) { + this.warp(player, user, gtmUser, target, price, delay, null); + } + + public void warp(Player player, User user, GTMUser gtmUser, TaxiTarget target, int price, int delay, String msg) { + GTMUtils.giveGameItems(player); + if (delay < 0) delay = GTMUtils.getWarpDelay(user.getUserRank()); + UUID uuid = player.getUniqueId(); + + if (gtmUser.cancelVehicleTeleport()) + player.sendMessage(Lang.VEHICLES.f("&7You cancelled " + (gtmUser.isSendAway() ? "sending away" : "calling") + " your personal vehicle!")); + + if (this.cancelTaxi(player, gtmUser)) + player.sendMessage(Utils.f(Lang.TAXI + "&eThe previous taxi was cancelled.")); + + if (player.getGameMode() == GameMode.SPECTATOR) { + player.sendMessage(Lang.TAXI.f("&7You can't teleport to players while you're dead!")); + return; + } + + if (gtmUser.isInCombat()) { + player.sendMessage(Utils.f(Lang.COMBATTAG + "&7You can't call a cab while in combat!")); + return; + } + + if (user.isInTutorial()) return; + if (gtmUser.isArrested()) { + player.sendMessage(Lang.JAIL.f("&7You can't teleport in jail!")); + return; + } + + if (price > 0 && !user.isRank(UserRank.ELITE)) { + if (!gtmUser.hasMoney(price) && !gtmUser.hasBank(price)) { + player.sendMessage(Utils.f(Lang.TAXI + "&eYou can't afford to pay &a$&l" + + price + "&e for the ride! Taxi cancelled.")); + } + } + + if (target == null || target.getExactLocation() == null) { + player.sendMessage(Utils.f(Lang.TAXI + "&eThat location does not exist!")); + return; + } + + player.sendMessage(Utils.f(Lang.TAXI + "&eYou called a taxi!")); + gtmUser.setTaxiTimer(delay); + gtmUser.setTaxiTarget(target); + gtmUser.setTaxiPrice(price); + + this.warpCache.put(uuid, new WarpCache(user, gtmUser, target, price, delay)); + } + + public void tpa(Player player, User user, GTMUser gtmUser, Player target) { + GTMUtils.giveGameItems(player); + if (target == null) { + player.sendMessage(Utils.f(Lang.TAXI + "&eThat player is not online!")); + return; + } + GTMUser targetGTMUser = GTM.getUserManager().getLoadedUser(target.getUniqueId()); + if (!user.isSpecial()) { + player.sendMessage(Utils.f(Lang.TAXI + + "&eYou don't have access to teleport to other players! Buy &6&lVIP&e to unlock it!")); + return; + } + if (player.getGameMode() == GameMode.SPECTATOR) { + player.sendMessage(Lang.TAXI.f("&7You can't teleport to players while you're dead!")); + return; + } + if (gtmUser.isInCombat()) { + player.sendMessage(Utils.f(Lang.COMBATTAG + "&7You can't call a cab while in combat!")); + return; + } + if (targetGTMUser.isInCombat()) { + player.sendMessage(Utils.f(Lang.COMBATTAG + target.getDisplayName() + "&7 is in combat!")); + return; + } + if (user.isInTutorial()) return; + if (gtmUser.isArrested()) { + player.sendMessage(Lang.JAIL.f("&7You can't teleport in jail!")); + return; + } + UUID uuid = player.getUniqueId(); + if (gtmUser.cancelVehicleTeleport()) + player.sendMessage(Lang.VEHICLES.f("&7You cancelled " + (gtmUser.isSendAway() ? "sending away" : "calling") + " your personal vehicle!")); + if (this.cancelTaxi(player, gtmUser)) + player.sendMessage(Utils.f(Lang.TAXI + "&eThe previous taxi was cancelled.")); + + User targetUser = Core.getUserManager().getLoadedUser(target.getUniqueId()); + if (!targetUser.getPref(Pref.TP_REQUESTS)) { + player.sendMessage(Utils.f(Lang.TAXI + "&eThat player has disabled teleport requests!")); + return; + } + if (targetUser.isInTutorial()) { + player.sendMessage(Lang.TUTORIALS.f("&7That player is in a tutorial!")); + return; + } + TPEvent e = new TPEvent(player, target, TPType.TPA_REQ).call(); + if (e.isCancelled()) { + gtmUser.unsetTpaRequests(); + player.sendMessage(Lang.TAXI.f(e.getCancelMessage())); + return; + } + player.sendMessage( + Utils.f(Lang.TAXI + "&eYou requested to teleport to " + targetUser.getColoredName(target) + "&e!")); + target.sendMessage(Utils.f(Lang.TAXI + user.getColoredName(player) + + "&e requested to teleport to you. Use &a\'/tpaccept\'&e to accept.")); + GTMUser targetGtmUser = GTM.getUserManager().getLoadedUser(target.getUniqueId()); + gtmUser.setTpaRequestSentUUID(target.getUniqueId()); + gtmUser.setTpaHere(false); + targetGtmUser.setTpaRequestUUID(uuid); + } + + public void tpaHere(Player player, User user, GTMUser gtmUser, Player target) { + GTMUtils.giveGameItems(player); + if (target == null) { + player.sendMessage(Utils.f(Lang.TAXI + "&eThat player is not online!")); + return; + } + GTMUser targetGTMUser = GTM.getUserManager().getLoadedUser(target.getUniqueId()); + if (!user.getUserRank().isHigherThan(UserRank.PREMIUM)) { + player.sendMessage(Utils.f(Lang.TAXI + + "&eYou don't have access to teleport other players to yourself! Buy &b&lELITE&e to unlock it!")); + return; + } + if (player.getGameMode() == GameMode.SPECTATOR) { + player.sendMessage(Lang.TAXI.f("&7You can't teleport players to you while you're dead!")); + return; + } + if (gtmUser.isArrested()) { + player.sendMessage(Lang.JAIL.f("&7You can't teleport players to yourself in jail!")); + return; + } + if (gtmUser.isInCombat()) { + player.sendMessage(Utils.f(Lang.COMBATTAG + "&7You can't request teleportation while in combat!")); + return; + } + if (targetGTMUser.isInCombat()) { + player.sendMessage(Utils.f(Lang.COMBATTAG + target.getDisplayName() + "&7 is in combat!")); + return; + } + if (user.isInTutorial()) return; + if (target.getGameMode() == GameMode.SPECTATOR) { + player.sendMessage(Lang.TAXI.f("&7You can't teleport dead players to you!")); + return; + } + UUID uuid = player.getUniqueId(); + if (gtmUser.cancelVehicleTeleport()) + player.sendMessage(Lang.VEHICLES.f("&7You cancelled " + (gtmUser.isSendAway() ? "sending away" : "calling") + " your personal vehicle!")); + if (this.cancelTaxi(player, gtmUser)) + player.sendMessage(Utils.f(Lang.TAXI + "&eThe previous taxi was cancelled.")); + User targetUser = Core.getUserManager().getLoadedUser(target.getUniqueId()); + if (!targetUser.getPref(Pref.TP_REQUESTS)) { + player.sendMessage(Utils.f(Lang.TAXI + "&eThat player has disabled teleport requests!")); + return; + } + if (targetUser.isInTutorial()) { + player.sendMessage(Lang.TUTORIALS.f("&7That player is in a tutorial!")); + return; + } + TPEvent e = new TPEvent(player, target, TPType.TPAHERE_REQ).call(); + if (e.isCancelled()) { + gtmUser.unsetTpaRequests(); + player.sendMessage(Lang.TAXI.f(e.getCancelMessage())); + return; + } + player.sendMessage( + Utils.f(Lang.TAXI + "&eYou requested " + targetUser.getColoredName(target) + "&e to teleport to you!")); + target.sendMessage(Utils.f(Lang.TAXI + user.getColoredName(player) + + "&e requested you to teleport to them. Use &a\'/tpaccept\'&e to accept.")); + GTMUser targetGtmUser = GTM.getUserManager().getLoadedUser(target.getUniqueId()); + gtmUser.setTpaRequestSentUUID(target.getUniqueId()); + gtmUser.setTpaHere(true); + targetGtmUser.setTpaRequestUUID(uuid); + } + + public void tpDeny(Player player, User user, GTMUser gtmUser) { + GTMUtils.giveGameItems(player); + if (!gtmUser.hasTpaRequest()) { + player.sendMessage(Utils.f(Lang.TAXI + "&eNobody has requested to teleport to you!")); + return; + } + if (user.isInTutorial()) return; + Player target = Bukkit.getPlayer(gtmUser.getTpaRequestUUID()); + if (target == null) { + player.sendMessage(Utils.f(Lang.TAXI + "&eNobody has requested to teleport to you!")); + return; + } + User targetUser = Core.getUserManager().getLoadedUser(target.getUniqueId()); + GTMUser targetGtmUser = GTM.getUserManager().getLoadedUser(target.getUniqueId()); + if (!targetUser.isInTutorial()) + target.sendMessage(Lang.TAXI.f("&a" + user.getColoredName(player) + "&e denied your request!")); + player.sendMessage(Lang.TAXI.f("&e You denied &a" + targetUser.getColoredName(target) + "&e's request!")); + targetGtmUser.unsetTpaRequests(); + gtmUser.unsetTpaRequests(); + } + + public void tpAccept(Player target, User targetUser, GTMUser targetGtmUser) { + GTMUtils.giveGameItems(target); + if (!targetGtmUser.hasTpaRequest()) { + target.sendMessage(Utils.f(Lang.TAXI + "&eNobody has requested to teleport to you!")); + return; + } + if (target.getGameMode() == GameMode.SPECTATOR) { + target.sendMessage(Lang.VEHICLES.f("&7You can't teleport while you're dead!")); + return; + } + if (targetGtmUser.isArrested()) { + target.sendMessage(Lang.JAIL.f("&7You can't teleport in jail!")); + return; + } + if (targetUser.isInTutorial()) return; + UUID uuid = targetGtmUser.getTpaRequestUUID(); + Player player = Bukkit.getPlayer(uuid); + if (player == null) { + target.sendMessage(Utils.f(Lang.TAXI + "&eNobody has requested to teleport to you!")); + return; + } + GTMUser gtmUser = GTM.getUserManager().getLoadedUser(uuid); + if (gtmUser.isInCombat()) { + player.sendMessage(Utils.f(Lang.COMBATTAG + "&7Teleport cancelled due to combat tag!")); + return; + } + if (targetGtmUser.isInCombat()) { + player.sendMessage(Utils.f(Lang.COMBATTAG + "&7Teleport cancelled due to combat tag!")); + return; + } + if (player.getGameMode() == GameMode.SPECTATOR) { + target.sendMessage(Lang.VEHICLES.f("&7You can't teleport to a dead player!")); + return; + } + if (gtmUser.isArrested()) { + target.sendMessage(Lang.JAIL.f("&7You can't teleport in jail!")); + return; + } + User user = Core.getUserManager().getLoadedUser(uuid); + if (user.isInTutorial()) { + target.sendMessage(Lang.TUTORIALS.f("&7That player is in a tutorial!")); + return; + } + if (gtmUser.isTpaHere()) { + int delay = GTMUtils.getWarpDelay(targetUser.getUserRank()); + TPEvent e = new TPEvent(target, player, TPType.TPAHERE_ACCEPT).call(); + if (e.isCancelled()) { + targetGtmUser.unsetTpaRequests(); + gtmUser.unsetTpaRequests(); + target.sendMessage(Lang.TAXI.f(e.getCancelMessage())); + return; + } + target.sendMessage(Utils.f(Lang.TAXI + "&eYou accepted &a" + user.getColoredName(player) + + "&e's request to teleport to them!")); + player.sendMessage(Utils.f(Lang.TAXI + "&a" + targetUser.getColoredName(target) + "&e accepted your request to teleport to them! Their cab will arrive in &a" + delay + "&e second" + (delay == 1 ? "" : "s"))); + targetGtmUser.unsetTpaRequests(); + gtmUser.unsetTpaRequests(); + this.warp(target, targetUser, targetGtmUser, new TaxiTarget(player), 0, delay); + return; + } + int delay = GTMUtils.getWarpDelay(user.getUserRank()); + TPEvent e = new TPEvent(player, target, TPType.TPA_ACCEPT).call(); + if (e.isCancelled()) { + targetGtmUser.unsetTpaRequests(); + gtmUser.unsetTpaRequests(); + player.sendMessage(Lang.TAXI.f(e.getCancelMessage())); + return; + } + target.sendMessage(Utils.f(Lang.TAXI + "&eYou accepted &a" + user.getColoredName(player) + + "&e's teleport request. Their cab will arrive in &a" + delay + "&e second" + (delay == 1 ? "" : "s") + + '!')); + player.sendMessage( + Utils.f(Lang.TAXI + "&a" + targetUser.getColoredName(target) + "&e accepted your teleport request!")); + targetGtmUser.unsetTpaRequests(); + gtmUser.unsetTpaRequests(); + this.warp(player, user, gtmUser, new TaxiTarget(target), 0, delay); + } + + public void backupAccept(Player player, GTMUser gtmUser, Player target, GTMUser targetGtmUser) { + User targetUser = Core.getUserManager().getLoadedUser(target.getUniqueId()); + GTMUtils.giveGameItems(target); + if (targetUser.isInTutorial()) return; + if (gtmUser.getJobMode() != JobMode.COP) { + player.sendMessage(Lang.COP_MODE.f("&7You must be in &3&lCOP Mode&7 to request backup!")); + return; + } + if (player.getGameMode() == GameMode.SPECTATOR) { + player.sendMessage(Lang.VEHICLES.f("&7You can't teleport while you're dead!")); + return; + } + if (target.getGameMode() == GameMode.SPECTATOR || !targetGtmUser.hasRequestedBackup()) { + player.sendMessage(Lang.COP_MODE.f("&7That player has not requested backup!")); + return; + } + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (user.isInTutorial()) + return; + + int delay = GTMUtils.getWarpDelay(user.getUserRank()); + TPEvent e = new TPEvent(player, target, TPType.BACKUP).call(); + if (e.isCancelled()) { + player.sendMessage(Lang.COP_MODE.f(e.getCancelMessage())); + return; + } + target.sendMessage(Lang.COP_MODE.f("&7" + user.getColoredName(player) + "&7 has accepted your backup request. They will arrive in &a" + delay + "&e second" + (delay == 1 ? "" : "s") + + '!')); + player.sendMessage( + Utils.f(Lang.COP_MODE.f("&7You are providing backup to " + targetUser.getColoredName(target) + "&7!"))); + this.warp(player, user, gtmUser, new TaxiTarget(target), 0, delay); + } + + + public Warp getWarpFromPad(Location blockLocation) { + String name = this.warpPads.get(blockLocation); + if (name == null) + return null; + if ("random".equalsIgnoreCase(name)) + return this.warps.get(Utils.getRandom().nextInt(this.warps.size())); + return this.getWarp(name); + } + + public void loadWarps() { + YamlConfiguration c = GTM.getSettings().getWarpsConfig(); + this.tutorialSpawn = new Warp("spawn", Utils.teleportLocationFromString(c.getString("tutorialSpawn"))); + this.spawn = new Warp("tutorialSpawn", Utils.teleportLocationFromString(c.getString("spawn"))); + this.jail = new Warp("jail", Utils.teleportLocationFromString(c.getString("jail"))); + this.warps = new ArrayList<>(); + if (c.get("warps") != null) + this.warps.addAll(c.getConfigurationSection("warps").getKeys(false).stream().map(s -> new Warp(s, Utils.teleportLocationFromString(c.getString("warps." + s)))).collect(Collectors.toList())); + this.warpPads = new HashMap<>(); + if (c.get("warpPads") != null) + for (String loc : c.getConfigurationSection("warpPads").getKeys(false)) + this.warpPads.put(Utils.blockLocationFromString(loc), c.getString("warpPads." + loc)); + + } + + public void saveWarps() { + YamlConfiguration c = GTM.getSettings().getWarpsConfig(); + c.set("spawn", Utils.teleportLocationToString(this.spawn.getLocation())); + c.set("tutorialSpawn", Utils.teleportLocationToString(this.tutorialSpawn.getLocation())); + c.set("jail", Utils.teleportLocationToString(this.jail.getLocation())); + c.set("warps", null); + for (Warp warp : this.warps) + c.set("warps." + warp.getName(), Utils.teleportLocationToString(warp.getLocation())); + c.set("warpPads", null); + for (Map.Entry<Location, String> locationStringEntry : this.warpPads.entrySet()) + c.set(Utils.blockLocationToString(locationStringEntry.getKey()), this.warpPads.get(locationStringEntry.getKey())); + Utils.saveConfig(c, "warps"); + } + +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/wastedbarrels/BarrelListener.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/wastedbarrels/BarrelListener.java new file mode 100644 index 0000000..04ca888 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/wastedbarrels/BarrelListener.java @@ -0,0 +1,41 @@ +package net.grandtheftmc.gtm.wastedbarrels; + +import net.grandtheftmc.gtm.GTM; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.player.PlayerMoveEvent; + +public class BarrelListener implements Listener { + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void playerMoveEvent(PlayerMoveEvent event) { + if (GTM.getBarrelManager().getUnloadedBarrels().isEmpty()) return; + GTM.getBarrelManager().getUnloadedBarrels().forEach(location -> { + if (event.getTo().getWorld() != location.getWorld()) return; + if (location.distance(event.getTo()) < 10) { + GTM.getBarrelManager().spawnWastedBarrel(location); + GTM.getBarrelManager().getUnloadedBarrels().remove(location); + } + }); + } + + @EventHandler + public void entityDamageEntityEvent(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) return; + if (!(event.getEntity() instanceof ArmorStand)) return; + Player player = (Player) event.getDamager(); + ArmorStand armorStand = (ArmorStand) event.getEntity(); + if(armorStand.getHelmet().getType() != Material.TNT) return; + WastedBarrel wastedBarrel; + wastedBarrel = armorStand.hasMetadata("WastedBarrel") ? (WastedBarrel) armorStand.getMetadata("WastedBarrel").get(0).value() : new WastedBarrel(armorStand); + wastedBarrel.onDamage(event.getDamage(), player); + player.getWorld().playSound(player.getLocation(), Sound.BLOCK_METAL_HIT, 5.0F, 5.0F); + event.setCancelled(true); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/wastedbarrels/BarrelManager.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/wastedbarrels/BarrelManager.java new file mode 100644 index 0000000..d2eba56 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/wastedbarrels/BarrelManager.java @@ -0,0 +1,95 @@ +package net.grandtheftmc.gtm.wastedbarrels; + +import com.j0ach1mmall3.jlib.methods.ReflectionAPI; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.EntityType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Optional; + +public class BarrelManager { + private Collection<WastedBarrel> wastedBarrels; + private Collection<Location> unloadedBarrels; + + public BarrelManager() { + if (this.wastedBarrels == null) this.wastedBarrels = new ArrayList<>(); + if (this.unloadedBarrels == null) this.unloadedBarrels = new ArrayList<>(); + new BukkitRunnable() { + @Override + public void run() { + BarrelManager.this.loadBarrels(); + } + }.runTaskLater(GTM.getInstance(), 100); + } + + public Collection<WastedBarrel> getWastedBarrels() { + return this.wastedBarrels; + } + + public Collection<Location> getUnloadedBarrels() { + return this.unloadedBarrels; + } + + public WastedBarrel spawnWastedBarrel(Location location) { + ArmorStand armorStand = location.getWorld().spawn(location, ArmorStand.class); + armorStand.setHelmet(new ItemStack(Material.TNT)); + armorStand.setBasePlate(false); + armorStand.setSmall(false); + armorStand.setArms(false); + armorStand.setAI(false); + armorStand.setCanPickupItems(false); + armorStand.setGravity(false); + armorStand.setMaxHealth(50.0D); + armorStand.setHealth(50.0D); + armorStand.setVisible(false); + armorStand.setSilent(true); + armorStand.setRemoveWhenFarAway(false); + armorStand.setHelmet(new ItemStack(Material.TNT)); + + try { + Object handle = ReflectionAPI.getHandle((Object) armorStand); + handle.getClass().getMethod("setSize", float.class, float.class).invoke(handle, 1.00F, 1.50F); + } catch (Exception e) { + e.printStackTrace(); + } + + WastedBarrel wastedBarrel = new WastedBarrel(armorStand); + armorStand.setMetadata("WastedBarrel", new FixedMetadataValue(GTM.getInstance(), wastedBarrel)); + return wastedBarrel; + } + + public void loadBarrels() { + for (String string : GTM.getSettings().getBarrelsConfig().getStringList("barrels")) { + Optional<Location> loc = GTMUtils.deserializeLocation(string); + if (!loc.isPresent()) continue; + Optional<ArmorStand> barrel = Arrays.stream(loc.get().getChunk().getEntities()).filter(entity -> !(entity.getLocation().distance(loc.get()) > 2)).filter(entity -> entity.getType() == EntityType.ARMOR_STAND).map(entity -> (ArmorStand) entity).filter(armorStand -> armorStand.getHelmet().getType() == Material.TNT).findFirst().map(Optional::of).orElse(Optional.empty()); + if (barrel.isPresent()) { + new WastedBarrel(barrel.get()); + } else { + this.unloadedBarrels.add(loc.get()); + } + } + } + + public void unloadBarrels() { + YamlConfiguration barrelsConfig = GTM.getSettings().getBarrelsConfig(); + Collection<String> barrelLocations = new ArrayList<>(); + this.wastedBarrels.forEach(wastedBarrel -> { + barrelLocations.add(GTMUtils.serializeLocation(wastedBarrel.getArmorStand().getLocation())); + wastedBarrel.respawn(); + }); + barrelsConfig.set("barrels", barrelLocations); + Utils.saveConfig(barrelsConfig, "barrels"); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/wastedbarrels/WastedBarrel.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/wastedbarrels/WastedBarrel.java new file mode 100644 index 0000000..c2628fa --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/wastedbarrels/WastedBarrel.java @@ -0,0 +1,133 @@ +package net.grandtheftmc.gtm.wastedbarrels; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.stream.Collectors; + +import org.bukkit.Bukkit; +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.LivingEntity; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitScheduler; + +import com.j0ach1mmall3.wastedguns.MathUtil; +import com.j0ach1mmall3.wastedguns.api.events.explosives.ExplosionDamageEntityEvent; + +import net.grandtheftmc.gtm.GTM; + +public class WastedBarrel { + private final ArmorStand armorStand; + private final Collection<Integer> tasks; + + public WastedBarrel(ArmorStand armorStand) { + this.armorStand = armorStand; + this.tasks = new ArrayList<>(); + GTM.getBarrelManager().getWastedBarrels().add(this); + if (!armorStand.hasMetadata("WastedBarrel")) { + this.armorStand.setMetadata("WastedBarrel", new FixedMetadataValue(GTM.getInstance(), this)); + } + } + + public ArmorStand getArmorStand() { + return this.armorStand; + } + + public Collection<Integer> getTasks() { + return this.tasks; + } + + public void onDamage(double amount, LivingEntity shooter) { + double afterDamage = this.armorStand.getHealth() - amount; + if (afterDamage < 1) { + this.onDestroy(shooter); + } else if (afterDamage > 0 && afterDamage <= 15) { + this.armorStand.setHealth(afterDamage); + this.damageEffects(2, shooter); + } else if (afterDamage > 15 && afterDamage <= 25) { + this.armorStand.setHealth(afterDamage); + this.damageEffects(3, shooter); + } else if (afterDamage > 25 && afterDamage <= 50) { + this.armorStand.setHealth(afterDamage); + this.armorStand.getWorld().playSound(this.armorStand.getLocation(), Sound.ENTITY_SHULKER_BULLET_HIT, 3.0F, 3.0F); + } else { + this.armorStand.setHealth(50.0D); + } + } + + public void onDestroy(LivingEntity shooter) { + this.damageEffects(1, shooter); + this.armorStand.setHelmet(null); + this.armorStand.setFireTicks(0); + new BukkitRunnable() { + @Override + public void run() { + WastedBarrel.this.respawn(); + } + }.runTaskLater(GTM.getInstance(), 6000); + this.tasks.forEach(task -> GTM.getInstance().getServer().getScheduler().cancelTask(task)); + } + + public void respawn() { + this.armorStand.setHelmet(new ItemStack(Material.TNT)); + this.armorStand.setMaxHealth(50.0D); + this.armorStand.setHealth(50.0D); + } + + public void damageEffects(int tier, LivingEntity shooter) { + BukkitScheduler scheduler = GTM.getInstance().getServer().getScheduler(); + if (tier == 1) { + this.armorStand.getWorld().spigot().playEffect(this.armorStand.getLocation(), Effect.EXPLOSION_LARGE, 0, 0, 0, 0, 0, 0.01F, 50, 50); + this.armorStand.getWorld().playSound(this.armorStand.getLocation(), Sound.ENTITY_GENERIC_EXPLODE, 10.0F, 10.0F); + + // get nearby entities + Collection<LivingEntity> eventVictims = MathUtil.getNearbyEntities(this.armorStand, 7).collect(Collectors.toList()); + + // call explosion evnet + ExplosionDamageEntityEvent damageEntityEvent = new ExplosionDamageEntityEvent(shooter, null, eventVictims, null); + Bukkit.getServer().getPluginManager().callEvent(damageEntityEvent); + if (damageEntityEvent.isCancelled()) return; + + // for each entity + Collection<LivingEntity> victims = damageEntityEvent.getVictims(); + if (!victims.isEmpty()) { + victims.forEach(e -> { + + // damage them + double damage = 40.0 / this.armorStand.getLocation().distance(e.getLocation()); + e.damage(damage); + if (!(e instanceof ArmorStand)) e.setVelocity(e.getLocation().getDirection().multiply(-2.5F)); + }); + } + for (int x = 0; x < 2; x++) { + for (int z = 0; z < 2; z++) { + this.armorStand.getWorld().spigot().playEffect(this.armorStand.getLocation().add(x, 0, z), + Effect.FLAME, 0, 0, 0.5F, 0.5F, 0.5F, 0.001F, 50, 50); + this.armorStand.getWorld().spigot().playEffect(this.armorStand.getLocation().add(x, 0, z), + Effect.MOBSPAWNER_FLAMES, 0, 0, 0.5F, 0.5F, 0.5F, 0.001F, 50, 50); + this.armorStand.getWorld().spigot().playEffect(this.armorStand.getLocation().add(x, 0, z), + Effect.LARGE_SMOKE, 0, 0, 0.5F, 0.5F, 0.5F, 0.001F, 50, 50); + } + } + } else if (tier == 2) { + this.tasks.add(scheduler.scheduleSyncRepeatingTask(GTM.getInstance(), () -> { + if (this.armorStand.getHelmet().getType() != Material.TNT || this.armorStand.isDead()) + this.tasks.forEach(scheduler::cancelTask); + this.armorStand.getWorld().spigot().playEffect(this.armorStand.getLocation(), Effect.SMALL_SMOKE, 0, 0, 0.5F, 0.5F, 0.5F, 0.001F, 50, 50); + this.armorStand.getWorld().spigot().playEffect(this.armorStand.getLocation(), Effect.FLAME, 0, 0, 0.5F, 0.5F, 0.5F, 0.001F, 30, 30); + this.armorStand.getWorld().spigot().playEffect(this.armorStand.getLocation(), Effect.LARGE_SMOKE, 0, 0, 0.5F, 0.5F, 0.5F, 0.001F, 30, 50); + }, 0L, 20L)); + } else if (tier == 3) { + this.tasks.add(scheduler.scheduleSyncRepeatingTask(GTM.getInstance(), () -> { + if (this.armorStand.getHelmet().getType() != Material.TNT || this.armorStand.isDead()) + this.tasks.forEach(scheduler::cancelTask); + this.armorStand.getWorld().spigot().playEffect(this.armorStand.getLocation(), Effect.FLAME, 0, 0, 0.5F, 0.5F, 0.5F, 0.001F, 3, 10); + this.armorStand.getWorld().spigot().playEffect(this.armorStand.getLocation(), Effect.LARGE_SMOKE, 0, 0, 0.5F, 0.5F, 0.5F, 0.001F, 5, 40); + }, 0L, 20L)); + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/README.MD b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/README.MD new file mode 100644 index 0000000..c1e78cb --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/README.MD @@ -0,0 +1,61 @@ +# Weapons: + +### --Ranged: +<p><b>Pistols:</b><br> +Pistol 1<br> +StunGun 11<br> +CombatPistol 21<br> +HeavyPistol 31<br> +MarksmanPistol 41<br><br> + +<b>SMG:</b><br> +MicroSMG 51<br> +SMG 61<br> +AssaultSMG 71<br> +CombatPDW 81<br> +GusenbergSweeper 91<br><br> + +<b>Shotgun:</b><br> +SawedoffShotgun 101<br> +PumpShotgun 111<br> +Musket 121<br> +AssaultShotgun 131<br> +HeavyShotgun 141<br><br> + +<b>Assault:</b><br> +AssaultRifle 151<br> +CarbineRifle 161<br> +BullpupRifle 171<br> +AdvancedRifle 181<br> +SpecialCarbine 191<br><br> + +<b>LMG:</b><br> +MG 201<br> +CombatMG 211<br><br> + +<b>Sniper:</b><br> +SniperRifle 221<br> +HeavySniper 231<br><br> + +<b>Special:</b><br> +Minigun 241<br><br> + +<b>Launcher:</b><br> +RPG 251<br> +HomingLauncher 261<br> +GrenadeLauncher 271<br></p><br><br> + + +### --Melee: +<p>BaseballBat 281<br> +Chainsaw 291<br> +Knife 301<br> +NightStick 311<br> +Rake 321<br></p><br><br> + +### --Throwable: +<p>Grenade 331<br> +MolotovCocktail 341<br> +ProximityMine 351<br> +StickyBomb 361<br> +TearGas 371<br></p> diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/WeaponRegistry.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/WeaponRegistry.java new file mode 100644 index 0000000..36079c1 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/WeaponRegistry.java @@ -0,0 +1,419 @@ +package net.grandtheftmc.gtm.weapon; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.player.PlayerArmorStandManipulateEvent; +import org.bukkit.event.player.PlayerChangedWorldEvent; +import org.bukkit.event.player.PlayerInteractAtEntityEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.java.JavaPlugin; + +import com.gmail.filoghost.holographicdisplays.api.Hologram; +import com.gmail.filoghost.holographicdisplays.api.HologramsAPI; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.Component; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.items.GameItem; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.weapon.explosive.Grenade; +import net.grandtheftmc.gtm.weapon.explosive.MolotovCocktail; +import net.grandtheftmc.gtm.weapon.explosive.ProximityMine; +import net.grandtheftmc.gtm.weapon.explosive.StickyBomb; +import net.grandtheftmc.gtm.weapon.explosive.TearGas; +import net.grandtheftmc.gtm.weapon.melee.BaseballBat; +import net.grandtheftmc.gtm.weapon.melee.Chainsaw; +import net.grandtheftmc.gtm.weapon.melee.Dildo; +import net.grandtheftmc.gtm.weapon.melee.Katana; +import net.grandtheftmc.gtm.weapon.melee.Knife; +import net.grandtheftmc.gtm.weapon.melee.NightStick; +import net.grandtheftmc.gtm.weapon.melee.Rake; +import net.grandtheftmc.gtm.weapon.ranged.assault.AdvancedRifle; +import net.grandtheftmc.gtm.weapon.ranged.assault.AssaultRifle; +import net.grandtheftmc.gtm.weapon.ranged.assault.BullpupRifle; +import net.grandtheftmc.gtm.weapon.ranged.assault.CarbineRifle; +import net.grandtheftmc.gtm.weapon.ranged.assault.SpecialCarbine; +import net.grandtheftmc.gtm.weapon.ranged.launcher.GrenadeLauncher; +import net.grandtheftmc.gtm.weapon.ranged.launcher.HomingLauncher; +import net.grandtheftmc.gtm.weapon.ranged.launcher.NetLauncher; +import net.grandtheftmc.gtm.weapon.ranged.launcher.RPG; +import net.grandtheftmc.gtm.weapon.ranged.lmg.CombatMG; +import net.grandtheftmc.gtm.weapon.ranged.lmg.MG; +import net.grandtheftmc.gtm.weapon.ranged.pistol.CombatPistol; +import net.grandtheftmc.gtm.weapon.ranged.pistol.HeavyPistol; +import net.grandtheftmc.gtm.weapon.ranged.pistol.MarksmanPistol; +import net.grandtheftmc.gtm.weapon.ranged.pistol.Pistol; +import net.grandtheftmc.gtm.weapon.ranged.pistol.StunGun; +import net.grandtheftmc.gtm.weapon.ranged.shotgun.AssaultShotgun; +import net.grandtheftmc.gtm.weapon.ranged.shotgun.HeavyShotgun; +import net.grandtheftmc.gtm.weapon.ranged.shotgun.Musket; +import net.grandtheftmc.gtm.weapon.ranged.shotgun.PumpShotgun; +import net.grandtheftmc.gtm.weapon.ranged.shotgun.SawedoffShotgun; +import net.grandtheftmc.gtm.weapon.ranged.smg.AssaultSMG; +import net.grandtheftmc.gtm.weapon.ranged.smg.CombatPDW; +import net.grandtheftmc.gtm.weapon.ranged.smg.GusenbergSweeper; +import net.grandtheftmc.gtm.weapon.ranged.smg.MicroSMG; +import net.grandtheftmc.gtm.weapon.ranged.smg.SMG; +import net.grandtheftmc.gtm.weapon.ranged.sniper.HeavySniper; +import net.grandtheftmc.gtm.weapon.ranged.sniper.SniperRifle; +import net.grandtheftmc.gtm.weapon.ranged.special.Clausinator; +import net.grandtheftmc.gtm.weapon.ranged.special.Flamethrower; +import net.grandtheftmc.gtm.weapon.ranged.special.GoldMinigun; +import net.grandtheftmc.gtm.weapon.ranged.special.Minigun; +import net.grandtheftmc.guns.WeaponManager; +import net.grandtheftmc.guns.weapon.Weapon; +import net.grandtheftmc.guns.weapon.WeaponSkin; + +/** + * Created by Luke Bingham on 25/07/2017. + */ +public class WeaponRegistry implements Component<WeaponRegistry, GTM> { + + private static final Set<Material> EMPTY_SET = Sets.newHashSet(); + + private final ConcurrentHashMap<UUID, PlayerStateCache> playerCache = new ConcurrentHashMap<>(); + private final ConcurrentHashMap<String, Hologram> weaponHolograms = new ConcurrentHashMap<>(); + private final Location minLoc, maxLoc; + + public WeaponRegistry(JavaPlugin plugin, WeaponManager weaponManager) { + List<Weapon<?>> list = new ArrayList<Weapon<?>>(); + + Bukkit.getPluginManager().registerEvents(this, plugin); + + if (!Core.getSettings().isSister()) { + list.add(new Dildo()); + } + + list.addAll(Arrays.asList( + + //PISTOL + new Pistol(), + new StunGun(), + new CombatPistol(), + new MarksmanPistol(), + new HeavyPistol(), + + //SMG + new SMG(), + new MicroSMG(), + new CombatPDW(), + new GusenbergSweeper(), + new AssaultSMG(), + + //SHOTGUN + new SawedoffShotgun(), + new PumpShotgun(), + new Musket(), + new AssaultShotgun(), + new HeavyShotgun(), + + //ASSAULT RIFLE + new AssaultRifle(), + new CarbineRifle(), + new BullpupRifle(), + new AdvancedRifle(), + new SpecialCarbine(), + + //LMG + new MG(), + new CombatMG(), + + //SNIPER + new SniperRifle(), + new HeavySniper(), + + //SPECIAL + new Minigun(), + new GoldMinigun(), + new NetLauncher(), + new Flamethrower(), + new Clausinator(), + + //LAUNCHER + new RPG(), + new HomingLauncher(), + new GrenadeLauncher(), + + //MELEE + new Knife(), + new BaseballBat(), + new Rake(), + new NightStick(), + new Chainsaw(), + new Katana(), +// new Dildo(), + + //THROWABLE + new Grenade(), + new MolotovCocktail(), + new ProximityMine(), + new StickyBomb(), + new TearGas() + )); + + + weaponManager.registerWeapons(list); + + final World spawn = Bukkit.getWorld("spawn"); + this.minLoc = new Location(spawn, -358.0, 0, 226.0); + this.maxLoc = new Location(spawn, -378.0, 0, 247.0); + + for (Weapon<?> weapon : list) { + if (!(weapon instanceof WeaponVisualStatue)) continue; + WeaponVisualStatue statue = (WeaponVisualStatue) weapon; + + Location origin = statue.getOrigin(spawn); + if (!origin.getChunk().isLoaded()) origin.getChunk().load(); + for (Entity entity : origin.getWorld().getNearbyEntities(origin, 2, 2, 2)) { + if (entity.getType() != EntityType.ARMOR_STAND) continue; + entity.remove(); + } + } + + ServerUtil.runTaskLater(() -> { + for (Weapon<?> weapon : list) { + if (!(weapon instanceof WeaponVisualStatue)) continue; + ((WeaponVisualStatue) weapon).spawnVisual(spawn); + } + }, 20 * 15); + } + + @EventHandler + protected final void onArmorstandInteract(PlayerArmorStandManipulateEvent event) { + if (event.getRightClicked() == null) return; + if (!event.getRightClicked().hasMetadata("statue")) return; + event.setCancelled(true); + } + + @EventHandler + protected final void onPlayerMove(PlayerMoveEvent event) { + Player player = event.getPlayer(); + if (!player.getWorld().equals(this.maxLoc.getWorld())) return; + + ServerUtil.runTaskAsync(() -> { + if (!this.isInRegion(player)) return; + + for (Entity entity : player.getWorld().getNearbyEntities(player.getLocation(), 6, 6, 6)) { + if (entity == null) return; + if (entity.getType() != EntityType.ARMOR_STAND) continue; + if (!this.isLookingAt(player, (LivingEntity) entity)) continue; + + ArmorStand statue = (ArmorStand) entity; + if (!statue.hasMetadata("statueview")) continue; + + this.createAndShow(player, statue); + break; + } + }); + } + + @EventHandler + protected final void onEntityDamage(EntityDamageEvent event) { + if (event.getEntity() == null) return; + if (!event.getEntity().hasMetadata("statue")) return; + event.setCancelled(true); + } + + @EventHandler + protected final void onArmorstandInteract(PlayerInteractAtEntityEvent event) { + if (event.getRightClicked() == null) return; + if (!event.getRightClicked().hasMetadata("statue")) return; + event.setCancelled(true); + + Weapon<?> weapon = (Weapon<?>) event.getRightClicked().getMetadata("statueview").get(0).value(); + if (weapon == null) return; + + Player player = event.getPlayer(); + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + + if (!GTM.getSettings().canBuy()){ + player.sendMessage(ChatColor.RED + "Buying things is currently disabled."); + return; + } + + GameItem gi = GTM.getItemManager().getItem(weapon.getCompactName()); + double price = gi.getBuyPrice(); + if (user.hasMoney(price)) { + user.takeMoney(price); + player.sendMessage(Lang.MONEY_TAKE.f(String.valueOf(price))); + } else { + if (user.hasBank(price)) { + user.takeBank(price); + player.sendMessage(Lang.BANK_TAKE.f(String.valueOf(price))); + } else { + player.sendMessage(Lang.MONEY.f("&7You do not have enough money!")); + return; + } + } + GTMUtils.updateBoard(player, Core.getUserManager().getLoadedUser(player.getUniqueId()), user); + + ItemStack stack = gi.getItem(); + WeaponSkin weaponSkin = user.getEquippedWeaponSkin(weapon); + + if (weaponSkin != null){ + stack.setDurability(weaponSkin.getIdentifier()); + } + + Utils.giveItems(player, stack); + } + + private Location getLocationFromSize(Location original, double x, double y, double z, int size) { + Location loc = original.clone(); + loc.setY((loc.getY() + y) + (0.25 * size)); + loc.setX(loc.getX() + x); + loc.setZ(loc.getZ() + z); + return loc; + } + + @EventHandler + protected final void onWorldChange(PlayerChangedWorldEvent event) { + for (Hologram otherHologram : weaponHolograms.values()) { + otherHologram.getVisibilityManager().hideTo(event.getPlayer()); + } + } + + @EventHandler + protected final void onLeave(PlayerQuitEvent event) { + for (Hologram otherHologram : weaponHolograms.values()) { + otherHologram.getVisibilityManager().hideTo(event.getPlayer()); + } + } + + private synchronized void createAndShow(Player player, ArmorStand statue) { + Weapon<?> weapon = (Weapon<?>) statue.getMetadata("statue").get(0).value(); + if (weapon == null) { + return; + } + + //IN DEV (works, movement event doesn't) + if (this.playerCache.containsKey(player.getUniqueId())) { + PlayerStateCache cache = this.playerCache.get(player.getUniqueId()); + if (cache.expired()) { + cache.weapon = weapon; + cache.time = System.currentTimeMillis() + 6000; + } + else { + if (cache.weapon.getCompactName().equals(weapon.getCompactName())) + return; + + cache.weapon = weapon; + cache.time = System.currentTimeMillis() + 6000; + } + } + else { + this.playerCache.put(player.getUniqueId(), new PlayerStateCache(weapon, System.currentTimeMillis() + 6000)); + } + + if (weaponHolograms.containsKey(weapon.getCompactName())) { + Hologram hologram = weaponHolograms.get(weapon.getCompactName()); + + for (Hologram otherHologram : weaponHolograms.values()) { + if (otherHologram.equals(hologram)) continue; + otherHologram.getVisibilityManager().hideTo(player); + } + + if (hologram.getVisibilityManager().isVisibleTo(player)) + hologram.getVisibilityManager().hideTo(player); + else hologram.getVisibilityManager().showTo(player); + return; + } + + ItemStack weaponClone = weapon.createItemStack().clone(); + LinkedList<String> displayList = Lists.newLinkedList(); + + double price = GTM.getItemManager().getItem(weapon.getCompactName()).getBuyPrice(); + + //Name & Spacer. + displayList.add(C.YELLOW + C.BOLD + weapon.getName() + C.RESET + C.GREEN + " $" + C.BOLD + price + C.RESET); + displayList.add(" "); + + //Load the weapon description into the List. + for (String str : weapon.getDescription()) { + displayList.add(C.GRAY + C.ITALIC + str + C.RESET); + } + + //Spacer + displayList.add(" "); + + //Load the weapon stats into the List. + for (String str : weaponClone.getItemMeta().getLore()) { + if (!ChatColor.stripColor(str).contains("::::::::")) continue; + displayList.add(str + C.RESET); + } + + ServerUtil.runTask(() -> { + double x = 0, y = 0, z = 0; + if (statue.hasMetadata("statue_X")) x = (double) statue.getMetadata("statue_X").get(0).value(); + if (statue.hasMetadata("statue_Y")) y = (double) statue.getMetadata("statue_Y").get(0).value(); + if (statue.hasMetadata("statue_Z")) z = (double) statue.getMetadata("statue_Z").get(0).value(); + + Hologram hologram = HologramsAPI.createHologram(GTM.getInstance(), this.getLocationFromSize(((WeaponVisualStatue) weapon).getOrigin(statue.getWorld()), x, y, z, displayList.size())); + for (String str : displayList) hologram.appendTextLine(str); + hologram.getVisibilityManager().setVisibleByDefault(false); + + weaponHolograms.put(weapon.getCompactName(), hologram); + + for (Hologram otherHologram : weaponHolograms.values()) { + if (otherHologram.equals(hologram)) continue; + otherHologram.getVisibilityManager().hideTo(player); + } + + hologram.getVisibilityManager().showTo(player); + }); + } + + private boolean isInRegion(Player player) { + Location loc = player.getLocation(); + return (loc.getX() > this.maxLoc.getX() && loc.getX() < this.minLoc.getX()) && + (loc.getZ() < this.maxLoc.getZ() && loc.getZ() > this.minLoc.getZ()); + } + + private boolean isLookingAt(Player player, LivingEntity entity) { + Location eye = player.getEyeLocation(); + org.bukkit.util.Vector toEntity = entity.getEyeLocation().toVector().subtract(eye.toVector()); + double dot = toEntity.normalize().dot(eye.getDirection()); + + return dot > 0.99D; + } + + private class PlayerStateCache { + public Weapon<?> weapon = null; + public long time; + + public PlayerStateCache(Weapon<?> weapon, long time) { + this.weapon = weapon; + this.time = time; + } + + public boolean expired() { + return System.currentTimeMillis() >= time; + } + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/WeaponVisualStatue.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/WeaponVisualStatue.java new file mode 100644 index 0000000..f3cccb8 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/WeaponVisualStatue.java @@ -0,0 +1,52 @@ +package net.grandtheftmc.gtm.weapon; + +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.guns.weapon.Weapon; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.metadata.FixedMetadataValue; + +public interface WeaponVisualStatue { + + Location spawnVisual(World world); + + Location getOrigin(World world); + + default ArmorStand spawnEntity(Location location, Weapon<?> weapon, VisualType visualType) { + ArmorStand entity = location.getWorld().spawn(location, ArmorStand.class); + if (visualType == VisualType.NAME && weapon != null) { +// entity.setCustomName(C.YELLOW + C.BOLD + weapon.getName()); +// entity.setCustomNameVisible(true); + entity.setMetadata("statueview", new FixedMetadataValue(GTM.getInstance(), weapon)); + } + else if (visualType == VisualType.PRICE && weapon != null) { +// double price = 0.0; +// entity.setCustomName(C.GREEN + C.BOLD + "$" + price); +// entity.setCustomNameVisible(true); + } + + entity.setGravity(false); + entity.setRemoveWhenFarAway(false); + entity.setAI(false); +// entity.setInvulnerable(true); + entity.setBasePlate(true); + entity.setVisible(false); + entity.setInvulnerable(true); +// entity.setCollidable(false); + entity.setMetadata("statue", new FixedMetadataValue(GTM.getInstance(), weapon)); + extras(entity); + + return entity; + } + + default void extras(ArmorStand entity) {} + + public static enum VisualType { + NAME, + PRICE, + NONE, + ; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/airstrike/Airstrike.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/airstrike/Airstrike.java new file mode 100644 index 0000000..f483c22 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/airstrike/Airstrike.java @@ -0,0 +1,34 @@ +package net.grandtheftmc.gtm.weapon.airstrike; + +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AirstrikeWeapon; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponType; + +/** + * Created by Luke Bingham on 18/07/2017. + */ +public class Airstrike extends AirstrikeWeapon { + + /** + * Construct a new Weapon. + */ + public Airstrike() { + super( + (short) 51, + "Airstrke", //Name + WeaponType.DROPPABLE, //Weapon Type + AmmoType.NONE, //AmmoType + new ItemFactory(Material.WOOD_BUTTON).build(), //ItemStack + new Sound[] { + Sound.ENTITY_SKELETON_SHOOT, + Sound.ENTITY_BAT_TAKEOFF, + Sound.ENTITY_BAT_TAKEOFF, + Sound.ENTITY_GENERIC_EXPLODE + } + ); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/airstrike/Nuke.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/airstrike/Nuke.java new file mode 100644 index 0000000..9aa505e --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/airstrike/Nuke.java @@ -0,0 +1,33 @@ +package net.grandtheftmc.gtm.weapon.airstrike; + +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AirstrikeWeapon; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponType; + +/** + * Created by Luke Bingham on 18/07/2017. + */ +public class Nuke extends AirstrikeWeapon { + + /** + * Construct a new Weapon. + */ + public Nuke() { + super( + (short) 52, + "Nuke", //Name + WeaponType.DROPPABLE, //Weapon Type + AmmoType.NONE, //AmmoType + new ItemFactory(Material.WOOD_BUTTON).build(), //ItemStack + new Sound[] { + Sound.ENTITY_SKELETON_SHOOT, + Sound.ENTITY_BAT_TAKEOFF, + Sound.ENTITY_BAT_TAKEOFF, + } + ); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/explosive/Grenade.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/explosive/Grenade.java new file mode 100644 index 0000000..670dcf2 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/explosive/Grenade.java @@ -0,0 +1,83 @@ +package net.grandtheftmc.gtm.weapon.explosive; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.ThrowableWeapon; +import net.grandtheftmc.guns.weapon.WeaponType; + +/** + * Created by Luke Bingham on 18/07/2017. + */ +public class Grenade extends ThrowableWeapon implements WeaponVisualStatue { + + /** + * Construct a new Weapon. + */ + public Grenade() { + super( + (short) 34, + "Grenade", //Name + WeaponType.THROWABLE, //Weapon Type + AmmoType.EXPLOSIVE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 331).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_SKELETON_SHOOT, + Sound.ENTITY_BAT_TAKEOFF, + Sound.ENTITY_BAT_TAKEOFF, + Sound.ENTITY_GENERIC_EXPLODE + } + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.FIREWORK_CHARGE).setName(getName()).build()); + setDescription("How to clear a room", "in 3..2..1."); + + this.particles = Effect.EXPLOSION_HUGE; + this.delay = 55; + this.damage = 12; + this.meleeDamage = 1.0; + this.explosionSize = 6.0; + this.explosionDelay = 60; + this.explosionStrength = 2.0; + this.scaledDamage = false; + } + + @Override + public Location spawnVisual(World world) { + Location origin = getOrigin(world); + ArmorStand glass = spawnEntity(origin.clone(), this, VisualType.NAME); + glass.setHelmet(new ItemStack(Material.GLASS)); + + Location weaponLoc = origin.clone().add(0.3, 0.85, -0.5); + weaponLoc.setYaw(-30.0f); + ArmorStand weapon = spawnEntity(weaponLoc, this, VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setMarker(true); + + + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -365.5, 25.5, 233.5, -0.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.25)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/explosive/MolotovCocktail.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/explosive/MolotovCocktail.java new file mode 100644 index 0000000..43c8cef --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/explosive/MolotovCocktail.java @@ -0,0 +1,81 @@ +package net.grandtheftmc.gtm.weapon.explosive; + +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import org.bukkit.*; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.ThrowableWeapon; +import net.grandtheftmc.guns.weapon.WeaponType; +import org.bukkit.entity.ArmorStand; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +/** + * Created by Luke Bingham on 18/07/2017. + */ +public class MolotovCocktail extends ThrowableWeapon implements WeaponVisualStatue { + + /** + * Construct a new Weapon. + */ + public MolotovCocktail() { + super( + (short) 36, + "Molotov Cocktail", //Name + WeaponType.THROWABLE, //Weapon Type + AmmoType.EXPLOSIVE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 351).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_SKELETON_SHOOT, + Sound.ENTITY_BAT_TAKEOFF, + Sound.ENTITY_BAT_TAKEOFF, + Sound.ENTITY_GENERIC_EXPLODE + } + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.MAGMA_CREAM).setName(getName()).build()); + setDescription("Nothing says angst quite", "as much as a bottle of", "liquid fire."); + + this.particles = Effect.FLAME; + this.delay = 60; + this.flammable = true; + this.duration = 140; + this.damage = 20; + this.explosionSize = 5.0; + this.explosionDelay = 40; + this.explosionStrength = 0.3; + } + + @Override + public Location spawnVisual(World world) { + Location origin = getOrigin(world); + ArmorStand glass = spawnEntity(origin.clone(), this, VisualType.NAME); + glass.setHelmet(new ItemStack(Material.GLASS)); + + Location weaponLoc = origin.clone().add(0.3, 0.85, -0.5); + weaponLoc.setYaw(-30.0f); + ArmorStand weapon = spawnEntity(weaponLoc, this, VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setMarker(true); + + + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -365.5, 25.5, 235.5, -0.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.25)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/explosive/ProximityMine.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/explosive/ProximityMine.java new file mode 100644 index 0000000..cc1dd3b --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/explosive/ProximityMine.java @@ -0,0 +1,88 @@ +package net.grandtheftmc.gtm.weapon.explosive; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.ThrowableWeapon; +import net.grandtheftmc.guns.weapon.WeaponType; + +/** + * Created by Luke Bingham on 18/07/2017. + */ +public class ProximityMine extends ThrowableWeapon implements WeaponVisualStatue { + + /** + * Construct a new Weapon. + */ + public ProximityMine() { + super( + (short) 38, + "Proximity Mine", //Name + WeaponType.THROWABLE, //Weapon Type + AmmoType.EXPLOSIVE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 371).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_SKELETON_SHOOT, + Sound.ENTITY_BAT_TAKEOFF, + Sound.ENTITY_BAT_TAKEOFF, + Sound.ENTITY_GENERIC_EXPLODE + } + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.GLOWSTONE_DUST).setName(getName()).build()); + setDescription("Enjoy your spawn camping..."); + + this.particles = Effect.EXPLOSION_HUGE; + this.delay = 40; + this.proximity = true; +// this.duration = 100; + this.damage = 10; + this.meleeDamage = 1.0; + this.explosionSize = 5.0; + this.explosionDelay = 0; + this.explosionStrength = 3.0; + this.scaledDamage = false; + } + + @Override + public Location spawnVisual(World world) { + Location origin = getOrigin(world); + ArmorStand glass = spawnEntity(origin.clone(), this, VisualType.NAME); + glass.setHelmet(new ItemStack(Material.GLASS)); + + Location weaponLoc = origin.clone().add(0.9, 0.3, -0.5); + weaponLoc.setYaw(-30.0f); + ArmorStand weapon = spawnEntity(weaponLoc, this, VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setRightArmPose(new EulerAngle(0, AngleUtil.getRadianFromDegree(180), AngleUtil.getRadianFromDegree(90))); + weapon.setMarker(true); + + + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -367.5, 25.5, 233.5, -0.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.25)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/explosive/StickyBomb.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/explosive/StickyBomb.java new file mode 100644 index 0000000..969d691 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/explosive/StickyBomb.java @@ -0,0 +1,89 @@ +package net.grandtheftmc.gtm.weapon.explosive; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.ThrowableWeapon; +import net.grandtheftmc.guns.weapon.WeaponType; + +/** + * Created by Luke Bingham on 18/07/2017. + */ +public class StickyBomb extends ThrowableWeapon implements WeaponVisualStatue { + + /** + * Construct a new Weapon. + */ + public StickyBomb() { + super( + (short) 37, + "Sticky Bomb", //Name + WeaponType.THROWABLE, //Weapon Type + AmmoType.EXPLOSIVE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 361).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_SKELETON_SHOOT, + Sound.ENTITY_BAT_TAKEOFF, + Sound.ENTITY_BAT_TAKEOFF, + Sound.ENTITY_GENERIC_EXPLODE + } + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.FIREBALL).setName(getName()).build()); + setDescription("It's like the explosion", "is hugging you!"); + + this.particles = Effect.EXPLOSION_HUGE; + this.delay = 60; + this.sticky = true; +// this.duration = 100; + this.damage = 16; + this.explosionSize = 5.0; + //this.explosionDelay = 100; + this.meleeDamage = 1; + //this.tntFuseDelay = 80; + this.explosionStrength = 0.9; + this.scaledDamage = true; + } + + @Override + public Location spawnVisual(World world) { + Location origin = getOrigin(world); + ArmorStand glass = spawnEntity(origin.clone(), this, VisualType.NAME); + glass.setHelmet(new ItemStack(Material.GLASS)); + + Location weaponLoc = origin.clone().add(0.85, 0.3, -0.5); + weaponLoc.setYaw(-30.0f); + ArmorStand weapon = spawnEntity(weaponLoc, this, VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setRightArmPose(new EulerAngle(0, AngleUtil.getRadianFromDegree(180), AngleUtil.getRadianFromDegree(90))); + weapon.setMarker(true); + + + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -366.5, 25.5, 233.5, -0.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.25)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/explosive/TearGas.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/explosive/TearGas.java new file mode 100644 index 0000000..8a484dd --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/explosive/TearGas.java @@ -0,0 +1,82 @@ +package net.grandtheftmc.gtm.weapon.explosive; + +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import org.bukkit.*; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.ThrowableWeapon; +import net.grandtheftmc.guns.weapon.WeaponType; +import org.bukkit.entity.ArmorStand; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +/** + * Created by Luke Bingham on 18/07/2017. + */ +public class TearGas extends ThrowableWeapon implements WeaponVisualStatue { + + /** + * Construct a new Weapon. + */ + public TearGas() { + super( + (short) 35, + "Tear Gas", //Name + WeaponType.THROWABLE, //Weapon Type + AmmoType.EXPLOSIVE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 341).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_SKELETON_SHOOT, + Sound.ENTITY_BAT_TAKEOFF, + Sound.ENTITY_BAT_TAKEOFF, + Sound.BLOCK_LAVA_EXTINGUISH + } + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.GHAST_TEAR).setName(getName()).build()); + setDescription("This will make them", "cry more than your ex."); + + this.particles = Effect.CLOUD; + this.delay = 60; + this.teargas = true; + this.duration = 140; + this.damage = 1.0; + this.meleeDamage = 1.0; + this.explosionSize = 5.0; + this.explosionDelay = 40; + this.explosionStrength = 0.0; + } + + @Override + public Location spawnVisual(World world) { + Location origin = getOrigin(world); + ArmorStand glass = spawnEntity(origin.clone(), this, VisualType.NAME); + glass.setHelmet(new ItemStack(Material.GLASS)); + + Location weaponLoc = origin.clone().add(0.3, 0.85, -0.5); + weaponLoc.setYaw(-30.0f); + ArmorStand weapon = spawnEntity(weaponLoc, this, VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setMarker(true); + + + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -365.5, 25.5, 234.5, -0.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.25)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/melee/BaseballBat.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/melee/BaseballBat.java new file mode 100644 index 0000000..beb9f69 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/melee/BaseballBat.java @@ -0,0 +1,104 @@ +package net.grandtheftmc.gtm.weapon.melee; + +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.MeleeWeapon; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +/** + * Created by Luke Bingham on 18/07/2017. + */ +public class BaseballBat extends MeleeWeapon implements WeaponVisualStatue { + + /** + * Construct a new Weapon. + */ + public BaseballBat() { + super( + (short) 4, + "Baseball Bat", //Name + WeaponType.MELEE, //Weapon Type + AmmoType.MELEE, //AmmoType + + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 31).build(), //ItemStack + new Sound[] { //Sounds + Sound.ENTITY_PLAYER_ATTACK_STRONG, + Sound.ITEM_ARMOR_EQUIP_GENERIC, + Sound.ITEM_ARMOR_EQUIP_GENERIC + } + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.IRON_BARDING).setName(getName()).build()); + setDescription("Are you a cave man?"); + + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.delay = 7; + this.meleeDamage = 6.5; + } + + @Override + public Location spawnVisual(World world) { + Location origin = this.getOrigin(world); + Location clickLoc = origin.clone().add(0.4, 1.5, 0.4); + clickLoc.setYaw(-45.0f); + ArmorStand clickable = spawnEntity(clickLoc, this, WeaponVisualStatue.VisualType.NAME); + clickable.setSmall(true); + + ArmorStand weapon = spawnEntity(origin.clone().add(-0.3, 1.25, 0.125), this, WeaponVisualStatue.VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setRightArmPose(new EulerAngle(AngleUtil.getRadianFromDegree(260), 0, AngleUtil.getRadianFromDegree(180))); + weapon.setMarker(true); + +// Location hookLoc = origin.clone().add(0.045, 1.02, -0.68); +// hookLoc.setPitch(0); +// hookLoc.setYaw(0); +// ArmorStand hook = spawnEntity(hookLoc, this, WeaponVisualStatue.VisualType.NONE); +// hook.setHelmet(new ItemStack(Material.TRIPWIRE_HOOK)); +// hook.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(45), 0, 0)); +// hook.setSmall(true); +// hook.setMarker(true); + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -370.5, 25.5, 228.5, 180.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.5)); + entity.setMetadata("statue_X", new FixedMetadataValue(GTM.getInstance(), 0.4)); + entity.setMetadata("statue_Z", new FixedMetadataValue(GTM.getInstance(), 0.4)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/melee/Chainsaw.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/melee/Chainsaw.java new file mode 100644 index 0000000..8371da2 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/melee/Chainsaw.java @@ -0,0 +1,131 @@ +package net.grandtheftmc.gtm.weapon.melee; + +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.MeleeWeapon; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.attribute.RankedWeapon; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +/** + * Created by Luke Bingham on 18/07/2017. + */ +public class Chainsaw extends MeleeWeapon implements RankedWeapon, WeaponVisualStatue { + + /** + * Construct a new Weapon. + */ + public Chainsaw() { + super( + (short) 5, + "Chainsaw", //Name + WeaponType.MELEE, //Weapon Type + AmmoType.ENERGY, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 41).build(), //ItemStack + new Sound[] { //Sounds + Sound.ENTITY_WOLF_GROWL, + Sound.ITEM_ARMOR_EQUIP_GENERIC, + Sound.ITEM_ARMOR_EQUIP_GENERIC + } + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.DIAMOND_BARDING).setName(getName()).build()); + setDescription("A chainsaw?", "You absolute monster!"); + + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.delay = 5; + this.meleeDamage = 6.5; + this.range = 2.5; + } + + /*@Override + public void onRightClick(Player player) { + ServerUtil.debug("20"); + MathUtil.getNearbyEntities(player, this.range).forEach(e -> { + ServerUtil.debug("21"); + if (player.hasLineOfSight(e)) { + ServerUtil.debug("they have line of sight.2"); + Vector toEntity = e.getLocation().toVector().subtract(player.getLocation().toVector()); + double dot = toEntity.normalize().dot(player.getLocation().getDirection()); + ServerUtil.debug(dot + " / dot2"); + if (dot <= 1 && dot >= 0) { + ServerUtil.debug("yup.2"); + e.setNoDamageTicks(0); + e.damage(getMeleeDamage(), player); + } + } + }); + Sounds.broadcastSound(getSounds()[0], player.getEyeLocation()); + }//todo: moved to the meleeweapon class, don't know why this isn't working.*/ + + @Override + public UserRank requiredRank() { + return UserRank.PREMIUM; + } + + @Override + public Location spawnVisual(World world) { + Location origin = this.getOrigin(world); + Location clickLoc = origin.clone().add(0.4, 1.5, -0.4); + clickLoc.setYaw(-135.0f); + ArmorStand clickable = spawnEntity(clickLoc, this, WeaponVisualStatue.VisualType.NAME); + clickable.setSmall(true); + + ArmorStand weapon = spawnEntity(origin.clone().add(0.25, 0.45, -0.65), this, WeaponVisualStatue.VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setRightArmPose(new EulerAngle(AngleUtil.getRadianFromDegree(280), 0, 0)); + weapon.setMarker(true); + +// Location hookLoc = origin.clone().add(0.045, 1.02, -0.68); +// hookLoc.setPitch(0); +// hookLoc.setYaw(0); +// ArmorStand hook = spawnEntity(hookLoc, this, WeaponVisualStatue.VisualType.NONE); +// hook.setHelmet(new ItemStack(Material.TRIPWIRE_HOOK)); +// hook.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(45), 0, 0)); +// hook.setSmall(true); +// hook.setMarker(true); + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -375.5, 25.5, 243.5, 0.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.5)); + entity.setMetadata("statue_X", new FixedMetadataValue(GTM.getInstance(), 0.4)); + entity.setMetadata("statue_Z", new FixedMetadataValue(GTM.getInstance(), -0.4)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/melee/Dildo.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/melee/Dildo.java new file mode 100644 index 0000000..27ff033 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/melee/Dildo.java @@ -0,0 +1,58 @@ +package net.grandtheftmc.gtm.weapon.melee; + +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.MeleeWeapon; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; + +/** + * Created by Luke Bingham on 03/08/2017. + */ +public class Dildo extends MeleeWeapon { + + /** + * Construct a new Weapon. + */ + public Dildo() { + super( + (short) 41, + "Dildo", //Name + WeaponType.MELEE, //Weapon Type + AmmoType.MELEE, //AmmoType + + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 401).build(), //ItemStack + new Sound[] { //Sounds + Sound.ENTITY_PLAYER_ATTACK_STRONG, + Sound.ITEM_ARMOR_EQUIP_GENERIC, + Sound.ITEM_ARMOR_EQUIP_GENERIC + } + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.SAPLING, (byte) 1).setName(getName()).build()); + setDescription("Certified 'me time'."); + + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.delay = 7; + this.meleeDamage = 9; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/melee/Katana.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/melee/Katana.java new file mode 100644 index 0000000..e8c2d18 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/melee/Katana.java @@ -0,0 +1,59 @@ +package net.grandtheftmc.gtm.weapon.melee; + +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.MeleeWeapon; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; + +/** + * Created by Luke Bingham on 03/08/2017. + */ +public class Katana extends MeleeWeapon { + + /** + * Construct a new Weapon. + */ + public Katana() { + super( + (short) 43, + "Katana", //Name + WeaponType.MELEE, //Weapon Type + AmmoType.MELEE, //AmmoType + + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 421).build(), //ItemStack + new Sound[] { //Sounds + Sound.ENTITY_PLAYER_ATTACK_STRONG, + Sound.ITEM_ARMOR_EQUIP_GENERIC, + Sound.ITEM_ARMOR_EQUIP_GENERIC + } + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.FLINT_AND_STEEL).setDurability((short) 56).setName(getName()).build()); + setDescription("An cold-iron forged,", "ancient Japanese samurai sword"); + + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.delay = 12; + this.meleeDamage = 10; + } +} + diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/melee/Knife.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/melee/Knife.java new file mode 100644 index 0000000..9ab362a --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/melee/Knife.java @@ -0,0 +1,103 @@ +package net.grandtheftmc.gtm.weapon.melee; + +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.MeleeWeapon; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +/** + * Created by Luke Bingham on 18/07/2017. + */ +public class Knife extends MeleeWeapon implements WeaponVisualStatue { + + /** + * Construct a new Weapon. + */ + public Knife() { + super( + (short) 3, + "Knife", //Name + WeaponType.MELEE, //Weapon Type + AmmoType.MELEE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 21).build(), //ItemStack + new Sound[] { //Sounds + Sound.ENTITY_SKELETON_SHOOT, + Sound.ITEM_ARMOR_EQUIP_GENERIC, + Sound.ITEM_ARMOR_EQUIP_GENERIC + } + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.GOLD_BARDING).setName(getName()).build()); + setDescription("Don't bring a knife", "to a gun fight."); + + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.delay = 7; + this.meleeDamage = 7.5; + } + + @Override + public Location spawnVisual(World world) { + Location origin = this.getOrigin(world); + Location clickLoc = origin.clone().add(0.4, 1.5, 0.4); + clickLoc.setYaw(-45.0f); + ArmorStand clickable = spawnEntity(clickLoc, this, WeaponVisualStatue.VisualType.NAME); + clickable.setSmall(true); + + ArmorStand weapon = spawnEntity(origin.clone().add(-0.3, 0.74, -0.3), this, WeaponVisualStatue.VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setRightArmPose(new EulerAngle(AngleUtil.getRadianFromDegree(260), 0, AngleUtil.getRadianFromDegree(180))); + weapon.setMarker(true); + +// Location hookLoc = origin.clone().add(0.045, 1.02, -0.68); +// hookLoc.setPitch(0); +// hookLoc.setYaw(0); +// ArmorStand hook = spawnEntity(hookLoc, this, WeaponVisualStatue.VisualType.NONE); +// hook.setHelmet(new ItemStack(Material.TRIPWIRE_HOOK)); +// hook.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(45), 0, 0)); +// hook.setSmall(true); +// hook.setMarker(true); + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -371.5, 25.5, 229.5, -70.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.5)); + entity.setMetadata("statue_X", new FixedMetadataValue(GTM.getInstance(), 0.4)); + entity.setMetadata("statue_Z", new FixedMetadataValue(GTM.getInstance(), 0.4)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/melee/NightStick.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/melee/NightStick.java new file mode 100644 index 0000000..404a001 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/melee/NightStick.java @@ -0,0 +1,103 @@ +package net.grandtheftmc.gtm.weapon.melee; + +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.MeleeWeapon; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +/** + * Created by Luke Bingham on 18/07/2017. + */ +public class NightStick extends MeleeWeapon implements WeaponVisualStatue { + + /** + * Construct a new Weapon. + */ + public NightStick() { + super( + (short) 2, + "Night Stick", //Name + WeaponType.MELEE, //Weapon Type + AmmoType.MELEE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 11).build(), //ItemStack + new Sound[] { //Sounds + Sound.ENTITY_PLAYER_ATTACK_WEAK, + Sound.ITEM_ARMOR_EQUIP_GENERIC, + Sound.ITEM_ARMOR_EQUIP_GENERIC + } + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.BLAZE_ROD).setName(getName()).build()); + setDescription("Enjoy trying to beat", "armed criminals to death."); + + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.delay = 5; + this.meleeDamage = 5.5; + } + + @Override + public Location spawnVisual(World world) { + Location origin = this.getOrigin(world); + Location clickLoc = origin.clone().add(-0.4, 1.5, -0.4); + clickLoc.setYaw(-45.0f); + ArmorStand clickable = spawnEntity(clickLoc, this, WeaponVisualStatue.VisualType.NAME); + clickable.setSmall(true); + + ArmorStand weapon = spawnEntity(origin.clone().add(0.3, 1.1, -0.2), this, WeaponVisualStatue.VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setRightArmPose(new EulerAngle(AngleUtil.getRadianFromDegree(260), 0, AngleUtil.getRadianFromDegree(180))); + weapon.setMarker(true); + +// Location hookLoc = origin.clone().add(0.045, 1.02, -0.68); +// hookLoc.setPitch(0); +// hookLoc.setYaw(0); +// ArmorStand hook = spawnEntity(hookLoc, this, WeaponVisualStatue.VisualType.NONE); +// hook.setHelmet(new ItemStack(Material.TRIPWIRE_HOOK)); +// hook.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(45), 0, 0)); +// hook.setSmall(true); +// hook.setMarker(true); + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -361.5, 25.5, 239.5, 0.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.5)); + entity.setMetadata("statue_X", new FixedMetadataValue(GTM.getInstance(), -0.4)); + entity.setMetadata("statue_Z", new FixedMetadataValue(GTM.getInstance(), -0.4)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/melee/Rake.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/melee/Rake.java new file mode 100644 index 0000000..2e77684 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/melee/Rake.java @@ -0,0 +1,103 @@ +package net.grandtheftmc.gtm.weapon.melee; + +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.MeleeWeapon; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +/** + * Created by Luke Bingham on 18/07/2017. + */ +public class Rake extends MeleeWeapon implements WeaponVisualStatue { + + /** + * Construct a new Weapon. + */ + public Rake() { + super( + (short) 1, + "Rake", //Name + WeaponType.MELEE, //Weapon Type + AmmoType.MELEE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 1).build(), //ItemStack + new Sound[] { //Sounds + Sound.ENTITY_PLAYER_ATTACK_NODAMAGE, + Sound.ITEM_ARMOR_EQUIP_GENERIC, + Sound.ITEM_ARMOR_EQUIP_GENERIC + } + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.STICK).setName(getName()).build()); + setDescription("This...isn't even a", "proper weapon."); + + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.delay = 6; + this.meleeDamage = 4; + } + + @Override + public Location spawnVisual(World world) { + Location origin = this.getOrigin(world); + Location clickLoc = origin.clone().add(-0.4, 1.5, -0.4); + clickLoc.setYaw(-45.0f); + ArmorStand clickable = spawnEntity(clickLoc, this, WeaponVisualStatue.VisualType.NAME); + clickable.setSmall(true); + + ArmorStand weapon = spawnEntity(origin.clone().add(-0.225, 1.1, -0.26), this, WeaponVisualStatue.VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setRightArmPose(new EulerAngle(AngleUtil.getRadianFromDegree(260), 0, AngleUtil.getRadianFromDegree(180))); + weapon.setMarker(true); + +// Location hookLoc = origin.clone().add(0.045, 1.02, -0.68); +// hookLoc.setPitch(0); +// hookLoc.setYaw(0); +// ArmorStand hook = spawnEntity(hookLoc, this, WeaponVisualStatue.VisualType.NONE); +// hook.setHelmet(new ItemStack(Material.TRIPWIRE_HOOK)); +// hook.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(45), 0, 0)); +// hook.setSmall(true); +// hook.setMarker(true); + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -360.5, 25.5, 238.5, -90.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.5)); + entity.setMetadata("statue_X", new FixedMetadataValue(GTM.getInstance(), -0.4)); + entity.setMetadata("statue_Z", new FixedMetadataValue(GTM.getInstance(), -0.4)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/assault/AdvancedRifle.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/assault/AdvancedRifle.java new file mode 100644 index 0000000..57d7ee9 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/assault/AdvancedRifle.java @@ -0,0 +1,114 @@ +package net.grandtheftmc.gtm.weapon.ranged.assault; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.AssultRifleWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class AdvancedRifle extends AssultRifleWeapon implements WeaponVisualStatue { + /** + * Construct a new RangedWeapon. + */ + public AdvancedRifle() { + super( + (short) 24, + "Advanced Rifle", //Name + WeaponType.ASSAULT, //Weapon Type + AmmoType.ASSAULT_RIFLE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 231).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_ITEM_BREAK, + Sound.ITEM_ARMOR_EQUIP_IRON, + Sound.ITEM_ARMOR_EQUIP_IRON, + Sound.ENTITY_SKELETON_AMBIENT, + }, + Effect.VOID_FOG //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.STONE_AXE).setName(getName()).build()); + setDescription("Bit egotistical to name", "your gun 'advanced', no?"); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.18; //Weapon + + this.damage = 3.5; //RangedWeapon + this.meleeDamage = 5.0; //RangedWeapon + this.accuracy = 0.015; //RangedWeapon + this.magSize = 30; //RangedWeapon + this.reloadTime = 35; //RangedWeapon + this.range = 45; //RangedWeapon + this.recoil = 0.1; //RangedWeapon + this.zoom = 3; //RangedWeapon + this.rps = 8; + this.rpm = 500; //AssultRifleWeapon + this.multiShoot = true; + } + + @Override + public Location spawnVisual(World world) { + Location origin = this.getOrigin(world); + ArmorStand clickable = spawnEntity(origin.clone().add(0, 1.5, 0), this, WeaponVisualStatue.VisualType.NAME); + clickable.setSmall(true); + + ArmorStand weapon = spawnEntity(origin.clone().add(-0.2, 0, 0.4), this, WeaponVisualStatue.VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setRightArmPose(new EulerAngle(AngleUtil.getRadianFromDegree(180), 0, AngleUtil.getRadianFromDegree(20))); + weapon.setMarker(true); + +// Location hookLoc = origin.clone().add(0.045, 1.02, -0.68); +// hookLoc.setPitch(0); +// hookLoc.setYaw(0); +// ArmorStand hook = spawnEntity(hookLoc, this, WeaponVisualStatue.VisualType.NONE); +// hook.setHelmet(new ItemStack(Material.TRIPWIRE_HOOK)); +// hook.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(45), 0, 0)); +// hook.setSmall(true); +// hook.setMarker(true); + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -371.5, 25.5, 244.5, 90.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.5)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/assault/AssaultRifle.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/assault/AssaultRifle.java new file mode 100644 index 0000000..bb2ba11 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/assault/AssaultRifle.java @@ -0,0 +1,114 @@ +package net.grandtheftmc.gtm.weapon.ranged.assault; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.AssultRifleWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class AssaultRifle extends AssultRifleWeapon implements WeaponVisualStatue { + /** + * Construct a new RangedWeapon. + */ + public AssaultRifle() { + super( + (short) 21, + "Assault Rifle", //Name + WeaponType.ASSAULT, //Weapon Type + AmmoType.ASSAULT_RIFLE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 201).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_ITEM_BREAK, + Sound.ITEM_ARMOR_EQUIP_IRON, + Sound.ITEM_ARMOR_EQUIP_IRON, + Sound.ENTITY_SKELETON_AMBIENT, + }, + Effect.VOID_FOG //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.STONE_SWORD).setName(getName()).build()); + setDescription("Great stock weapon for", "medium range gunfights."); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.18; //Weapon + + this.damage = 2.75; //RangedWeapon + this.meleeDamage = 5.0; //RangedWeapon + this.accuracy = 0.025; //RangedWeapon + this.magSize = 30; //RangedWeapon + this.reloadTime = 40; //RangedWeapon + this.range = 45; //RangedWeapon + this.recoil = 0.15; //RangedWeapon + this.zoom = 2; //RangedWeapon + this.rps = 6; + this.rpm = 380; //AssultRifleWeapon + this.multiShoot = true; + } + + @Override + public Location spawnVisual(World world) { + Location origin = this.getOrigin(world); + ArmorStand clickable = spawnEntity(origin.clone().add(0, 1.5, 0), this, WeaponVisualStatue.VisualType.NAME); + clickable.setSmall(true); + + ArmorStand weapon = spawnEntity(origin.clone().add(-0.2, -0.16, 0.325), this, WeaponVisualStatue.VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setRightArmPose(new EulerAngle(AngleUtil.getRadianFromDegree(180), 0, AngleUtil.getRadianFromDegree(20))); + weapon.setMarker(true); + +// Location hookLoc = origin.clone().add(0.045, 1.02, -0.68); +// hookLoc.setPitch(0); +// hookLoc.setYaw(0); +// ArmorStand hook = spawnEntity(hookLoc, this, WeaponVisualStatue.VisualType.NONE); +// hook.setHelmet(new ItemStack(Material.TRIPWIRE_HOOK)); +// hook.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(45), 0, 0)); +// hook.setSmall(true); +// hook.setMarker(true); + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -368.5, 25.5, 244.5, 90.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.5)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/assault/BullpupRifle.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/assault/BullpupRifle.java new file mode 100644 index 0000000..d2082bf --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/assault/BullpupRifle.java @@ -0,0 +1,114 @@ +package net.grandtheftmc.gtm.weapon.ranged.assault; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.AssultRifleWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class BullpupRifle extends AssultRifleWeapon implements WeaponVisualStatue { + /** + * Construct a new RangedWeapon. + */ + public BullpupRifle() { + super( + (short) 23, + "Bullpup Rifle", //Name + WeaponType.ASSAULT, //Weapon Type + AmmoType.ASSAULT_RIFLE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 221).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_ITEM_BREAK, + Sound.ITEM_ARMOR_EQUIP_IRON, + Sound.ITEM_ARMOR_EQUIP_IRON, + Sound.ENTITY_SKELETON_AMBIENT, + }, + Effect.VOID_FOG //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.STONE_PICKAXE).setName(getName()).build()); + setDescription("It's a bit like the", "normal AR, but Chinese..", "很好!"); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.18; //Weapon + + this.damage = 3.0; //RangedWeapon + this.meleeDamage = 5.0; //RangedWeapon + this.accuracy = 0.02; //RangedWeapon + this.magSize = 30; //RangedWeapon + this.reloadTime = 40; //RangedWeapon + this.range = 45; //RangedWeapon + this.recoil = 0.3; //RangedWeapon + this.zoom = 2; //RangedWeapon + this.rps = 9; + this.rpm = 500; //AssultRifleWeapon + this.multiShoot = true; + } + + @Override + public Location spawnVisual(World world) { + Location origin = this.getOrigin(world); + ArmorStand clickable = spawnEntity(origin.clone().add(0, 1.5, 0), this, WeaponVisualStatue.VisualType.NAME); + clickable.setSmall(true); + + ArmorStand weapon = spawnEntity(origin.clone().add(-0.2, -0.08, 0.4), this, WeaponVisualStatue.VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setRightArmPose(new EulerAngle(AngleUtil.getRadianFromDegree(180), 0, AngleUtil.getRadianFromDegree(20))); + weapon.setMarker(true); + +// Location hookLoc = origin.clone().add(0.045, 1.02, -0.68); +// hookLoc.setPitch(0); +// hookLoc.setYaw(0); +// ArmorStand hook = spawnEntity(hookLoc, this, WeaponVisualStatue.VisualType.NONE); +// hook.setHelmet(new ItemStack(Material.TRIPWIRE_HOOK)); +// hook.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(45), 0, 0)); +// hook.setSmall(true); +// hook.setMarker(true); + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -370.5, 25.5, 244.5, 90.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.5)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/assault/CarbineRifle.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/assault/CarbineRifle.java new file mode 100644 index 0000000..d976ac9 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/assault/CarbineRifle.java @@ -0,0 +1,114 @@ +package net.grandtheftmc.gtm.weapon.ranged.assault; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.AssultRifleWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class CarbineRifle extends AssultRifleWeapon implements WeaponVisualStatue { + /** + * Construct a new RangedWeapon. + */ + public CarbineRifle() { + super( + (short) 22, + "Carbine Rifle", //Name + WeaponType.ASSAULT, //Weapon Type + AmmoType.ASSAULT_RIFLE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 211).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_ITEM_BREAK, + Sound.ITEM_ARMOR_EQUIP_IRON, + Sound.ITEM_ARMOR_EQUIP_IRON, + Sound.ENTITY_SKELETON_AMBIENT, + }, + Effect.VOID_FOG //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.STONE_SPADE).setName(getName()).build()); + setDescription("A longer range version", "of your stock AR."); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.18; //Weapon + + this.damage = 3; //RangedWeapon + this.meleeDamage = 5.0; //RangedWeapon + this.accuracy = 0.005; //RangedWeapon + this.magSize = 30; //RangedWeapon + this.reloadTime = 40; //RangedWeapon + this.range = 45; //RangedWeapon + this.recoil = 0.1; //RangedWeapon + this.zoom = 2; //RangedWeapon + this.rps = 7; + this.rpm = 445; //AssultRifleWeapon + this.multiShoot = true; + } + + @Override + public Location spawnVisual(World world) { + Location origin = this.getOrigin(world); + ArmorStand clickable = spawnEntity(origin.clone().add(0, 1.5, 0), this, WeaponVisualStatue.VisualType.NAME); + clickable.setSmall(true); + + ArmorStand weapon = spawnEntity(origin.clone().add(-0.2, -0.1, 0.35), this, WeaponVisualStatue.VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setRightArmPose(new EulerAngle(AngleUtil.getRadianFromDegree(180), 0, AngleUtil.getRadianFromDegree(20))); + weapon.setMarker(true); + +// Location hookLoc = origin.clone().add(0.045, 1.02, -0.68); +// hookLoc.setPitch(0); +// hookLoc.setYaw(0); +// ArmorStand hook = spawnEntity(hookLoc, this, WeaponVisualStatue.VisualType.NONE); +// hook.setHelmet(new ItemStack(Material.TRIPWIRE_HOOK)); +// hook.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(45), 0, 0)); +// hook.setSmall(true); +// hook.setMarker(true); + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -369.5, 25.5, 244.5, 90.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.5)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/assault/SpecialCarbine.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/assault/SpecialCarbine.java new file mode 100644 index 0000000..7fe7315 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/assault/SpecialCarbine.java @@ -0,0 +1,121 @@ +package net.grandtheftmc.gtm.weapon.ranged.assault; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.attribute.RankedWeapon; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.AssultRifleWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class SpecialCarbine extends AssultRifleWeapon implements RankedWeapon, WeaponVisualStatue { + /** + * Construct a new RangedWeapon. + */ + public SpecialCarbine() { + super( + (short) 25, + "Special Carbine", //Name + WeaponType.ASSAULT, //Weapon Type + AmmoType.ASSAULT_RIFLE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 241).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_ITEM_BREAK, + Sound.ITEM_ARMOR_EQUIP_IRON, + Sound.ITEM_ARMOR_EQUIP_IRON, + Sound.ENTITY_SKELETON_AMBIENT, + }, + Effect.VOID_FOG //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.STONE_HOE).setName(getName()).build()); + setDescription("Super solid gun choice;", "very versatile."); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.18; //Weapon + + this.damage = 4; //RangedWeapon + this.meleeDamage = 5.0; //RangedWeapon + this.accuracy = 0.005; //RangedWeapon + this.magSize = 30; //RangedWeapon + this.reloadTime = 30; //RangedWeapon + this.range = 35; //RangedWeapon + this.recoil = 0.05; //RangedWeapon + this.zoom = 3; //RangedWeapon + this.rps = 7; + this.rpm = 445; //AssultRifleWeapon + this.multiShoot = true; + } + + @Override + public UserRank requiredRank() { + return UserRank.ELITE; + } + + @Override + public Location spawnVisual(World world) { + Location origin = this.getOrigin(world); + ArmorStand clickable = spawnEntity(origin.clone().add(0, 1.5, 0), this, WeaponVisualStatue.VisualType.NAME); + clickable.setSmall(true); + + ArmorStand weapon = spawnEntity(origin.clone().add(-0.2, -0.18, 0.4), this, WeaponVisualStatue.VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setRightArmPose(new EulerAngle(AngleUtil.getRadianFromDegree(180), 0, AngleUtil.getRadianFromDegree(20))); + weapon.setMarker(true); + +// Location hookLoc = origin.clone().add(0.045, 1.02, -0.68); +// hookLoc.setPitch(0); +// hookLoc.setYaw(0); +// ArmorStand hook = spawnEntity(hookLoc, this, WeaponVisualStatue.VisualType.NONE); +// hook.setHelmet(new ItemStack(Material.TRIPWIRE_HOOK)); +// hook.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(45), 0, 0)); +// hook.setSmall(true); +// hook.setMarker(true); + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -372.5, 25.5, 244.5, 90.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.5)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/launcher/GrenadeLauncher.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/launcher/GrenadeLauncher.java new file mode 100644 index 0000000..37b5f54 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/launcher/GrenadeLauncher.java @@ -0,0 +1,84 @@ +package net.grandtheftmc.gtm.weapon.ranged.launcher; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.attribute.RankedWeapon; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.LauncherWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class GrenadeLauncher extends LauncherWeapon implements RankedWeapon { + + /** + * Construct a new RangedWeapon. + */ + public GrenadeLauncher() { + super( + (short) 31, + "Grenade Launcher", //Name + WeaponType.LAUNCHER, //Weapon Type + AmmoType.GRENADE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 301).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_CHICKEN_EGG, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.BLOCK_PISTON_CONTRACT, + }, + Effect.FIREWORKS_SPARK //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.SHEARS).setName(getName()).build()); + setDescription("For if your throwing", "game is weak " + (Core.getSettings().isSister() ? "." : "AF.")); + + setSupportedAttachments(Attachment.GRIP); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.12; //Weapon + this.delay = 40; + + this.damage = 12; //RangedWeapon + this.meleeDamage = 3.0; //RangedWeapon + this.accuracy = 0.02; //RangedWeapon + this.magSize = 6; //RangedWeapon + this.reloadTime = 50; //RangedWeapon + this.range = 50; //RangedWeapon + this.recoil = 0.5; //RangedWeapon + this.zoom = 1; //RangedWeapon + + this.blowOnHit = false; //LauncherWeapon + this.blowDelay = 5; + this.explosionSize = 5; + this.scaledDamage = true; + } + + @Override + public UserRank requiredRank() { + return UserRank.SPONSOR; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/launcher/HomingLauncher.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/launcher/HomingLauncher.java new file mode 100644 index 0000000..6a0ad3d --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/launcher/HomingLauncher.java @@ -0,0 +1,129 @@ +package net.grandtheftmc.gtm.weapon.ranged.launcher; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.attribute.RankedWeapon; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.LauncherWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class HomingLauncher extends LauncherWeapon implements RankedWeapon, WeaponVisualStatue { + + /** + * Construct a new RangedWeapon. + */ + public HomingLauncher() { + super( + (short) 32, + "Homing Launcher", //Name + WeaponType.LAUNCHER, //Weapon Type + AmmoType.ROCKET, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 311).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_FIREWORK_LAUNCH, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.BLOCK_PISTON_CONTRACT, + }, + Effect.FIREWORKS_SPARK //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.SULPHUR).setName(getName()).build()); + setDescription("Imagine a homing pidgeon.", "But it explodes."); + + setSupportedAttachments(Attachment.GRIP); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.12; //Weapon + this.delay = 60; + + this.damage = 16; //RangedWeapon + this.meleeDamage = 4.0; //RangedWeapon + this.accuracy = 0.003; //RangedWeapon + this.magSize = 1; //RangedWeapon + this.reloadTime = 80; //RangedWeapon + this.range = 100; //RangedWeapon + this.recoil = 1.0; //RangedWeapon + this.zoom = 1; //RangedWeapon + + this.homingLauncher = true; //LauncherWeapon + this.rocketSpeed = 1.0; //LauncherWeapon + this.explosionSize = 2.5; //LauncherWeapon + this.explosionStrength = 1.7; //LauncherWeapon + } + + @Override + public UserRank requiredRank() { + return UserRank.SUPREME; + } + + @Override + public Location spawnVisual(World world) { + Location origin = this.getOrigin(world); + + ArmorStand clickable = spawnEntity(origin.clone().add(0.2, 0.5, 0), this, WeaponVisualStatue.VisualType.NAME); +// clickable.setVisible(true); + + ArmorStand clickable2 = spawnEntity(origin.clone().add(-0.6, 0.5, 0), this, WeaponVisualStatue.VisualType.NAME); +// clickable2.setVisible(true); + + Location weaponLoc = origin.clone().add(0.3, 0.02, 0.4); + weaponLoc.setYaw(90.0f); + ArmorStand weapon = spawnEntity(weaponLoc, this, WeaponVisualStatue.VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setRightArmPose(new EulerAngle(AngleUtil.getRadianFromDegree(255), 0f, 0f)); + weapon.setMarker(true); + + ArmorStand support = spawnEntity(origin.clone().add(-0.92, -0.4, 0.25), this, WeaponVisualStatue.VisualType.NONE); + support.setHelmet(new ItemStack(Material.END_ROD)); + support.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(300), 0f, 0f)); + support.setMarker(true); + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -367.5, 25.5, 241.5, 0.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.25)); + entity.setMetadata("statue_X", new FixedMetadataValue(GTM.getInstance(), -0.2d)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/launcher/NetLauncher.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/launcher/NetLauncher.java new file mode 100644 index 0000000..5cabf75 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/launcher/NetLauncher.java @@ -0,0 +1,132 @@ +package net.grandtheftmc.gtm.weapon.ranged.launcher; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.users.GTMUserManager; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.LauncherWeapon; + +/** + * Created by Luke Bingham on 03/08/2017. + */ +public class NetLauncher extends LauncherWeapon { + + /** + * Construct a new RangedWeapon. + */ + public NetLauncher() { + super( + (short) 39, + "Net Launcher", //Name + WeaponType.NETGUN, //TODO Weapon Type + AmmoType.ROCKET, //TODO AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 381).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_SHULKER_SHOOT, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.BLOCK_PISTON_CONTRACT, + }, + Effect.BLAZE_SHOOT //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.SAPLING).setName(getName()).build()); + setDescription("It's like discount,", (Core.getSettings().isSister() ? "weak" : "shitty") + " spiderman."); + + setSupportedAttachments(Attachment.GRIP); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.12; //Weapon + this.delay = 50; + + this.damage = 1.5; //RangedWeapon + this.meleeDamage = 1.0; //RangedWeapon + this.accuracy = 0.005; //RangedWeapon + this.magSize = 4; //RangedWeapon + this.reloadTime = 80; //RangedWeapon + this.range = 35; //RangedWeapon + this.recoil = 1.0; //RangedWeapon + this.zoom = 1; //RangedWeapon + + this.baseNetgunStun = 20; + + //this.netgun = true; //Launcher weapon todo: disabled because it was updating the actual class, now it just uses getName().equalsignorecase("net launcher") + } + + /** + * Called when the netgun hits an entity. + * + * @param location - the location of the hit + * @param shooter - the shooter of the netgun + * @param target - the target being shot, if one is specified + */ + @Override + public void onNetgunHit(Location location, Player shooter, LivingEntity target) { + + // call super method + super.onNetgunHit(location, shooter, target); + + // if target is valid + if (target != null && !target.isDead()){ + if (target instanceof Player){ + + // grab player + Player targetPlayer = (Player) target; + GTMUser gtmUser = GTMUserManager.getInstance().getUser(targetPlayer.getUniqueId()).orElse(null); + if (gtmUser != null){ + + // disable jetpack for length of stun + int disableTicks = (int) (baseNetgunStun * 2.0); + // convert from ticks to milliseconds + gtmUser.setEnableJetpackTime(System.currentTimeMillis() + (disableTicks * 50)); + + // disable fly + targetPlayer.setFlying(false); + } + } + } + } +} + + + + + + + + + + + + + + + + + diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/launcher/RPG.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/launcher/RPG.java new file mode 100644 index 0000000..ec0ee16 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/launcher/RPG.java @@ -0,0 +1,90 @@ +package net.grandtheftmc.gtm.weapon.ranged.launcher; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.LauncherWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class RPG extends LauncherWeapon { + + /** + * Construct a new RangedWeapon. + */ + public RPG() { + super( + (short) 30, + "RPG", //Name + WeaponType.LAUNCHER, //Weapon Type + AmmoType.ROCKET, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 291).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_FIREWORK_LAUNCH, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.BLOCK_PISTON_CONTRACT, + }, + Effect.FIREWORKS_SPARK //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.FEATHER).setName(getName()).build()); + setDescription("Want to take out", "the side of a building?", "Use this."); + + setSupportedAttachments(Attachment.GRIP); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.12; //Weapon + this.delay = 80; + + this.damage = 16; //RangedWeapon + this.meleeDamage = 4.0; //RangedWeapon + this.accuracy = 0.005; //RangedWeapon + this.magSize = 1; //RangedWeapon + this.reloadTime = 80; //RangedWeapon + this.range = 60; //RangedWeapon + this.recoil = 1.0; //RangedWeapon + this.zoom = 1; //RangedWeapon + + this.rocketSpeed = 2.0; //LauncherWeapon + this.explosionSize = 6.0; //LauncherWeapon + this.explosionStrength = 1.7; //LauncherWeapon + this.scaledDamage = true; + } +} + + + + + + + + + + + + + + diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/lmg/CombatMG.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/lmg/CombatMG.java new file mode 100644 index 0000000..d56acee --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/lmg/CombatMG.java @@ -0,0 +1,81 @@ +package net.grandtheftmc.gtm.weapon.ranged.lmg; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.attribute.RankedWeapon; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.LMGWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class CombatMG extends LMGWeapon implements RankedWeapon { + + /** + * Construct a new RangedWeapon. + */ + public CombatMG() { + super( + (short) 27, + "Combat MG", //Name + WeaponType.LMG, //Weapon Type + AmmoType.LMG, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 261).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.BLOCK_NOTE_SNARE, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ENTITY_SKELETON_STEP, + }, + Effect.VOID_FOG //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.DIAMOND_SPADE).setName(getName()).build()); + setDescription("Cover me,", "I'm going in! (Military style)"); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.14; //Weapon + //this.delay = 5; + + this.damage = 3.0; //RangedWeapon + this.meleeDamage = 6.0; //RangedWeapon + this.accuracy = 0.035; //RangedWeapon + this.magSize = 75; //RangedWeapon + this.reloadTime = 80; //RangedWeapon + this.range = 60; //RangedWeapon + this.recoil = 0.05; //RangedWeapon + this.zoom = 5; //RangedWeapon + this.rps = 9; + this.rpm = 550; //LMGWeapon + this.multiShoot = true; + } + + @Override + public UserRank requiredRank() { + return UserRank.SPONSOR; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/lmg/MG.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/lmg/MG.java new file mode 100644 index 0000000..8a7a30b --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/lmg/MG.java @@ -0,0 +1,74 @@ +package net.grandtheftmc.gtm.weapon.ranged.lmg; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.LMGWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class MG extends LMGWeapon { + + /** + * Construct a new RangedWeapon. + */ + public MG() { + super( + (short) 26, + "MG", //Name + WeaponType.LMG, //Weapon Type + AmmoType.LMG, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 251).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.BLOCK_NOTE_SNARE, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ENTITY_SKELETON_STEP, + }, + Effect.VOID_FOG //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.DIAMOND_SWORD).setName(getName()).build()); + setDescription("Cover me,", "I'm going in!"); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.14; //Weapon + //this.delay = 5; + + this.damage = 2.5; //RangedWeapon + this.meleeDamage = 6.0; //RangedWeapon + this.accuracy = 0.055; //RangedWeapon + this.magSize = 55; //RangedWeapon + this.reloadTime = 50; //RangedWeapon + this.range = 60; //RangedWeapon + this.recoil = 0.1; //RangedWeapon + this.zoom = 3; //RangedWeapon + this.rpm = 760; //LMGWeapon + this.rps = 7; + this.multiShoot = true; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/pistol/CombatPistol.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/pistol/CombatPistol.java new file mode 100644 index 0000000..a9bddb1 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/pistol/CombatPistol.java @@ -0,0 +1,100 @@ +package net.grandtheftmc.gtm.weapon.ranged.pistol; + +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import org.bukkit.*; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.PistolWeapon; +import org.bukkit.entity.ArmorStand; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class CombatPistol extends PistolWeapon implements WeaponVisualStatue { + + /** + * Construct a new RangedWeapon. + */ + public CombatPistol() { + super( + (short) 8, + "Combat Pistol", //Name + WeaponType.PISTOL, //Weapon Type + AmmoType.PISTOL, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 71).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_FIREWORK_BLAST, + Sound.ITEM_ARMOR_EQUIP_LEATHER, + Sound.ITEM_ARMOR_EQUIP_LEATHER, + Sound.BLOCK_NOTE_HAT, + }, + Effect.CRIT //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.WOOD_PICKAXE).setName(getName()).build()); + setDescription("Standard Military grade", "Pistol, Don't bring it", "to a proper gunfight."); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.2; //Weapon + this.delay = 5; //Weapon + + this.damage = 4; //RangedWeapon + this.meleeDamage = 3.0; //RangedWeapon + this.accuracy = 0.015; //RangedWeapon + this.magSize = 12; //RangedWeapon + this.reloadTime = 30; //RangedWeapon + this.range = 30; //RangedWeapon + this.zoom = 4; //RangedWeapon + } + + @Override + public Location spawnVisual(World world) { + Location origin = getOrigin(world); + ArmorStand glass = spawnEntity(origin.clone(), this, WeaponVisualStatue.VisualType.NAME); + glass.setHelmet(new ItemStack(Material.GLASS)); + + ArmorStand weapon = spawnEntity(origin.clone().add(-0.12, 0.2, -1.05), this, WeaponVisualStatue.VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setRightArmPose(new EulerAngle(0, AngleUtil.getRadianFromDegree(25), AngleUtil.getRadianFromDegree(90))); + weapon.setMarker(true); + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -359.5, 25.5, 233.5, -90.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.25)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/pistol/HeavyPistol.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/pistol/HeavyPistol.java new file mode 100644 index 0000000..5a30949 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/pistol/HeavyPistol.java @@ -0,0 +1,101 @@ +package net.grandtheftmc.gtm.weapon.ranged.pistol; + +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import org.bukkit.*; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.PistolWeapon; +import org.bukkit.entity.ArmorStand; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class HeavyPistol extends PistolWeapon implements WeaponVisualStatue { + + /** + * Construct a new RangedWeapon. + */ + public HeavyPistol() { + super( + (short) 9, + "Heavy Pistol", //Name + WeaponType.PISTOL, //Weapon Type + AmmoType.PISTOL, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 81).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_FIREWORK_BLAST, + Sound.ITEM_ARMOR_EQUIP_LEATHER, + Sound.ITEM_ARMOR_EQUIP_LEATHER, + Sound.BLOCK_NOTE_HAT, + }, + Effect.CRIT //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.WOOD_AXE).setName(getName()).build()); + setDescription("Like the" + (Core.getSettings().isSister() ? "" : " bitch") + " basic", "pistol, but bigger.", "And badder."); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.2; //Weapon + this.delay = 6; //Weapon + + this.damage = 5.5; //RangedWeapon + this.meleeDamage = 5.0; //RangedWeapon + this.accuracy = 0.01; //RangedWeapon + this.magSize = 18; //RangedWeapon + this.reloadTime = 40; //RangedWeapon + this.range = 35; //RangedWeapon + this.zoom = 4; //RangedWeapon + } + + @Override + public Location spawnVisual(World world) { + Location origin = getOrigin(world); + ArmorStand glass = spawnEntity(origin.clone(), this, WeaponVisualStatue.VisualType.NAME); + glass.setHelmet(new ItemStack(Material.GLASS)); + + ArmorStand weapon = spawnEntity(origin.clone().add(-0.12, 0.2, -1.05), this, WeaponVisualStatue.VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setRightArmPose(new EulerAngle(0, AngleUtil.getRadianFromDegree(25), AngleUtil.getRadianFromDegree(90))); + weapon.setMarker(true); + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -359.5, 25.5, 234.5, -90.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.25)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/pistol/MarksmanPistol.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/pistol/MarksmanPistol.java new file mode 100644 index 0000000..d06aa74 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/pistol/MarksmanPistol.java @@ -0,0 +1,105 @@ +package net.grandtheftmc.gtm.weapon.ranged.pistol; + +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import org.bukkit.*; + +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.attribute.RankedWeapon; +import net.grandtheftmc.guns.weapon.ranged.guns.PistolWeapon; +import org.bukkit.entity.ArmorStand; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class MarksmanPistol extends PistolWeapon implements RankedWeapon, WeaponVisualStatue { + + /** + * Construct a new RangedWeapon. + */ + public MarksmanPistol() { + super( + (short) 10, + "Marksman Pistol", //Name + WeaponType.PISTOL, //Weapon Type + AmmoType.PISTOL, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 91).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_FIREWORK_BLAST, + Sound.ITEM_ARMOR_EQUIP_LEATHER, + Sound.ITEM_ARMOR_EQUIP_LEATHER, + Sound.BLOCK_NOTE_HAT, + }, + Effect.CRIT //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.WOOD_HOE).setName(getName()).build()); + setDescription("For when you can't afford", "a real sniper rifle."); + + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.2; //Weapon + this.delay = 47; //Weapon + + this.damage = 12.5; //RangedWeapon + this.meleeDamage = 4.0; //RangedWeapon + this.accuracy = 0.03; //RangedWeaponz + this.magSize = 1; //RangedWeapon + this.reloadTime = 50; //RangedWeapon + this.range = 30; //RangedWeapon + this.zoom = 4; //RangedWeapon + } + + @Override + public UserRank requiredRank() { + return UserRank.VIP; + } + + @Override + public Location spawnVisual(World world) { + Location origin = getOrigin(world); + ArmorStand glass = spawnEntity(origin.clone(), this, WeaponVisualStatue.VisualType.NAME); + glass.setHelmet(new ItemStack(Material.GLASS)); + + ArmorStand weapon = spawnEntity(origin.clone().add(-0.12, 0.2, -1.1625), this, WeaponVisualStatue.VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setRightArmPose(new EulerAngle(0, AngleUtil.getRadianFromDegree(25), AngleUtil.getRadianFromDegree(90))); + weapon.setMarker(true); + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -359.5, 25.5, 235.5, -90.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.25)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/pistol/Pistol.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/pistol/Pistol.java new file mode 100644 index 0000000..f90aa55 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/pistol/Pistol.java @@ -0,0 +1,103 @@ +package net.grandtheftmc.gtm.weapon.ranged.pistol; + +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import org.bukkit.*; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.PistolWeapon; +import org.bukkit.entity.ArmorStand; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class Pistol extends PistolWeapon implements WeaponVisualStatue { + + /** + * Construct a new RangedWeapon. + */ + public Pistol() { + super( + (short) 6, + "Pistol", //Name + WeaponType.PISTOL, //Weapon Type + AmmoType.PISTOL, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 51).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_FIREWORK_BLAST, + Sound.ITEM_ARMOR_EQUIP_LEATHER, + Sound.ITEM_ARMOR_EQUIP_LEATHER, + Sound.BLOCK_NOTE_HAT, + }, + Effect.CRIT //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.WOOD_SWORD).setName(getName()).build()); + setDescription((Core.getSettings().isSister() ? "." : "Bitch ") + "basic pistol,", "great for scaring the cat"); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.2; //Weapon + this.delay = 5; //Weapon + + this.damage = 3.5; //RangedWeapon + this.meleeDamage = 3.0; //RangedWeapon + this.accuracy = 0.02; //RangedWeapon + this.magSize = 12; //RangedWeapon + this.reloadTime = 40; //RangedWeapon + this.range = 25; //RangedWeapon + this.zoom = 4; //RangedWeapon + } + + @Override + public Location spawnVisual(World world) { + Location origin = getOrigin(world); + ArmorStand glass = spawnEntity(origin.clone(), this, VisualType.NAME); + glass.setHelmet(new ItemStack(Material.GLASS)); + + ArmorStand weapon = spawnEntity(origin.clone().add(-0.12, 0.2, -1.05), this, VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setRightArmPose(new EulerAngle(0, AngleUtil.getRadianFromDegree(25), AngleUtil.getRadianFromDegree(90))); + weapon.setMarker(true); + + + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -359.5, 25.5, 231.5, -90.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.25)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/pistol/StunGun.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/pistol/StunGun.java new file mode 100644 index 0000000..646ecab --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/pistol/StunGun.java @@ -0,0 +1,108 @@ +package net.grandtheftmc.gtm.weapon.ranged.pistol; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.PistolWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class StunGun extends PistolWeapon implements WeaponVisualStatue { + + /** + * Construct a new RangedWeapon. + */ + public StunGun() { + super( + (short) 7, + "Stun Gun", //Name + WeaponType.PISTOL, //Weapon Type + AmmoType.NONE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 61).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.BLOCK_DISPENSER_DISPENSE, + Sound.ITEM_ARMOR_EQUIP_LEATHER, + Sound.ITEM_ARMOR_EQUIP_LEATHER, + Sound.BLOCK_NOTE_HAT, + }, + Effect.MAGIC_CRIT //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.WOOD_SPADE).setName(getName()).build()); + setDescription("Nothing quite like", "50,000 volts straight", "to the " + (Core.getSettings().isSister() ? "head." : "nipples.")); + + setSupportedAttachments(Attachment.GRIP); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.2; //Weapon + this.delay = 47; //Weapon + + this.damage = 2.5; //RangedWeapon + this.meleeDamage = 3.0; //RangedWeaponz + this.accuracy = 0.015 ; //RangedWeapon + this.magSize = 1; //RangedWeapon + this.reloadTime = 40; //RangedWeapon + this.range = 20; //RangedWeapon + this.zoom = 0; //RangedWeapon + + this.stun = true; //PistolWeapon + this.duration = 120; //PistolWeapon + } + + @Override + public Location spawnVisual(World world) { + Location origin = getOrigin(world); + ArmorStand glass = spawnEntity(origin.clone(), this, WeaponVisualStatue.VisualType.NAME); + glass.setHelmet(new ItemStack(Material.GLASS)); + + ArmorStand weapon = spawnEntity(origin.clone().add(-0.12, 0.2, -1.05), this, WeaponVisualStatue.VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setRightArmPose(new EulerAngle(0, AngleUtil.getRadianFromDegree(25), AngleUtil.getRadianFromDegree(90))); + weapon.setMarker(true); + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -359.5, 25.5, 232.5, -90.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.25)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/shotgun/AssaultShotgun.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/shotgun/AssaultShotgun.java new file mode 100644 index 0000000..390eac4 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/shotgun/AssaultShotgun.java @@ -0,0 +1,116 @@ +package net.grandtheftmc.gtm.weapon.ranged.shotgun; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.ShotgunWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class AssaultShotgun extends ShotgunWeapon implements WeaponVisualStatue { + + /** + * Construct a new RangedWeapon. + */ + public AssaultShotgun() { + super( + (short) 19, + "Assault Shotgun", //Name + WeaponType.SHOTGUN, //Weapon Type + AmmoType.SHOTGUN, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 181).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_ZOMBIE_ATTACK_DOOR_WOOD, + Sound.ITEM_ARMOR_EQUIP_CHAIN, + Sound.ITEM_ARMOR_EQUIP_CHAIN, + Sound.ENTITY_IRONGOLEM_ATTACK, + }, + Effect.SMALL_SMOKE //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.GOLD_AXE).setName(getName()).build()); + setDescription("Aggressive? Yes.", "Overkill? Most definitely."); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.14; //Weapon + this.delay = 5; + + this.damage = 4.0; //RangedWeapon + this.meleeDamage = 5.0; //RangedWeapon + //this.accuracy = 0.035; //RangedWeapon + this.accuracy = 0.15; //RangedWeapon + this.magSize = 8; //RangedWeapon + this.reloadTime = 40; //RangedWeapon + this.range = 8; //RangedWeapon + this.recoil = 0.15; //RangedWeapon + this.zoom = 2; //RangedWeapon + + this.shellSize = 6; //AssultRifleWeapon + } + + @Override + public Location spawnVisual(World world) { + Location origin = this.getOrigin(world); + ArmorStand clickable = spawnEntity(origin.clone().add(0, 1.5, 0), this, WeaponVisualStatue.VisualType.NAME); + clickable.setSmall(true); + + ArmorStand weapon = spawnEntity(origin.clone().add(-0.35, 0.02, -0.1), this, WeaponVisualStatue.VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setRightArmPose(new EulerAngle(AngleUtil.getRadianFromDegree(180), 0, AngleUtil.getRadianFromDegree(20))); + weapon.setMarker(true); + +// Location hookLoc = origin.clone().add(0.045, 1.02, -0.68); +// hookLoc.setPitch(0); +// hookLoc.setYaw(0); +// ArmorStand hook = spawnEntity(hookLoc, this, WeaponVisualStatue.VisualType.NONE); +// hook.setHelmet(new ItemStack(Material.TRIPWIRE_HOOK)); +// hook.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(45), 0, 0)); +// hook.setSmall(true); +// hook.setMarker(true); + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -376.5, 25.5, 237.5, 180.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.5)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/shotgun/HeavyShotgun.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/shotgun/HeavyShotgun.java new file mode 100644 index 0000000..54931e6 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/shotgun/HeavyShotgun.java @@ -0,0 +1,123 @@ +package net.grandtheftmc.gtm.weapon.ranged.shotgun; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.attribute.RankedWeapon; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.ShotgunWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class HeavyShotgun extends ShotgunWeapon implements RankedWeapon, WeaponVisualStatue { + + /** + * Construct a new RangedWeapon. + */ + public HeavyShotgun() { + super( + (short) 20, + "Heavy Shotgun", //Name + WeaponType.SHOTGUN, //Weapon Type + AmmoType.SHOTGUN, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 191).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_ZOMBIE_ATTACK_DOOR_WOOD, + Sound.ITEM_ARMOR_EQUIP_CHAIN, + Sound.ITEM_ARMOR_EQUIP_CHAIN, + Sound.ENTITY_IRONGOLEM_ATTACK, + }, + Effect.SMALL_SMOKE //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.GOLD_HOE).setName(getName()).build()); + setDescription("Like your normal shotgun,", "but even heftier."); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.12; //Weapon + this.delay = 6; + + this.damage = 6.5; //RangedWeapon + this.meleeDamage = 6.0; //RangedWeapon + //this.accuracy = 0.075; //RangedWeapon + this.accuracy = 0.15; //RangedWeapon + this.magSize = 6; //RangedWeapon + this.reloadTime = 40; //RangedWeapon + this.range = 8; //RangedWeapon + this.recoil = 0.15; //RangedWeapon + this.zoom = 3; //RangedWeapon + + this.shellSize = 6; //AssultRifleWeapon + } + + @Override + public UserRank requiredRank() { + return UserRank.VIP; + } + + @Override + public Location spawnVisual(World world) { + Location origin = this.getOrigin(world); + ArmorStand clickable = spawnEntity(origin.clone().add(0, 1.5, 0), this, WeaponVisualStatue.VisualType.NAME); + clickable.setSmall(true); + + ArmorStand weapon = spawnEntity(origin.clone().add(-0.35, 0.08, -0.1), this, WeaponVisualStatue.VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setRightArmPose(new EulerAngle(AngleUtil.getRadianFromDegree(180), 0, AngleUtil.getRadianFromDegree(20))); + weapon.setMarker(true); + +// Location hookLoc = origin.clone().add(0.045, 1.02, -0.68); +// hookLoc.setPitch(0); +// hookLoc.setYaw(0); +// ArmorStand hook = spawnEntity(hookLoc, this, WeaponVisualStatue.VisualType.NONE); +// hook.setHelmet(new ItemStack(Material.TRIPWIRE_HOOK)); +// hook.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(45), 0, 0)); +// hook.setSmall(true); +// hook.setMarker(true); + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -376.5, 25.5, 236.5, 180.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.5)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/shotgun/Musket.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/shotgun/Musket.java new file mode 100644 index 0000000..26281f7 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/shotgun/Musket.java @@ -0,0 +1,113 @@ +package net.grandtheftmc.gtm.weapon.ranged.shotgun; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.guns.ShotgunWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class Musket extends ShotgunWeapon implements WeaponVisualStatue { + + /** + * Construct a new RangedWeapon. + */ + public Musket() { + super( + (short) 18, + "Musket", //Name + WeaponType.SHOTGUN, //Weapon Type + AmmoType.SHOTGUN, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 171).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_ZOMBIE_ATTACK_DOOR_WOOD, + Sound.ITEM_ARMOR_EQUIP_CHAIN, + Sound.ITEM_ARMOR_EQUIP_CHAIN, + Sound.ENTITY_IRONGOLEM_ATTACK, + }, + Effect.SMOKE //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.GOLD_PICKAXE).setName(getName()).build()); + setDescription("Great if you want to", "roleplay a battle in 1776"); + + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.14; //Weapon + this.delay = 82; + + this.damage = 20; //RangedWeapon + this.meleeDamage = 4.0; //RangedWeapon + this.accuracy = 0.025; //RangedWeapon + this.magSize = 1; //RangedWeapon + this.reloadTime = 90; //RangedWeapon + this.range = 100; //RangedWeapon + this.recoil = 0.4; //RangedWeapon + this.zoom = 4; //RangedWeapon + + this.shellSize = 1; //AssultRifleWeapon + } + + @Override + public Location spawnVisual(World world) { + Location origin = this.getOrigin(world); + ArmorStand clickable = spawnEntity(origin.clone().add(0, 1.5, 0), this, WeaponVisualStatue.VisualType.NAME); + clickable.setSmall(true); + + ArmorStand weapon = spawnEntity(origin.clone().add(-0.2, -0.05, -0.2), this, WeaponVisualStatue.VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setRightArmPose(new EulerAngle(AngleUtil.getRadianFromDegree(180), 0, AngleUtil.getRadianFromDegree(20))); + weapon.setMarker(true); + +// Location hookLoc = origin.clone().add(0.045, 1.02, -0.68); +// hookLoc.setPitch(0); +// hookLoc.setYaw(0); +// ArmorStand hook = spawnEntity(hookLoc, this, WeaponVisualStatue.VisualType.NONE); +// hook.setHelmet(new ItemStack(Material.TRIPWIRE_HOOK)); +// hook.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(45), 0, 0)); +// hook.setSmall(true); +// hook.setMarker(true); + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -376.5, 25.5, 238.5, 180.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.5)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/shotgun/PumpShotgun.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/shotgun/PumpShotgun.java new file mode 100644 index 0000000..66d0905 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/shotgun/PumpShotgun.java @@ -0,0 +1,115 @@ +package net.grandtheftmc.gtm.weapon.ranged.shotgun; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.guns.ShotgunWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class PumpShotgun extends ShotgunWeapon implements WeaponVisualStatue { + + /** + * Construct a new RangedWeapon. + */ + public PumpShotgun() { + super( + (short) 17, + "Pump Shotgun", //Name + WeaponType.SHOTGUN, //Weapon Type + AmmoType.SHOTGUN, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 161).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_ZOMBIE_ATTACK_DOOR_WOOD, + Sound.ITEM_ARMOR_EQUIP_CHAIN, + Sound.ITEM_ARMOR_EQUIP_CHAIN, + Sound.ENTITY_IRONGOLEM_ATTACK, + }, + Effect.SMALL_SMOKE //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.GOLD_SPADE).setName(getName()).build()); + setDescription("Standard, solid shotgun.", "This'll keep you going."); + + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.14; //Weapon + this.delay = 13; + + this.damage = 2.5; //RangedWeapon + this.meleeDamage = 5.0; //RangedWeapon + //this.accuracy = 0.025; //RangedWeapon + this.accuracy = 0.12; //RangedWeapon + this.magSize = 8; //RangedWeapon + this.reloadTime = 56; //RangedWeapon + this.range = 10; //RangedWeapon + this.recoil = 0.25; //RangedWeapon + this.zoom = 6; //RangedWeapon + this.reloadShoot = true; + + this.shellSize = 8; //AssultRifleWeapon + } + + @Override + public Location spawnVisual(World world) { + Location origin = this.getOrigin(world); + ArmorStand clickable = spawnEntity(origin.clone().add(0, 1.5, 0), this, WeaponVisualStatue.VisualType.NAME); + clickable.setSmall(true); + + ArmorStand weapon = spawnEntity(origin.clone().add(-0.35, 0.08, -0.1), this, WeaponVisualStatue.VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setRightArmPose(new EulerAngle(AngleUtil.getRadianFromDegree(180), 0, AngleUtil.getRadianFromDegree(20))); + weapon.setMarker(true); + +// Location hookLoc = origin.clone().add(0.045, 1.02, -0.68); +// hookLoc.setPitch(0); +// hookLoc.setYaw(0); +// ArmorStand hook = spawnEntity(hookLoc, this, WeaponVisualStatue.VisualType.NONE); +// hook.setHelmet(new ItemStack(Material.TRIPWIRE_HOOK)); +// hook.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(45), 0, 0)); +// hook.setSmall(true); +// hook.setMarker(true); + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -376.5, 25.5, 239.5, 180.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.5)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/shotgun/SawedoffShotgun.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/shotgun/SawedoffShotgun.java new file mode 100644 index 0000000..2e31408 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/shotgun/SawedoffShotgun.java @@ -0,0 +1,115 @@ +package net.grandtheftmc.gtm.weapon.ranged.shotgun; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.guns.ShotgunWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class SawedoffShotgun extends ShotgunWeapon implements WeaponVisualStatue { + + /** + * Construct a new RangedWeapon. + */ + public SawedoffShotgun() { + super( + (short) 16, + "Sawed-off Shotgun", //Name + WeaponType.SHOTGUN, //Weapon Type + AmmoType.SHOTGUN, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 151).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_ZOMBIE_ATTACK_DOOR_WOOD, + Sound.ITEM_ARMOR_EQUIP_CHAIN, + Sound.ITEM_ARMOR_EQUIP_CHAIN, + Sound.ENTITY_IRONGOLEM_ATTACK, + }, + Effect.SMALL_SMOKE //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.GOLD_SWORD).setName(getName()).build()); + setDescription("Yehaw, time t'shoot me", "some uppities!"); + + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.18; //Weapon + this.delay = 18; + + this.damage = 3.0; //RangedWeapon + this.meleeDamage = 4.0; //RangedWeapon + //this.accuracy = 0.04; //RangedWeapon + this.accuracy = 0.18; //RangedWeapon + this.magSize = 2; //RangedWeapon + this.reloadTime = 20; //RangedWeapon + this.range = 10; //RangedWeapon + this.recoil = 0.3; //RangedWeapon + this.zoom = 6; //RangedWeapon + this.reloadShoot = true; + + this.shellSize = 8; //AssultRifleWeapon + } + + @Override + public Location spawnVisual(World world) { + Location origin = this.getOrigin(world); + ArmorStand clickable = spawnEntity(origin.clone().add(0, 1.5, 0), this, WeaponVisualStatue.VisualType.NAME); + clickable.setSmall(true); + + ArmorStand weapon = spawnEntity(origin.clone().add(-0.35, -0.2, -0.2), this, WeaponVisualStatue.VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setRightArmPose(new EulerAngle(AngleUtil.getRadianFromDegree(180), 0, AngleUtil.getRadianFromDegree(20))); + weapon.setMarker(true); + +// Location hookLoc = origin.clone().add(0.045, 1.02, -0.68); +// hookLoc.setPitch(0); +// hookLoc.setYaw(0); +// ArmorStand hook = spawnEntity(hookLoc, this, WeaponVisualStatue.VisualType.NONE); +// hook.setHelmet(new ItemStack(Material.TRIPWIRE_HOOK)); +// hook.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(45), 0, 0)); +// hook.setSmall(true); +// hook.setMarker(true); + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -376.5, 25.5, 240.5, 180.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.5)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/smg/AssaultSMG.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/smg/AssaultSMG.java new file mode 100644 index 0000000..d4420b4 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/smg/AssaultSMG.java @@ -0,0 +1,117 @@ +package net.grandtheftmc.gtm.weapon.ranged.smg; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.SMGWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class AssaultSMG extends SMGWeapon implements WeaponVisualStatue { + + /** + * Construct a new RangedWeapon. + */ + public AssaultSMG() { + super( + (short) 13, + "Assault SMG", //Name + WeaponType.SMG, //Weapon Type + AmmoType.SMG, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 121).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_BLAZE_HURT, + Sound.ITEM_ARMOR_EQUIP_GOLD, + Sound.ITEM_ARMOR_EQUIP_GOLD, + Sound.BLOCK_WOODEN_DOOR_OPEN, + }, + Effect.FLYING_GLYPH //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.IRON_PICKAXE).setName(getName()).build()); + setDescription("A solid,", "Military grade weapon.", "Good for mowing down enemies."); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.2; //Weapon + + this.damage = 2.0; //RangedWeapon + this.meleeDamage = 4.0; //RangedWeapon + this.accuracy = 0.03; //RangedWeapon + this.magSize = 30; //RangedWeapon + this.reloadTime = 50; //RangedWeapon + this.range = 35; //RangedWeapon + this.recoil = 0.0; //RangedWeapon + this.zoom = 4; //RangedWeapon + + this.rpm = 460; //AssultRifleWeapon + this.rps = 7; + this.multiShoot = true; + } + + @Override + public Location spawnVisual(World world) { + Location origin = this.getOrigin(world); + ArmorStand clickable = spawnEntity(origin.clone().add(0, 1.5, 0), this, WeaponVisualStatue.VisualType.NAME); + clickable.setSmall(true); + + ArmorStand weapon = spawnEntity(origin.clone().add(0.2, -0.1, -0.4), this, WeaponVisualStatue.VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setRightArmPose(new EulerAngle(AngleUtil.getRadianFromDegree(180), 0, AngleUtil.getRadianFromDegree(20))); + weapon.setMarker(true); + + Location hookLoc = origin.clone().add(0.045, 1.02, -0.68); + hookLoc.setPitch(0); + hookLoc.setYaw(0); + ArmorStand hook = spawnEntity(hookLoc, this, WeaponVisualStatue.VisualType.NONE); + hook.setHelmet(new ItemStack(Material.TRIPWIRE_HOOK)); + hook.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(45), 0, 0)); + hook.setSmall(true); + hook.setMarker(true); + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -365.5, 25.5, 227.5, -90.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.5)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/smg/CombatPDW.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/smg/CombatPDW.java new file mode 100644 index 0000000..58613e5 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/smg/CombatPDW.java @@ -0,0 +1,117 @@ +package net.grandtheftmc.gtm.weapon.ranged.smg; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.SMGWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class CombatPDW extends SMGWeapon implements WeaponVisualStatue { + + /** + * Construct a new RangedWeapon. + */ + public CombatPDW() { + super( + (short) 14, + "Combat PDW", //Name + WeaponType.SMG, //Weapon Type + AmmoType.SMG, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 131).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_BLAZE_HURT, + Sound.ITEM_ARMOR_EQUIP_GOLD, + Sound.ITEM_ARMOR_EQUIP_GOLD, + Sound.BLOCK_WOODEN_DOOR_OPEN, + }, + Effect.FLYING_GLYPH //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.IRON_AXE).setName(getName()).build()); + setDescription("It's a defensive weapon.", "With a supressor.", "Thanks, Congress!"); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.2; //Weapon + + this.damage = 2.1; //RangedWeapon + this.meleeDamage = 4.0; //RangedWeapon + this.accuracy = 0.025; //RangedWeapon + this.magSize = 30; //RangedWeapon + this.reloadTime = 40; //RangedWeapon + this.range = 40; //RangedWeapon + this.recoil = 0.0; //RangedWeapon + this.zoom = 4; //RangedWeapon + + this.rpm = 450; //AssultRifleWeapon + this.rps = 7; + this.multiShoot = true; + } + + @Override + public Location spawnVisual(World world) { + Location origin = this.getOrigin(world); + ArmorStand clickable = spawnEntity(origin.clone().add(0, 1.5, 0), this, WeaponVisualStatue.VisualType.NAME); + clickable.setSmall(true); + + ArmorStand weapon = spawnEntity(origin.clone().add(0.2, -0.15, -0.38), this, WeaponVisualStatue.VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setRightArmPose(new EulerAngle(AngleUtil.getRadianFromDegree(180), 0, AngleUtil.getRadianFromDegree(20))); + weapon.setMarker(true); + + Location hookLoc = origin.clone().add(0.045, 1.07, -0.7); + hookLoc.setPitch(0); + hookLoc.setYaw(0); + ArmorStand hook = spawnEntity(hookLoc, this, WeaponVisualStatue.VisualType.NONE); + hook.setHelmet(new ItemStack(Material.TRIPWIRE_HOOK)); + hook.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(45), 0, 0)); + hook.setSmall(true); + hook.setMarker(true); + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -364.5, 25.5, 227.5, -90.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.5)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/smg/GusenbergSweeper.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/smg/GusenbergSweeper.java new file mode 100644 index 0000000..26fc0c4 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/smg/GusenbergSweeper.java @@ -0,0 +1,124 @@ +package net.grandtheftmc.gtm.weapon.ranged.smg; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.attribute.RankedWeapon; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.SMGWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class GusenbergSweeper extends SMGWeapon implements RankedWeapon, WeaponVisualStatue { + + /** + * Construct a new RangedWeapon. + */ + public GusenbergSweeper() { + super( + (short) 15, + "Gusenberg Sweeper", //Name + WeaponType.SMG, //Weapon Type + AmmoType.SMG, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 141).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_BLAZE_HURT, + Sound.ITEM_ARMOR_EQUIP_GOLD, + Sound.ITEM_ARMOR_EQUIP_GOLD, + Sound.BLOCK_WOODEN_DOOR_OPEN, + }, + Effect.FLYING_GLYPH //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.IRON_HOE).setName(getName()).build()); + setDescription("With this gun, you can", "make them an offer they", "can't refuse."); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.2; //Weapon + + this.damage = 2.25; //RangedWeapon + this.meleeDamage = 5.0; //RangedWeapon + this.accuracy = 0.025; //RangedWeapon + this.magSize = 50; //RangedWeapon + this.reloadTime = 40; //RangedWeapon + this.range = 40; //RangedWeapon + this.recoil = 0.0; //RangedWeapon + this.zoom = 2; //RangedWeapon + + this.rpm = 555; //AssultRifleWeapon + this.rps = 9; + this.multiShoot = true; + } + + @Override + public UserRank requiredRank() { + return UserRank.PREMIUM; + } + + @Override + public Location spawnVisual(World world) { + Location origin = this.getOrigin(world); + ArmorStand clickable = spawnEntity(origin.clone().add(0, 1.5, 0), this, WeaponVisualStatue.VisualType.NAME); + clickable.setSmall(true); + + ArmorStand weapon = spawnEntity(origin.clone().add(0.2, -0.06, -0.4), this, WeaponVisualStatue.VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setRightArmPose(new EulerAngle(AngleUtil.getRadianFromDegree(180), 0, AngleUtil.getRadianFromDegree(20))); + weapon.setMarker(true); + + Location hookLoc = origin.clone().add(0.01, 1.22, -0.75); + hookLoc.setPitch(0); + hookLoc.setYaw(0); + ArmorStand hook = spawnEntity(hookLoc, this, WeaponVisualStatue.VisualType.NONE); + hook.setHelmet(new ItemStack(Material.TRIPWIRE_HOOK)); + hook.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(45), 0, 0)); + hook.setSmall(true); + hook.setMarker(true); + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -363.5, 25.5, 227.5, -90.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.5)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/smg/MicroSMG.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/smg/MicroSMG.java new file mode 100644 index 0000000..76206f9 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/smg/MicroSMG.java @@ -0,0 +1,117 @@ +package net.grandtheftmc.gtm.weapon.ranged.smg; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.SMGWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class MicroSMG extends SMGWeapon implements WeaponVisualStatue { + + /** + * Construct a new RangedWeapon. + */ + public MicroSMG() { + super( + (short) 11, + "Micro SMG", //Name + WeaponType.SMG, //Weapon Type + AmmoType.SMG, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 101).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_BLAZE_HURT, + Sound.ITEM_ARMOR_EQUIP_GOLD, + Sound.ITEM_ARMOR_EQUIP_GOLD, + Sound.BLOCK_WOODEN_DOOR_OPEN, + }, + Effect.FLYING_GLYPH //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.IRON_SWORD).setName(getName()).build()); + setDescription("It's like a peashooter,", "on steriods."); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.2; //Weapon + + this.damage = 1.6; //RangedWeapon + this.meleeDamage = 4.0; //RangedWeapon + this.accuracy = 0.03; //RangedWeapon + this.magSize = 16; //RangedWeapon + this.reloadTime = 40; //RangedWeapon + this.range = 25; //RangedWeapon + this.recoil = 0.0; //RangedWeapon + this.zoom = 4; //RangedWeapon + + this.rpm = 600; //AssultRifleWeapon + this.rps = 10; + this.multiShoot = true; + } + + @Override + public Location spawnVisual(World world) { + Location origin = this.getOrigin(world); + ArmorStand clickable = spawnEntity(origin.clone().add(0, 1.5, 0), this, VisualType.NAME); + clickable.setSmall(true); + + ArmorStand weapon = spawnEntity(origin.clone().add(0.2, 0.21, -0.4), this, VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setRightArmPose(new EulerAngle(AngleUtil.getRadianFromDegree(180), 0, AngleUtil.getRadianFromDegree(20))); + weapon.setMarker(true); + + Location hookLoc = origin.clone().add(-0.03, 1.2, -0.64); + hookLoc.setPitch(0); + hookLoc.setYaw(0); + ArmorStand hook = spawnEntity(hookLoc, this, VisualType.NONE); + hook.setHelmet(new ItemStack(Material.TRIPWIRE_HOOK)); + hook.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(45), 0, 0)); + hook.setSmall(true); + hook.setMarker(true); + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -367.5, 25.5, 227.5, -90.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.5)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/smg/SMG.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/smg/SMG.java new file mode 100644 index 0000000..6681086 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/smg/SMG.java @@ -0,0 +1,117 @@ +package net.grandtheftmc.gtm.weapon.ranged.smg; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.SMGWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class SMG extends SMGWeapon implements WeaponVisualStatue { + + /** + * Construct a new RangedWeapon. + */ + public SMG() { + super( + (short) 12, + "SMG", //Name + WeaponType.SMG, //Weapon Type + AmmoType.SMG, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 111).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_BLAZE_HURT, + Sound.ITEM_ARMOR_EQUIP_GOLD, + Sound.ITEM_ARMOR_EQUIP_GOLD, + Sound.BLOCK_WOODEN_DOOR_OPEN, + }, + Effect.FLYING_GLYPH //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.IRON_SPADE).setName(getName()).build()); + setDescription("The intro to proper", "gang warfare."); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.2; //Weapon + + this.damage = 1.9; //RangedWeapon + this.meleeDamage = 4.0; //RangedWeapon + this.accuracy = 0.03; //RangedWeapon + this.magSize = 30; //RangedWeapon + this.reloadTime = 50; //RangedWeapon + this.range = 35; //RangedWeapon + this.recoil = 0.0; //RangedWeapon + this.zoom = 4; //RangedWeapon + + this.rpm = 510; //AssultRifleWeapon + this.rps = 9; + this.multiShoot = true; + } + + @Override + public Location spawnVisual(World world) { + Location origin = this.getOrigin(world); + ArmorStand clickable = spawnEntity(origin.clone().add(0, 1.5, 0), this, WeaponVisualStatue.VisualType.NAME); + clickable.setSmall(true); + + ArmorStand weapon = spawnEntity(origin.clone().add(0.2, -0.15, -0.35), this, WeaponVisualStatue.VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setRightArmPose(new EulerAngle(AngleUtil.getRadianFromDegree(180), 0, AngleUtil.getRadianFromDegree(20))); + weapon.setMarker(true); + + Location hookLoc = origin.clone().add(0, 1.05, -0.64); + hookLoc.setPitch(0); + hookLoc.setYaw(0); + ArmorStand hook = spawnEntity(hookLoc, this, WeaponVisualStatue.VisualType.NONE); + hook.setHelmet(new ItemStack(Material.TRIPWIRE_HOOK)); + hook.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(45), 0, 0)); + hook.setSmall(true); + hook.setMarker(true); + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -366.5, 25.5, 227.5, -90.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.5)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/sniper/HeavySniper.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/sniper/HeavySniper.java new file mode 100644 index 0000000..659d03e --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/sniper/HeavySniper.java @@ -0,0 +1,124 @@ +package net.grandtheftmc.gtm.weapon.ranged.sniper; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.attribute.RankedWeapon; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.SniperWeapon; +import org.bukkit.*; +import org.bukkit.entity.ArmorStand; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class HeavySniper extends SniperWeapon implements RankedWeapon, WeaponVisualStatue { + + /** + * Construct a new RangedWeapon. + */ + public HeavySniper() { + super( + (short) 29, + "Heavy Sniper", //Name + WeaponType.SNIPER, //Weapon Type + AmmoType.SNIPER, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 281).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_IRONGOLEM_HURT, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.BLOCK_PISTON_EXTEND, + }, + Effect.CLOUD //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.DIAMOND_AXE).setName(getName()).build()); + setDescription("When you really like", "killing people without", "getting your hands dirty."); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.GRIP, Attachment.ADVANCED_SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.14; //Weapon + this.delay = 40; + + this.damage = 20; //RangedWeapon + this.meleeDamage = 6.0; //RangedWeapon + this.accuracy = 0.003; //RangedWeapon + this.magSize = 6; //RangedWeapon + this.reloadTime = 80; //RangedWeapon + this.range = 100; //RangedWeapon + this.recoil = 0.3; //RangedWeapon + this.zoom = 9; //RangedWeapon + } + + @Override + public UserRank requiredRank() { + return UserRank.ELITE; + } + + @Override + public Location spawnVisual(World world) { + Location origin = this.getOrigin(world); + + Location clickLoc = origin.clone().add(0, 0.2, 0.6); + clickLoc.setYaw(90); + ArmorStand clickable = spawnEntity(clickLoc, this, WeaponVisualStatue.VisualType.NAME); +// clickable.setVisible(true); + + Location clickLoc2 = origin.clone().add(0, 0.2, 0); + clickLoc2.setYaw(90); + ArmorStand clickable2 = spawnEntity(clickLoc2, this, WeaponVisualStatue.VisualType.NAME); +// clickable2.setVisible(true); + + Location weaponLoc = origin.clone().add(0.3, 0.28, -0.7); + ArmorStand weapon = spawnEntity(weaponLoc, this, WeaponVisualStatue.VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setRightArmPose(new EulerAngle(AngleUtil.getRadianFromDegree(280), 0f, 0f)); + weapon.setMarker(true); + +// ArmorStand support = spawnEntity(origin.clone().add(-1.75, -0.34, 0.25), this, WeaponVisualStatue.VisualType.NONE); +// support.setHelmet(new ItemStack(Material.END_ROD)); +// support.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(300), 0f, 0f)); +// support.setMarker(true); + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -373.5, 25.5, 235.5, 0.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.25)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/sniper/SniperRifle.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/sniper/SniperRifle.java new file mode 100644 index 0000000..598dc89 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/sniper/SniperRifle.java @@ -0,0 +1,113 @@ +package net.grandtheftmc.gtm.weapon.ranged.sniper; + +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.SniperWeapon; +import org.bukkit.*; +import org.bukkit.entity.ArmorStand; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class SniperRifle extends SniperWeapon implements WeaponVisualStatue { + + /** + * Construct a new RangedWeapon. + */ + public SniperRifle() { + super( + (short) 28, + "Sniper Rifle", //Name + WeaponType.SNIPER, //Weapon Type + AmmoType.SNIPER, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 271).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_IRONGOLEM_HURT, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.BLOCK_PISTON_EXTEND, + }, + Effect.CLOUD //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.DIAMOND_PICKAXE).setName(getName()).build()); + setDescription("When you like killing", "people without getting", "your hands dirty."); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.GRIP, Attachment.ADVANCED_SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.14; //Weapon + this.delay = 50; + + this.damage = 18; //RangedWeapon + this.meleeDamage = 5.0; //RangedWeapon + this.accuracy = 0.005; //RangedWeapon + this.magSize = 10; //RangedWeapon + this.reloadTime = 80; //RangedWeapon + this.range = 95; //RangedWeapon + this.recoil = 0.3; //RangedWeapon + this.zoom = 8; //RangedWeapon + } + + @Override + public Location spawnVisual(World world) { + Location origin = this.getOrigin(world); + + Location clickLoc = origin.clone().add(0, 0.2, -0.6); + clickLoc.setYaw(90); + ArmorStand clickable = spawnEntity(clickLoc, this, WeaponVisualStatue.VisualType.NAME); +// clickable.setVisible(true); + + Location clickLoc2 = origin.clone().add(0, 0.2, 0); + clickLoc2.setYaw(90); + ArmorStand clickable2 = spawnEntity(clickLoc2, this, WeaponVisualStatue.VisualType.NAME); +// clickable2.setVisible(true); + + Location weaponLoc = origin.clone().add(0.3, 0.28, -1.2); + ArmorStand weapon = spawnEntity(weaponLoc, this, WeaponVisualStatue.VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setRightArmPose(new EulerAngle(AngleUtil.getRadianFromDegree(280), 0f, 0f)); + weapon.setMarker(true); + +// ArmorStand support = spawnEntity(origin.clone().add(-1.75, -0.34, 0.25), this, WeaponVisualStatue.VisualType.NONE); +// support.setHelmet(new ItemStack(Material.END_ROD)); +// support.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(300), 0f, 0f)); +// support.setMarker(true); + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -373.5, 25.5, 233.5, 0.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.25)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/special/Clausinator.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/special/Clausinator.java new file mode 100644 index 0000000..197408c --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/special/Clausinator.java @@ -0,0 +1,51 @@ +package net.grandtheftmc.gtm.weapon.ranged.special; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.inventory.ItemStack; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.guns.PistolWeapon; + +/** + * Created by Timothy Lampen on 2017-12-12. + */ +public class Clausinator extends PistolWeapon { + public Clausinator() { + super( + (short) 50, + "Clausinator", //Name + WeaponType.CLAUSINATOR, //Weapon Type + AmmoType.NONE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 1011).build(), + new Sound[] { //Gun Sounds + Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ITEM_FLINTANDSTEEL_USE, + }, + Effect.FLYING_GLYPH //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setDescription("Snowball fight!"); + + setOldItemStack(new ItemStack(Material.ACACIA_DOOR_ITEM)); + + + + this.walkSpeed = 0.1; //Weapon + this.delay = 40; //Weapon + + this.damage = 0.001; //RangedWeapon + this.meleeDamage = 3.0; //RangedWeapon + this.accuracy = 0.025; //RangedWeapon + this.magSize = 600; //RangedWeapon + this.reloadTime = 40; //RangedWeapon + this.range = 25; //RangedWeapon + this.zoom = 4; //RangedWeapon + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/special/Flamethrower.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/special/Flamethrower.java new file mode 100644 index 0000000..ea4472b --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/special/Flamethrower.java @@ -0,0 +1,85 @@ +package net.grandtheftmc.gtm.weapon.ranged.special; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.ShotgunWeapon; + +/** + * Created by Luke Bingham on 03/08/2017. + */ +public class Flamethrower extends ShotgunWeapon { + + /** + * Construct a new RangedWeapon. + */ + public Flamethrower() { + super( + (short) 40, + "Flamethrower", //Name + WeaponType.FLAMETHROWER, //TODO Weapon Type + AmmoType.NONE, //TODO AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 391).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ITEM_FIRECHARGE_USE, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.UI_BUTTON_CLICK, + }, + Effect.MOBSPAWNER_FLAMES //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.FLINT_AND_STEEL).setDurability((short) 10).setName(getName()).build()); + setDescription("Is it me, or is it", "getting hot in here?"); + + setSupportedAttachments(Attachment.GRIP); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.2; //Weapon + this.delay = 2; + + this.damage = 3.0; //RangedWeapon + this.meleeDamage = 3.0; //RangedWeapon + this.accuracy = 0.04; //RangedWeapon + this.magSize = 25; //RangedWeapon + this.reloadTime = 100; //RangedWeapon + this.range = 25; //RangedWeapon + this.recoil = 0.001; //RangedWeapon + this.zoom = 3; //RangedWeapon + this.shellSize = 5; + +// this.flamethrower = true; //SpecialWeapon +// this.rpm = 200; //SpecialWeapon + } + + @Override + public int getRpm() { + return 200; + } + + @Override + public boolean isAutomatic() { + return true; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/special/GoldMinigun.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/special/GoldMinigun.java new file mode 100644 index 0000000..4cfc511 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/special/GoldMinigun.java @@ -0,0 +1,83 @@ +package net.grandtheftmc.gtm.weapon.ranged.special; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.attribute.RankedWeapon; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.SpecialWeapon; + +/** + * Created by Luke Bingham on 03/08/2017. + */ +public class GoldMinigun extends SpecialWeapon implements RankedWeapon { + + /** + * Construct a new RangedWeapon. + */ + public GoldMinigun() { + super( + (short) 42, + "Gold Minigun", //Name + WeaponType.MINIGUN, //Weapon Type + AmmoType.MINIGUN, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 411).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ITEM_FLINTANDSTEEL_USE, + }, + Effect.FLYING_GLYPH //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.DIAMOND_HOE).setDurability((short) -1/* IDK?.. */).setName(getName()).build());//TODO Unknown at the moment. + setDescription("Is it me, or is it", "getting hot in here?"); + + setSupportedAttachments(Attachment.GRIP); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.1; //Weapon + + this.damage = 2.25; //RangedWeapon + this.meleeDamage = 3.0; //RangedWeapon + this.accuracy = 0.05; //RangedWeapon + this.magSize = 600; //RangedWeapon + this.reloadTime = 100; //RangedWeapon + this.range = 55; //RangedWeapon + this.recoil = 0.05; //RangedWeapon + this.zoom = 3; //RangedWeapon + this.reloadShoot = true; + + this.minigun = true; //SpecialWeapon + this.rpm = 1200; //SpecialWeapon + this.rps = 20; + this.multiShoot = true; + } + + @Override + public UserRank requiredRank() { + return UserRank.SUPREME; + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/special/Handcuffs.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/special/Handcuffs.java new file mode 100644 index 0000000..e284d5f --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/special/Handcuffs.java @@ -0,0 +1,43 @@ +package net.grandtheftmc.gtm.weapon.ranged.special; + +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.inventory.ItemStack; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.MeleeWeapon; +import net.grandtheftmc.guns.weapon.WeaponType; + +/** + * Created by Timothy Lampen on 2017-11-22. + */ +public class Handcuffs extends MeleeWeapon { + public Handcuffs() { + super((short) 57, + "Handcuffs", + WeaponType.MELEE, + AmmoType.MELEE, + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 1003).build(), + new Sound[] { + Sound.ENTITY_SKELETON_SHOOT, + Sound.ITEM_ARMOR_EQUIP_GENERIC, + Sound.ITEM_ARMOR_EQUIP_GENERIC + }); + setOldItemStack(new ItemStack(Material.ACACIA_DOOR)); + setDescription("Multipurpose tool", "for work or for kink"); + + + this.delay = 10; + this.meleeDamage = 1.0; + } + +// @Override +// public void onHit(EntityDamageByEntityEvent event){ +// if(event.getDamager() instanceof Player && event.getEntity() instanceof Player){ +// Player player = (Player)event.getDamager(); +// Player victim = (Player)event.getEntity(); +// GTMUtils.arrestPlayer(event, this, player, victim); +// } +// } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/special/Minigun.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/special/Minigun.java new file mode 100644 index 0000000..949c205 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/ranged/special/Minigun.java @@ -0,0 +1,129 @@ +package net.grandtheftmc.gtm.weapon.ranged.special; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; + +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.AngleUtil; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.weapon.WeaponVisualStatue; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.attribute.RankedWeapon; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.SpecialWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class Minigun extends SpecialWeapon implements RankedWeapon, WeaponVisualStatue { + + /** + * Construct a new RangedWeapon. + */ + public Minigun() { + super( + (short) 33, + "Minigun", //Name + WeaponType.MINIGUN, //Weapon Type + AmmoType.MINIGUN, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 321).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ITEM_FLINTANDSTEEL_USE, + }, + Effect.FLYING_GLYPH //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.DIAMOND_HOE).setName(getName()).build()); + setDescription("Say hello to my", "little friend."); + + setSupportedAttachments(Attachment.GRIP); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), "&6&lPurple") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.1; //Weapon + + this.damage = 2.25; //RangedWeapon + this.meleeDamage = 3.0; //RangedWeapon + this.accuracy = 0.05; //RangedWeapon + this.magSize = 600; //RangedWeapon + this.reloadTime = 100; //RangedWeapon + this.range = 55; //RangedWeapon + this.recoil = 0.05; //RangedWeapon + this.zoom = 3; //RangedWeapon + this.reloadShoot = true; + + this.minigun = true; //SpecialWeapon + this.rpm = 1200; //SpecialWeapon + this.rps = 20; + this.multiShoot = true; + } + + @Override + public UserRank requiredRank() { + return UserRank.SUPREME; + } + + @Override + public Location spawnVisual(World world) { + Location origin = this.getOrigin(world); + + ArmorStand clickable = spawnEntity(origin.clone().add(-0.6, 0.6, 0), this, WeaponVisualStatue.VisualType.NAME); +// clickable.setVisible(true); + + ArmorStand clickable2 = spawnEntity(origin.clone().add(-1.4, 0.6, 0), this, WeaponVisualStatue.VisualType.NAME); +// clickable2.setVisible(true); + + Location weaponLoc = origin.clone().add(-0.3, 1.1, 0.4); + weaponLoc.setYaw(90.0f); + ArmorStand weapon = spawnEntity(weaponLoc, this, WeaponVisualStatue.VisualType.NONE); + weapon.setArms(true); + weapon.setItemInHand(this.createItemStack().clone()); + weapon.setRightArmPose(new EulerAngle(AngleUtil.getRadianFromDegree(315), 0f, 0f)); + weapon.setMarker(true); + + ArmorStand support = spawnEntity(origin.clone().add(-1.75, -0.34, 0.25), this, WeaponVisualStatue.VisualType.NONE); + support.setHelmet(new ItemStack(Material.END_ROD)); + support.setHeadPose(new EulerAngle(AngleUtil.getRadianFromDegree(300), 0f, 0f)); + support.setMarker(true); + + return origin; + } + + @Override + public Location getOrigin(World world) { + return new Location(world, -364.5, 25.5, 241.5, 0.0f, 0.0f); + } + + @Override + public void extras(ArmorStand entity) { + entity.setMetadata("statue_Y", new FixedMetadataValue(GTM.getInstance(), 2.25)); + entity.setMetadata("statue_X", new FixedMetadataValue(GTM.getInstance(), -1d)); + } +} diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/skins/WeaponSkinDAO.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/skins/WeaponSkinDAO.java new file mode 100644 index 0000000..c13e36c --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/skins/WeaponSkinDAO.java @@ -0,0 +1,136 @@ +package net.grandtheftmc.gtm.weapon.skins; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.guns.weapon.Weapon; +import net.grandtheftmc.guns.weapon.WeaponSkin; + +public class WeaponSkinDAO { + public static boolean lockSkin(Connection connection, UUID uuid, Weapon<?> weapon, WeaponSkin skin) { + String query = "DELETE FROM user_weapon_skin WHERE weapon_id=? AND skin_id=? AND uuid=UNHEX(?);"; + + try (PreparedStatement statement = connection.prepareStatement(query)) { + statement.setShort(1, weapon.getUniqueIdentifier()); + statement.setShort(2, (short) (skin.getIdentifier() - weapon.getWeaponIdentifier())); + statement.setString(3, uuid.toString().replaceAll("-", "")); + statement.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + + return false; + } + + return true; + } + + public static boolean unlockSkin(Connection connection, UUID uuid, Weapon<?> weapon, WeaponSkin skin) { + String query = "INSERT INTO user_weapon_skin (uuid, server_key, weapon_id, skin_id) VALUES (UNHEX(?), ?, ?, ?);"; + + try (PreparedStatement statement = connection.prepareStatement(query)) { + statement.setString(1, uuid.toString().replaceAll("-", "")); + statement.setString(2, Core.name().toUpperCase()); + statement.setShort(3, weapon.getUniqueIdentifier()); + statement.setShort(4, (short) (skin.getIdentifier() - weapon.getWeaponIdentifier())); + statement.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + + return false; + } + + return true; + } + + public static boolean enableSkin(Connection connection, UUID uuid, Weapon<?> weapon, short skinID) { + String query = "UPDATE user_weapon_skin SET enabled=1 WHERE server_key=? AND weapon_id=? AND skin_id=? AND uuid=UNHEX(?);"; + + try (PreparedStatement statement = connection.prepareStatement(query)) { + statement.setString(1, Core.name().toUpperCase()); + statement.setShort(2, weapon.getUniqueIdentifier()); + statement.setShort(3, skinID); + statement.setString(4, uuid.toString().replaceAll("-", "")); + statement.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + + return false; + } + + return true; + } + + public static boolean disableSkin(Connection connection, UUID uuid, Weapon<?> weapon, short skinID) { + String query = "UPDATE user_weapon_skin SET enabled=0 WHERE server_key=? AND weapon_id=? AND skin_id=? AND uuid=UNHEX(?);"; + + try (PreparedStatement statement = connection.prepareStatement(query)) { + statement.setString(1, Core.name().toUpperCase()); + statement.setShort(2, weapon.getUniqueIdentifier()); + statement.setShort(3, skinID); + statement.setString(4, uuid.toString().replaceAll("-", "")); + statement.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + + return false; + } + + return true; + } + + public static Map<Short, List<Short>> getUnlockedSkins(Connection connection, UUID uuid) { + Map<Short, List<Short>> skins = new HashMap<Short, List<Short>>(); + String query = "SELECT * FROM user_weapon_skin WHERE server_key=? AND uuid=UNHEX(?);"; + + try (PreparedStatement statement = connection.prepareStatement(query)) { + statement.setString(1, Core.name().toUpperCase()); + statement.setString(2, uuid.toString().replaceAll("-", "")); + + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + short weaponID = result.getShort("weapon_id"); + + if (skins.containsKey(weaponID)) { + skins.get(weaponID).add(result.getShort("skin_id")); + } else { + skins.put(weaponID, new ArrayList<Short>()); + skins.get(weaponID).add(result.getShort("skin_id")); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + + return skins; + } + + public static Map<Short, Short> getEquippedSkins(Connection connection, UUID uuid) { + Map<Short, Short> skins = new HashMap<Short, Short>(); + String query = "SELECT * FROM user_weapon_skin WHERE server_key=? AND uuid=UNHEX(?) AND enabled=?;"; + + try (PreparedStatement statement = connection.prepareStatement(query)) { + statement.setString(1, Core.name().toUpperCase()); + statement.setString(2, uuid.toString().replaceAll("-", "")); + statement.setShort(3, (short) 1); + + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + skins.put(result.getShort("weapon_id"), result.getShort("skin_id")); + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + + return skins; + } +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/skins/WeaponSkinManager.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/skins/WeaponSkinManager.java new file mode 100644 index 0000000..c170d19 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/skins/WeaponSkinManager.java @@ -0,0 +1,246 @@ +package net.grandtheftmc.gtm.weapon.skins; + +import java.util.Arrays; +import java.util.Optional; + +import net.grandtheftmc.core.util.C; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryMoveItemEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import com.j0ach1mmall3.wastedguns.api.events.WeaponDropEvent; +import com.j0ach1mmall3.wastedguns.api.events.WeaponPickupEvent; + +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.gui.ConfirmationMenu; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.guns.WeaponManager; +import net.grandtheftmc.guns.weapon.Weapon; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.minecraft.server.v1_12_R1.NBTTagCompound; + +public class WeaponSkinManager { + + public WeaponSkinManager() { + Bukkit.getPluginManager().registerEvents(new SkinListener(), GTM.getInstance()); + } + + public void updateWeaponSkin(Player player, Weapon<?> weapon, WeaponSkin skin) { + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + user.equipWeaponSkin(weapon, skin); + + for (ItemStack stack : player.getInventory().getContents()) { + Optional<Weapon<?>> weaponOpt = GTM.getWastedGuns().getWeaponManager().getWeapon(stack); + + if (weaponOpt.isPresent()) { + if (weaponOpt.get().getUniqueIdentifier() == weapon.getUniqueIdentifier()) { + stack.setDurability(skin.getIdentifier()); + } + } + } + } + + public WeaponSkin getHeldItemWeaponSkin(ItemStack stack) { + WeaponManager weaponManager = GTM.getWastedGuns().getWeaponManager(); + + if (stack != null) { + Optional<Weapon<?>> weaponOpt = weaponManager.getWeapon(stack); + + if (weaponOpt.isPresent()) { + Weapon<?> weapon = weaponOpt.get(); + + if (weapon.getWeaponSkins() != null) { + for (WeaponSkin skin : weapon.getWeaponSkins()) { + if (stack.getDurability() == skin.getIdentifier()) { + return skin; + } + } + } + } + } + + return null; + } + + public WeaponSkin getWeaponSkinFromIdentifier(Weapon<?> weapon, short identifier) { + for (WeaponSkin skin : weapon.getWeaponSkins()) { + if ((skin.getIdentifier() - weapon.getWeaponIdentifier()) == identifier) { + return skin; + } + } + + return null; + } + + public ItemStack createSkinItem(Weapon<?> weapon, WeaponSkin skin) { + ItemStack stack = new ItemStack(Material.ENCHANTED_BOOK); + ItemMeta meta = stack.getItemMeta(); + + meta.setLore(Arrays.asList( + Utils.f("&7Included skin:"), + Utils.f("&8- &7" + ChatColor.stripColor(Utils.f(skin.getDisplayName())) + " (" + weapon.getName() + ")")) + ); + + String color = "&f"; + short id = (short) (skin.getIdentifier() - weapon.getWeaponIdentifier()); + if (id == 5 || id == 7) color = "&a"; + else if (id == 2 || id == 6) color = "&9"; + + meta.setDisplayName(Utils.f(color + "&lWeapon Skin")); + stack.setItemMeta(meta); + + net.minecraft.server.v1_12_R1.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack); + NBTTagCompound compound = nmsStack.getTag(); + compound.setShort("weapon_id", weapon.getUniqueIdentifier()); + compound.setShort("skin_id", (short) (skin.getIdentifier() - weapon.getWeaponIdentifier())); + nmsStack.setTag(compound); + + return CraftItemStack.asBukkitCopy(nmsStack); + } + + private class SkinListener implements Listener { + @EventHandler + public void onWeaponPickup(WeaponPickupEvent event) { + ItemStack stack = event.getItem().getItemStack(); + Optional<Weapon<?>> weaponOpt = GTM.getWastedGuns().getWeaponManager().getWeapon(stack); + + if (weaponOpt.isPresent()) { + + // grab living entity + LivingEntity le = event.getLivingEntity(); + + if (le instanceof Player){ + Player player = (Player) le; + + GTMUser gtmUser = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + + if (gtmUser != null){ + // might not have any skins + WeaponSkin weaponSkin = gtmUser.getEquippedWeaponSkin(weaponOpt.get()); + + if (weaponSkin != null){ + stack.setDurability(weaponSkin.getIdentifier()); + } + } + } + } + } + + @EventHandler + public void onWeaponDrop(WeaponDropEvent event) { + ItemStack stack = event.getItemDrop().getItemStack(); +// if (stack.getType() == Material.ENCHANTED_BOOK) { +// if (event.getLivingEntity() instanceof Player) +// ((Player) event.getLivingEntity()).closeInventory(); +// } + + Optional<Weapon<?>> weaponOpt = GTM.getWastedGuns().getWeaponManager().getWeapon(stack); + + if (weaponOpt.isPresent()) { + stack.setDurability(weaponOpt.get().getWeaponIdentifier()); + } + } + + @EventHandler + public void onItemMove(InventoryMoveItemEvent event) { + InventoryHolder holder = event.getSource().getHolder(); + + if (holder instanceof Player) { + Player player = (Player) holder; + + if (event.getDestination() != player.getInventory()) { + ItemStack stack = event.getItem(); + Optional<Weapon<?>> weaponOpt = GTM.getWastedGuns().getWeaponManager().getWeapon(stack); + + if (weaponOpt.isPresent() && stack.getDurability() != 0) { + stack.setDurability(weaponOpt.get().getWeaponIdentifier()); + } + } else { + ItemStack stack = event.getItem(); + Optional<Weapon<?>> weaponOpt = GTM.getWastedGuns().getWeaponManager().getWeapon(stack); + + if (weaponOpt.isPresent()) { + stack.setDurability(GTM.getUserManager().getLoadedUser(player.getUniqueId()).getEquippedWeaponSkin(weaponOpt.get()).getIdentifier()); + } + } + } + } + + @EventHandler + public void onItemRightClick(PlayerInteractEvent event) { + if (event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_AIR) { + ItemStack item = event.getItem(); + + net.minecraft.server.v1_12_R1.ItemStack nmsStack = CraftItemStack.asNMSCopy(item); + NBTTagCompound compound = nmsStack.getTag(); + + if (compound != null && compound.hasKey("weapon_id") && compound.hasKey("skin_id") && item.getType() == Material.ENCHANTED_BOOK) { + + ItemStack updated = event.getPlayer().getInventory().getItemInMainHand(); + if (updated == null || updated.getType() == Material.AIR) + return; + + ConfirmationMenu menu = new ConfirmationMenu(GTM.getInstance(), event.getItem()) { + @Override + protected void onConfirm(InventoryClickEvent e, Player p) { + ItemStack updated = event.getPlayer().getInventory().getItemInMainHand(); + if (updated == null || updated.getType() == Material.AIR) + return; + + net.minecraft.server.v1_12_R1.ItemStack nmsStack = CraftItemStack.asNMSCopy(event.getItem()); + NBTTagCompound compound = nmsStack.getTag(); + + short weaponID = compound.getShort("weapon_id"); + short skinID = compound.getShort("skin_id"); + + Optional<Weapon<?>> weaponOpt = GTM.getWastedGuns().getWeaponManager().getWeaponFromUniqueIdentifier(weaponID); + if (weaponOpt.isPresent()) { + Weapon<?> weapon = weaponOpt.get(); + WeaponSkin skin = getWeaponSkinFromIdentifier(weapon, skinID); + + GTMUser user = GTM.getUserManager().getLoadedUser(p.getUniqueId()); + + if (!user.hasSkinUnlocked(weapon, skin)) { + user.unlockWeaponSkin(weapon, skin); + + for (int i = 0; i < p.getInventory().getSize(); i++) { + ItemStack found = p.getInventory().getItem(i); + if (found == null || found.getType() == Material.AIR) continue; + if (!found.isSimilar(event.getItem())) continue; + + if (found.getAmount() > 1) found.setAmount(found.getAmount() - 1); + else p.getInventory().setItem(i, new ItemStack(Material.AIR)); + break; + } +// p.getInventory().remove(event.getItem()); + p.updateInventory(); + + p.sendMessage(Utils.f("&aYou have unlocked a " + skin.getDisplayName() + " Skin &afor &6&l" + weapon.getName() + "&a! Please go to Mr Skinner at spawn to equip it.")); + } else { + p.sendMessage(Utils.f("&cYou already have this skin unlocked!")); + } + + event.setCancelled(true); + } + } + }; + + menu.open(event.getPlayer()); + } + } + } + } +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/skins/menu/MainMenu.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/skins/menu/MainMenu.java new file mode 100644 index 0000000..c9cf553 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/skins/menu/MainMenu.java @@ -0,0 +1,171 @@ +package net.grandtheftmc.gtm.weapon.skins.menu; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import org.bukkit.ChatColor; +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import net.grandtheftmc.core.inventory.CoreMenu; +import net.grandtheftmc.core.inventory.button.ClickableItem; +import net.grandtheftmc.core.inventory.button.MenuItem; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.items.GameItem; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.weapon.melee.Dildo; +import net.grandtheftmc.gtm.weapon.ranged.special.GoldMinigun; +import net.grandtheftmc.guns.weapon.MeleeWeapon; +import net.grandtheftmc.guns.weapon.Weapon; +import net.grandtheftmc.guns.weapon.ranged.RangedWeapon; + +public class MainMenu extends CoreMenu { + private final Player holder; + private final int page; + + public MainMenu(Player holder) { + super(5, "Weapon Skins"); + + this.holder = holder; + this.page = 0; + + this.setup(); + } + + private MainMenu(Player holder, int page) { + super(5, "Weapon Skins"); + + this.holder = holder; + this.page = page; + + this.setup(); + } + + @SuppressWarnings("deprecation") + protected void setup() { + for (int i = 0; i < 45; i++) { + ItemStack stack = new ItemStack(Material.STAINED_GLASS_PANE, 1, DyeColor.BLACK.getWoolData()); + ItemMeta meta = stack.getItemMeta(); + meta.setDisplayName(""); + stack.setItemMeta(meta); + + this.addItem(new MenuItem(i, stack, false)); + } + + this.createMenuContent(); + } + + private void createMenuContent() { + List<Weapon<?>> weapons = new ArrayList<Weapon<?>>(); + List<Weapon<?>> pageWeapons = null; + + for (GameItem gameItem : GTM.getItemManager().getItems()) { + if (gameItem.getType() == GameItem.ItemType.WEAPON) { + + Optional<Weapon<?>> optional = GTM.getWastedGuns().getWeaponManager().getWeapon(gameItem.getWeaponOrVehicleOrDrug()); + + if (optional.isPresent()) { + Weapon<?> weapon = optional.get(); + + if (weapon instanceof GoldMinigun || weapon instanceof Dildo) + continue; + + if ((weapon instanceof RangedWeapon || weapon instanceof MeleeWeapon) && weapon.getWeaponSkins().length > 1) { + weapons.add(weapon); + } + } + } + } + + try { + pageWeapons = weapons.subList(this.page * 15, (this.page * 15) + 15); + } catch (IndexOutOfBoundsException e) { + pageWeapons = weapons.subList(this.page * 15, weapons.size()); + } + + int index = 11; + for (int i = 0; i < pageWeapons.size(); i++) { + Weapon<?> weapon = weapons.get(i + (this.page * 15)); + + this.addItem(new ClickableItem(index, this.createSkinButton(weapon), (player, action) -> { + new SkinsMenu(player, weapon).open(); + })); + + if (i == 4 || i == 9) { + index += 5; + } else { + index++; + } + } + + this.createNextPageButtons((int) Math.ceil((weapons.size()) / 15.0)); + this.createPreviousPageButtons(); + } + + @SuppressWarnings("deprecation") + private void createNextPageButtons(int numPages) { + for (int i = 0; i < 3; i++) { + if (numPages > 1 && (this.page + 1) < numPages) { + ItemStack stack = new ItemStack(Material.STAINED_GLASS_PANE, 1, DyeColor.LIME.getWoolData()); + ItemMeta meta = stack.getItemMeta(); + meta.setDisplayName("Next Page"); + stack.setItemMeta(meta); + + this.addItem(new ClickableItem((i * 9) + 17, stack, (player, action) -> { + new MainMenu(this.holder, this.page + 1).open(); + })); + } + } + } + + @SuppressWarnings("deprecation") + private void createPreviousPageButtons() { + for (int i = 0; i < 3; i++) { + if (this.page != 0) { + ItemStack stack = new ItemStack(Material.STAINED_GLASS_PANE, 1, DyeColor.RED.getWoolData()); + ItemMeta meta = stack.getItemMeta(); + meta.setDisplayName("Next Page"); + stack.setItemMeta(meta); + + this.addItem(new ClickableItem((i * 9) + 9, stack, (player, action) -> { + new MainMenu(this.holder, this.page - 1).open(); + })); + } + } + } + + private ItemStack createSkinButton(Weapon<?> weapon) { + ItemStack stack = weapon.createItemStack(); + ItemMeta meta = stack.getItemMeta(); + meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', "&e&l" + weapon.getName())); + + int unlockedSkins = 0; + GTMUser user = GTM.getUserManager().getLoadedUser(this.holder.getUniqueId()); + + if (user.getUnlockedWeaponSkins(weapon) != null) { + unlockedSkins = user.getUnlockedWeaponSkins(weapon).size(); + } + + meta.setLore(Arrays.asList( + ChatColor.translateAlternateColorCodes('&', "&6Unlocked:&r " + (1 + unlockedSkins) + "/" + weapon.getWeaponSkins().length), " ", + ChatColor.translateAlternateColorCodes('&', "&7Click to view the skins for this weapon.") + )); + + stack.setItemMeta(meta); + + return stack; + } + + public void open() { + this.openInventory(this.holder); + } + + protected Player getHolder() { + return this.holder; + } +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/skins/menu/SkinsMenu.java b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/skins/menu/SkinsMenu.java new file mode 100644 index 0000000..5d88c3c --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/java/net/grandtheftmc/gtm/weapon/skins/menu/SkinsMenu.java @@ -0,0 +1,173 @@ +package net.grandtheftmc.gtm.weapon.skins.menu; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.bukkit.ChatColor; +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import net.grandtheftmc.core.inventory.CoreMenu; +import net.grandtheftmc.core.inventory.button.ClickableItem; +import net.grandtheftmc.core.inventory.button.MenuItem; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.guns.weapon.Weapon; +import net.grandtheftmc.guns.weapon.WeaponSkin; + +public class SkinsMenu extends CoreMenu { + + private static final int[] SKIN_SLOTS = {11, 13, 15, 30, 32}; + + private final Player holder; + private final Weapon<?> weapon; + + public SkinsMenu(Player holder, Weapon<?> weapon) { + super(6, "Weapon Skins"); + + this.holder = holder; + this.weapon = weapon; + + this.setup(); + } + + private void setup() { + GTMUser user = GTM.getUserManager().getLoadedUser(this.holder.getUniqueId()); + List<WeaponSkin> unlockedSkins = user.getUnlockedWeaponSkins().get(this.weapon.getUniqueIdentifier()); + + for (int i = 0; i < 54; i++) { + ItemStack stack = new ItemStack(Material.STAINED_GLASS_PANE, 1, DyeColor.BLACK.getWoolData()); + ItemMeta meta = stack.getItemMeta(); + meta.setDisplayName(""); + stack.setItemMeta(meta); + + this.addItem(new MenuItem(i, stack, false)); + } + + for (int i = 0; i < this.weapon.getWeaponSkins().length; i++) { + WeaponSkin skin = this.weapon.getWeaponSkins()[i]; + + if ((unlockedSkins != null && unlockedSkins.contains(skin)) || (skin.getIdentifier() - this.weapon.getWeaponIdentifier()) == 0) { + WeaponSkin currentSkin = user.getEquippedWeaponSkin(this.weapon); + boolean selected = false; + + if (currentSkin != null) { + if (skin == currentSkin) { + selected = true; + } + } + + this.addItem(selected ? + new MenuItem(SKIN_SLOTS[i], this.createSkinStack(skin, true), false) : + new ClickableItem(SKIN_SLOTS[i], this.createSkinStack(skin, false), (player, action) -> { + GTM.getWeaponSkinManager().updateWeaponSkin(this.holder, this.weapon, skin); + + new SkinsMenu(this.holder, this.weapon).open(); + }) + ); + continue; +// if (i >= 0 && i <= 2) { +// if (!selected) { +// this.addItem(new ClickableItem(i + 12, this.createSkinStack(skin, selected), (player, action) -> { +// GTM.getWeaponSkinManager().updateWeaponSkin(this.holder, this.weapon, skin); +// +// new SkinsMenu(this.holder, this.weapon).open(); +// })); +// } else { +// this.addItem(new MenuItem(i + 12, this.createSkinStack(skin, selected), false)); +// } +// } else { +// if (!selected) { +// this.addItem(new ClickableItem(22, this.createSkinStack(skin, selected), (player, action) -> { +// GTM.getWeaponSkinManager().updateWeaponSkin(this.holder, this.weapon, skin); +// +// new SkinsMenu(this.holder, this.weapon).open(); +// })); +// } else { +// this.addItem(new MenuItem(22, this.createSkinStack(skin, selected), false)); +// } +// } + } + + this.addItem(new MenuItem(SKIN_SLOTS[i], this.createLockedSkinStack(), false)); + } + + //Back button. + this.addItem(new ClickableItem(49, this.createBackStack(), (player, action) -> new MainMenu(player).open())); + } + + private ItemStack createBackStack() { + ItemStack stack = new ItemStack(Material.REDSTONE, 1); + + ItemMeta meta = stack.getItemMeta(); + meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', "&c&lBack")); + meta.setLore(Collections.singletonList( + ChatColor.translateAlternateColorCodes('&', "&7Return to the home page!") + )); + + stack.setItemMeta(meta); + + return stack; + } + + private ItemStack createSkinStack(WeaponSkin skin, boolean selected) { + ItemStack stack = this.weapon.createItemStack(skin); + + ItemMeta meta = stack.getItemMeta(); + meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', skin.getDisplayName())); + + if (selected) { + meta.setLore(Arrays.asList( + ChatColor.translateAlternateColorCodes('&', "&7This is the currently selected skin"), + ChatColor.translateAlternateColorCodes('&', "&7for this weapon.") + )); + + meta.addEnchant(Enchantment.SILK_TOUCH, 1, false); + meta.addItemFlags(ItemFlag.HIDE_ENCHANTS); + } + else { + meta.setLore(Collections.singletonList( + ChatColor.translateAlternateColorCodes('&', "&7Click to change the selected skin.") + )); + } + + stack.setItemMeta(meta); + + return stack; + } + + private ItemStack createLockedSkinStack() { + ItemStack stack = new ItemStack(Material.STRING); + + ItemMeta meta = stack.getItemMeta(); + meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', "&4&l????")); + meta.setLore(Arrays.asList( + ChatColor.translateAlternateColorCodes('&', "&7Unknown skin. Find it at the following places:"), + ChatColor.translateAlternateColorCodes('&', "&8- &7Skin Crates"), + ChatColor.translateAlternateColorCodes('&', "&8- &7Loot Chests"), + ChatColor.translateAlternateColorCodes('&', "&8- &7Crowbar Crates") + )); + + stack.setItemMeta(meta); + + return stack; + } + + public void open() { + this.openInventory(this.holder); + } + + protected Player getHolder() { + return this.holder; + } + + protected Weapon<?> getWeapon() { + return this.weapon; + } +} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/resources/barrels.yml b/gtm-master@bf01c650f8f/src/main/resources/barrels.yml new file mode 100644 index 0000000..ef3597d --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/resources/barrels.yml @@ -0,0 +1 @@ +barrels: diff --git a/gtm-master@bf01c650f8f/src/main/resources/bounties.yml b/gtm-master@bf01c650f8f/src/main/resources/bounties.yml new file mode 100644 index 0000000..6c37909 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/resources/bounties.yml @@ -0,0 +1,11 @@ +0e4a6028-3d9a-4a2e-9797-eb1ddcb0aca9: + name: Presidentx + placers: + b5d6834b-465b-4593-8b8d-c2cba400015c: + name: Samuri629 + amount: 10000 + anonymous: true + 5c8bb461-a075-4526-b0e1-e3a701c2dc98: + name: 2Legiit4U + amount: 5000 + anonymous: false \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/resources/christmasdrops.yml b/gtm-master@bf01c650f8f/src/main/resources/christmasdrops.yml new file mode 100644 index 0000000..ff316dd --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/resources/christmasdrops.yml @@ -0,0 +1,2 @@ +locs: + - "spawn,1,1,1" \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/resources/drugblocks.yml b/gtm-master@bf01c650f8f/src/main/resources/drugblocks.yml new file mode 100644 index 0000000..6a40527 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/resources/drugblocks.yml @@ -0,0 +1 @@ +blocks: diff --git a/gtm-master@bf01c650f8f/src/main/resources/drugdealer.yml b/gtm-master@bf01c650f8f/src/main/resources/drugdealer.yml new file mode 100644 index 0000000..edc2c23 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/resources/drugdealer.yml @@ -0,0 +1,57 @@ +drugs: + alcohol: + min: 10 + max: 20 + chance: 50 + minprice: 100 + maxprice: 100 + roofied_chocolate: + min: 15 + max: 45 + chance: 50 + minprice: 125 + maxprice: 320 + cocaine: + min: 5 + max: 19 + chance: 50 + minprice: 400 + maxprice: 750 + lsd: + min: 13 + max: 54 + chance: 50 + minprice: 250 + maxprice: 500 + mdma: + min: 1 + max: 89 + chance: 50 + minprice: 75 + maxprice: 150 + weed: + min: 43 + max: 910 + chance: 50 + minprice: 75 + maxprice: 150 + heroin: + min: 10 + max: 23 + chance: 12 + minprice: 250 + maxprice: 500 + meth: + min: 10 + max: 23 + chance: 43 + minprice: 250 + maxprice: 500 + "anabolic steroids": + min: 3 + max: 129 + chance: 100 + minprice: 500 + maxprice: 1000 + +locs: diff --git a/gtm-master@bf01c650f8f/src/main/resources/gtm.yml b/gtm-master@bf01c650f8f/src/main/resources/gtm.yml new file mode 100644 index 0000000..54ca728 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/resources/gtm.yml @@ -0,0 +1 @@ +map: test \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/resources/items.yml b/gtm-master@bf01c650f8f/src/main/resources/items.yml new file mode 100644 index 0000000..e69de29 diff --git a/gtm-master@bf01c650f8f/src/main/resources/kits.yml b/gtm-master@bf01c650f8f/src/main/resources/kits.yml new file mode 100644 index 0000000..116d3e7 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/resources/kits.yml @@ -0,0 +1,13 @@ +hobo: + delay: 300 + items: + - chicken + - beef,pork +kak: + cost: 50 + delay: 300 + items: + - chicken + - beef:40,pork:50 +vip: + delay: 86400 \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/resources/loot.yml b/gtm-master@bf01c650f8f/src/main/resources/loot.yml new file mode 100644 index 0000000..3f468b8 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/resources/loot.yml @@ -0,0 +1,6 @@ +loot: + chicken: + chance: 5 + min: 2 + max: 5 +lootcrates: {} \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/resources/lootcrates.yml b/gtm-master@bf01c650f8f/src/main/resources/lootcrates.yml new file mode 100644 index 0000000..5a61cd1 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/resources/lootcrates.yml @@ -0,0 +1,2 @@ +lootcrates: +cooldown: 30 \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/resources/plugin.yml b/gtm-master@bf01c650f8f/src/main/resources/plugin.yml new file mode 100644 index 0000000..ba51112 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/resources/plugin.yml @@ -0,0 +1,76 @@ +name: GTM +version: 1.0 +description: GTMPlugin +author: Presidentx +main: net.grandtheftmc.gtm.GTM +depend: [Core,ProtocolLib,JLib,WastedGuns,WastedVehicles,BuycraftX] +commands: + ammo: + lootcrates: + aliases: ["lc", "lootc", "lcrates", "lootcrate", "lcrate"] + warp: + spawn: + gtmadmin: + gameitem: + aliases: [gi, gamei, gitem] + kit: + aliases: [kits] + shop: + gtmrank: + rankup: + drugcheck: + aliases: [dc] + drugdealer: + gangadmin: + aliases: [ga, ganga, gadmin] + gangchat: + aliases: ["gc", "gangc", "gchat"] + money: + aliases: [bal,balance,eco,economy,cash] + pay: + tpa: + tpahere: + tpaccept: + aliases: [tpyes] + tpdeny: + aliases: [tpdeny] + permits: + kill: + suicide: + picker: + aliases: [modepicker, armorstandpicker] + feed: + aliases: [eat,food,saturate] + vehicle: + aliases: [wv, vehicles, wastedvehicles, wastedvehicle, wvehicle, wvehicles, wastedv] + backpack: + aliases: [bp, backp, bpack] + bribe: + aliases: [bail] + reset: + tokenshop: + antiaura: + clear: + aliases: [clearinventory, cleari, ci, clearinv] + fix: + aliases: [repair] + near: + teleport: + aliases: [tp, tpo] + spectator: + aliases: [gm3staff, spectatormode] + backup: + lottery: + speed: + chunkunload: + topkillers: + stats: + aliases: [stat] + resourcepack: + aliases: [respack, rp, texturepack, texpack] + drugs: + aliases: [drug] + gtmranks: + aliases: [ranks] + stack: + event: \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/resources/rules.yml b/gtm-master@bf01c650f8f/src/main/resources/rules.yml new file mode 100644 index 0000000..7da18e6 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/resources/rules.yml @@ -0,0 +1,5 @@ +rules: + - "" + - "" + - "" + - "" \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/resources/salemenus.yml b/gtm-master@bf01c650f8f/src/main/resources/salemenus.yml new file mode 100644 index 0000000..61dcfd6 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/resources/salemenus.yml @@ -0,0 +1,60 @@ +#sale-menu-name: +# menu-title: +# subcategories: +# subcategoryA: +# category-name: +# display-item: +# subcategories: +# subcategoryAa: +# category-name: +# display-item: +# sale-items: +# -game-item-name +# -game-item-name +# -game-item-name +# subcategoryAb: +# category-name: +# display-item: +# subcategories: +# subcategoryAba: +# category-name: +# display-item: +# sale-items: +# -game-item-name +# -game-item-name +# -game-item-name +# +#All subcategories MUST terminate with a sale-items array. + +weapons: + menu-title: "&a&lWeapons" + subcategories: + smgs: + display-item: 267 + sale-items: + - smg + - microsmg + - assaultsmg + - combatpdw + rifles: + display-item: 272 + sale-items: + - assaultrifle + - carbinerifle + pistols: + display-item: 268 + sale-items: + - pistol + - stungun + - combatpistol + - heavypistol + - marksmanpistol + shotguns: + display-item: 284 + sale-items: + - sawedoffshotgun + - pumpshotgun + - assaultshotgun + - heavyshotgun + + \ No newline at end of file diff --git a/gtm-master@bf01c650f8f/src/main/resources/warps.yml b/gtm-master@bf01c650f8f/src/main/resources/warps.yml new file mode 100644 index 0000000..5b73fb1 --- /dev/null +++ b/gtm-master@bf01c650f8f/src/main/resources/warps.yml @@ -0,0 +1,3 @@ +firstSpawn: spawn,0,0,0,0,0 +spawn: spawn,0,50,0,0,0 +warps: {} \ No newline at end of file diff --git a/houses-master@c2d95d8e6a6/.gitignore b/houses-master@c2d95d8e6a6/.gitignore new file mode 100644 index 0000000..49750e2 --- /dev/null +++ b/houses-master@c2d95d8e6a6/.gitignore @@ -0,0 +1,103 @@ + +\.idea/ + +target/classes/ + +target/ + +*.iml + +/bin/ +/build/ + +##### Gradle ##### +.gradle +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache + +# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 +# gradle/wrapper/gradle-wrapper.properties + +##### Eclipse ##### +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders + +.project + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# PyDev specific (Python IDE for Eclipse) +*.pydevproject + +# CDT-specific (C/C++ Development Tooling) +.cproject + +# JDT-specific (Eclipse Java Development Tools) +.classpath + +# Java annotation processor (APT) +.factorypath + +# PDT-specific (PHP Development Tools) +.buildpath + +# sbteclipse plugin +.target + +# Tern plugin +.tern-project + +# TeXlipse plugin +.texlipse + +# STS (Spring Tool Suite) +.springBeans + +# Code Recommenders +.recommenders/ + +*.class + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear + + +##### IntelliJ ##### +*.iml +*.ipr +*.iws +.idea/ + +##### NetBeans ##### +/.nb-gradle/ + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +##### MacOS ##### +.DS_Store + diff --git a/houses-master@c2d95d8e6a6/README.md b/houses-master@c2d95d8e6a6/README.md new file mode 100644 index 0000000..fdaec0e --- /dev/null +++ b/houses-master@c2d95d8e6a6/README.md @@ -0,0 +1 @@ +First commit. \ No newline at end of file diff --git a/houses-master@c2d95d8e6a6/pom.xml b/houses-master@c2d95d8e6a6/pom.xml new file mode 100644 index 0000000..0fb0f5d --- /dev/null +++ b/houses-master@c2d95d8e6a6/pom.xml @@ -0,0 +1,128 @@ +<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>net.grandtheftmc</groupId> + <artifactId>houses</artifactId> + <version>1.0.5</version> + <name>Houses</name> + + <repositories> + <repository> + <id>spigot-repo</id> + <url>https://hub.spigotmc.org/nexus/content/repositories/public/</url> + </repository> + <repository> + <id>jitpack.io</id> + <url>https://jitpack.io</url> + </repository> + <repository> + <id>sk89q-repo</id> + <url>>http://maven.sk89q.com/repo/</url> + </repository> + <repository> + <id>nexus-release</id> + <url>http://nexus.grandtheftmc.net/content/repositories/releases</url> + </repository> + </repositories> + + <distributionManagement> + <repository> + <id>nexus-release</id> + <name>Internal Releases</name> + <url>http://nexus.grandtheftmc.net/content/repositories/releases</url> + </repository> + <snapshotRepository> + <id>nexus-snapshot</id> + <name>Internal Snapshots</name> + <url>http://nexus.grandtheftmc.net/content/repositories/snapshots</url> + </snapshotRepository> + </distributionManagement> + + <dependencies> + <dependency> + <groupId>com.sk89q.worldedit</groupId> + <artifactId>worldedit-bukkit</artifactId> + <version>6.1.5</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>net.grandtheftmc</groupId> + <artifactId>wastedguns</artifactId> + <version>1.0.9.rewrite</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.spigotmc</groupId> + <artifactId>spigot-api</artifactId> + <version>LATEST</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.github.j0ach1mmall3</groupId> + <artifactId>JLib</artifactId> + <version>LATEST</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>net.grandtheftmc</groupId> + <artifactId>core</artifactId> + <version>2.3.2.develop</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>net.grandtheftmc</groupId> + <artifactId>gtm</artifactId> + <version>2.4</version> + <scope>provided</scope> + </dependency> + </dependencies> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <maven.compiler.source>1.8</maven.compiler.source> + <maven.compiler.target>1.8</maven.compiler.target> + </properties> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-shade-plugin</artifactId> + <configuration> + <finalName>Houses</finalName> + </configuration> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>shade</goal> + </goals> + </execution> + </executions> + </plugin> + + <!-- Nexus deploy --> + <plugin> + <groupId>org.sonatype.plugins</groupId> + <artifactId>nexus-staging-maven-plugin</artifactId> + <version>1.6.8</version> + <extensions>true</extensions> + <executions> + <execution> + <id>default-deploy</id> + <phase>deploy</phase> + <goals> + <goal>deploy</goal> + </goals> + </execution> + </executions> + <configuration> + <serverId>nexus</serverId> + <nexusUrl>http://nexus.grandtheftmc.net/</nexusUrl> + <skipStaging>true</skipStaging> + </configuration> + </plugin> + </plugins> + </build> +</project> \ No newline at end of file diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/HouseUtils.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/HouseUtils.java new file mode 100644 index 0000000..3f6f5c2 --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/HouseUtils.java @@ -0,0 +1,220 @@ +package net.grandtheftmc.houses; + +import com.google.common.collect.Lists; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.houses.houses.House; +import net.grandtheftmc.houses.houses.PremiumHouse; +import net.grandtheftmc.houses.users.HouseUser; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public final class HouseUtils { + + private HouseUtils() { + } + + public static void openHouseMenu(Player player, House house, HouseUser user) { + if (player == null || house == null) + return; + player.sendMessage(Utils.f(Lang.HOUSES + "&7Opening up the menu for house &a" + house.getId() + "&7.")); + user.setMenuHouseId(house.getId()); + MenuManager.openMenu(player, "house"); + + } + + public static void openPremiumHouseMenu(Player player, PremiumHouse house, HouseUser user) { + if (player == null || house == null) + return; + player.sendMessage(Utils.f(Lang.HOUSES + "&7Opening up the menu for premium house &a" + house.getId() + "&7.")); + user.setMenuHouseId(house.getId()); + MenuManager.openMenu(player, "premiumhouse"); + } + + public static void openPremiumHouseGuestMenu(Player player, PremiumHouse house, HouseUser user) { + if (player == null || house == null) + return; + player.sendMessage( + Utils.f(Lang.HOUSES + "&7Opening up the guest menu for premium house &a" + house.getId() + "&7.")); + user.setMenuHouseId(house.getId()); + MenuManager.openMenu(player, "guests"); + } + + public static void openChangeBlocksMenu(Player player, PremiumHouse house, HouseUser user) { + if (player == null || house == null) + return; + player.sendMessage( + Utils.f(Lang.HOUSES + "&7Opening up the change blocks menu for premium house &a" + house.getId() + "&7.")); + user.setMenuHouseId(house.getId()); + MenuManager.openMenu(player, "editblocks"); + } + + public static void openAddGuestMenu(Player player, PremiumHouse house) { + + } + + public static void openRemoveGuestMenu(Player player, PremiumHouse house, HouseUser user) { + if (player == null || house == null) + return; + player.sendMessage(Utils + .f(Lang.HOUSES + "&7Opening up the remove guest menu for premium house &a" + house.getId() + "&7.")); + user.setMenuHouseId(house.getId()); + MenuManager.openMenu(player, "removeguests"); + } + + public static void openHousesMenu(Player player, HouseUser user) { + if (player == null) + return; + player.sendMessage(Utils.f(Lang.HOUSES + "&7Opening up the houses menu.")); + MenuManager.openMenu(player, "houses"); + } + + public static void openHelpMenu(Player player) { + if (player == null) + return; + player.sendMessage(Utils.f(Lang.HOUSES + "&7Opening up the houses help menu.")); + MenuManager.openMenu(player, "houseshelp"); + } + + public static int getHouses(UserRank userRank) { + switch (userRank) { + case DEFAULT: + return 0; + case VIP: + return 1; + case PREMIUM: + return 2; + case ELITE: + return 3; + case SPONSOR: + return 5; + default: + return 10; + } + } + + public static int getHouseDelay(UserRank userRank) { + switch (userRank) { + case DEFAULT: + return 60; + case VIP: + return 50; + case PREMIUM: + return 40; + case ELITE: + return 30; + default: + return 12; + } + } + + public static Collection<Block> getBlocks(Location loc1, Location loc2) { + Collection<Block> blocks = new ArrayList<>(); + + int topBlockX = (loc1.getBlockX() < loc2.getBlockX() ? loc2.getBlockX() : loc1.getBlockX()); + int bottomBlockX = (loc1.getBlockX() > loc2.getBlockX() ? loc2.getBlockX() : loc1.getBlockX()); + + int topBlockY = (loc1.getBlockY() < loc2.getBlockY() ? loc2.getBlockY() : loc1.getBlockY()); + int bottomBlockY = (loc1.getBlockY() > loc2.getBlockY() ? loc2.getBlockY() : loc1.getBlockY()); + + int topBlockZ = (loc1.getBlockZ() < loc2.getBlockZ() ? loc2.getBlockZ() : loc1.getBlockZ()); + int bottomBlockZ = (loc1.getBlockZ() > loc2.getBlockZ() ? loc2.getBlockZ() : loc1.getBlockZ()); + + for (int x = bottomBlockX; x <= topBlockX; x++) { + for (int z = bottomBlockZ; z <= topBlockZ; z++) { + for (int y = bottomBlockY; y <= topBlockY; y++) { + Block block = loc1.getWorld().getBlockAt(x, y, z); + blocks.add(block); + } + } + } + + return blocks; + } + + public static JSONObject dataToJson(KeyVal<String, String>[] keyVal) { + JSONObject json = new JSONObject(); + for (KeyVal<String, String> obj : keyVal) { + json.append(obj.getKey(), obj.getVal()); + } + return json; + } + + public static JSONObject dataToJson(String data) { + if (data == null) return new JSONObject(); + + try { + JSONObject object = new JSONObject(data); + return object; + } catch (Exception e) { + return new JSONObject(); + } + } + + public static Location getLocationFromString(String data) { + String[] s = data.split(","); + World w = Bukkit.getWorld(s[0]); + double x = Double.parseDouble(s[1]), y = Double.parseDouble(s[2]), z = Double.parseDouble(s[3]); + if (s.length > 4) { + double yaw = Double.parseDouble(s[4]), pitch = Double.parseDouble(s[5]); + return new Location(w, x, y, z, (float)yaw, (float)pitch); + } + return new Location(w, x, y, z); + } + + public static Location[] getLocationArrayFromString(String data) { + List<Location> locationList = Lists.newArrayList(); + + for(String loc : data.split(";")) { + String[] s = loc.split(","); + World w = Bukkit.getWorld(s[0]); + double x = Double.parseDouble(s[1]), y = Double.parseDouble(s[2]), z = Double.parseDouble(s[3]); + if (s.length > 4) { + double yaw = Double.parseDouble(s[4]), pitch = Double.parseDouble(s[5]); + locationList.add(new Location(w, x, y, z, (float) yaw, (float) pitch)); + } + locationList.add(new Location(w, x, y, z)); + } + + return locationList.toArray(new Location[locationList.size()]); + } + + public static String locationToString(Location location) { + return location.getWorld().getName() + "," + location.getX() + "," + location.getY() + "," + location.getZ() + "," + location.getYaw() + "," + location.getPitch(); + } + + public static String locationsToString(List<Location> locations) { + StringBuilder str = new StringBuilder(); + for (Location l : locations) { + str.append(l.getWorld().getName()).append(",") + .append(l.getX()).append(",") + .append(l.getY()).append(",") + .append(l.getZ()).append(",") + .append(l.getYaw()).append(",") + .append(l.getPitch()).append(";"); + } + + str.setLength(str.length() - 1); + return str.toString(); + } + + public static boolean locEqualsLoc(Location loc1, Location loc2, boolean pitchYaw) { + if (loc1 == null || loc2 == null) return false; + if (!loc1.getWorld().equals(loc2.getWorld())) return false; + if (loc1.getX() == loc2.getX() && loc1.getY() == loc2.getY() && loc1.getZ() == loc2.getZ()) { + if (pitchYaw) return loc1.getPitch() == loc2.getPitch() && loc1.getYaw() == loc2.getYaw(); + return true; + } + return false; + } +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/Houses.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/Houses.java new file mode 100644 index 0000000..5745a03 --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/Houses.java @@ -0,0 +1,233 @@ +package net.grandtheftmc.houses; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.Optional; +import java.util.logging.Level; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.java.JavaPlugin; + +import com.sk89q.worldedit.bukkit.WorldEditPlugin; + +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.houses.commands.HouseChestCommand; +import net.grandtheftmc.houses.commands.HouseDisableCommand; +import net.grandtheftmc.houses.commands.HouseDoorCommand; +import net.grandtheftmc.houses.commands.HouseSignCommand; +import net.grandtheftmc.houses.commands.HouseTrashcanCommand; +import net.grandtheftmc.houses.commands.HousesCommand; +import net.grandtheftmc.houses.houses.HousesManager; +import net.grandtheftmc.houses.listeners.BreakBlock; +import net.grandtheftmc.houses.listeners.Chat; +import net.grandtheftmc.houses.listeners.Damage; +import net.grandtheftmc.houses.listeners.Death; +import net.grandtheftmc.houses.listeners.Interact; +import net.grandtheftmc.houses.listeners.InventoryClose; +import net.grandtheftmc.houses.listeners.InventoryInteract; +import net.grandtheftmc.houses.listeners.Join; +import net.grandtheftmc.houses.listeners.Leave; +import net.grandtheftmc.houses.listeners.Login; +import net.grandtheftmc.houses.listeners.MenuListener; +import net.grandtheftmc.houses.listeners.PetListener; +import net.grandtheftmc.houses.listeners.Teleport; +import net.grandtheftmc.houses.listeners.WeaponShoot; +import net.grandtheftmc.houses.users.HouseUser; +import net.grandtheftmc.houses.users.HouseUserManager; +import net.grandtheftmc.houses.users.UserHouse; + +public class Houses extends JavaPlugin { + + public static boolean ENABLED = true; + + private static Houses instance; + + private static HouseUserManager um; + private static HousesManager hm; + + private static HousesSettings settings; + private static WorldEditPlugin worldEditPlugin; + + public static Houses getInstance() { + return instance; + } + + public static HouseUserManager getUserManager() { + return um; + } + + public static HousesManager getManager() { + return hm; + } + + public static HousesManager getHousesManager() { + return hm; + } + + public static HousesSettings getSettings() { + return settings; + } + + public static void log(String s) { + Houses.getInstance().getLogger().log(Level.ALL, s); + } + + public static void error(String s) { + Houses.getInstance().getLogger().log(Level.SEVERE, s); + } + + public static Optional<WorldEditPlugin> getWorldEdit() { + return Optional.of(worldEditPlugin); + } + + @Override + public void onEnable() { + instance = this; + settings = new HousesSettings(); + this.load(); + this.setupDatabase(); + um = new HouseUserManager(); + hm = new HousesManager(); + + this.registerListeners(); + this.registerCommands(); + } + + @Override + public void onDisable() { + + System.out.println("[Houses] Disabling houses..."); + + HandlerList.unregisterAll(this); + + // note that this is sync because any async calls will not run + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + for (Player player : Bukkit.getOnlinePlayers()) { + if (player.getOpenInventory() == null) return; + + // TODO remove later + System.out.println("[Houses] Player " + player.getName() + " has open inventory: " + player.getOpenInventory().getTitle()); + + // TODO remove later + if (player.getOpenInventory() != null && player.getOpenInventory().getTopInventory() != null){ + System.out.println("[Houses] Player " + player.getName() + " has open TOP inventory: " + player.getOpenInventory().getTopInventory().getTitle()); + } + + HouseUser user = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + if (user != null){ + System.out.println("[Houses] Player " + player.getName() + " is inside house: " + user.isInsideHouse() + " and lastChest=" + user.getLastChestId()); + } + + if (user.isInsideHouse() && user.getLastChestId() != -1) { + + // TODO remove later + System.out.println("[Houses] Player " + player.getName() + " is inside house with last chest ID: " + user.getLastChestId()); + + // If chest is open. + if (player.getOpenInventory() != null && player.getOpenInventory().getTopInventory() != null) { + String name = ChatColor.stripColor(player.getOpenInventory().getTopInventory().getTitle()).toLowerCase(); + + // TODO remove later + System.out.println("[Houses] Player " + player.getName() + " top inventory stripped: " + name); + + if (!name.contains("chest:")) continue; + + UserHouse house = user.getUserHouse(user.getInsideHouse()); + + // TODO remove later + System.out.println("[Houses] Player " + player.getName() + " is inside house id=" + house.getId() + " with chest id=" + user.getLastChestId()); + + try (PreparedStatement statement = connection.prepareStatement( + "UPDATE gtm_house_chest SET content=? WHERE house_id=? AND uuid=UNHEX(?) AND chest_id=?")) { + statement.setString(1, GTMUtils.toBase64(player.getOpenInventory().getTopInventory().getContents())); + statement.setInt(2, house.getUniqueId()); + statement.setString(3, player.getUniqueId().toString().replaceAll("-", "")); + statement.setInt(4, user.getLastChestId()); + + statement.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + } + + player.closeInventory(); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + + this.save(); + } + + private void load() { + settings.setHousesConfig(Utils.loadConfig("houses")); + settings.setPremiumHousesConfig(Utils.loadConfig("premiumHouses")); + this.setupDatabase(); + this.loadMenus(); + if(Bukkit.getPluginManager().getPlugin("WorldEdit") != null) { + worldEditPlugin = (WorldEditPlugin)Bukkit.getPluginManager().getPlugin("WorldEdit"); + } + } + + private void save() { + hm.save(); + } + + private void registerListeners() { + PluginManager pm = Bukkit.getPluginManager(); + pm.registerEvents(new BreakBlock(), this); + pm.registerEvents(new Damage(), this); + pm.registerEvents(new Death(), this); + pm.registerEvents(new Interact(), this); + pm.registerEvents(new InventoryClose(), this); + pm.registerEvents(new InventoryInteract(), this); + pm.registerEvents(new Join(), this); + pm.registerEvents(new Leave(), this); + pm.registerEvents(new Login(this), this); + pm.registerEvents(new Teleport(), this); + pm.registerEvents(new MenuListener(), this); + pm.registerEvents(new PetListener(), this); + pm.registerEvents(new Chat(), this); + pm.registerEvents(new WeaponShoot(), this); + } + + private void registerCommands() { + this.getCommand("houses").setExecutor(new HousesCommand()); + this.getCommand("premiumhouses").setExecutor(new HousesCommand()); + this.getCommand("housechest").setExecutor(new HouseChestCommand()); + this.getCommand("housedoor").setExecutor(new HouseDoorCommand()); + this.getCommand("housesign").setExecutor(new HouseSignCommand()); + this.getCommand("housetrashcan").setExecutor(new HouseTrashcanCommand()); + new HouseDisableCommand(); + } + + public void setupDatabase() { +// BaseDatabase.runCustomQuery("create table if not exists " + Core.name() + "_houses(uuid varchar(255), name varchar(255), houseId integer)"); +// BaseDatabase.runCustomQuery("create table if not exists " + Core.name() + "_houses_chests(uuid varchar(255), houseId integer, chestId integer, contents blob);"); + } + + private void loadMenus() { + MenuManager.addMenu("houses", 54, "&3&lMy Houses"); + MenuManager.addMenu("house", 54, "&3&lHouse"); + MenuManager.addMenu("premiumhouse", 54, "&3&lPremium House"); + MenuManager.addMenu("buyhouse", 54, "&3&lBuy House"); + MenuManager.addMenu("buypremiumhouse", 54, "&3&lBuy Premium House"); + MenuManager.addMenu("sellhouse", 54, "&3&lSell House"); + MenuManager.addMenu("sellpremiumhouse", 54, "&3&lSell Premium House"); + MenuManager.addMenu("guests", 54, "&3&lPremium House Guests"); + MenuManager.addMenu("removeguests", 54, "&3&lRemove Guests"); + MenuManager.addMenu("houseshelp", 54, "&3&lHouses Help"); + MenuManager.addMenu("editblocks", 54, "&3&lChange Blocks"); + MenuManager.addMenu("buytrashcan", 54, "&3&lBuy Trashcan"); + MenuManager.addMenu("confirmtrashcanbuy", 54, "&3&lConfirm Purchase"); + } +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/HousesSettings.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/HousesSettings.java new file mode 100644 index 0000000..e1cae5b --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/HousesSettings.java @@ -0,0 +1,24 @@ +package net.grandtheftmc.houses; + +import org.bukkit.configuration.file.YamlConfiguration; + +public class HousesSettings { + private YamlConfiguration housesConfig; + private YamlConfiguration premiumHousesConfig; + + public YamlConfiguration getHousesConfig() { + return this.housesConfig; + } + + public void setHousesConfig(YamlConfiguration c) { + this.housesConfig = c; + } + public YamlConfiguration getPremiumHousesConfig() { + return this.premiumHousesConfig; + } + + public void setPremiumHousesConfig(YamlConfiguration c) { + this.premiumHousesConfig = c; + } + +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/JSONHelper.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/JSONHelper.java new file mode 100644 index 0000000..641249a --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/JSONHelper.java @@ -0,0 +1,31 @@ +package net.grandtheftmc.houses; + +import org.json.JSONObject; + +public class JSONHelper { + + private final JSONObject object; + + public JSONHelper() { + this.object = new JSONObject(); + } + + public JSONHelper put(String k, int v) { + object.put(k, v); + return this; + } + + public JSONHelper put(String k, String v) { + object.put(k, v); + return this; + } + + public JSONHelper put(String k, boolean v) { + object.put(k, v); + return this; + } + + public String string() { + return object.toString(); + } +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/KeyVal.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/KeyVal.java new file mode 100644 index 0000000..f1e29fa --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/KeyVal.java @@ -0,0 +1,19 @@ +package net.grandtheftmc.houses; + +public class KeyVal<K, V> { + private final K key; + private final V val; + + public KeyVal(K key, V val) { + this.key = key; + this.val = val; + } + + public K getKey() { + return key; + } + + public V getVal() { + return val; + } +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/commands/HouseChestCommand.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/commands/HouseChestCommand.java new file mode 100644 index 0000000..1c1dc80 --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/commands/HouseChestCommand.java @@ -0,0 +1,156 @@ +package net.grandtheftmc.houses.commands; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.houses.House; +import net.grandtheftmc.houses.houses.HouseChest; +import net.grandtheftmc.houses.houses.PremiumHouse; +import net.grandtheftmc.houses.houses.PremiumHouseChest; +import net.grandtheftmc.houses.users.HouseUser; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.List; +import java.util.UUID; + +public class HouseChestCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command cmd, String label, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Utils.f("&cYou are not a player!")); + return true; + } + Player player = (Player) s; + UUID uuid = player.getUniqueId(); + if (!s.hasPermission("houses.admin")) { + s.sendMessage(Utils.f("&cYou don't have permission to execute this command!")); + return true; + } + if (args.length == 0) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7&lChests Help")); + s.sendMessage(Utils.f("&3/housechest&7 add")); + s.sendMessage(Utils.f("&3/housechest&7 remove")); + s.sendMessage(Utils.f("&3/housechest&7 removeall")); + s.sendMessage(Utils.f("&3/housechest&7 stop")); + s.sendMessage(Utils.f("&3/housechest&7 list")); + return true; + } + HouseUser user = Houses.getUserManager().getLoadedUser(uuid); + House house = user.getEditingHouse(); + PremiumHouse premiumHouse = user.getEditingPremiumHouse(); + if (house == null && premiumHouse == null) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7You are not editing any house! Use &3/house edit &a<id>&7.")); + return true; + } + switch (args[0].toLowerCase()) { + case "add": + if (args.length != 1) { + s.sendMessage(Utils.f("&c/housechest add")); + return true; + } + user.setAddingChests(true); + user.setRemovingChests(false); + s.sendMessage(Utils.f(Lang.HOUSES + "&7Right click chests to add them!")); + return true; + case "remove": + if (args.length != 1) { + s.sendMessage(Utils.f("&c/housechest add")); + return true; + } + user.setRemovingChests(true); + user.setAddingChests(false); + s.sendMessage(Utils.f(Lang.HOUSES + + "&7Right click chests to remove them! Warning: removing a chest will remove all stored items for all owners from that chest!")); + return true; + case "removeall": + if (args.length > 2) { + s.sendMessage(Utils.f("&c/housechest removeall")); + return true; + } + if (args.length == 1) { + s.sendMessage(Utils.f(Lang.HOUSES + + "&7Are you sure? This will delete all chests and their contents for all owners of this house! Type &3/house removeall confirm&7 to proceed...")); + return true; + } + if (!"confirm".equalsIgnoreCase(args[1])) { + s.sendMessage(Utils.f("&c/housechest removeall")); + return true; + } + if (house == null) { + premiumHouse.removeAllChests(); + s.sendMessage(Utils.f(Lang.HOUSES + "&7All chests were removed from this premium house.")); + return true; + } + house.removeAllChests(); + s.sendMessage(Utils.f(Lang.HOUSES + "&7All chests were removed from this house.")); + return true; + case "stop": + if (args.length != 1) { + s.sendMessage(Utils.f("&c/housechest stop")); + return true; + } + user.setRemovingChests(false); + user.setAddingChests(false); + s.sendMessage(Utils.f(Lang.HOUSES + "&7You are no longer adding/removing chests to/from " + + (house == null ? "premium house &a" + premiumHouse.getId() : "house &a" + house.getId()) + + "&7.")); + return true; + case "list": + int page = 1; + if (args.length > 1) { + try { + page = Integer.parseInt(args[1]); + } catch (NumberFormatException e) { + page = 1; + } + } + int start = (page << 3) - 7; + int end = page << 3; + if (house == null) { + List<PremiumHouseChest> chests = user.getEditingPremiumHouse().getChests(start, end); + s.sendMessage(Utils.f(Lang.HOUSES + "&3&lPage &a" + page + " &3&lTotal Premium Chests: &a" + + user.getEditingPremiumHouse().getChests().size())); + for (PremiumHouseChest chest : chests) + s.sendMessage(Utils.f(" &3&lID: &a" + chest.getId() + " &3&lLocation 1: &a" + + Utils.blockLocationToString(chest.getLoc1()) + (chest.getLoc2() == null ? "" : " &3&lLocation 2: &a" + Utils.blockLocationToString(chest.getLoc2())))); + return true; + } + List<HouseChest> chests = user.getEditingHouse().getChests(start, end); + s.sendMessage(Utils.f(Lang.HOUSES + "&3&lPage &a" + page + " &3&lTotal Chests: &a" + + user.getEditingHouse().getChests().size())); + for (HouseChest chest : chests) + s.sendMessage(Utils.f(" &3&lID: &a" + chest.getId() + " &3&lLocation 1: &a" + + Utils.blockLocationToString(chest.getLoc1()) + (chest.getLoc2() == null ? "" : " &3&lLocation 2: &a" + Utils.blockLocationToString(chest.getLoc2())))); + return true; + case "clear": + if (args.length == 1) { + premiumHouse.getChests().forEach(premiumHouseChest -> { + premiumHouseChest.clear(); + player.sendMessage(Lang.HOUSES.f("&7Cleared chest &a" + premiumHouseChest.getId() + + " &7of premium house &a" + premiumHouse.getId())); + }); + } else if (args[1].equalsIgnoreCase("all")) { + Houses.getHousesManager().getPremiumHouses().forEach(targetHouse -> { + targetHouse.getChests().forEach(premiumHouseChest -> { + premiumHouseChest.clear(); + player.sendMessage(Lang.HOUSES.f("&7Cleared chest &a" + premiumHouseChest.getId() + + " &7of premium house &a" + targetHouse.getId())); + }); + }); + } + return true; + default: + s.sendMessage(Utils.f(Lang.HOUSES + "&7&lChests Help")); + s.sendMessage(Utils.f("&3/housechest&7 add")); + s.sendMessage(Utils.f("&3/housechest&7 remove")); + s.sendMessage(Utils.f("&3/housechest&7 removeall")); + s.sendMessage(Utils.f("&3/housechest&7 stop")); + s.sendMessage(Utils.f("&3/housechest&7 list")); + return true; + } + } +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/commands/HouseDisableCommand.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/commands/HouseDisableCommand.java new file mode 100644 index 0000000..b4db7a8 --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/commands/HouseDisableCommand.java @@ -0,0 +1,26 @@ +package net.grandtheftmc.houses.commands; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.commands.CoreCommand; +import net.grandtheftmc.core.commands.RankedCommand; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.houses.Houses; +import org.bukkit.entity.Player; + +public class HouseDisableCommand extends CoreCommand<Player> implements RankedCommand { + + public HouseDisableCommand() { + super("housedisable", "Temp command to disable house features."); + } + + @Override + public void execute(Player sender, String[] strings) { + Houses.ENABLED = !Houses.ENABLED; + sender.sendMessage(Lang.HOUSES.f("&cBuying/Selling & Info editing is " + (Houses.ENABLED ? "Enabled." : "Disabled!"))); + } + + @Override + public UserRank requiredRank() { + return UserRank.ADMIN; + } +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/commands/HouseDoorCommand.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/commands/HouseDoorCommand.java new file mode 100644 index 0000000..a00ad45 --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/commands/HouseDoorCommand.java @@ -0,0 +1,227 @@ +package net.grandtheftmc.houses.commands; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.houses.House; +import net.grandtheftmc.houses.houses.HouseDoor; +import net.grandtheftmc.houses.houses.PremiumHouse; +import net.grandtheftmc.houses.houses.PremiumHouseDoor; +import net.grandtheftmc.houses.users.HouseUser; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.List; +import java.util.UUID; + +public class HouseDoorCommand implements CommandExecutor { + @Override + public boolean onCommand(CommandSender s, Command cmd, String label, String[] args) { + if (!s.hasPermission("houses.admin") ) { + s.sendMessage(Utils.f("&cYou don't have permission to execute this command!")); + return true; + } + if (!(s instanceof Player)) { + s.sendMessage(Utils.f("&cYou are not a player!")); + return true; + } + if (args.length == 0) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7&lChests Help")); + s.sendMessage(Utils.f("&3/housedoor&7 add")); + s.sendMessage(Utils.f("&3/housedoor&7 remove &a(id)")); + s.sendMessage(Utils.f("&3/housedoor&7 stop")); + s.sendMessage(Utils.f("&3/housedoor&7 removeall")); + s.sendMessage(Utils.f("&3/housedoor&7 list")); + return true; + } + Player player = (Player) s; + UUID uuid = player.getUniqueId(); + HouseUser user = Houses.getUserManager().getLoadedUser(uuid); + House house = user.getEditingHouse(); + PremiumHouse premiumHouse = user.getEditingPremiumHouse(); + if (house == null && premiumHouse == null) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7You are not editing any house! Use &3/house edit &a<id>&7.")); + return true; + } + switch (args[0].toLowerCase()) { + case "add": { + if (args.length != 1) { + s.sendMessage(Utils.f("&c/housedoor add")); + return true; + } + + if (house == null) { + premiumHouse.addDoor(result -> { + if (result == null) return; + + ServerUtil.runTask(() -> { + user.setAddingPremiumDoor(result); + s.sendMessage(Utils.f(Lang.HOUSES + "&7You are adding a door with id &a" + result.getId() + "&7. Please right click the door to add it. After that, right click to set the outside location and left click to set the inside location.")); + }); + }); +// user.setAddingPremiumDoor(door); +// s.sendMessage(Utils.f(Lang.HOUSES + "&7You are adding a door with id &a" + door.getId() +// + "&7. Please right click the door to add it. After that, right click to set the outside location and left click to set the inside location.")); + return true; + } + + house.addDoor(result -> { + if (result != null) { + ServerUtil.runTask(() -> { + user.setAddingDoor(result); + s.sendMessage(Utils.f(Lang.HOUSES + "&7You are adding a door with id " + result.getId() + ". Please right click the door to add it. After that, right click to set the outside location and left click to set the inside location.")); + }); + } + }); + +// user.setAddingDoor(door); +// s.sendMessage(Utils.f(Lang.HOUSES + "&7You are adding a door with id " + door.getId() +// + ". Please right click the door to add it. After that, right click to set the outside location and left click to set the inside location.")); + return true; + } + case "remove": + if (args.length == 2) { + int id; + try { + id = Integer.parseInt(args[1]); + } catch (NumberFormatException e) { + s.sendMessage(Lang.HOUSES.f("&7The id must be a number!")); + return true; + } + if (house == null) { + PremiumHouseDoor door = premiumHouse.getDoor(id); + if (door == null) { + s.sendMessage(Lang.HOUSES.f("&7No door with id &a" + id + "&7 exists in this premium house!")); + return true; + } + premiumHouse.removeDoor(door); + player.sendMessage(Utils.f(Lang.HOUSES + "&7You removed a door with id &a" + door.getId() + + "&7 from premium house &a" + premiumHouse.getId() + "&7.")); + return true; + } + HouseDoor door = house.getDoor(id); + if (door == null) { + s.sendMessage(Lang.HOUSES.f("&7No door with id &a" + id + "&7 exists in this house!")); + return true; + } + house.removeDoor(door); + player.sendMessage(Utils.f(Lang.HOUSES + "&7You removed a door with id &a" + door.getId() + + "&7 from house &a" + premiumHouse.getId() + "&7.")); + return true; + + } + if (args.length != 1) { + s.sendMessage(Utils.f("&c/housedoor remove")); + return true; + } + user.setRemovingDoor(true); + user.setAddingDoor(null); + s.sendMessage(Utils.f(Lang.HOUSES + "&7Right click doors to remove them!")); + return true; + + case "removeall": + if (args.length > 2) { + s.sendMessage(Utils.f("&c/housedoor removeall")); + return true; + } + if (args.length == 1) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7Are you sure you want to do this? Type &3/" + label + + " removeall confirm&7 to proceed...")); + return true; + } + if (!"confirm".equals(args[1])) { + s.sendMessage(Utils.f("&c/housedoor removeall")); + return true; + } + if (house == null) { + premiumHouse.removeAllDoors(); + player.sendMessage(Utils.f( + Lang.HOUSES + "&7You removed all doors from premium house &a" + premiumHouse.getId() + "&7.")); + return true; + } + house.removeAllDoors(); + player.sendMessage( + Utils.f(Lang.HOUSES + "&7You removed all doors from house &a" + premiumHouse.getId() + "&7.")); + return true; + + case "stop": + if (args.length != 1) { + s.sendMessage(Utils.f("&c/housedoor add")); + return true; + } + if (house == null) { + if (user.isAddingPremiumDoor()) { + premiumHouse.removeDoor(user.getAddingPremiumDoor()); + user.setAddingPremiumDoor(null); + s.sendMessage(Lang.HOUSES.f("&7The door you were adding was deleted from premium house &a" + + premiumHouse.getId() + "&7.")); + return true; + } else if (user.isRemovingDoor()) { + user.setRemovingDoor(false); + s.sendMessage(Lang.HOUSES.f( + "&7You are no longer removing doors from premium house &a" + premiumHouse.getId() + "&7.")); + return true; + } + s.sendMessage(Lang.HOUSES.f("&7You are not adding/removing doors!")); + return true; + } + if (user.isAddingDoor()) { + house.removeDoor(user.getAddingDoor()); + user.setAddingDoor(null); + s.sendMessage( + Lang.HOUSES.f("&7The door you were adding was deleted from house &a" + house.getId() + "&7.")); + return true; + } else if (user.isRemovingDoor()) { + user.setRemovingDoor(false); + s.sendMessage( + Lang.HOUSES.f("&7You are no longer removing doors from house &a" + house.getId() + "&7.")); + return true; + } + s.sendMessage(Lang.HOUSES.f("&7You are not adding/removing doors!")); + return true; + case "list": + int page = 1; + if (args.length > 1) { + try { + page = Integer.parseInt(args[1]); + } catch (NumberFormatException ignored) { + } + } + int start = (page << 3) - 7; + int end = page << 3; + if (house == null) { + List<PremiumHouseDoor> doors = user.getEditingPremiumHouse().getDoors(start, + end); + s.sendMessage(Utils.f(Lang.HOUSES + "&3&lPage &a" + page + " &3&lTotal Premium Doors: &a" + + premiumHouse.getDoors().size())); + for (PremiumHouseDoor door : doors) + s.sendMessage(Utils.f(" &3&lID: &a" + door.getId() + " &3&lLocation: &a" + + Utils.blockLocationToString(door.getLocation()) + " &3&lOutside: &a" + + Utils.teleportLocationToString(door.getOutsideLocation()) + " &3&lInside: &a" + + Utils.teleportLocationToString(door.getInsideLocation()))); + return true; + } + List<HouseDoor> doors = user.getEditingHouse().getDoors(start, + end); + s.sendMessage( + Utils.f(Lang.HOUSES + "&3&lPage &a" + page + " &3&lTotal Doors: &a" + house.getDoors().size())); + for (HouseDoor door : doors) + s.sendMessage(Utils.f(" &3&lID: &a" + door.getId() + " &3&lLocation: &a" + + Utils.blockLocationToString(door.getLocation()) + " &3&lOutside: &a" + + Utils.teleportLocationToString(door.getOutsideLocation()) + " &3&lInside: &a" + + Utils.teleportLocationToString(door.getInsideLocation()))); + return true; + default: + s.sendMessage(Utils.f(Lang.HOUSES + "&7&lChests Help")); + s.sendMessage(Utils.f("&3/housedoor&7 add")); + s.sendMessage(Utils.f("&3/housedoor&7 remove")); + s.sendMessage(Utils.f("&3/housedoor&7 stop")); + s.sendMessage(Utils.f("&3/housedoor&7 removeall")); + s.sendMessage(Utils.f("&3/housedoor&7 list")); + return true; + } + } +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/commands/HouseSignCommand.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/commands/HouseSignCommand.java new file mode 100644 index 0000000..8975ce3 --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/commands/HouseSignCommand.java @@ -0,0 +1,181 @@ +package net.grandtheftmc.houses.commands; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.houses.House; +import net.grandtheftmc.houses.houses.HouseSign; +import net.grandtheftmc.houses.houses.PremiumHouse; +import net.grandtheftmc.houses.users.HouseUser; +import org.bukkit.Location; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.List; +import java.util.UUID; + +public class HouseSignCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command cmd, String label, String[] args) { + if (!s.hasPermission("houses.admin") ) { + s.sendMessage(Utils.f("&cYou don't have permission to execute this command!")); + return true; + } + if (!(s instanceof Player)) { + s.sendMessage(Utils.f("&cYou are not a player!")); + return true; + } + Player player = (Player) s; + UUID uuid = player.getUniqueId(); + if (args.length == 0) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7&lSigns Help")); + s.sendMessage(Utils.f("&3/housesign&7 add")); + s.sendMessage(Utils.f("&3/housesign&7 remove")); + s.sendMessage(Utils.f("&3/housesign&7 removeall")); + s.sendMessage(Utils.f("&3/housesign&7 stop")); + s.sendMessage(Utils.f("&3/housesign&7 list")); + s.sendMessage(Utils.f("&3/housesign&7 update &a<all>")); + return true; + } + HouseUser user = Houses.getUserManager().getLoadedUser(uuid); + House house = user.getEditingHouse(); + PremiumHouse premiumHouse = user.getEditingPremiumHouse(); + switch (args[0].toLowerCase()) { + case "add": + if (house == null && premiumHouse == null) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7You are not editing any house! Use &3/house edit &a<id>&7.")); + return true; + } + if (args.length != 1) { + s.sendMessage(Utils.f("&c/housesign add")); + return true; + } + user.setAddingSigns(true); + user.setRemovingSigns(false); + s.sendMessage(Utils.f(Lang.HOUSES + "&7Right click signs to add them!")); + return true; + case "remove": + if (house == null && premiumHouse == null) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7You are not editing any house! Use &3/house edit &a<id>&7.")); + return true; + } + if (args.length != 1) { + s.sendMessage(Utils.f("&c/housesign add")); + return true; + } + user.setRemovingSigns(true); + user.setAddingChests(false); + s.sendMessage(Utils.f(Lang.HOUSES + + "&7Right click signs to remove them!")); + return true; + case "removeall": + if (house == null && premiumHouse == null) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7You are not editing any house! Use &3/house edit &a<id>&7.")); + return true; + } + if (args.length > 2) { + s.sendMessage(Utils.f("&c/housesign removeall")); + return true; + } + if (args.length == 1) { + s.sendMessage(Utils.f(Lang.HOUSES + + "&7Are you sure? This will delete all signs of this house! Type &3/housesign removeall confirm&7 to proceed...")); + return true; + } + if (!"confirm".equalsIgnoreCase(args[1])) { + s.sendMessage(Utils.f("&c/housesign removeall")); + return true; + } + if (house == null) { + premiumHouse.removeAllSigns(); + s.sendMessage(Utils.f(Lang.HOUSES + "&7All signs were removed from this premium house.")); + return true; + } + house.removeAllSigns(); + s.sendMessage(Utils.f(Lang.HOUSES + "&7All signs were removed from this house.")); + return true; + case "stop": + if (house == null && premiumHouse == null) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7You are not editing any house! Use &3/house edit &a<id>&7.")); + return true; + } + if (args.length != 1) { + s.sendMessage(Utils.f("&c/housesign stop")); + return true; + } + user.setRemovingSigns(false); + user.setAddingSigns(false); + s.sendMessage(Utils.f(Lang.HOUSES + "&7You are no longer adding/removing signs to/from " + + (house == null ? "premium house &a" + premiumHouse.getId() : "house &a" + house.getId()) + + "&7.")); + return true; + case "list": + if (house == null && premiumHouse == null) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7You are not editing any house! Use &3/house edit &a<id>&7.")); + return true; + } + int page = 1; + if (args.length > 1) { + try { + page = Integer.parseInt(args[1]); + } catch (NumberFormatException e) { + page = 1; + } + } + int start = (page << 3) - 8; + int end = (page << 3) - 1; + + if (house == null) { + int size = user.getEditingPremiumHouse().getSigns().size(); + List<HouseSign> signs = user.getEditingPremiumHouse().getSigns(start, end > size ? size : end); + s.sendMessage(Utils.f(Lang.HOUSES + "&3&lPage &a" + page + " &3&lTotal Premium House Signs: &a" + user.getEditingPremiumHouse().getSigns().size())); + for (HouseSign loc : signs) + s.sendMessage(Utils.f(" &3&lLocation: &a" + Utils.blockLocationToString(loc.getLocation()))); + return true; + } + + int size = user.getEditingHouse().getSigns().size(); + List<HouseSign> signs = user.getEditingHouse().getSigns().subList(start, end > size ? size : end); + s.sendMessage(Utils.f(Lang.HOUSES + "&3&lPage &a" + page + " &3&lTotal House Signs: &a" + user.getEditingHouse().getSigns().size())); + for (HouseSign loc : signs) + s.sendMessage(Utils.f(" &3&lLocation: &a" + Utils.blockLocationToString(loc.getLocation()))); + return true; + + case "update": + if (user.getEditingPremiumHouse() != null) { + PremiumHouse premHouse = user.getEditingPremiumHouse(); + premHouse.updateSigns(); + s.sendMessage(Utils.f(Lang.HOUSES + "&7You updated the signs of premium house &a" + premHouse.getId())); + return true; + } else if (user.getEditingHouse() != null) { + house = user.getEditingHouse(); + house.updateSigns(); + s.sendMessage(Utils.f(Lang.HOUSES + "&7You updated the signs of house &a" + house.getId())); + } else { + if (args.length == 2) { + if (args[1].equalsIgnoreCase("all")) { + Houses.getHousesManager().getPremiumHouses().forEach(PremiumHouse::updateSigns); + s.sendMessage(Utils.f(Lang.HOUSES + "&7You updated the signs of &aALL &7premium houses")); + } else { + s.sendMessage(Utils.f("&3/housesign&7 update <all>")); + } + return true; + } + s.sendMessage(Utils.f(Lang.HOUSES + "&7You are not editing any house!")); + } + return true; + default: + s.sendMessage(Utils.f(Lang.HOUSES + "&7&lChests Help")); + s.sendMessage(Utils.f("&3/housesign&7 add")); + s.sendMessage(Utils.f("&3/housesign&7 remove")); + s.sendMessage(Utils.f("&3/housesign&7 removeall")); + s.sendMessage(Utils.f("&3/housesign&7 stop")); + s.sendMessage(Utils.f("&3/housesign&7 list")); + s.sendMessage(Utils.f("&3/housesign&7 update &a<all>")); + return true; + } + } +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/commands/HouseTrashcanCommand.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/commands/HouseTrashcanCommand.java new file mode 100644 index 0000000..c1c1b90 --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/commands/HouseTrashcanCommand.java @@ -0,0 +1,80 @@ +package net.grandtheftmc.houses.commands; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.houses.PremiumHouse; +import net.grandtheftmc.houses.users.HouseUser; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.UUID; + +public class HouseTrashcanCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command cmd, String label, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Utils.f("&cYou are not a player!")); + return true; + } + Player player = (Player) s; + UUID uuid = player.getUniqueId(); + if (!s.hasPermission("houses.admin")) { + s.sendMessage(Utils.f("&cYou don't have permission to execute this command!")); + return true; + } + if (args.length == 0) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7&lTrashCan Help")); + s.sendMessage(Utils.f("&3/housetrashcan&7 add")); + s.sendMessage(Utils.f("&3/housetrashcan&7 remove")); + s.sendMessage(Utils.f("&3/housetrashcan&7 stop")); + return true; + } + HouseUser user = Houses.getUserManager().getLoadedUser(uuid); + PremiumHouse premiumHouse = user.getEditingPremiumHouse(); + if (premiumHouse == null) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7You are not editing any house! Use &3/house edit &a<id>&7.")); + return true; + } + switch (args[0].toLowerCase()) { + case "add": + if (args.length != 1) { + s.sendMessage(Utils.f("&c/housetrashcan add")); + return true; + } + user.setAddingTrashcans(true); + user.setRemovingTrashcans(false); + s.sendMessage(Utils.f(Lang.HOUSES + "&7Right click trashcans to add them!")); + return true; + case "remove": + if (args.length != 1) { + s.sendMessage(Utils.f("&c/housechest add")); + return true; + } + user.setRemovingTrashcans(true); + user.setAddingTrashcans(false); + s.sendMessage(Utils.f(Lang.HOUSES + + "&7Right click trashcans to remove them!")); + return true; + case "stop": + if (args.length != 1) { + s.sendMessage(Utils.f("&c/housechest stop")); + return true; + } + user.setRemovingTrashcans(false); + user.setAddingTrashcans(false); + s.sendMessage(Utils.f(Lang.HOUSES + "&7You are no longer adding/removing trashcans to/from " + + "premium house &a" + premiumHouse.getId())); + return true; + default: + s.sendMessage(Utils.f(Lang.HOUSES + "&7&lTrashCan Help")); + s.sendMessage(Utils.f("&3/housetrashcan&7 add")); + s.sendMessage(Utils.f("&3/housetrashcan&7 remove")); + s.sendMessage(Utils.f("&3/housetrashcan&7 stop")); + return true; + } + } +} \ No newline at end of file diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/commands/HousesCommand.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/commands/HousesCommand.java new file mode 100644 index 0000000..1183291 --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/commands/HousesCommand.java @@ -0,0 +1,942 @@ +package net.grandtheftmc.houses.commands; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import java.util.stream.Collectors; + +import org.bukkit.Bukkit; +import org.bukkit.block.Block; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import com.sk89q.worldedit.bukkit.WorldEditPlugin; +import com.sk89q.worldedit.bukkit.selections.Selection; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.UserDAO; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.houses.HouseUtils; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.houses.Blocks; +import net.grandtheftmc.houses.houses.EditableBlock; +import net.grandtheftmc.houses.houses.House; +import net.grandtheftmc.houses.houses.HouseDoor; +import net.grandtheftmc.houses.houses.HousesManager; +import net.grandtheftmc.houses.houses.PremiumHouse; +import net.grandtheftmc.houses.houses.PremiumHouseDoor; +import net.grandtheftmc.houses.houses.PremiumHouseGuest; +import net.grandtheftmc.houses.users.HouseUser; +import net.grandtheftmc.houses.users.UserHouse; + +public class HousesCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command cmd, String label, String[] args) { + boolean isPremium = "premiumhouses".equalsIgnoreCase(cmd.getName()); + if (args.length == 0) { + if (!s.hasPermission("houses.admin.all")) { + s.sendMessage(Utils.f("&cYou don't have permission to execute this command!")); + return true; + } + s.sendMessage(Lang.HOUSES.f("&7&lHouses Help")); + s.sendMessage(Utils.f("&3/" + label + "&7 add")); + s.sendMessage(Utils.f("&3/" + label + "&7 edit &a<id>")); + s.sendMessage(Utils.f("&3/" + label + "&7 stop")); + s.sendMessage(Utils.f("&3/" + label + "&7 setprice &a<price>")); + s.sendMessage(Utils.f("&3/" + label + "&7 remove &a<id>")); + s.sendMessage(Utils.f("&3/" + label + "&7 list &a[page]")); + s.sendMessage(Utils.f("&3/" + label + "&7 setowner &a<id> <player>")); + s.sendMessage(Utils.f("&3/" + label + "&7 removeowner &a<id>" + (isPremium ? "" : " <player>"))); + s.sendMessage(Utils.f("&3/" + label + "&7 tp &a<id>")); + s.sendMessage(Utils.f("&3/" + label + "&7 info &a<id>")); + if (isPremium) { + s.sendMessage(Utils.f("&3/" + label + "&7 owner &a<id>")); + s.sendMessage(Utils.f("&3/" + label + "&7 addblocks/delblocks &a<we>")); + s.sendMessage(Utils.f("&3/" + label + "&7 reset &a<id>")); + } + s.sendMessage(Utils.f("&3/" + label + "&7 player &a<player>")); + return true; + } + HousesManager hm = Houses.getManager(); + if (!s.hasPermission("houses.admin.all")) { + if (!s.hasPermission("houses.admin." + args[0].toLowerCase())) { + s.sendMessage(Utils.f("&cYou don't have permission to execute this command!")); + return true; + } + } + switch (args[0].toLowerCase()) { + case "add": { + if (!(s instanceof Player)) { + s.sendMessage(Utils.f("&cYou are not a player!")); + return true; + } + Player player = (Player) s; + UUID uuid = player.getUniqueId(); + HouseUser user = Houses.getUserManager().getLoadedUser(uuid); + if (args.length != 1) { + s.sendMessage(Utils.f("&c/" + label + " add")); + return true; + } + if (isPremium) { + hm.createPremiumHouse(result -> { + if (result == null) { + ServerUtil.runTask(() -> s.sendMessage("Something went wrong, contact Luke. (#err02784)")); + return; + } + + ServerUtil.runTask(() -> { + user.setEditingHouse(null); + user.setEditingPremiumHouse(result); + Core.getUserManager().getLoadedUser(uuid).setEditMode(true); + s.sendMessage(Utils.f(Lang.HOUSES + "&7A premium house with id &a" + result.getId() + "&7 has been created! You are now editing this premium house, you should set the price, add doors and add chests.")); + }); + }); + return true; + } + hm.createHouse(result -> { + if (result == null) { + ServerUtil.runTask(() -> s.sendMessage("Something went wrong, contact Luke. (#err02783)")); + return; + } + + ServerUtil.runTask(() -> { + user.setEditingHouse(result); + user.setEditingPremiumHouse(null); + Core.getUserManager().getLoadedUser(uuid).setEditMode(true); + s.sendMessage(Utils.f(Lang.HOUSES + "&7A house with id &a" + result.getId() + "&7 has been created! You are now editing this house, you should set the price, add doors and add chests.")); + }); + }); +// user.setEditingHouse(house); +// user.setEditingPremiumHouse(null); +// Core.getUserManager().getLoadedUser(uuid).setEditMode(true); +// s.sendMessage(Utils.f(Lang.HOUSES + "&7A house with id &a" + house.getId() +// + "&7 has been created! You are now editing this house, you should set the price, add doors and add chests.")); + return true; + } + case "edit": { + if (!(s instanceof Player)) { + s.sendMessage(Utils.f("&cYou are not a player!")); + return true; + } + Player player = (Player) s; + UUID uuid = player.getUniqueId(); + HouseUser user = Houses.getUserManager().getLoadedUser(uuid); + if (args.length != 2) { + s.sendMessage(Utils.f("&c/" + label + " edit <id>")); + return true; + } + int id; + try { + id = Integer.parseInt(args[1]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7The id must be a number!")); + return true; + } + if (id < 1) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7The id must be bigger than 0!")); + return true; + } + if (isPremium) { + PremiumHouse house = hm.getPremiumHouse(id); + if (house == null) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7No premium house with that ID exists!")); + return true; + } + user.setAddingChests(false); + user.setAddingDoor(null); + user.setAddingPremiumDoor(null); + user.setRemovingChests(false); + user.setRemovingDoor(false); + user.setEditingPremiumHouse(house); + user.setEditingHouse(null); + Core.getUserManager().getLoadedUser(uuid).setEditMode(true); + s.sendMessage(Utils.f(Lang.HOUSES + "&7You are now editing premium house &a" + house.getId() + "&7.")); + return true; + } + House house = hm.getHouse(id); + if (house == null) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7No house with that ID exists!")); + return true; + } + user.setAddingChests(false); + user.setAddingDoor(null); + user.setAddingPremiumDoor(null); + user.setRemovingChests(false); + user.setRemovingDoor(false); + user.setEditingPremiumHouse(null); + user.setEditingHouse(house); + Core.getUserManager().getLoadedUser(uuid).setEditMode(true); + s.sendMessage(Utils.f(Lang.HOUSES + "&7You are now editing house &a" + house.getId() + "&7.")); + return true; + + } + case "stop": { + if (!(s instanceof Player)) { + s.sendMessage(Utils.f("&cYou are not a player!")); + return true; + } + if (args.length != 1) { + s.sendMessage(Utils.f("&c/" + label + " stop <id>")); + return true; + } + Player player = (Player) s; + UUID uuid = player.getUniqueId(); + HouseUser user = Houses.getUserManager().getLoadedUser(uuid); + if (isPremium) { + PremiumHouse premiumHouse = user.getEditingPremiumHouse(); + if (premiumHouse == null) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7You are not editing any premium house!")); + return true; + } + user.setAddingChests(false); + user.setAddingDoor(null); + user.setAddingPremiumDoor(null); + user.setRemovingChests(false); + user.setRemovingDoor(false); + user.setEditingHouse(null); + user.setEditingPremiumHouse(null); + s.sendMessage(Utils.f( + Lang.HOUSES + "&7You are no longer editing premium house &a" + premiumHouse.getId() + "&7.")); + return true; + } + House house = user.getEditingHouse(); + if (house == null) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7You are not editing any house!")); + return true; + } + user.setAddingChests(false); + user.setAddingDoor(null); + user.setAddingPremiumDoor(null); + user.setRemovingChests(false); + user.setRemovingDoor(false); + user.setEditingHouse(null); + user.setEditingPremiumHouse(null); + s.sendMessage(Utils.f(Lang.HOUSES + "&7You are no longer editing house &a" + house.getId() + "&7.")); + return true; + } + case "setprice": { + if (!(s instanceof Player)) { + s.sendMessage(Utils.f("&cYou are not a player!")); + return true; + } + if (args.length != 2) { + s.sendMessage(Utils.f("&c/" + label + " setprice <amnt>")); + return true; + } + Player player = (Player) s; + UUID uuid = player.getUniqueId(); + HouseUser user = Houses.getUserManager().getLoadedUser(uuid); + int amnt; + try { + amnt = Integer.parseInt(args[1]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7The amount must be a number!")); + return true; + } + if (amnt < 1) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7The amount must be bigger than 0!")); + return true; + } + if (isPremium) { + PremiumHouse house = user.getEditingPremiumHouse(); + if (house == null) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7You are not editing any premium house!")); + return true; + } + house.setPermits(amnt); + s.sendMessage(Utils.f(Lang.HOUSES + "&7You set the price of premium house &a" + house.getId() + + "&7 to &3&l" + house.getPermits() + " Permits&7.")); + return true; + } + House house = user.getEditingHouse(); + if (house == null) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7You are not editing any house!")); + return true; + } + house.setPrice(amnt); + s.sendMessage(Utils.f(Lang.HOUSES + "&7You set the price of house &a" + house.getId() + "&7 to &a$&l" + house.getPrice() + "&7.")); + return true; + } + case "remove": { + if (args.length > 3) { + s.sendMessage(Utils.f("&c/" + label + " remove <id>")); + return true; + } + if (args.length == 2) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7Are you sure you want to do this? Type &3/" + label + + " remove &a<id>&3 confirm&7 to proceed...")); + return true; + } + if (!Objects.equals("confirm", args[2])) { + s.sendMessage(Utils.f("&c/" + label + " remove <id>")); + return true; + } + int id; + try { + id = Integer.parseInt(args[1]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7The id must be a number!")); + return true; + } + if (id < 1) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7The id must be bigger than 0!")); + return true; + } + if (isPremium) { + PremiumHouse house = hm.getPremiumHouse(id); + if (house == null) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7That premium house does not exist!")); + return true; + } + hm.removePremiumHouse(house); + s.sendMessage(Utils.f(Lang.HOUSES + "&7You removed the premium house &a" + house.getId() + "&7.")); + return true; + } + House house = hm.getHouse(id); + if (house == null) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7That house does not exist!")); + return true; + } + hm.removeHouse(house); + if (s instanceof Player) { + HouseUser user = Houses.getUserManager().getLoadedUser(((Player) s).getUniqueId()); + user.setAddingChests(false); + user.setAddingDoor(null); + user.setAddingPremiumDoor(null); + user.setRemovingChests(false); + user.setRemovingDoor(false); + user.setEditingHouse(null); + user.setEditingPremiumHouse(null); + } + Utils.insertLogLater((s instanceof Player) ? ((Player)s).getUniqueId() : UUID.randomUUID(), s.getName(), "remove" + (isPremium ? "Premium" : "") + "House", "REMOVE_" + (isPremium ? "PREMIUM" : "") + "_HOUSE", (isPremium ? "Premium" : "") + "House ID: " + id, -1, -1); + s.sendMessage(Utils.f(Lang.HOUSES + "&7You removed the house &a" + house.getId() + "&7.")); + return true; + } + case "list": { + int page = 1; + if (args.length > 1) { + try { + page = Integer.parseInt(args[1]); + } catch (NumberFormatException ignored) { + } + } + + int batch = 8; + int start = batch * (page - 1); + + if (isPremium) { + s.sendMessage(Utils.f(Lang.HOUSES + "&3&lPage &a" + page + " &3&lTotal Premium Houses: &a" + hm.getPremiumHouses().size())); + + for (int i = start; i < start + batch; i++) { + if (hm.getPremiumHouses().size() > i) { + PremiumHouse premiumHouse = hm.getPremiumHouse(i + 1); + s.sendMessage(Utils.f(" &3&lID: &a" + premiumHouse.getId() + " &3&lPermits: &a" + premiumHouse.getPermits() + " &3&lChests: &a" + premiumHouse.getAmountOfChests() + " &3&lDoors: &a" + premiumHouse.getDoors().size())); + } + } + +// for (PremiumHouse premiumHouse : hm.getPremiumHouses()) { +// if (premiumHouse != null) { +// n++; +// s.sendMessage(Utils.f(" &3&lID: &a" + premiumHouse.getId() + " &3&lPermits: &a" + premiumHouse.getPermits() + " &3&lChests: &a" + premiumHouse.getAmountOfChests() + " &3&lDoors: &a" + premiumHouse.getDoors().size())); +// } +// if (n == 8) break; +// } + return true; + } + else { + s.sendMessage(Utils.f(Lang.HOUSES + "&3&lPage &a" + page + " &3&lTotal Houses: &a" + hm.getHouses().size())); + + for (int i = start; i < start + batch; i++) { + if (hm.getHouses().size() > i) { + House house = hm.getHouse(i + 1); + s.sendMessage(Utils.f(" &3&lID: &a" + house.getId() + " &3&lPrice: &a" + house.getPrice() + " &3&lChests: &a" + house.getAmountOfChests() + " &3&lDoors: &a" + house.getDoors().size())); + } + } + +// int n = 0; +// for (int i = 0; i < hm.getHouses().size(); i++) { +// House house = hm.getHouse(start + i); +// if (house != null) { +// n++; +// s.sendMessage(Utils.f(" &3&lID: &a" + house.getId() + " &3&lPrice: &a" + house.getPrice() + " &3&lChests: &a" + house.getAmountOfChests() + " &3&lDoors: &a" + house.getDoors().size())); +// } +// if (n == 8) break; +// } + } + return true; + } + case "unowned": { + int page = 1; + if (args.length > 1) { + try { + page = Integer.parseInt(args[1]); + } catch (NumberFormatException ignored) { + } + } + int start = (page << 3) - 7; + if (isPremium) { + List<PremiumHouse> unowned = new ArrayList<>(); + hm.getPremiumHouses().forEach(premiumHouse -> { + if (premiumHouse.getOwner() == null) unowned.add(premiumHouse); + }); + s.sendMessage(Utils.f(Lang.HOUSES + "&3&lPage &a" + page + " &3&lTotal &a&l(Unowned) &3&lPremium Houses: &a" + + unowned.size())); + int n = 0; + for (int i = 0; i < unowned.size(); i++) { + if (unowned.size() <= start + i) break; + PremiumHouse house = unowned.get(start + i); + if (house != null && house.getOwner() == null) { + n++; + s.sendMessage(Utils.f(" &3&lID: &a" + house.getId() + " &3&lPermits: &a" + house.getPermits() + + " &3&lChests: &a" + house.getAmountOfChests() + " &3&lDoors: &a" + + house.getDoors().size())); + } + if (n == 8) break; + } + } else { + s.sendMessage(Lang.HOUSES.f("&7Premium Houses only! (/ph)")); + } + return true; + } + case "setowner": { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/" + label + " setowner <id> <player>")); + return true; + } + + int id; + try { + id = Integer.parseInt(args[1]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7The id must be a number!")); + return true; + } + if (id < 1) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7The id must be bigger than 0!")); + return true; + } + Player player = Bukkit.getPlayer(args[2]); + if (isPremium) { + + // if player is not online + if (player == null) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + s.sendMessage(Lang.HOUSES.f("&7Please hold on while data is pulled from the database for the offline player.")); + UUID senderUUID = ((Player) s).getUniqueId(); + new BukkitRunnable() { + @Override + public void run() { + UUID uuid = null; + String name = null; + + uuid = UserDAO.getUuidByName(args[2]); + if (uuid != null){ + // this call is perhaps for case sensitivity + name = UserDAO.getNameByUuid(uuid); + } + +// try (Connection connection = BaseDatabase.getInstance().getConnection()) { +// try (PreparedStatement statement = connection.prepareStatement("select uuid,lastname from users where lastname='" + args[2] + "';")) { +// try (ResultSet result = statement.executeQuery()) { +// uuid = UUID.fromString(result.getString("uuid")); +// name = result.getString("lastname"); +// } +// } +// } catch (SQLException e) { +// e.printStackTrace(); +// } + + UUID finalUuid = uuid; + String finalName = name; + new BukkitRunnable() { + @Override + public void run() { + Player sender = Bukkit.getPlayer(senderUUID); + if (sender == null) return; + PremiumHouse house = hm.getPremiumHouse(id); + if (house == null) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7That premium house does not exist!")); + return; + } + + Player newOwner = Bukkit.getPlayer(finalUuid); + if (newOwner != null) { + + house.forceSetOwner(player); + Utils.insertLogLater(sender.getUniqueId(), sender.getName(), "setOwner" + (isPremium ? "Premium" : "") + "HouseTo" + finalName, "SET_OWNER_" + (isPremium ? "PREMIUM" : "") + "_HOUSE", (isPremium ? "Premium" : "") + "House ID: " + id, -1, -1); + s.sendMessage(Lang.HOUSES + .f("&7Player &a" + player.getName() + "&7 now owns premium house &a" + house.getId() + "&7!")); + return; + } + + Player old = Bukkit.getPlayer(house.getOwner()); + if (old != null) { + HouseUser user = Houses.getUserManager().getLoadedUser(old.getUniqueId()); + old.sendMessage(Lang.HOUSES.f("&7You no longer own premium house &a" + house.getId() + "&7!")); + if (user.isInsidePremiumHouse(house.getId())) + user.teleportInOrOutPremiumHouse(old, house); + } + + house.setOwner(finalUuid, finalName, true); + } + }.runTask(Houses.getInstance()); + } + }.runTaskAsynchronously(Houses.getInstance()); + return true; + } + + + PremiumHouse house = hm.getPremiumHouse(id); + if (house == null) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7That premium house does not exist!")); + return true; + } + + + + house.forceSetOwner(player); + s.sendMessage(Lang.HOUSES + .f("&7Player &a" + player.getName() + "&7 now owns premium house &a" + house.getId() + "&7!")); + return true; + } + + if (player == null) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7That player is not online!")); + return true; + } + + House house = hm.getHouse(id); + if (house == null) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7That house does not exist!")); + return true; + } + + HouseUser user = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + house.addOwner(player, user); + s.sendMessage(Lang.HOUSES.f("&7Player &a" + player.getName() + "&7 now owns house &a" + house.getId() + "&7!")); + return true; + } + case "removeowner": { + if (isPremium) { + if (args.length != 2) { + s.sendMessage(Utils.f("&c/" + label + " removeowner <id>")); + return true; + } + } else if (args.length != 3) { + s.sendMessage(Utils.f("&c/" + label + " removeowner <id> <player>")); + return true; + } + + int id; + try { + id = Integer.parseInt(args[1]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7The id must be a number!")); + return true; + } + + if (id < 1) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7The id must be bigger than 0!")); + return true; + } + + if (isPremium) { + PremiumHouse house = hm.getPremiumHouse(id); + if (house == null) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7That premium house does not exist!")); + return true; + } + s.sendMessage(Lang.HOUSES.f("&7Player &a" + house.getOwner() + "&7 no longer owns premium house &a" + house.getId() + "&7!")); + house.removeOwner(true); + return true; + + } + + House house = hm.getHouse(id); + if (house == null) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7That house does not exist!")); + return true; + } + + Player player = Bukkit.getPlayer(args[2]); + if (player == null) { +// Core.sql.updateAsyncLater("delete from " + Core.name() + "_houses where houseId=" + id + " and name='" + args[2] + "';"); + ServerUtil.runTaskAsync(() -> { +// BaseDatabase.runCustomQuery("delete from " + Core.name() + "_houses where houseId=" + id + " and name='" + args[2] + "';"); + + }); + s.sendMessage(Lang.HOUSES.f("&7That player is not online, so the house was removed from them in the database.")); + return true; + } + + HouseUser user = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + if (!user.ownsHouse(id)) { + s.sendMessage(Lang.HOUSES.f("&7That player does not own house &a" + id + "&7!")); + return true; + } + house.removeOwner(player, user); + s.sendMessage(Lang.HOUSES + .f("&7Player &a" + player.getName() + "&7 no longer owns house &a" + house.getId() + "&7!")); + Utils.insertLogLater(s instanceof Player ? ((Player)s).getUniqueId() : UUID.randomUUID(), s.getName(), "removeOwner" + (isPremium ? "Premium" : "") + "House" , "REMOVE_OWNER_" + (isPremium ? "PREMIUM" : "") + "_HOUSE", (isPremium ? "Premium" : "") + "House ID: " + id, -1, -1); + return true; + } + case "owners": + case "owner": { + if (args.length != 2) { + s.sendMessage(Utils.f("&c/houses owner" + (isPremium ? "" : "s") + " <id>")); + return true; + } + + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + + int id; + try { + id = Integer.parseInt(args[1]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7The id must be a number!")); + return true; + } + if (id < 1) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7The id must be bigger than 0!")); + return true; + } + + if (isPremium) { + PremiumHouse house = hm.getPremiumHouse(id); + if (house == null) { + s.sendMessage(Lang.HOUSES.f("&7That premium house does not exist!")); + return true; + } + s.sendMessage(Lang.HOUSES.f("&7The owner of premium house &a" + house.getId() + "&7 is &a" + house.getOwner() + "&7!")); + return true; + } + + House house = hm.getHouse(id); + if (house == null) { + s.sendMessage(Lang.HOUSES.f("&7That house does not exist!")); + return true; + } + + s.sendMessage(Lang.HOUSES.f("&7Pulling house owners from the database! Please wait a couple of (milli)seconds!")); + int houseId = house.getId(); + UUID uuid = ((Player) s).getUniqueId(); + +// new BukkitRunnable() { +// @Override +// public void run() { +// List<String> names = new ArrayList<>(); +// try (Connection connection = BaseDatabase.getInstance().getConnection()) { +// try (PreparedStatement statement = connection.prepareStatement("select * from " + Core.name() + "_houses where houseId=" + houseId + ';')) { +// try (ResultSet result = statement.executeQuery()) { +// while (result.next()) { +// names.add(result.getString("name")); +// } +// } +// } +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// +// List<String> copy = new ArrayList<>(names); +// new BukkitRunnable() { +// @Override +// public void run() { +// Player player = Bukkit.getPlayer(uuid); +// if (player == null) +// return; +// player.sendMessage(Lang.HOUSES.f("&7Owners of House &a" + houseId + "&7:")); +// String msg = ""; +// for (String s : copy) +// msg = msg + "&a" + s + "&7, "; +// if (msg.endsWith("&7, ")) +// msg = msg.substring(0, msg.length() - 4); +// player.sendMessage(Utils.f(msg)); +// } +// }.runTask(Houses.getInstance()); +// } +// }.runTaskAsynchronously(Houses.getInstance()); + + return true; + } + case "player": + if (args.length != 2 && args.length != 3) { + s.sendMessage(Utils.f("&c/" + label + " player <player> [page]")); + return true; + } + int page = 1; + if (args.length == 3) + try { + page = Integer.parseInt(args[1]); + } catch (NumberFormatException ignored) { + } + int start = (page << 3) - 7; + int end = page << 3; + Player player = Bukkit.getPlayer(args[1]); + if (isPremium) { + List<PremiumHouse> allHouses = Houses.getHousesManager().getPremiumHouses().stream().filter(house -> house.getOwnerName() != null && house.getOwnerName().equalsIgnoreCase(args[1])).collect(Collectors.toList()); + List<PremiumHouse> listHouses = start < 0 || end > allHouses.size() ? allHouses : allHouses.subList(start, end); + if (allHouses.isEmpty() || listHouses == null) { + s.sendMessage(Lang.HOUSES.f("&7That player has no houses!")); + return true; + } + + s.sendMessage(Utils.f(Lang.HOUSES + "&3&lPage &a" + page + " &a&l" + (player == null ? args[1] : player.getName()) + "&3&l's Premium Houses: &a" + allHouses.size())); + for (PremiumHouse house : listHouses) { + s.sendMessage(Utils.f(" &3&lID: &a" + house.getId() + " &3&lPermits: &a" + house.getPermits() + " &3&lChests: &a" + house.getAmountOfChests() + " &3&lDoors: &a" + house.getDoors().size())); + } + return true; + } + + if (player == null) { + s.sendMessage(Lang.HOUSES.f("&7That player is not online!")); + return true; + } + + HouseUser user = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + List<UserHouse> houses = user.getHouses(start, end); + if (houses.isEmpty() || houses == null) { + s.sendMessage(Lang.HOUSES.f("&7That player has no houses!")); + return true; + } + + s.sendMessage(Utils.f(Lang.HOUSES + "&3&lPage &a" + page + " &a&l" + player.getName() + "&3&l's Houses: &a" + user.getHouses().size())); + for (UserHouse house : houses) { + House h = hm.getHouse(house.getId()); + s.sendMessage(Utils.f(" &3&lID: &a" + house.getId() + " &3&lPrice: &a" + h.getPrice() + " &3&lChests: &a" + h.getAmountOfChests() + " &3&lDoors: &a" + h.getDoors().size())); + } + return true; + case "tp": { + if (args.length != 2) { + s.sendMessage(Utils.f("&c/" + label + " tp <id>")); + return true; + } + int id; + try { + id = Integer.parseInt(args[1]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7The id must be a number!")); + return true; + } + if (id < 1) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7The id must be bigger than 0!")); + return true; + } + if (isPremium) { + PremiumHouse house = hm.getPremiumHouse(id); + if (house == null) { + s.sendMessage(Lang.HOUSES.f("&7That premium house does not exist!")); + return true; + } + PremiumHouseDoor door = house.getDoor(); + if (door == null) { + s.sendMessage(Lang.HOUSES.f("&7That premium house doesn't have any doors!")); + return true; + } + ((Player) s).teleport(door.getOutsideLocation()); + s.sendMessage(Lang.HOUSES.f("&7You were teleported to the outside location of door &a" + door.getId() + + "&7 of premium house &a" + house.getId() + "&7!")); + return true; + } + House house = hm.getHouse(id); + if (house == null) { + s.sendMessage(Lang.HOUSES.f("&7That house does not exist!")); + return true; + } + HouseDoor door = house.getDoor(); + if (door == null) { + s.sendMessage(Lang.HOUSES.f("&7That house doesn't have any doors!")); + return true; + } + ((Player) s).teleport(door.getOutsideLocation()); + s.sendMessage(Lang.HOUSES.f("&7You were teleported to the outside location of door &a" + door.getId() + + "&7 of house &a" + house.getId() + "&7!")); + return true; + } + case "info": + if (args.length != 2) { + s.sendMessage(Utils.f("&c/" + label + " info <id>")); + return true; + } + int id; + try { + id = Integer.parseInt(args[1]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7The id must be a number!")); + return true; + } + if (id < 1) { + s.sendMessage(Utils.f(Lang.HOUSES + "&7The id must be bigger than 0!")); + return true; + } + if (isPremium) { + PremiumHouse house = hm.getPremiumHouse(id); + if (house == null) { + s.sendMessage(Lang.HOUSES.f("&7That premium house does not exist!")); + return true; + } + s.sendMessage(Lang.HOUSES.f("&3&lInfo of Premium House &a&l" + house.getId())); + s.sendMessage(Utils.f("&3&lChests: &a&l" + house.getAmountOfChests())); + s.sendMessage(Utils.f("&3&lDoors: &a&l" + house.getDoors().size())); + s.sendMessage(Utils.f("&3&lSigns: &a&l" + house.getSigns().size())); + s.sendMessage(Utils.f("&3&lPermits: &a&l" + house.getPermits())); + if (house.isOwned()) { + s.sendMessage(Utils.f("&3&lOwner: &a&l" + house.getOwnerName())); + String guests = ""; + for (PremiumHouseGuest guest : house.getGuests()) + guests = guests + "&a" + guest.getName() + "&7, "; + if (guests.endsWith("&7, ")) + guests = guests.substring(0, guests.length() - 2); + guests += "."; + s.sendMessage(Utils.f("&3&lGuests: &a&l" + guests)); + } + return true; + + } + House house = hm.getHouse(id); + if (house == null) { + s.sendMessage(Lang.HOUSES.f("&7That house does not exist!")); + return true; + } + s.sendMessage(Lang.HOUSES.f("&3&lInfo of House &a&l" + house.getId())); + s.sendMessage(Utils.f("&3&lChests: &a&l" + house.getAmountOfChests())); + s.sendMessage(Utils.f("&3&lDoors: &a&l" + house.getDoors().size())); + s.sendMessage(Utils.f("&3&lSigns: &a&l" + house.getSigns().size())); + s.sendMessage(Utils.f("&3&lPrice: &a&l" + house.getPrice())); + return true; + case "addblocks": + player = (Player) s; + user = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + if (user.getEditingPremiumHouse() != null) { + if (args.length == 2 && args[1].equalsIgnoreCase("we")) { + if (Houses.getWorldEdit().isPresent()) { + WorldEditPlugin we = Houses.getWorldEdit().get(); + if (we.getSelection(player) != null) { + Selection selection = we.getSelection(player); + Collection<Block> blocks = HouseUtils.getBlocks(selection.getMinimumPoint(), selection.getMaximumPoint()); + int before = user.getEditingPremiumHouse().getEditableBlocks().size(); + blocks.forEach(block -> { + if (Blocks.getMaterials().contains(block.getType())) { + user.getEditingPremiumHouse().addEditableBlock(block.getLocation(), block.getType(), block.getData(), res -> {}); + } + }); + int after = user.getEditingPremiumHouse().getEditableBlocks().size(); + player.sendMessage(Lang.HOUSES.f("&a" + String.valueOf(after - before) + " &7blocks have been added.")); + } else { + player.sendMessage(Lang.HOUSES.f("&7You must make a selection with WorldEdit first!")); + } + } else { + player.sendMessage(Lang.HOUSES.f("&cError! Contact a manager.")); + } + return true; + } + if (user.isAddingBlocks()) { + user.setAddingBlocks(false); + player.sendMessage(Lang.HOUSES.f("&7You're no longer adding blocks.")); + } else { + if (user.isRemovingBlocks()) user.setRemovingBlocks(false); + user.setAddingBlocks(true); + player.sendMessage(Lang.HOUSES.f("&7You're now adding blocks.")); + } + } + return true; + case "delblocks": + player = (Player) s; + user = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + if (user.getEditingPremiumHouse() != null) { + if (args.length == 2 && args[1].equalsIgnoreCase("we")) { + if (Houses.getWorldEdit().isPresent()) { + WorldEditPlugin we = Houses.getWorldEdit().get(); + if (we.getSelection(player) != null) { + Selection selection = we.getSelection(player); + Collection<EditableBlock> blocks = new ArrayList<>(); + int before = user.getEditingPremiumHouse().getEditableBlocks().size(); + user.getEditingPremiumHouse().getEditableBlocks().forEach(editableBlock -> { + if (selection.contains(editableBlock.getLocation())) { + blocks.add(editableBlock); + } + }); + user.getEditingPremiumHouse().getEditableBlocks().removeAll(blocks); + int after = user.getEditingPremiumHouse().getEditableBlocks().size(); + player.sendMessage(Lang.HOUSES.f("&a" + String.valueOf(before - after) + " &7blocks have been removed.")); + } else { + player.sendMessage(Lang.HOUSES.f("&7You must make a selection with WorldEdit first!")); + } + } else { + player.sendMessage(Lang.HOUSES.f("&cError! Contact a manager.")); + } + return true; + } + if (user.isRemovingBlocks()) { + user.setRemovingBlocks(false); + player.sendMessage(Lang.HOUSES.f("&7You're no longer removing blocks.")); + } else { + if (user.isAddingBlocks()) user.setAddingBlocks(false); + user.setRemovingBlocks(true); + player.sendMessage(Lang.HOUSES.f("&7You're now removing blocks.")); + } + } + return true; + case "wipedata": + if (s instanceof Player) { + s.sendMessage("console only"); + return true; + } + Houses.getHousesManager().getPremiumHouses().forEach(premiumHouse -> premiumHouse.removeOwner(true)); + Houses.getHousesManager().save(); + s.sendMessage(Lang.HOUSES.f("&cAll house data wiped")); + return true; + case "reset": + if (args.length != 2) { + s.sendMessage(Utils.f("&c/" + label + " reset <id>")); + return true; + } + player = (Player) s; + String houseId = args[1]; + PremiumHouse premiumHouse = Houses.getHousesManager().getPremiumHouse(Integer.valueOf(houseId)); + if (premiumHouse == null) { + s.sendMessage(Lang.HOUSES.f("&7Could not find house with ID " + houseId)); + return true; + } + if (!premiumHouse.isOwned()) { + s.sendMessage(Lang.HOUSES.f("&7That house isn't owned!")); + return true; + } + Utils.insertLogLater(player.getUniqueId(), player.getName(), "reset" + (isPremium ? "Premium" : "") + "House" , "RESET_" + (isPremium ? "PREMIUM" : "") + "_HOUSE", (isPremium ? "Premium" : "") + "House ID: " + houseId, -1, -1); + Houses.getHousesManager().forceSell(premiumHouse, player); + return true; + default: + s.sendMessage(Lang.HOUSES.f("&7&lHouses Help")); + s.sendMessage(Utils.f("&3/" + label + "&7 add")); + s.sendMessage(Utils.f("&3/" + label + "&7 edit &a<id>")); + s.sendMessage(Utils.f("&3/" + label + "&7 stop")); + s.sendMessage(Utils.f("&3/" + label + "&7 setprice &a<price>")); + s.sendMessage(Utils.f("&3/" + label + "&7 remove &a<id>")); + s.sendMessage(Utils.f("&3/" + label + "&7 list &a[page]")); + s.sendMessage(Utils.f("&3/" + label + "&7 setowner &a<id> <player>")); + s.sendMessage(Utils.f("&3/" + label + "&7 removeowner &a<id>" + (isPremium ? "" : " <player>"))); + s.sendMessage(Utils.f("&3/" + label + "&7 tp &a<id>")); + s.sendMessage(Utils.f("&3/" + label + "&7 info &a<id>")); + s.sendMessage(Utils.f("&3/" + label + "&7 player &a<player>")); + if (isPremium) { + s.sendMessage(Utils.f("&3/" + label + "&7 owner &a<id>")); + s.sendMessage(Utils.f("&3/" + label + "&7 addblocks/delblocks &a<we>")); + s.sendMessage(Utils.f("&3/" + label + "&7 reset &a<id>")); + } + return true; + } + } +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/dao/HouseDAO.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/dao/HouseDAO.java new file mode 100644 index 0000000..acbb546 --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/dao/HouseDAO.java @@ -0,0 +1,681 @@ +package net.grandtheftmc.houses.dao; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +import org.bukkit.Location; +import org.bukkit.inventory.ItemStack; +import org.json.JSONObject; + +import com.google.common.collect.Lists; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.houses.HouseUtils; +import net.grandtheftmc.houses.JSONHelper; +import net.grandtheftmc.houses.houses.House; +import net.grandtheftmc.houses.houses.HouseChest; +import net.grandtheftmc.houses.houses.HouseDoor; +import net.grandtheftmc.houses.houses.HouseSign; +import net.grandtheftmc.houses.houses.HousesManager; +import net.grandtheftmc.houses.users.HouseUser; +import net.grandtheftmc.houses.users.UserHouse; +import net.grandtheftmc.houses.users.UserHouseChest; + +public class HouseDAO { + + public static List<House> loadHouses(Connection connection) { + List<House> list = Lists.newArrayList(); + + try (PreparedStatement statement = connection.prepareStatement( + "SELECT id, house_num, price FROM gtm_house WHERE server_key=? AND premium=?;")) { + statement.setString(1, Core.name().toUpperCase()); + statement.setBoolean(2, false); + + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + int uniqueHouseIdentifier = result.getInt("id"); + House house = new House(uniqueHouseIdentifier, result.getInt("house_num"), result.getInt("price")); + loadChests(connection, uniqueHouseIdentifier, house); + loadDoors(connection, uniqueHouseIdentifier, house); + loadSigns(connection, uniqueHouseIdentifier, house); + list.add(house); + } + + return list; + } + + } catch (SQLException e) { + e.printStackTrace(); + } + return list; + } + + public static House addHouse(Connection connection, int houseId, int price) { + try (PreparedStatement statement = connection.prepareStatement( + "INSERT INTO gtm_house (house_num, server_key, premium, currency, price) VALUES (?, ?, ?, ?, ?);", Statement.RETURN_GENERATED_KEYS)) { + statement.setInt(1, houseId); + statement.setString(2, Core.name().toUpperCase()); + statement.setBoolean(3, false); + statement.setString(4, "MONEY"); + statement.setInt(5, price); + + statement.executeUpdate(); + + try (ResultSet result = statement.getGeneratedKeys()) { + if(result.next()) { + return new House(result.getInt(1), houseId, price); + } + } + + } catch (SQLException e) { + e.printStackTrace(); + } + return null; + } + + public static House deleteHouse(Connection connection, int uniqueHouseId) { + try (PreparedStatement statement = connection.prepareStatement( + "DELETE FROM gtm_house WHERE id=?")) { + statement.setInt(1, uniqueHouseId); + + statement.execute(); + + } catch (SQLException e) { + e.printStackTrace(); + } + return null; + } + + public static boolean loadChests(Connection connection, int uniqueHouseIdentifier, House house) { + + // keep track of invalid chests (by hotspot) + List<Integer> invalidChests = new ArrayList<>(); + + try (PreparedStatement statement = connection.prepareStatement( + "SELECT hotspot_id, data FROM gtm_house_data WHERE house_id=? AND hotspot_type=?;")) { + statement.setInt(1, uniqueHouseIdentifier); + statement.setString(2, "CHEST"); + + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + int hotspotID = result.getInt("hotspot_id"); + JSONObject object = HouseUtils.dataToJson(result.getString("data")); + + try { + if (object.has("id")) { + int data_id = object.getInt("id"); + Location loc1 = HouseUtils.getLocationFromString(object.getString("loc1")); + + if (object.has("loc2")) { + Location loc2 = HouseUtils.getLocationFromString(object.getString("loc2")); + house.addChest(new HouseChest(hotspotID, data_id, house.getId(), loc1, loc2)); + } else { + house.addChest(new HouseChest(hotspotID, data_id, house.getId(), loc1)); + } + } + } catch (Exception e) { +// e.printStackTrace(); + Core.error("House (" + uniqueHouseIdentifier + ") couldn't load CHEST."); + invalidChests.add(hotspotID); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + // set invalid in db so we can fix + if (!invalidChests.isEmpty()){ + for (Integer hotspotID : invalidChests){ + setValidData(connection, uniqueHouseIdentifier, hotspotID, false); + } + } + + return true; + } + + public static boolean loadDoors(Connection connection, int uniqueHouseIdentifier, House house) { + + // keep track of invalid doors (by hotspot) + List<Integer> invalidDoors = new ArrayList<>(); + + try (PreparedStatement statement = connection.prepareStatement( + "SELECT data, hotspot_id FROM gtm_house_data WHERE house_id=? AND hotspot_type=?;")) { + statement.setInt(1, uniqueHouseIdentifier); + statement.setString(2, "DOOR"); + + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + int hotspotID = result.getInt("hotspot_id"); + JSONObject object = HouseUtils.dataToJson(result.getString("data")); + + try { + if (object.has("id")) { + int data_id = object.getInt("id"); +// System.out.println(object.toString()); + + Location location = null, inside = null, outside = null; + if (object.has("location")) { + location = HouseUtils.getLocationFromString(object.getString("location")); + } + + if (object.has("insideLocation")) { + inside = HouseUtils.getLocationFromString(object.getString("insideLocation")); + } + + if (object.has("outsideLocation")) { + outside = HouseUtils.getLocationFromString(object.getString("outsideLocation")); + } + + house.addDoor(new HouseDoor(hotspotID, data_id, house.getId(), location, inside, outside)); + + // if we get here it's valid + // this must be async because if its not, connection leak +// ServerUtil.runTaskAsync(() -> { +// try (Connection conn = BaseDatabase.getInstance().getConnection()){ +// setValidData(conn, uniqueHouseIdentifier, hotspotID, true); +// } +// catch(Exception exc){ +// exc.printStackTrace(); +// } +// }); + } + } catch (Exception e) { +// e.printStackTrace(); + Core.error("House (" + uniqueHouseIdentifier + ") couldn't load DOOR."); + invalidDoors.add(hotspotID); + } + } + } + + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + // set invalid in db so we can fix + if (!invalidDoors.isEmpty()){ + for (Integer hotspotID : invalidDoors){ + setValidData(connection, uniqueHouseIdentifier, hotspotID, false); + } + } + + return true; + } + + public static boolean loadSigns(Connection connection, int uniqueHouseIdentifier, House house) { + + // keep track of invalid doors (by hotspot) + List<Integer> invalidSigns = new ArrayList<>(); + + try (PreparedStatement statement = connection.prepareStatement( + "SELECT data, hotspot_id FROM gtm_house_data WHERE house_id=? AND hotspot_type=?;")) { + statement.setInt(1, uniqueHouseIdentifier); + statement.setString(2, "SIGN"); + + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + int hotspotID = result.getInt("hotspot_id"); + JSONObject object = HouseUtils.dataToJson(result.getString("data")); + + try { + if (object.has("loc")) { + Location loc = HouseUtils.getLocationFromString(object.getString("loc")); + house.addSign(new HouseSign(hotspotID, uniqueHouseIdentifier, loc)); + + // if we get here it's valid + // this must be async because if its not, connection leak +// ServerUtil.runTaskAsync(() -> { +// try (Connection conn = BaseDatabase.getInstance().getConnection()){ +// setValidData(conn, uniqueHouseIdentifier, hotspotID, true); +// } +// catch(Exception exc){ +// exc.printStackTrace(); +// } +// }); + } + } catch (Exception e) { +// e.printStackTrace(); + Core.error("House (" + uniqueHouseIdentifier + ") couldn't load SIGN."); + invalidSigns.add(hotspotID); + } + } + } + + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + // set invalid in db so we can fix + if (!invalidSigns.isEmpty()){ + for (Integer hotspotID : invalidSigns){ + setValidData(connection, uniqueHouseIdentifier, hotspotID, false); + } + } + + return true; + } + + public static boolean addChest(Connection connection, int uniqueHouseId, HouseChest chest, JSONHelper data) { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO gtm_house_data (house_id, hotspot_type, data) VALUES (?, ?, ?);", Statement.RETURN_GENERATED_KEYS)) { + statement.setInt(1, uniqueHouseId); + statement.setString(2, "CHEST"); + statement.setString(3, data == null ? null : data.string()); + + statement.executeUpdate(); + + try (ResultSet result = statement.getGeneratedKeys()) { + if (result.next()) { + chest.setHotspotId(result.getInt(1)); + return true; + } + } + + } catch (SQLException e) { + e.printStackTrace(); + } + + return false; + } + + public static boolean addDoor(Connection connection, int uniqueHouseId, HouseDoor door, JSONHelper data) { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO gtm_house_data (house_id, hotspot_type, data) VALUES (?, ?, ?);", Statement.RETURN_GENERATED_KEYS)) { + statement.setInt(1, uniqueHouseId); + statement.setString(2, "DOOR"); + statement.setString(3, data == null ? null : data.string()); + + statement.executeUpdate(); + + try (ResultSet result = statement.getGeneratedKeys()) { + if (result.next()) { + door.setHotspotId(result.getInt(1)); + return true; + } + } + + } catch (SQLException e) { + e.printStackTrace(); + } + + return false; + } + + public static boolean addSign(Connection connection, int uniqueHouseId, HouseSign sign, JSONHelper data) { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO gtm_house_data (house_id, hotspot_type, data) VALUES (?, ?, ?);", Statement.RETURN_GENERATED_KEYS)) { + statement.setInt(1, uniqueHouseId); + statement.setString(2, "SIGN"); + statement.setString(3, data == null ? null : data.string()); + + statement.executeUpdate(); + + try (ResultSet result = statement.getGeneratedKeys()) { + if (result.next()) { + sign.setHotspotId(result.getInt(1)); + return true; + } + } + + } catch (SQLException e) { + e.printStackTrace(); + } + + return false; + } + + public static boolean deleteSign(Connection connection, int hotspotId) { + try (PreparedStatement statement = connection.prepareStatement("DELETE FROM gtm_house_data WHERE hotspot_id=?;")) { + statement.setInt(1, hotspotId); + + statement.execute(); + + } catch (SQLException e) { + e.printStackTrace(); + } + + return false; + } + + public static boolean deleteAllSigns(Connection connection, int uniqueHouseId) { + try (PreparedStatement statement = connection.prepareStatement("DELETE FROM gtm_house_data WHERE house_id=? AND hotspot_type=?;")) { + statement.setInt(1, uniqueHouseId); + statement.setString(2, "SIGN"); + + statement.execute(); + + } catch (SQLException e) { + e.printStackTrace(); + } + + return false; + } + + public static boolean updateData(Connection connection, int hotspotId, JSONHelper data) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE gtm_house_data SET data=? WHERE hotspot_id=?;")) { + statement.setString(1, data == null ? null : data.string()); + statement.setInt(2, hotspotId); + + statement.executeUpdate(); + + } catch (SQLException e) { + e.printStackTrace(); + } + + return false; + } + + public static boolean updateDoor(Connection connection, int hotspotId, int doorId, Location door, Location inside, Location outside) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE gtm_house_data SET data=? WHERE hotspot_id=?;")) { + JSONHelper helper = new JSONHelper().put("id", doorId); + helper.put("location", HouseUtils.locationToString(door)); + helper.put("insideLocation", HouseUtils.locationToString(inside)); + helper.put("outsideLocation", HouseUtils.locationToString(outside)); + statement.setString(1, helper.string()); + statement.setInt(2, hotspotId); + + statement.executeUpdate(); + + } catch (SQLException e) { + e.printStackTrace(); + } + + return false; + } + + public static boolean deleteChestData(Connection connection, int hotspotId) { + try (PreparedStatement statement = connection.prepareStatement("DELETE FROM gtm_house_data WHERE hotspot_id=?;")) { + statement.setInt(1, hotspotId); + + statement.executeUpdate(); + + } catch (SQLException e) { + e.printStackTrace(); + } + + return false; + } + + public static boolean deleteUserChest(Connection connection, int uniqueHouseId, int chestId) { + try (PreparedStatement statement = connection.prepareStatement("DELETE FROM gtm_house_chest WHERE house_id=? AND chest_id=?;")) { + statement.setInt(1, uniqueHouseId); + statement.setInt(2, chestId); + + statement.executeUpdate(); + + } catch (SQLException e) { + e.printStackTrace(); + } + + return false; + } + + public static boolean deleteAllChestData(Connection connection, int uniqueHouseId) { + try (PreparedStatement statement = connection.prepareStatement("DELETE FROM gtm_house_data WHERE house_id=? AND hotspot_type=?;")) { + statement.setInt(1, uniqueHouseId); + statement.setString(2, Core.name().toUpperCase()); + + statement.executeUpdate(); + + } catch (SQLException e) { + e.printStackTrace(); + } + + return false; + } + + public static boolean deleteAllUserChest(Connection connection, int uniqueHouseId) { + try (PreparedStatement statement = connection.prepareStatement("DELETE FROM gtm_house_chest WHERE house_id=?;")) { + statement.setInt(1, uniqueHouseId); + + statement.executeUpdate(); + + } catch (SQLException e) { + e.printStackTrace(); + } + + return false; + } + + public static boolean deleteAllOwners(Connection connection, int uniqueHouseId) { + try (PreparedStatement statement = connection.prepareStatement("DELETE FROM gtm_house_user WHERE house_id=?;")) { + statement.setInt(1, uniqueHouseId); + + statement.executeUpdate(); + + } catch (SQLException e) { + e.printStackTrace(); + } + + return false; + } + + public static boolean deleteOwner(Connection connection, int uniqueHouseId, UUID uuid) { + try (PreparedStatement statement = connection.prepareStatement("DELETE FROM gtm_house_user WHERE uuid=UNHEX(?) AND house_id=?;")) { + statement.setString(1, uuid.toString().replaceAll("-", "")); + statement.setInt(2, uniqueHouseId); + + statement.executeUpdate(); + + } catch (SQLException e) { + e.printStackTrace(); + } + + return false; + } + + public static boolean setPrice(Connection connection, int uniqueHouseId, int price) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE gtm_house SET price=? WHERE id=?;")) { + statement.setInt(1, price); + statement.setInt(2, uniqueHouseId); + + statement.executeUpdate(); + + } catch (SQLException e) { + e.printStackTrace(); + } + + return false; + } + + public static boolean removeDoor(Connection connection, int uniqueHouseId, int hotspotId) { + try (PreparedStatement statement = connection.prepareStatement("DELETE FROM gtm_house_data WHERE hotspot_id=? AND house_id=?;")) { + statement.setInt(1, hotspotId); + statement.setInt(2, uniqueHouseId); + + statement.executeUpdate(); + + } catch (SQLException e) { + e.printStackTrace(); + } + + return false; + } + + public static boolean removeAllDoors(Connection connection, int uniqueHouseId) { + try (PreparedStatement statement = connection.prepareStatement("DELETE FROM gtm_house_data WHERE house_id=? AND hotspot_type=?;")) { + statement.setInt(1, uniqueHouseId); + statement.setString(2, "DOOR"); + + statement.executeUpdate(); + + } catch (SQLException e) { + e.printStackTrace(); + } + + return false; + } + + public static boolean addChestContent(Connection connection, int uniqueHouseId, int chestId, UUID uuid, ItemStack[] content) { + try (PreparedStatement statement = connection.prepareStatement( + "INSERT INTO gtm_house_chest (house_id, uuid, chest_id, content) VALUES (?, UNHEX(?), ?, ?) ON DUPLICATE KEY UPDATE content=?;")) { + statement.setInt(1, uniqueHouseId); + statement.setString(2, uuid.toString().replaceAll("-", "")); + statement.setInt(3, chestId); + statement.setString(4, GTMUtils.toBase64(content)); + statement.setString(5, GTMUtils.toBase64(content)); + + statement.execute(); + return true; + + } catch (SQLException e) { + e.printStackTrace(); + } + return false; + } + + public static boolean updateChestContent(Connection connection, int uniqueHouseId, int chestId, UUID uuid, ItemStack[] content) { + try (PreparedStatement statement = connection.prepareStatement( + "UPDATE gtm_house_chest SET content=? WHERE house_id=? AND uuid=UNHEX(?) AND chest_id=?")) { + statement.setString(1, GTMUtils.toBase64(content)); + statement.setInt(2, uniqueHouseId); + statement.setString(3, uuid.toString().replaceAll("-", "")); + statement.setInt(4, chestId); + + statement.executeUpdate(); + return true; + + } catch (SQLException e) { + e.printStackTrace(); + } + return false; + } + + public static boolean getChestContent(Connection connection, HouseUser houseUser, UUID uuid) { + try (PreparedStatement statement = connection.prepareStatement( + "SELECT * FROM gtm_house_chest WHERE uuid=UNHEX(?);")) { + statement.setString(1, uuid.toString().replaceAll("-", "")); + + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + int id = result.getInt("house_id"); + int chestId = result.getInt("chest_id"); + UserHouse userHouse = houseUser.getUserHouseByUniqueId(id); + if (userHouse == null) continue; + + UserHouseChest chest = userHouse.getChestOrNull(chestId); + if (chest == null) { + userHouse.addChest(new UserHouseChest(id, chestId, GTMUtils.fromBase64(result.getString("content")))); + } else { + chest.setContents(GTMUtils.fromBase64(result.getString("content"))); + } + } + } + return true; + + } catch (SQLException e) { + e.printStackTrace(); + } + return false; + } + + public static Optional<List<UserHouse>> loadUser(Connection connection, HousesManager housesManager, UUID uuid) { + List<UserHouse> list = Lists.newArrayList(); + + try (PreparedStatement statement = connection.prepareStatement("SELECT HU.house_id, H.house_num FROM gtm_house_user HU, gtm_house H WHERE HU.uuid=UNHEX(?) AND HU.house_id=H.id AND server_key=? AND H.premium=?;")) { + statement.setString(1, uuid.toString().replaceAll("-", "")); + statement.setString(2, Core.name().toUpperCase()); + statement.setBoolean(3, false); + + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + int uniqueId = result.getInt("house_id"); + int number = result.getInt("house_num"); + + System.out.println("Debug 1"); + House house = housesManager.getHouse(number); + if (house == null) continue; + + System.out.println("Debug 2"); + list.add(new UserHouse(uuid, uniqueId, house.getId())); + } + return Optional.of(list); + } + + } catch (SQLException e) { + e.printStackTrace(); + } + return Optional.empty(); + } + + public static void addUser(Connection connection, int uniqueHouseId, UUID uuid) { + List<UserHouse> list = Lists.newArrayList(); + + try (PreparedStatement statement = connection.prepareStatement( + "INSERT INTO gtm_house_user (house_id, uuid, is_owner) VALUES (?, UNHEX(?), ?);")) { + statement.setInt(1, uniqueHouseId); + statement.setString(2, uuid.toString().replaceAll("-", "")); + statement.setBoolean(3, true); + + statement.execute(); + + } catch (SQLException e) { + e.printStackTrace(); + } + } + + /** + * Sets the record for the house data as valid or invalid depending on the arguments. + * <p> + * This is used to see which records are getting loaded correctly, and which aren't. + * </p> + * + * @param conn - the database connection thread + * @param uniqueHouseId - the unique id for the house, generated by the db + * @param hotspotId - the unique id for the hotspot, generated by the db + * @param isValid - {@code true} if this is valid data that was loaded, {@code false} for invalid + * + * @return {@code true} if the query ran, {@code false} otherwise. + */ + public static boolean setValidData(Connection conn, int uniqueHouseId, int hotspotId, boolean isValid){ + + String query = "UPDATE gtm_house_data SET is_valid=? WHERE house_id=? AND hotspot_id=?;"; + + try (PreparedStatement ps = conn.prepareStatement(query)){ + ps.setBoolean(1, isValid); + ps.setInt(2, uniqueHouseId); + ps.setInt(3, hotspotId); + + ps.executeUpdate(); + return true; + } + catch (SQLException e){ + e.printStackTrace(); + } + + return false; + } + + /** + * Resets all house data in the database as valid, in order to reset to not valid if it's still broken. + * <p> + * This is needed so during every server start up we can see if houses have been fixed. + * </p> + * + * @param conn - the database connection thread + * + * @return {@code true} if the query ran, {@code false} otherwise. + */ + public static boolean resetValidData(Connection conn){ + + String query = "UPDATE gtm_house_data SET is_valid=1 WHERE house_id IN (SELECT id FROM gtm_house WHERE server_key=?)"; + try (PreparedStatement ps = conn.prepareStatement(query)){ + ps.setString(1, Core.name().toUpperCase()); + ps.executeUpdate(); + return true; + } + catch(SQLException exc){ + exc.printStackTrace(); + } + + return false; + } +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/dao/PremiumHouseDAO.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/dao/PremiumHouseDAO.java new file mode 100644 index 0000000..748e59b --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/dao/PremiumHouseDAO.java @@ -0,0 +1,503 @@ +package net.grandtheftmc.houses.dao; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.json.JSONObject; + +import com.google.common.collect.Lists; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.UUIDUtil; +import net.grandtheftmc.houses.HouseUtils; +import net.grandtheftmc.houses.JSONHelper; +import net.grandtheftmc.houses.houses.EditableBlock; +import net.grandtheftmc.houses.houses.HouseSign; +import net.grandtheftmc.houses.houses.PremiumHouse; +import net.grandtheftmc.houses.houses.PremiumHouseChest; +import net.grandtheftmc.houses.houses.PremiumHouseDoor; +import net.grandtheftmc.houses.houses.PremiumHouseGuest; +import net.grandtheftmc.houses.houses.PremiumHouseTrashcan; + +public class PremiumHouseDAO { + + public static List<PremiumHouse> loadHouses(Connection connection) { + List<PremiumHouse> list = Lists.newArrayList(); + + try (PreparedStatement statement = connection.prepareStatement( + "SELECT id, house_num, price FROM gtm_house WHERE server_key=? AND premium=?;")) { + statement.setString(1, Core.name().toUpperCase()); + statement.setBoolean(2, true); + + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + int uniqueHouseIdentifier = result.getInt("id"); + PremiumHouse house = new PremiumHouse(uniqueHouseIdentifier, result.getInt("house_num"), result.getInt("price")); + loadChests(connection, uniqueHouseIdentifier, house); + loadDoors(connection, uniqueHouseIdentifier, house); + loadSigns(connection, uniqueHouseIdentifier, house); + loadTrashcans(connection, uniqueHouseIdentifier, house); + loadEditableBlocks(connection, uniqueHouseIdentifier, house); + loadUsers(connection, uniqueHouseIdentifier, house); + list.add(house); + } + + return list; + } + + } catch (SQLException e) { + e.printStackTrace(); + } + return list; + } + + public static PremiumHouse addHouse(Connection connection, int houseId, int price) { + try (PreparedStatement statement = connection.prepareStatement( + "INSERT INTO gtm_house (house_num, server_key, premium, currency, price) VALUES (?, ?, ?, ?, ?);", Statement.RETURN_GENERATED_KEYS)) { + statement.setInt(1, houseId); + statement.setString(2, Core.name().toUpperCase()); + statement.setBoolean(3, true); + statement.setString(4, "PERMIT"); + statement.setInt(5, price); + + statement.executeUpdate(); + + try (ResultSet result = statement.getGeneratedKeys()) { + if (result.next()) { + return new PremiumHouse(result.getInt(1), houseId, price); + } + } + + } catch (SQLException e) { + e.printStackTrace(); + } + return null; + } + + public static boolean loadChests(Connection connection, int uniqueHouseIdentifier, PremiumHouse house) { + + // keep track of invalid chests (by hotspot) + List<Integer> invalidChests = new ArrayList<>(); + + try (PreparedStatement statement = connection.prepareStatement( + "SELECT hotspot_id, data FROM gtm_house_data WHERE house_id=? AND hotspot_type=?;")) { + statement.setInt(1, uniqueHouseIdentifier); + statement.setString(2, "CHEST"); + + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + int hotspotID = result.getInt("hotspot_id"); + JSONObject object = HouseUtils.dataToJson(result.getString("data")); + + try { + if (object.has("id")) { + int data_id = object.getInt("id"); + Location loc1 = HouseUtils.getLocationFromString(object.getString("loc1")); + + if (object.has("loc2")) { + Location loc2 = HouseUtils.getLocationFromString(object.getString("loc2")); + house.addChest(new PremiumHouseChest(hotspotID, data_id, house.getId(), loc1, loc2)); + } else { + house.addChest(new PremiumHouseChest(hotspotID, data_id, house.getId(), loc1)); + } + } + } catch (Exception e) { +// e.printStackTrace(); + Core.error("House (" + uniqueHouseIdentifier + ") couldn't load CHEST."); + invalidChests.add(hotspotID); + } + } + } + + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + // set invalid in db so we can fix + if (!invalidChests.isEmpty()){ + for (Integer hotspotID : invalidChests){ + HouseDAO.setValidData(connection, uniqueHouseIdentifier, hotspotID, false); + } + } + + return true; + } + + public static boolean loadDoors(Connection connection, int uniqueHouseIdentifier, PremiumHouse house) { + + // keep track of invalid chests (by hotspot) + List<Integer> invalidDoors = new ArrayList<>(); + + try (PreparedStatement statement = connection.prepareStatement( + "SELECT hotspot_id, data FROM gtm_house_data WHERE house_id=? AND hotspot_type=?;")) { + statement.setInt(1, uniqueHouseIdentifier); + statement.setString(2, "DOOR"); + + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + int hotspotID = result.getInt("hotspot_id"); + JSONObject object = HouseUtils.dataToJson(result.getString("data")); + + try { + if (object.has("id")) { + int data_id = object.getInt("id"); +// Location location = HouseUtils.getLocationFromString(object.getString("location")); +// +// if (object.has("insideLocation") && object.has("outsideLocation")) { +// Location inside = HouseUtils.getLocationFromString(object.getString("insideLocation")); +// Location outside = HouseUtils.getLocationFromString(object.getString("outsideLocation")); +// house.addDoor(new PremiumHouseDoor(result.getInt("hotspot_id"), data_id, house.getId(), location, inside, outside)); +// } else { +// house.addDoor(new PremiumHouseDoor(result.getInt("hotspot_id"), data_id, house.getId(), location)); +// } + + Location location = null, inside = null, outside = null; + if (object.has("location")) { + location = HouseUtils.getLocationFromString(object.getString("location")); + } + + if (object.has("insideLocation")) { + inside = HouseUtils.getLocationFromString(object.getString("insideLocation")); + } + + if (object.has("outsideLocation")) { + outside = HouseUtils.getLocationFromString(object.getString("outsideLocation")); + } + + house.addDoor(new PremiumHouseDoor(hotspotID, data_id, house.getId(), location, inside, outside)); + } + } catch (Exception e) { +// e.printStackTrace(); + Core.error("House (" + uniqueHouseIdentifier + ") couldn't load DOOR."); + invalidDoors.add(hotspotID); + } + } + } + + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + // set invalid in db so we can fix + if (!invalidDoors.isEmpty()){ + for (Integer hotspotID : invalidDoors){ + HouseDAO.setValidData(connection, uniqueHouseIdentifier, hotspotID, false); + } + } + + return true; + } + + public static boolean loadSigns(Connection connection, int uniqueHouseIdentifier, PremiumHouse house) { + + // keep track of invalid chests (by hotspot) + List<Integer> invalidSigns = new ArrayList<>(); + + try (PreparedStatement statement = connection.prepareStatement( + "SELECT hotspot_id, data FROM gtm_house_data WHERE house_id=? AND hotspot_type=?;")) { + statement.setInt(1, uniqueHouseIdentifier); + statement.setString(2, "SIGN"); + + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + int hotspotID = result.getInt("hotspot_id"); + JSONObject object = HouseUtils.dataToJson(result.getString("data")); + + try { + if (object.has("loc")) { + Location loc = HouseUtils.getLocationFromString(object.getString("loc")); + house.addSign(new HouseSign(hotspotID, uniqueHouseIdentifier, loc)); + } + } catch (Exception e) { +// e.printStackTrace(); + Core.error("House (" + uniqueHouseIdentifier + ") couldn't load SIGN."); + invalidSigns.add(hotspotID); + } + } + } + + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + // set invalid in db so we can fix + if (!invalidSigns.isEmpty()){ + for (Integer hotspotID : invalidSigns){ + HouseDAO.setValidData(connection, uniqueHouseIdentifier, hotspotID, false); + } + } + + return true; + } + + public static boolean loadTrashcans(Connection connection, int uniqueHouseIdentifier, PremiumHouse house) { + + // keep track of invalid chests (by hotspot) + List<Integer> invalidTrashcans = new ArrayList<>(); + + try (PreparedStatement statement = connection.prepareStatement( + "SELECT hotspot_id, data FROM gtm_house_data WHERE house_id=? AND hotspot_type=?;")) { + statement.setInt(1, uniqueHouseIdentifier); + statement.setString(2, "TRASH"); + + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + int hotspotID = result.getInt("hotspot_id"); + JSONObject object = HouseUtils.dataToJson(result.getString("data")); + + try { + if (object.has("loc") && object.has("id") && object.has("owned")) { + Location loc = HouseUtils.getLocationFromString(object.getString("loc")); + int data_id = object.getInt("id"); + boolean owned = object.getBoolean("owned"); + house.addTrashcan(new PremiumHouseTrashcan(hotspotID, data_id, house.getId(), loc, owned)); + } + } catch (Exception e) { +// e.printStackTrace(); + invalidTrashcans.add(hotspotID); + Core.error("House (" + uniqueHouseIdentifier + ") couldn't load TRASHCAN."); + } + } + } + + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + // set invalid in db so we can fix + if (!invalidTrashcans.isEmpty()){ + for (Integer hotspotID : invalidTrashcans){ + HouseDAO.setValidData(connection, uniqueHouseIdentifier, hotspotID, false); + } + } + + return true; + } + + public static boolean loadEditableBlocks(Connection connection, int uniqueHouseIdentifier, PremiumHouse house) { + + // keep track of invalid chests (by hotspot) + List<Integer> invalidBlocks = new ArrayList<>(); + + try (PreparedStatement statement = connection.prepareStatement( + "SELECT hotspot_id, data FROM gtm_house_data WHERE house_id=? AND hotspot_type=?;")) { + statement.setInt(1, uniqueHouseIdentifier); + statement.setString(2, "BLOCK"); + + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + int hotspotID = result.getInt("hotspot_id"); + JSONObject object = HouseUtils.dataToJson(result.getString("data")); + + try { + if (object.has("loc") && object.has("block_data")) { + Location loc = HouseUtils.getLocationFromString(object.getString("loc")); + String[] split = object.getString("block_data").split(","); + house.addEditableBlock(new EditableBlock(hotspotID, loc, Material.valueOf(split[0]), Byte.parseByte(split[1]))); + } + } catch (Exception e) { +// e.printStackTrace(); + Core.error("House (" + uniqueHouseIdentifier + ") couldn't load BLOCK."); + invalidBlocks.add(hotspotID); + } + } + } + + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + // set invalid in db so we can fix + if (!invalidBlocks.isEmpty()){ + for (Integer hotspotID : invalidBlocks){ + HouseDAO.setValidData(connection, uniqueHouseIdentifier, hotspotID, false); + } + } + + return true; + } + + public static boolean loadUsers(Connection connection, int uniqueHouseIdentifier, PremiumHouse house) { + try (PreparedStatement statement = connection.prepareStatement( + "SELECT HEX(HU.uuid) as uid, U.name, HU.is_owner FROM gtm_house_user HU, user U WHERE HU.house_id=? AND U.uuid=HU.uuid;")) { + statement.setInt(1, uniqueHouseIdentifier); + + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + UUID uuid = UUIDUtil.createUUID(result.getString("uid")).orElse(null); + if (result.getBoolean("is_owner")) { + house.setOwner(uuid, result.getString("name")); + } else { + house.addGuest(new PremiumHouseGuest(uuid, result.getString("name"))); + } + } + + return true; + } + + } catch (SQLException e) { + e.printStackTrace(); + } + return false; + } + + public static boolean addChest(Connection connection, int uniqueHouseId, PremiumHouseChest chest, JSONHelper data) { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO gtm_house_data (house_id, hotspot_type, data) VALUES (?, ?, ?);", Statement.RETURN_GENERATED_KEYS)) { + statement.setInt(1, uniqueHouseId); + statement.setString(2, "CHEST"); + statement.setString(3, data == null ? null : data.string()); + + statement.executeUpdate(); + + try (ResultSet result = statement.getGeneratedKeys()) { + if (result.next()) { + chest.setHotspotId(result.getInt(1)); + return true; + } + } + + } catch (SQLException e) { + e.printStackTrace(); + } + + return false; + } + + public static boolean addDoor(Connection connection, int uniqueHouseId, PremiumHouseDoor door, JSONHelper data) { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO gtm_house_data (house_id, hotspot_type, data) VALUES (?, ?, ?);", Statement.RETURN_GENERATED_KEYS)) { + statement.setInt(1, uniqueHouseId); + statement.setString(2, "DOOR"); + statement.setString(3, data == null ? null : data.string()); + + statement.executeUpdate(); + + try (ResultSet result = statement.getGeneratedKeys()) { + if (result.next()) { + door.setHotspotId(result.getInt(1)); + return true; + } + } + + } catch (SQLException e) { + e.printStackTrace(); + } + + return false; + } + + public static boolean addBlock(Connection connection, int uniqueHouseId, EditableBlock block, JSONHelper data) { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO gtm_house_data (house_id, hotspot_type, data) VALUES (?, ?, ?);", Statement.RETURN_GENERATED_KEYS)) { + statement.setInt(1, uniqueHouseId); + statement.setString(2, "BLOCK"); + statement.setString(3, data == null ? null : data.string()); + + statement.executeUpdate(); + + try (ResultSet result = statement.getGeneratedKeys()) { + if (result.next()) { + block.setHotspotId(result.getInt(1)); + return true; + } + } + + } catch (SQLException e) { + e.printStackTrace(); + } + + return false; + } + + public static boolean addTrashcan(Connection connection, int uniqueHouseId, PremiumHouseTrashcan trashcan, JSONHelper data) { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO gtm_house_data (house_id, hotspot_type, data) VALUES (?, ?, ?);", Statement.RETURN_GENERATED_KEYS)) { + statement.setInt(1, uniqueHouseId); + statement.setString(2, "TRASH"); + statement.setString(3, data == null ? null : data.string()); + + statement.executeUpdate(); + + try (ResultSet result = statement.getGeneratedKeys()) { + if (result.next()) { + trashcan.setHotspotId(result.getInt(1)); + return true; + } + } + + } catch (SQLException e) { + e.printStackTrace(); + } + + return false; + } + + public static boolean deleteHouseUsers(Connection connection, int uniqueHouseId, boolean owner) { + try (PreparedStatement statement = connection.prepareStatement("DELETE FROM gtm_house_user WHERE house_id=? AND is_owner=?;")) { + statement.setInt(1, uniqueHouseId); + statement.setBoolean(2, owner); + + statement.executeUpdate(); + + } catch (SQLException e) { + e.printStackTrace(); + } + + return false; + } + + public static boolean deleteHouseGuest(Connection connection, int uniqueHouseId, UUID uuid) { + try (PreparedStatement statement = connection.prepareStatement("DELETE FROM gtm_house_user WHERE house_id=? AND uuid=UNHEX(?);")) { + statement.setInt(1, uniqueHouseId); + statement.setString(2, uuid.toString().replaceAll("-", "")); + + statement.executeUpdate(); + + } catch (SQLException e) { + e.printStackTrace(); + } + + return false; + } + + public static boolean addHouseGuest(Connection connection, int uniqueHouseId, UUID uuid, boolean owner) { + try (PreparedStatement statement = connection.prepareStatement( + "INSERT INTO gtm_house_user (house_id, uuid, is_owner) VALUES (?,UNHEX(?),?) ON DUPLICATE KEY UPDATE is_owner=VALUES(is_owner);")) { + statement.setInt(1, uniqueHouseId); + statement.setString(2, uuid.toString().replaceAll("-", "")); + statement.setBoolean(3, owner); + + statement.executeUpdate(); + + } catch (SQLException e) { + e.printStackTrace(); + } + + return false; + } + + public static boolean setTrashcanOwned(Connection connection, int hotspotId, JSONHelper helper) { + try (PreparedStatement statement = connection.prepareStatement( + "UPDATE gtm_house_data SET data=? WHERE hotspot_id=?")) { + statement.setString(1, helper.string()); + statement.setInt(2, hotspotId); + + statement.executeUpdate(); + + } catch (SQLException e) { + e.printStackTrace(); + } + + return false; + } +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/Blocks.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/Blocks.java new file mode 100644 index 0000000..fd4a500 --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/Blocks.java @@ -0,0 +1,96 @@ +package net.grandtheftmc.houses.houses; + +import org.bukkit.Material; + +import java.util.ArrayList; +import java.util.Collection; + +public enum Blocks { + + STONE(Material.STONE, (byte)0), + GRASS(Material.GRASS, (byte)0), + DIRT(Material.DIRT, (byte)0), + COBBLESTONE(Material.COBBLESTONE, (byte)0), + OAK_WOOD(Material.WOOD, (byte)0), + SPRUCE_WOOD(Material.WOOD, (byte)1), + BIRCH_WOOD(Material.WOOD, (byte)2), + JUNGLE_WOOD(Material.WOOD, (byte)3), + ACACIA_WOOD(Material.WOOD, (byte)4), + DARKOAK_WOOD(Material.WOOD, (byte)5), + SAND(Material.SAND, (byte)0), + GRAVEL(Material.GRAVEL, (byte)0), + LOG(Material.LOG, (byte)0), + GLASS(Material.THIN_GLASS, (byte)0), + GLOWSTONE(Material.GLOWSTONE, (byte)0), + SEA_LANTERN(Material.SEA_LANTERN, (byte)0), + COAL_BLOCK(Material.COAL_BLOCK, (byte)0), + GLASS_0(Material.STAINED_GLASS, (byte)0), + GLASS_7(Material.STAINED_GLASS, (byte)7), + GLASS_8(Material.STAINED_GLASS, (byte)8), + CARPET_0(Material.CARPET, (byte)0), + CARPET_1(Material.CARPET, (byte)1), + CARPET_2(Material.CARPET, (byte)2), + CARPET_3(Material.CARPET, (byte)3), + CARPET_4(Material.CARPET, (byte)4), + CARPET_6(Material.CARPET, (byte)6), + CARPET_7(Material.CARPET, (byte)7), + CARPET_8(Material.CARPET, (byte)8), + CARPET_9(Material.CARPET, (byte)9), + CARPET_10(Material.CARPET, (byte)10), + CARPET_11(Material.CARPET, (byte)11), + CARPET_12(Material.CARPET, (byte)12), + CARPET_13(Material.CARPET, (byte)13), + CARPET_14(Material.CARPET, (byte)14), + CARPET_15(Material.CARPET, (byte)15), + CLAY_0(Material.STAINED_CLAY, (byte)0), + CLAY_1(Material.STAINED_CLAY, (byte)1), + CLAY_2(Material.STAINED_CLAY, (byte)2), + CLAY_3(Material.STAINED_CLAY, (byte)3), + CLAY_4(Material.STAINED_CLAY, (byte)4), + CLAY_5(Material.STAINED_CLAY, (byte)5), + CLAY_6(Material.STAINED_CLAY, (byte)6), + CLAY_7(Material.STAINED_CLAY, (byte)7), + CLAY_8(Material.STAINED_CLAY, (byte)8), + CLAY_9(Material.STAINED_CLAY, (byte)9), + CLAY_10(Material.STAINED_CLAY, (byte)10), + CLAY_11(Material.STAINED_CLAY, (byte)11), + CLAY_12(Material.STAINED_CLAY, (byte)12), + CLAY_13(Material.STAINED_CLAY, (byte)13), + CLAY_14(Material.STAINED_CLAY, (byte)14), + CLAY_15(Material.STAINED_CLAY, (byte)15), + DIAMOND_BLOCK(Material.DIAMOND_BLOCK, (byte)0); + + public static Collection<Material> materials; + private Material type; + private byte data; + + Blocks(Material type, byte data) { + this.type = type; + this.data = data; + } + + public static Collection<Material> getMaterials() { + if(materials == null || materials.isEmpty()) { + materials = new ArrayList<>(); + for (Blocks mat : values()) { + materials.add(mat.getType()); + } + } + return materials; + } + + public static Blocks match(Material material, Byte data) { + for(Blocks block : Blocks.values()) { + if(block.getType() == material && block.getData() == data) return block; + } + return null; + } + + public Material getType() { + return this.type; + } + + public byte getData() { + return data; + } +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/EditableBlock.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/EditableBlock.java new file mode 100644 index 0000000..77e1944 --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/EditableBlock.java @@ -0,0 +1,52 @@ +package net.grandtheftmc.houses.houses; + +import org.bukkit.Location; +import org.bukkit.Material; + +public class EditableBlock { + + private int hotspotId; + + private Location location; + private Material defaultType; + private byte defaultData; + + public EditableBlock(int hotspotId, Location location, Material defaultType, byte defaultData) { + this.hotspotId = hotspotId; + this.location = location; + this.defaultType = defaultType; + this.defaultData = defaultData; + } + + public int getHotspotId() { + return hotspotId; + } + + public void setHotspotId(int hotspotId) { + this.hotspotId = hotspotId; + } + + public Location getLocation() { + return location; + } + + public void setLocation(Location location) { + this.location = location; + } + + public Material getDefaultType() { + return defaultType; + } + + public void setDefaultType(Material defaultType) { + this.defaultType = defaultType; + } + + public byte getDefaultData() { + return defaultData; + } + + public void setDefaultData(byte defaultData) { + this.defaultData = defaultData; + } +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/House.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/House.java new file mode 100644 index 0000000..28d3a57 --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/House.java @@ -0,0 +1,515 @@ +package net.grandtheftmc.houses.houses; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.util.Callback; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.houses.HouseUtils; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.JSONHelper; +import net.grandtheftmc.houses.dao.HouseDAO; +import net.grandtheftmc.houses.users.HouseUser; +import net.grandtheftmc.houses.users.UserHouse; +import net.grandtheftmc.houses.users.UserHouseChest; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.block.BlockState; +import org.bukkit.block.Sign; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.scheduler.BukkitRunnable; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class House { + + private int uniqueIdentifier; + + private final int id; + private int price; + private List<HouseChest> chests = new ArrayList<>(); + private List<HouseDoor> doors = new ArrayList<>(); + private List<HouseSign> signs = new ArrayList<>(); + + public House(int uniqueIdentifier, int id) { + this.uniqueIdentifier = uniqueIdentifier; + this.id = id; + } + + public House(int uniqueIdentifier, int id, int price) { + this.uniqueIdentifier = uniqueIdentifier; + this.id = id; + this.price = price; + } + + public House(int uniqueIdentifier, int id, int price, List<HouseChest> chests, List<HouseDoor> doors, List<HouseSign> signs) { + this.uniqueIdentifier = uniqueIdentifier; + this.id = id; + this.price = price; + this.chests = chests; + this.doors = doors; + this.signs = signs; + } + + public int getUniqueIdentifier() { + return uniqueIdentifier; + } + + public void setUniqueIdentifier(int uniqueIdentifier) { + this.uniqueIdentifier = uniqueIdentifier; + } + + public int getId() { + return this.id; + } + + public List<HouseChest> getChests() { + return this.chests; + } + + public List<HouseChest> getChests(int start, int end) { + return this.chests.stream().filter(door -> door.getId() >= start && door.getId() <= end).collect(Collectors.toList()); + } + + public int getAmountOfChests() { + int i = this.chests.size(); + for (HouseChest chest : this.chests) + if (chest.getLoc2() != null) + i++; + return i; + } + + public HouseChest getChest(int id) { + for (HouseChest chest : this.chests) + if (chest.getId() == id) + return chest; + return null; + } + + public HouseChest getChest(Location loc) { + for (HouseChest chest : this.chests) + if (chest.getLoc1().equals(loc) && chest.getLoc2().equals(loc)) + return chest; + return null; + } + + public List<HouseDoor> getDoors() { + return this.doors; + } + + public List<HouseDoor> getDoors(int start, int end) { + return this.doors.stream().filter(door -> door.getId() >= start && door.getId() <= end).collect(Collectors.toList()); + } + + public HouseDoor getDoor(int id) { + for (HouseDoor door : this.doors) + if (door.getId() == id) + return door; + return null; + } + + public HouseDoor getDoor() { + if (this.doors.isEmpty()) + return null; + for (int i = 1; ; i++) { + HouseDoor door = this.getDoor(i); + if (door != null) + return door; + } + } + + public void removeAllDoors() { + + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + HouseDAO.removeAllDoors(connection, this.uniqueIdentifier); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + + this.doors.clear(); + //TODO Remove all house doors from Database. + } + + public int getPrice() { + return this.price; + } + + public void setPrice(int i) { + //TODO Set database price. + this.price = i; + + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + HouseDAO.setPrice(connection, this.uniqueIdentifier, i); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + + this.updateSigns(); + } + + public int getUnusedChestId() { + for (int i = 1; ; i++) + if (this.getChest(i) == null) + return i; + } + + /** + * Only use for data pulled from the Database. + * @param chest + */ + public void addChest(HouseChest chest) { + this.chests.add(chest); + int chestId = chest.getId(); + Houses.getUserManager().getLoadedUsers().stream().filter(user -> user.ownsHouse(this.id)).forEach(user -> user.getUserHouse(this.id).getChest(chestId)); + this.updateSigns(); + } + + public void addChest(int chestId, int houseId, Location first, Location second, Callback<HouseChest> callback) { +// this.chests.add(chest); +// int chestId = chest.getId(); +// Houses.getUserManager().getLoadedUsers().stream().filter(user -> user.ownsHouse(this.id)).forEach(user -> user.getUserHouse(this.id).getChest(chestId)); +// this.updateSigns(); + + ServerUtil.runTaskAsync(() -> { + HouseChest chest = new HouseChest(-1, chestId, houseId, first); + if (second != null) chest.setLoc2(second); + + JSONHelper helper = new JSONHelper(); + helper.put("id", chestId); + helper.put("loc1", HouseUtils.locationToString(first)); + if (second != null) helper.put("loc2", HouseUtils.locationToString(second)); + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + HouseDAO.addChest(connection, this.uniqueIdentifier, chest, helper); + } catch (SQLException e) { + e.printStackTrace(); + callback.call(null); + return; + } + + this.chests.add(chest); + Houses.getUserManager().getLoadedUsers().stream().filter(user -> user.ownsHouse(this.id)).forEach(user -> user.getUserHouse(this.id).getChest(chestId)); + this.updateSigns(); + + callback.call(chest); + }); + } + + public void removeChest(HouseChest chest) { + this.chests.remove(chest); + +// Core.sql.updateAsyncLater("delete from " + Core.name() + "_houses_chests where houseId=" + this.id + " and chestId=" +// + chest.getId() + ';'); +// ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("delete from " + Core.name() + "_houses_chests where houseId=" + this.id + " and chestId=" + chest.getId() + ';')); + //TODO Remove house chest. + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + HouseDAO.deleteChestData(connection, chest.getHotspotId()); + HouseDAO.deleteUserChest(connection, this.uniqueIdentifier, chest.getId()); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + + Houses.getUserManager().getLoadedUsers().stream().filter(user -> user.ownsHouse(this.id)).forEach(user -> user.getUserHouse(this.id).removeChest(chest.getId())); + this.updateSigns(); + } + + public void removeAllChestsNonDB() { + this.chests.clear(); + Houses.getUserManager().getLoadedUsers().stream().filter(user -> user.ownsHouse(this.id)).forEach(user -> user.getUserHouse(this.id).removeChests()); + this.updateSigns(); + } + + public void removeAllChests() { + this.chests.clear(); + +// Core.sql.updateAsyncLater("delete from " + Core.name() + "_houses_chests where houseId=" + this.id + ';'); +// ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("delete from " + Core.name() + "_houses_chests where houseId=" + this.id + ';')); + //TODO Remove all house chests. + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + HouseDAO.deleteAllChestData(connection, this.uniqueIdentifier); + HouseDAO.deleteAllUserChest(connection, this.uniqueIdentifier); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + + Houses.getUserManager().getLoadedUsers().stream().filter(user -> user.ownsHouse(this.id)).forEach(user -> user.getUserHouse(this.id).removeChests()); + this.updateSigns(); + } + + public void removeAllOwnersNonDB() { + Houses.getUserManager().getLoadedUsers().stream().filter(user -> user.ownsHouse(this.id)).forEach(user -> user.removeHouse(Bukkit.getPlayer(user.getUUID()), this)); + this.updateSigns(); + } + + public void removeAllOwners() { +// Core.sql.updateAsyncLater("delete from " + Core.name() + "_houses where houseId=" + this.id + ';'); +// ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("delete from " + Core.name() + "_houses where houseId=" + this.id + ';')); + //TODO Remove all house owners. + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + HouseDAO.deleteAllOwners(connection, this.uniqueIdentifier); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + + Houses.getUserManager().getLoadedUsers().stream().filter(user -> user.ownsHouse(this.id)).forEach(user -> user.removeHouse(Bukkit.getPlayer(user.getUUID()), this)); + this.updateSigns(); + } + + public void addDoor(Callback<HouseDoor> callback) { + ServerUtil.runTaskAsync(() -> { + HouseDoor door = new HouseDoor(-1, this.getUnusedDoorId(), this.id); + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + HouseDAO.addDoor(connection, this.uniqueIdentifier, door, null); + } catch (SQLException e) { + e.printStackTrace(); + callback.call(null); + return; + } + + this.doors.add(door); + callback.call(door); + }); + +// HouseDoor door = new HouseDoor(-1, this.getUnusedDoorId(), this.id); +// +// this.doors.add(door); +// return door; + } + + public HouseDoor addDoor(HouseDoor door) { + this.doors.add(door); + return door; + } + + private int getUnusedDoorId() { + for (int i = 1; ; i++) + if (this.getDoor(i) == null) + return i; + } + + public void removeDoor(HouseDoor door) { + this.doors.remove(door); + //TODO Remove door from Database. + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + HouseDAO.removeDoor(connection, this.uniqueIdentifier, door.getHotspotId()); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } + + public List<HouseSign> getSigns() { + return this.signs; + } + + /** + * Only used when pulling from database. + * @param sign + */ + public void addSign(HouseSign sign) { + this.signs.add(sign); + ServerUtil.runTask(() -> this.updateSign(sign.getLocation())); +// this.updateSign(sign.getLocation()); + } + + public void addSign(Location loc, Callback<HouseSign> callback) { + //TODO Add sign to database. + ServerUtil.runTaskAsync(() -> { + HouseSign sign = new HouseSign(-1, this.uniqueIdentifier, loc); + + JSONHelper helper = new JSONHelper(); + helper.put("loc", HouseUtils.locationToString(loc)); + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + HouseDAO.addSign(connection, this.uniqueIdentifier, sign, helper); + } catch (SQLException e) { + e.printStackTrace(); + callback.call(null); + return; + } + + this.signs.add(sign); + + ServerUtil.runTask(() -> this.updateSign(sign.getLocation())); +// this.updateSign(sign.getLocation()); + callback.call(sign); + }); + } + + public void removeSign(Location loc) { + HouseSign sign = this.signs.stream().filter(s -> loc.equals(s.getLocation())).findFirst().orElse(null); + if (sign == null) return; + this.signs.remove(sign); + //TODO Remove sign from Database. + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + HouseDAO.deleteSign(connection, sign.getHotspotId()); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + + } + + public void removeAllSigns() { + this.signs.clear(); + //TODO Remove all sign from Database. + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + HouseDAO.deleteAllSigns(connection, this.uniqueIdentifier); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } + + public void updateSigns() { + int id = this.id; + new BukkitRunnable() { + @Override + public void run() { + House house = Houses.getHousesManager().getHouse(id); + if (house != null) + new ArrayList<>(house.getSigns()).forEach(s -> updateSign(s.getLocation())); + } + }.runTask(Houses.getInstance()); + } + + public void updateSign(Location loc) { + if (loc == null) return; + + BlockState state = loc.getBlock().getState(); + if (!(state instanceof Sign)) { + this.removeSign(loc); + return; + } + + Sign sign = (Sign) state; + sign.setLine(0, Utils.f("&3&lHouse")); + sign.setLine(1, Utils.f("&8Chests: &a&l" + this.getAmountOfChests())); + sign.setLine(2, Utils.f("&8Price:")); + sign.setLine(3, Utils.f("&a$&l" + this.price)); + sign.update(); + } + + public void openChest(Player player, Location chestLoc, HouseUser user, HouseChest chest) { + if (!user.ownsHouse(this.id)) { + player.sendMessage(Utils.f(Lang.HOUSES + "&7You don't own this house!")); + return; + } + + if(player.getOpenInventory().getType() == InventoryType.CHEST) return; + boolean isDub = chest.getLoc2() != null; + UserHouse userHouse = user.getUserHouse(this.id); + UserHouseChest userChest = userHouse.getChest(chest.getId()); + Inventory inv = Bukkit.createInventory(null, isDub ? 54 : 27, Utils.f("&3&lChest: &a&l" + this.id + ',' + chest.getId())); + inv.setContents(userChest.getContents()); + + if (chestLoc != null) + Utils.playChestAnimation(player, chestLoc, true); + + player.openInventory(inv); + } + + public boolean buyHouse(Player player, User user, GTMUser gtmUser, HouseUser houseUser) { + if (houseUser.ownsHouse(this.id)) { + player.sendMessage(Utils.f(Lang.HOUSES + "&7You already own this house!")); + return true; + } + + if (houseUser.hasMaxHouses(player, user, gtmUser)) { + player.sendMessage(Lang.HOUSES.f("&7You have hit the maximum amount of houses you can own!")); + return false; + } + + if (!gtmUser.hasMoney(this.price)) { + player.sendMessage(Lang.HOUSES.f("&7You can not afford the &a$&l" + this.price + "&7 to pay for this house!")); + return true; + } + + if (!Houses.ENABLED) { + player.sendMessage(Lang.HOUSES.f("&cHouses is currently disabled, try again soon!")); + return true; + } + + gtmUser.takeMoney(this.price); + GTMUtils.updateBoard(player, gtmUser); + houseUser.addHouse(this);//TODO Make sure this method updates database. + Utils.insertLogLater(player.getUniqueId(), player.getName(), "buyHouseMethod", "BUY_HOUSE", "House ID: " + this.id,1,this.price); + player.sendMessage(Lang.HOUSES.f("&7You bought house &a" + this.id + "&7 for &a$&l" + this.price + "&7!")); + return true; + } + + public void addOwner(Player player, HouseUser user) { + + if (!Houses.ENABLED) { + player.sendMessage(Lang.HOUSES.f("&cHouses is currently disabled, try again soon!")); + return; + } + + if (user.getUserHouse(this.id) == null) { + player.sendMessage(Lang.HOUSES.f("&7You now own house &a" + this.id + "&7!")); + user.addHouse(this);//TODO Make sure this method adds a user house. + } else + player.sendMessage(Lang.HOUSES.f("&7You already own house &a" + this.id + "&7!")); + } + + public boolean sellHouse(Player player, GTMUser gtmUser, HouseUser user) { + if (!user.ownsHouse(this.id)) { + player.sendMessage(Utils.f(Lang.HOUSES + "&7You don't own this house!")); + return true; + } + + if (!Houses.ENABLED) { + player.sendMessage(Lang.HOUSES.f("&cHouses is currently disabled, try again soon!")); + return true; + } + + gtmUser.addMoney(this.price / 2); + GTMUtils.updateBoard(player, gtmUser); + user.removeHouse(player, this);//TODO Make sure this method removes all data. + Utils.insertLogLater(player.getUniqueId(), player.getName(), "sellHouseMethod", "SELL_HOUSE", "House ID: " + this.id,1,this.price/2); + player.sendMessage(Lang.HOUSES.f("&7You sold house &a" + this.id + "&7 for &a$&l" + (this.price / 2) + "&7!")); + return true; + } + + public void removeOwner(Player player, HouseUser user) { + + if (!Houses.ENABLED) { + player.sendMessage(Lang.HOUSES.f("&cHouses is currently disabled, try again soon!")); + return; + } + + if (user.ownsHouse(this.id)) { + player.sendMessage(Lang.HOUSES.f("&7You no longer own house &a" + this.id + "&7!")); + user.removeHouse(player, this);//TODO Make sure this method removes all data. + if (user.isInsideHouse(this.id)) + user.teleportInOrOutHouse(player, this); + } else + player.sendMessage(Lang.HOUSES.f("&7You don't own house &a" + this.id + "&7!")); + } + + +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/HouseChest.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/HouseChest.java new file mode 100644 index 0000000..3d05f7e --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/HouseChest.java @@ -0,0 +1,61 @@ +package net.grandtheftmc.houses.houses; + +import org.bukkit.Location; + +public class HouseChest { + + private int hotspotId; + + private final int chestId; + private final int houseId; + private Location loc1; + private Location loc2; + + public HouseChest(int hotspotId, int chestId, int houseId, Location loc1) { + this.hotspotId = hotspotId; + this.chestId = chestId; + this.houseId = houseId; + this.loc1 = loc1; + } + + public HouseChest(int hotspotId, int chestId, int houseId, Location loc1, Location loc2) { + this.hotspotId = hotspotId; + this.chestId = chestId; + this.houseId = houseId; + this.loc1 = loc1; + this.loc2 = loc2; + } + + public int getHotspotId() { + return hotspotId; + } + + public void setHotspotId(int hotspotId) { + this.hotspotId = hotspotId; + } + + public int getId() { + return this.chestId; + } + + public Location getLoc1() { + return this.loc1; + } + + public void setLoc1(Location l) { + this.loc1 = l; + } + + public Location getLoc2() { + return this.loc2; + } + + public void setLoc2(Location l) { + this.loc2 = l; + } + + public int getHouseId() { + return this.houseId; + } + +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/HouseDoor.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/HouseDoor.java new file mode 100644 index 0000000..dcb13c5 --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/HouseDoor.java @@ -0,0 +1,78 @@ +package net.grandtheftmc.houses.houses; + +import org.bukkit.Location; + +public class HouseDoor { + + private int hotspotId; + + private final int doorId; + private final int houseId; + private Location doorLocation; + private Location insideLocation; + private Location outsideLocation; + + public HouseDoor(int hotspotId, int doorId, int houseId) { + this.hotspotId = hotspotId; + this.doorId = doorId; + this.houseId = houseId; + } + + public HouseDoor(int hotspotId, int doorId, int houseId, Location doorLocation) { + this.hotspotId = hotspotId; + this.doorId = doorId; + this.houseId = houseId; + this.doorLocation = doorLocation; + } + + public HouseDoor(int hotspotId, int doorId, int houseId, Location doorLocation, Location insideLocation, Location outsideLocation) { + this.hotspotId = hotspotId; + this.doorId = doorId; + this.houseId = houseId; + this.doorLocation = doorLocation; + this.insideLocation = insideLocation; + this.outsideLocation = outsideLocation; + } + + public int getHotspotId() { + return hotspotId; + } + + public void setHotspotId(int hotspotId) { + this.hotspotId = hotspotId; + } + + public int getId() { + return this.doorId; + } + + public int getHouseId() { + return this.houseId; + } + + public Location getLocation() { + return this.doorLocation; + } + + public void setLocation(Location doorLocation) { + this.doorLocation = doorLocation; + } + + public Location getInsideLocation() { + return this.insideLocation; + } + + public void setInsideLocation(Location insideLocation) { + this.insideLocation = insideLocation; + } + + public Location getOutsideLocation() { + return this.outsideLocation; + } + + public void setOutsideLocation(Location outsideLocation) { + this.outsideLocation = outsideLocation; + } + + +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/HouseSign.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/HouseSign.java new file mode 100644 index 0000000..dea00aa --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/HouseSign.java @@ -0,0 +1,37 @@ +package net.grandtheftmc.houses.houses; + +import org.bukkit.Location; + +public class HouseSign { + + private int hotspotId; + + private final int houseId; + private Location location; + + public HouseSign(int hotspotId, int houseId, Location location) { + this.hotspotId = hotspotId; + this.houseId = houseId; + this.location = location; + } + + public int getHotspotId() { + return hotspotId; + } + + public void setHotspotId(int hotspotId) { + this.hotspotId = hotspotId; + } + + public int getHouseId() { + return houseId; + } + + public Location getLocation() { + return location; + } + + public void setLocation(Location location) { + this.location = location; + } +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/HousesManager.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/HousesManager.java new file mode 100644 index 0000000..276843d --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/HousesManager.java @@ -0,0 +1,553 @@ +package net.grandtheftmc.houses.houses; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.block.Chest; +import org.bukkit.entity.Player; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.util.Callback; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.houses.HouseUtils; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.dao.HouseDAO; +import net.grandtheftmc.houses.dao.PremiumHouseDAO; + +public class HousesManager { + + private List<House> houses = new ArrayList<>(); + private List<PremiumHouse> premiumHouses = new ArrayList<>(); + + public HousesManager() { + this.load(); + this.saveTask(); + } + + public void saveTask() { +// Bukkit.getScheduler().scheduleSyncRepeatingTask(Houses.getInstance(), new Runnable() { +// @Override +// public void run() { +// HousesManager.this.save(); +// } +// }, 600L, 36000L); // 30 minutes + } + + public House getHouse(int id) { + for (House house : this.houses) + if (house.getId() == id) + return house; + return null; + } + + public List<House> getHouses() { + return this.houses; + } + + public void addHouse(int id, int price, Callback<House> callback) { +// House house = new House(id, price); +// this.houses.add(house); +// return house; + + ServerUtil.runTaskAsync(() -> { + House house = null; + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + house = HouseDAO.addHouse(connection, id, price); + } catch (SQLException e) { + e.printStackTrace(); + callback.call(null); + return; + } + + if (house == null) { + callback.call(null); + return; + } + + this.houses.add(house); + callback.call(house); + }); + } + + public PremiumHouse getPremiumHouse(int id) { + for (PremiumHouse house : this.premiumHouses) + if (house.getId() == id) + return house; + return null; + } + + public List<PremiumHouse> getPremiumHouses() { + return this.premiumHouses; + } + + public void addPremiumHouse(int id, int permits, Callback<PremiumHouse> callback) { +// PremiumHouse house = new PremiumHouse(id, permits); +// this.premiumHouses.add(house); +// return house; + ServerUtil.runTaskAsync(() -> { + PremiumHouse house = null; + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + house = PremiumHouseDAO.addHouse(connection, id, permits); + } catch (SQLException e) { + e.printStackTrace(); + callback.call(null); + return; + } + + if (house == null) { + callback.call(null); + return; + } + + this.premiumHouses.add(house); + callback.call(house); + }); + } + + public House getHouseFromChest(Location loc) { + for (House house : this.houses) + for (HouseChest chest : house.getChests()) + if (HouseUtils.locEqualsLoc(loc, chest.getLoc1(), false) || HouseUtils.locEqualsLoc(loc, chest.getLoc2(), false)) + return house; + return null; + } + + public Object[] getHouseAndChest(Location loc) { + for (House house : this.houses) + for (HouseChest chest : house.getChests()) +// if (loc.equals(chest.getLoc1()) || loc.equals(chest.getLoc2())) + if (HouseUtils.locEqualsLoc(loc, chest.getLoc1(), false) || HouseUtils.locEqualsLoc(loc, chest.getLoc2(), false)) + return new Object[]{house, chest}; + + for (PremiumHouse house : this.premiumHouses) + for (PremiumHouseChest chest : house.getChests()) +// if (loc.equals(chest.getLoc1()) || loc.equals(chest.getLoc2())) + if (HouseUtils.locEqualsLoc(loc, chest.getLoc1(), false) || HouseUtils.locEqualsLoc(loc, chest.getLoc2(), false)) + return new Object[]{house, chest}; + return null; + } + + public House getHouseFromDoor(Location loc) { + for (House house : this.houses) + for (HouseDoor door : house.getDoors()) +// if (loc.equals(door.getLocation())) + if (HouseUtils.locEqualsLoc(loc, door.getLocation(), false)) + return house; + return null; + } + + public Object[] getHouseAndDoor(Location loc) { + for (House house : this.houses) + for (HouseDoor door : house.getDoors()) +// if (loc.equals(door.getLocation())) + if (HouseUtils.locEqualsLoc(loc, door.getLocation(), false)) + return new Object[]{house, door}; + + for (PremiumHouse house : this.premiumHouses) + for (PremiumHouseDoor door : house.getDoors()) +// if (loc.equals(door.getLocation())) + if (HouseUtils.locEqualsLoc(loc, door.getLocation(), false)) + return new Object[]{house, door}; + return null; + } + + public PremiumHouse getPremiumHouseFromChest(Location loc) { + for (PremiumHouse house : this.premiumHouses) + for (PremiumHouseChest chest : house.getChests()) +// if (loc.equals(chest.getLoc1()) || loc.equals(chest.getLoc2())) + if (HouseUtils.locEqualsLoc(loc, chest.getLoc1(), false) || HouseUtils.locEqualsLoc(loc, chest.getLoc2(), false)) + return house; + return null; + } + + public void load() { + this.houses = new ArrayList<>(); + this.premiumHouses = new ArrayList<>(); + + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + long start = System.currentTimeMillis(); + + // set all house data to valid + HouseDAO.resetValidData(connection); + + this.houses.addAll(HouseDAO.loadHouses(connection)); + System.out.println("Houses and data loaded. [" + this.houses.size() + "] (took " + (System.currentTimeMillis() - start) + "ms)"); + + start = System.currentTimeMillis(); + this.premiumHouses.addAll(PremiumHouseDAO.loadHouses(connection)); + System.out.println("PremiumHouses and data loaded. [" + this.premiumHouses.size() + "] (took " + (System.currentTimeMillis() - start) + "ms)"); + + } catch (SQLException e) { + e.printStackTrace(); + } + }); + +// YamlConfiguration c = Houses.getSettings().getHousesConfig(); +// for (String idString : c.getKeys(false)) { +// try { +// int id; +// try { +// id = Integer.parseInt(idString); +// } catch (NumberFormatException e) { +// continue; +// } +// int price = c.getInt(id + ".price"); +// List<HouseDoor> doors = new ArrayList<>(); +// if (c.get(id + ".doors") != null) +// for (String doorIdString : c.getConfigurationSection(id + ".doors").getKeys(false)) { +// int doorId; +// try { +// doorId = Integer.parseInt(doorIdString); +// } catch (NumberFormatException e) { +// continue; +// } +// Location doorLocation = Utils +// .blockLocationFromString(c.getString(id + ".doors." + doorId + ".location")); +// Location insideLocation = Utils +// .teleportLocationFromString(c.getString(id + ".doors." + doorId + ".insideLocation")); +// Location outsideLocation = Utils +// .teleportLocationFromString(c.getString(id + ".doors." + doorId + ".outsideLocation")); +// doors.add(new HouseDoor(doorId, id, doorLocation, insideLocation, outsideLocation)); +// } +// List<HouseChest> chests = new ArrayList<>(); +// if (c.get(id + ".chests") != null) +// for (String chestIdString : c.getConfigurationSection(id + ".chests").getKeys(false)) { +// int chestId; +// try { +// chestId = Integer.parseInt(chestIdString); +// } catch (NumberFormatException e) { +// continue; +// } +// Location loc1 = Utils.blockLocationFromString(c.getString(id + ".chests." + chestId + ".loc1")); +// Location loc2 = Utils.blockLocationFromString(c.getString(id + ".chests." + chestId + ".loc2")); +// chests.add(new HouseChest(chestId, id, loc1, loc2)); +// } +// List<Location> signs = new ArrayList<>(); +// if (c.get(id + ".signs") != null) +// signs.addAll(c.getStringList(id + ".signs").stream().map(Utils::blockLocationFromString).collect(Collectors.toList())); +// this.houses.add(new House(id, price, chests, doors, signs)); +// } catch (Exception e) { +// Houses.error("Error while parsing house " + idString); +// e.printStackTrace(); +// } +// } + +// this.premiumHouses = new ArrayList<>(); +// c = Houses.getSettings().getPremiumHousesConfig(); +// for (String idString : c.getKeys(false)) { +// try { +// int id; +// try { +// id = Integer.parseInt(idString); +// } catch (NumberFormatException e) { +// continue; +// } +// int permits = c.get(id + ".permits") == null ? 1000 : c.getInt(id + ".permits"); +// UUID owner = c.get(id + ".owner") == null ? null : UUID.fromString(c.getString(id + ".owner")); +// String ownerName = c.getString(id + ".ownerName"); +// List<PremiumHouseDoor> doors = new ArrayList<>(); +// if (c.get(id + ".doors") != null) { +// for (String doorIdString : c.getConfigurationSection(id + ".doors").getKeys(false)) { +// int doorId; +// try { +// doorId = Integer.parseInt(doorIdString); +// } catch (NumberFormatException e) { +// continue; +// } +// Location doorLocation = Utils +// .blockLocationFromString(c.getString(id + ".doors." + doorId + ".location")); +// Location insideLocation = Utils +// .teleportLocationFromString(c.getString(id + ".doors." + doorId + ".insideLocation")); +// Location outsideLocation = Utils +// .teleportLocationFromString(c.getString(id + ".doors." + doorId + ".outsideLocation")); +// doors.add(new PremiumHouseDoor(doorId, id, doorLocation, insideLocation, outsideLocation)); +// } +// } +// List<PremiumHouseChest> chests = new ArrayList<>(); +// if (c.get(id + ".chests") != null) { +// for (String chestIdString : c.getConfigurationSection(id + ".chests").getKeys(false)) { +// int chestId; +// try { +// chestId = Integer.parseInt(chestIdString); +// } catch (NumberFormatException e) { +// continue; +// } +// Location loc1 = Utils.blockLocationFromString(c.getString(id + ".chests." + chestId + ".loc1")); +// Location loc2 = Utils.blockLocationFromString(c.getString(id + ".chests." + chestId + ".loc2")); +// chests.add(new PremiumHouseChest(chestId, id, loc1, loc2)); +// } +// } +// List<Location> signs = new ArrayList<>(); +// if (c.get(id + ".signs") != null) { +// signs.addAll(c.getStringList(id + ".signs").stream().map(Utils::blockLocationFromString).collect(Collectors.toList())); +// } +// List<PremiumHouseGuest> guests = new ArrayList<>(); +// if (c.get(id + ".guests") != null) { +// for (String uuidString : c.getConfigurationSection(id + ".guests").getKeys(false)) { +// guests.add(new PremiumHouseGuest(UUID.fromString(uuidString), +// c.getString(id + ".guests." + uuidString))); +// } +// } +// Collection<EditableBlock> editableBlocks = new ArrayList<>(); +// if(c.contains(id + ".blocks")) { +// for(String loc : c.getConfigurationSection(id + ".blocks").getKeys(false)) { +// String[] original = String.valueOf(c.get(id + ".blocks." + loc + ".default")).split(","); +// String originalMaterial = String.valueOf(original[0]); +// byte originalData = Byte.valueOf(original[1]); +// editableBlocks.add(new EditableBlock(Utils.blockLocationFromString(loc), Material.matchMaterial(originalMaterial), originalData)); +// } +// } +// Collection<PremiumHouseTrashcan> trashcans = new ArrayList<>(); +// if (c.contains(id + ".trashcans")) { +// for (String trashcanIdString : c.getConfigurationSection(id + ".trashcans").getKeys(false)) { +// int trashcanId; +// try { +// trashcanId = Integer.parseInt(trashcanIdString); +// } catch (NumberFormatException e) { +// continue; +// } +// Location location = Utils.blockLocationFromString(c.getString(id + ".trashcans." + trashcanIdString + ".loc")); +// boolean owned = c.getBoolean(id + ".trashcans." + trashcanIdString + ".owned"); +// trashcans.add(new PremiumHouseTrashcan(trashcanId, id, location, owned)); +// } +// } +// this.premiumHouses.add(new PremiumHouse(id, permits, owner, ownerName, doors, chests, signs, guests, editableBlocks, trashcans)); +// } catch (Exception e) { +// Houses.error("Error while parsing premium house " + idString); +// e.printStackTrace(); +// } +// } + } + + public void save() { +// YamlConfiguration c = Houses.getSettings().getHousesConfig(); +// for (String s : c.getKeys(false)) +// c.set(s, null); +// +// for (House house : this.houses) { +// int id = house.getId(); +// c.set(id + ".price", house.getPrice()); +// +// //Door save +// for (HouseDoor door : house.getDoors()) { +// int doorId = door.getId(); +// c.set(id + ".doors." + doorId + ".location", Utils.blockLocationToString(door.getLocation())); +// c.set(id + ".doors." + doorId + ".insideLocation", Utils.teleportLocationToString(door.getInsideLocation())); +// c.set(id + ".doors." + doorId + ".outsideLocation", Utils.teleportLocationToString(door.getOutsideLocation())); +// } +// +// //Chest save +// for (HouseChest chest : house.getChests()) { +// int chestId = chest.getId(); +// c.set(id + ".chests." + chestId + ".loc1", Utils.blockLocationToString(chest.getLoc1())); +// c.set(id + ".chests." + chestId + ".loc2", Utils.blockLocationToString(chest.getLoc2())); +// } +// +// //Sign save +// c.set(id + ".signs", house.getSigns().stream().map(Utils::blockLocationToString).collect(Collectors.toList())); +// } +// Utils.saveConfig(c, "houses"); +// +// c = Houses.getSettings().getPremiumHousesConfig(); +// for (String s : c.getKeys(false)) +// c.set(s, null); +// +// for (PremiumHouse house : this.premiumHouses) { +// int id = house.getId(); +// c.set(id + ".permits", house.getPermits()); +// c.set(id + ".owner", house.getOwner() == null ? null : house.getOwner().toString()); +// c.set(id + ".ownerName", house.getOwnerName()); +// +// //Door save +// for (PremiumHouseDoor door : house.getDoors()) { +// int doorId = door.getId(); +// c.set(id + ".doors." + doorId + ".location", Utils.blockLocationToString(door.getLocation())); +// c.set(id + ".doors." + doorId + ".insideLocation", +// Utils.teleportLocationToString(door.getInsideLocation())); +// c.set(id + ".doors." + doorId + ".outsideLocation", +// Utils.teleportLocationToString(door.getOutsideLocation())); +// } +// +// //Chest save +// for (PremiumHouseChest chest : house.getChests()) { +// int chestId = chest.getId(); +// c.set(id + ".chests." + chestId + ".loc1", Utils.blockLocationToString(chest.getLoc1())); +// c.set(id + ".chests." + chestId + ".loc2", Utils.blockLocationToString(chest.getLoc2())); +// } +// +// //Sign save +// c.set(id + ".signs", house.getSigns().stream().map(Utils::blockLocationToString).collect(Collectors.toList())); +// +// //Guest save +// for (PremiumHouseGuest guest : house.getGuests()) { +// String name = guest.getName(); +// c.set(id + ".guests." + guest.getUuid(), name == null ? guest.getUuid().toString() : name); +// } +// +// //Blocks save +// for(EditableBlock location : house.getEditableBlocks()) { +// c.set(id + ".blocks." + Utils.blockLocationToString(location.getLocation()) +// + ".default", location.getDefaultType().name() + "," + location.getDefaultData()); +// } +// +// //Trashcan save +// for (PremiumHouseTrashcan premiumHouseTrashcan : house.getTrashcans()) { +// int trashcanId = premiumHouseTrashcan.getId(); +// String location = Utils.blockLocationToString(premiumHouseTrashcan.getLocation()); +// c.set(id + ".trashcans." + trashcanId + ".loc", location); +// c.set(id + ".trashcans." + trashcanId + ".owned", premiumHouseTrashcan.isOwned()); +// } +// } +// Utils.saveConfig(c, "premiumHouses"); + } + + public void createHouse(Callback<House> callback) { +// House house = new House(this.getUnusedHouseId()); +// this.houses.add(house); +// return house; + + ServerUtil.runTaskAsync(() -> { + House house = null; + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + house = HouseDAO.addHouse(connection, this.getUnusedHouseId(), 1); + } catch (SQLException e) { + e.printStackTrace(); + callback.call(null); + return; + } + + if (house == null) { + callback.call(null); + return; + } + + this.houses.add(house); + callback.call(house); + }); + } + + public void createPremiumHouse(Callback<PremiumHouse> callback) { +// PremiumHouse house = new PremiumHouse(this.getUnusedPremiumHouseId()); +// this.premiumHouses.add(house); +// return house; + ServerUtil.runTaskAsync(() -> { + PremiumHouse house = null; + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + house = PremiumHouseDAO.addHouse(connection, this.getUnusedPremiumHouseId(), 1); + } catch (SQLException e) { + e.printStackTrace(); + callback.call(null); + return; + } + + if (house == null) { + callback.call(null); + return; + } + + this.premiumHouses.add(house); + callback.call(house); + }); + } + + public void removeHouse(House house) { + house.removeAllChestsNonDB(); + house.removeAllOwnersNonDB(); + this.houses.remove(house); + + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + HouseDAO.deleteHouse(connection, house.getUniqueIdentifier()); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } + + public void removePremiumHouse(PremiumHouse house) { + this.premiumHouses.remove(house); + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + HouseDAO.deleteHouse(connection, house.getUniqueIdentifier()); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } + + public int getUnusedHouseId() { + for (int i = 1; i < Integer.MAX_VALUE; i++) { + if (this.getHouse(i) == null) + return i; + } + + return -1; + } + + public int getUnusedPremiumHouseId() { + for (int i = 1; i < Integer.MAX_VALUE; i++) { + if (this.getPremiumHouse(i) == null) + return i; + } + + return -1; + } + + public List<House> getHouses(int start, int end) { + return this.houses.stream().filter(house -> house.getId() >= start && house.getId() <= end).collect(Collectors.toList()); + } + + public List<PremiumHouse> getPremiumHouses(int start, int end) { + return this.premiumHouses.stream().filter(house -> house.getId() >= start && house.getId() <= end).collect(Collectors.toList()); + } + + public House getHouseFromSign(Location loc) { +// for (House house : this.houses) +// for (Location l : house.getSigns()) +// if (l.equals(loc)) +// return house; + + return this.houses.stream().filter(h -> h.getSigns().stream().anyMatch(sign -> loc.equals(sign.getLocation()))).findFirst().orElse(null); + } + + public PremiumHouse getPremiumHouseFromSign(Location loc) { +// for (PremiumHouse house : this.premiumHouses) +// for (Location l : house.getSigns()) +// if (l.equals(loc)) +// return house; + + return this.premiumHouses.stream().filter(h -> h.getSigns().stream().anyMatch(sign -> loc.equals(sign.getLocation()))).findFirst().orElse(null); + } + + public void forceSell(PremiumHouse premiumHouse, Player sender) { + Integer permits = premiumHouse.getPermits(); + premiumHouse.getChests().forEach(PremiumHouseChest::clear); + premiumHouse.getEditableBlocks().forEach(block -> { + block.getLocation().getBlock().setType(block.getDefaultType()); + block.getLocation().getBlock().setData(block.getDefaultData()); + }); + Collection<PremiumHouseTrashcan> trashcans = premiumHouse.getTrashcans().stream().filter(PremiumHouseTrashcan::isOwned).collect(Collectors.toList()); + trashcans.forEach(trashCan -> trashCan.setOwned(false)); + permits += trashcans.size() * 5; + +// Core.sql.update("update " + Core.name() + " set permits=permits+" + permits + " where uuid='" + premiumHouse.getOwner().toString() + "';"); + Integer finalPermits = permits; + ServerUtil.runTaskAsync(() -> { + BaseDatabase.runCustomQuery("update " + Core.name() + " set permits=permits+" + finalPermits + " where uuid='" + premiumHouse.getOwner().toString() + "';"); + }); + + Bukkit.broadcastMessage(Lang.HOUSES.f(premiumHouse.getOwnerName() + " &7sold premium house " + "&a" + premiumHouse.getId() + " &7for &3&l" + premiumHouse.getPermits() + " Permits&7!")); + premiumHouse.removeOwner(true); + Houses.getHousesManager().save(); + } +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/PremiumHouse.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/PremiumHouse.java new file mode 100644 index 0000000..98e58cd --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/PremiumHouse.java @@ -0,0 +1,744 @@ +package net.grandtheftmc.houses.houses; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Collectors; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.BlockState; +import org.bukkit.block.Sign; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.Callback; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.houses.HouseUtils; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.JSONHelper; +import net.grandtheftmc.houses.dao.HouseDAO; +import net.grandtheftmc.houses.dao.PremiumHouseDAO; +import net.grandtheftmc.houses.users.HouseUser; + +public class PremiumHouse { + + private int uniqueIdentifier; + + private final int id; + private int permits; + private UUID owner; + private String ownerName; + private List<PremiumHouseChest> chests = new ArrayList<>(); + private List<PremiumHouseDoor> doors = new ArrayList<>(); + private List<PremiumHouseGuest> guests = new ArrayList<>(); + private List<HouseSign> signs = new ArrayList<>(); + private Collection<EditableBlock> editableBlocks = new ArrayList<>(); + private Collection<PremiumHouseTrashcan> trashcans = new ArrayList<>(); + + public PremiumHouse(int uniqueIdentifier, int id) { + this.uniqueIdentifier = uniqueIdentifier; + this.id = id; + } + + public PremiumHouse(int uniqueIdentifier, int id, int permits) { + this.uniqueIdentifier = uniqueIdentifier; + this.id = id; + this.permits = permits; + } + + public PremiumHouse(int uniqueIdentifier, int id, int permits, UUID owner, String ownerName, List<PremiumHouseDoor> doors, + List<PremiumHouseChest> chests, List<HouseSign> signs, List<PremiumHouseGuest> guests, + Collection<EditableBlock> editableBlocks, Collection<PremiumHouseTrashcan> trashcans) { + this.uniqueIdentifier = uniqueIdentifier; + this.id = id; + this.permits = permits; + this.owner = owner; + this.ownerName = ownerName; + this.doors = doors; + this.chests = chests; + this.signs = signs; + this.guests = guests; + this.editableBlocks = editableBlocks; + this.trashcans = trashcans; + } + + public int getUniqueIdentifier() { + return uniqueIdentifier; + } + + public void setUniqueIdentifier(int uniqueIdentifier) { + this.uniqueIdentifier = uniqueIdentifier; + } + + public int getId() { + return this.id; + } + + public UUID getOwner() { + return this.owner; + } + + public void setOwner(Player player) { + if (this.owner != null) { + if (Objects.equals(this.owner, player.getUniqueId())) { + player.sendMessage(Lang.HOUSES.f("&7You already own premium house &a" + this.id + "&7!")); + return; + } + player.sendMessage(Utils.f(Lang.HOUSES + "&7Someone already owns premium house &a" + this.id + "&7!")); + return; + } + player.sendMessage(Lang.HOUSES.f("&7You now own premium house &a" + this.id + "&7!")); + this.setOwner(player.getUniqueId(), player.getName(), true); + } + + public boolean isOwner(UUID uuid) { + return Objects.equals(uuid, this.owner); + } + + public int getPermits() { + return this.permits; + } + + public void setPermits(int i) { + this.permits = i; + + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + HouseDAO.setPrice(connection, this.uniqueIdentifier, i); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + + this.updateSigns(); + } + + public List<PremiumHouseChest> getChests() { + return this.chests; + } + + public List<PremiumHouseChest> getChests(int start, int end) { + return this.chests.stream().filter(chest -> chest.getId() >= start && chest.getId() <= end).collect(Collectors.toList()); + } + + public int getAmountOfChests() { + int i = this.chests.size(); + i += this.chests.stream().filter(chest -> chest.getLoc2() != null).count(); + return i; + } + + public PremiumHouseChest getChest(int id) { + return this.chests.stream().filter(chest -> chest.getId() == id).findFirst().orElse(null); + } + + public List<PremiumHouseGuest> getGuests() { + return this.guests; + } + + public PremiumHouseGuest getGuest(UUID uuid) { + return this.guests.stream().filter(guest -> Objects.equals(guest.getUuid(), uuid)).findFirst().orElse(null); + } + + public PremiumHouseGuest getGuest(String name) { + return this.guests.stream().filter(guest -> Objects.equals(guest.getName(), name)).findFirst().orElse(null); + } + + public void addGuest(UUID uuid, String name) { + if (this.getGuest(uuid) == null) { + this.guests.add(new PremiumHouseGuest(uuid, name)); + } + } + + /** + * Only use when pulling from database. + * @param guest + */ + public void addGuest(PremiumHouseGuest guest) { + this.guests.add(guest); + } + + public boolean isGuest(UUID uuid) { + return this.getGuest(uuid) != null; + } + + public boolean isGuest(String guest) { + return this.getGuest(guest) != null; + } + + public boolean hasAccess(Player player, HouseUser user) { + return player.isOp() || this.isGuest(player.getUniqueId()) || this.isOwner(player.getUniqueId()); + } + + public List<PremiumHouseDoor> getDoors() { + return this.doors; + } + + public List<PremiumHouseDoor> getDoors(int start, int end) { + return this.doors.stream().filter(door -> door.getId() >= start && door.getId() <= end).collect(Collectors.toList()); + } + + public PremiumHouseDoor getDoor(int id) { + return this.doors.stream().filter(door -> door.getId() == id).findFirst().orElse(null); + } + + public PremiumHouseDoor getDoor() { + if (this.doors.isEmpty()) + return null; + for (int i = 1; ; i++) { + PremiumHouseDoor door = this.getDoor(i); + if (door != null) + return door; + } + } + + public String getOwnerName() { + return this.ownerName; + } + + public void setOwnerName(String ownerName) { + this.ownerName = ownerName; + this.updateSigns(); + } + + public boolean isOwned() { + return this.owner != null; + } + + public int getUnusedChestId() { + for (int i = 1; ; i++) + if (this.getChest(i) == null) + return i; + } + + /** + * Only use for data pulled from the Database. + * @param chest + */ + public PremiumHouseChest addChest(PremiumHouseChest chest) { + this.chests.add(chest); + this.updateSigns(); + return chest; + } + + public void addChest(int chestId, int houseId, Location first, Location second, Callback<PremiumHouseChest> callback) { +// this.chests.add(chest); +// this.updateSigns(); +// return chest; + + ServerUtil.runTaskAsync(() -> { + PremiumHouseChest chest = new PremiumHouseChest(-1, chestId, houseId, first); + if (second != null) chest.setLoc2(second); + + JSONHelper helper = new JSONHelper(); + helper.put("id", chestId); + helper.put("loc1", HouseUtils.locationToString(first)); + if (second != null) helper.put("loc2", HouseUtils.locationToString(second)); + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + PremiumHouseDAO.addChest(connection, this.uniqueIdentifier, chest, helper); + } catch (SQLException e) { + e.printStackTrace(); + callback.call(null); + return; + } + + this.chests.add(chest); + Houses.getUserManager().getLoadedUsers().stream().filter(user -> user.ownsHouse(this.id)).forEach(user -> user.getUserHouse(this.id).getChest(chestId)); + this.updateSigns(); + + callback.call(chest); + }); + } + + public void removeChest(PremiumHouseChest chest) { + this.chests.remove(chest); + + //TODO Remove house chest. + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + HouseDAO.deleteChestData(connection, chest.getHotspotId()); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + + this.updateSigns(); + } + + public void removeAllChests() { + this.chests.clear(); + + //TODO Remove all house chests. + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + HouseDAO.deleteAllChestData(connection, this.uniqueIdentifier); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + + this.updateSigns(); + } + + public void addDoor(Callback<PremiumHouseDoor> callback) { + ServerUtil.runTaskAsync(() -> { + PremiumHouseDoor door = new PremiumHouseDoor(-1, this.getUnusedDoorId(), this.id); + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + PremiumHouseDAO.addDoor(connection, this.uniqueIdentifier, door, null); + } catch (SQLException e) { + e.printStackTrace(); + callback.call(null); + return; + } + + this.doors.add(door); + callback.call(door); + }); + } + + public PremiumHouseDoor addDoor(PremiumHouseDoor door) { + this.doors.add(door); + return door; + } + + private int getUnusedDoorId() { + for (int i = 1; ; i++) + if (this.getDoor(i) == null) + return i; + } + + public void removeDoor(PremiumHouseDoor door) { + this.doors.remove(door); + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + HouseDAO.removeDoor(connection, this.uniqueIdentifier, door.getHotspotId()); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } + + public void removeAllDoors() { + this.doors.clear(); + + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + HouseDAO.removeAllDoors(connection, this.uniqueIdentifier); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } + + public List<HouseSign> getSigns() { + return this.signs; + } + + /** + * Only used when pulling from database. + * @param sign + */ + public void addSign(HouseSign sign) { + this.signs.add(sign); + ServerUtil.runTask(() -> this.updateSign(sign.getLocation())); +// this.updateSign(sign.getLocation()); + } + + public void addSign(Location loc, Callback<HouseSign> callback) { + ServerUtil.runTaskAsync(() -> { + HouseSign sign = new HouseSign(-1, this.uniqueIdentifier, loc); + + JSONHelper helper = new JSONHelper(); + helper.put("loc", HouseUtils.locationToString(loc)); + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + HouseDAO.addSign(connection, this.uniqueIdentifier, sign, helper); + } catch (SQLException e) { + e.printStackTrace(); + callback.call(null); + return; + } + + this.signs.add(sign); + ServerUtil.runTask(() -> this.updateSign(sign.getLocation())); +// this.updateSign(sign.getLocation()); + callback.call(sign); + }); + } + + public void removeSign(Location loc) { + HouseSign sign = this.signs.stream().filter(s -> loc.equals(s.getLocation())).findFirst().orElse(null); + if (sign == null) return; + this.signs.remove(sign); + + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + HouseDAO.deleteSign(connection, sign.getHotspotId()); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } + + public void removeAllSigns() { + this.signs.clear(); + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + HouseDAO.deleteAllSigns(connection, this.uniqueIdentifier); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } + + public List<HouseSign> getSigns(int start, int end) { + return this.signs.subList(start, end); + } + + public void updateSigns() { + int id = this.id; + new BukkitRunnable() { + @Override + public void run() { + PremiumHouse house = Houses.getHousesManager().getPremiumHouse(id); + if (house != null) + new ArrayList<>(house.getSigns()).forEach(s -> updateSign(s.getLocation())); + } + }.runTask(Houses.getInstance()); + + } + + public void updateSign(Location loc) { + BlockState state = loc.getBlock().getState(); + if (!(state instanceof Sign)) { + this.removeSign(loc); + return; + } + Sign sign = (Sign) state; + sign.setLine(0, Utils.f("&3&lPremium House &a&l" + this.id)); + sign.setLine(1, Utils.f("&8Chests: &a&l" + this.getAmountOfChests())); + sign.setLine(2, Utils.f("&8Permits: &a&l" + this.permits)); + sign.setLine(3, Utils.f(this.isOwned() ? "&cOwned" : "&aVacant")); + sign.update(); + } + + public void buy(Player player, User user, GTMUser gtmUser, HouseUser houseUser) { + if (!Houses.ENABLED) { + player.sendMessage(Lang.HOUSES.f("&cHouses is currently disabled, try again soon!")); + return; + } + + if (this.owner != null) { + if (Objects.equals(this.owner, player.getUniqueId())) { + player.sendMessage(Utils.f(Lang.HOUSES + "&7You already own this premium house!")); + return; + } + player.sendMessage(Utils.f(Lang.HOUSES + "&7This premium house is already owned by &a" + this.owner + "&7!")); + return; + } + + /** + * Prevent house from being bought. + * + * Ignore the silly if check, it's so i can find the if statement later. + */ +// if ("disable".equalsIgnoreCase("disable")) { +// player.sendMessage(Utils.f(Lang.HOUSES + "&7Purchasing premium houses is temporarily disabled.")); +// player.sendMessage(Utils.f(Lang.HOUSES + "&7Try again later..")); +// return; +// } + + if (houseUser.hasMaxHouses(player, user, gtmUser)) { + player.sendMessage(Lang.HOUSES.f("&7You have hit the maximum amount of houses you can own!")); + return; + } + if (!gtmUser.hasPermits(this.permits)) { + player.sendMessage(Lang.HOUSES.f("&7You can not afford the &3&l" + this.permits + " Permits&7 to pay for this premium house!")); + return; + } + gtmUser.takePermits(this.permits); + this.setOwner(player.getUniqueId(), player.getName(), true);//TODO Make sure this method updates database. + player.sendMessage(Lang.HOUSES.f("&7You bought premium house &a" + this.id + "&7 for &3&l" + this.permits + " Permits&7!")); + Utils.insertLogLater(player.getUniqueId(), player.getName(), "buyPremiumHouseMethod", "BUY_PREMIUM_HOUSE", "Premium House ID: " + this.id,1,this.permits); + Bukkit.broadcastMessage(Lang.HOUSES.f(user.getColoredName(player) + " &7bought premium house " + "&a" + this.id + " &7for &3&l" + this.permits + " Permits&7!")); + Houses.getHousesManager().save(); + } + + public void forceSetOwner(Player player) { + if (!Houses.ENABLED) { + player.sendMessage(Lang.HOUSES.f("&cHouses is currently disabled, try again soon!")); + return; + } + + Player own = Bukkit.getPlayer(this.owner); + if (own != null) { + HouseUser user = Houses.getUserManager().getLoadedUser(own.getUniqueId()); + own.sendMessage(Lang.HOUSES.f("&7You no longer own premium house &a" + this.id + "&7!")); + if (user.isInsidePremiumHouse(this.id)) + user.teleportInOrOutPremiumHouse(own, this); + } + player.sendMessage(Lang.HOUSES.f("&7You now own premium house &a" + this.id + "&7!")); + this.setOwner(player.getUniqueId(), player.getName(), true);//TODO Make sure this method updates database. + } + + public void setOwner(UUID uuid, String name, boolean clearGuests) { + this.owner = uuid; + this.ownerName = name; + if (clearGuests) + this.guests.clear(); + + + //TODO Set owner of premium house. + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + + // if we clear guests + if (clearGuests){ + // delete all guests + PremiumHouseDAO.deleteHouseUsers(connection, this.uniqueIdentifier, false); + } + + // add the owner as the owner of the house + PremiumHouseDAO.addHouseGuest(connection, this.uniqueIdentifier, uuid, true); + } catch (SQLException e) { + e.printStackTrace(); + } + + ServerUtil.runTask(this::updateSigns); + }); + } + + /** + * Only use for setting data via DAO's + */ + public void setOwner(UUID uuid, String name) { + this.owner = uuid; + this.ownerName = name; + + this.updateSigns(); + } + + public void sell(Player player, GTMUser gtmUser, HouseUser houseUser) { + if (this.owner == null) { + player.sendMessage(Utils.f(Lang.HOUSES + "&7No one owns this premium house!")); + return; + } + + if (!Houses.ENABLED) { + player.sendMessage(Lang.HOUSES.f("&cHouses is currently disabled, try again soon!")); + return; + } + + if (!Objects.equals(this.owner, player.getUniqueId())) { + player.sendMessage(Utils.f(Lang.HOUSES + "&7You don't own this premium house!")); + return; + } + + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + gtmUser.addPermits(this.permits); + this.removeOwner(true);//TODO Make sure this method updates database. + if (houseUser.isInsidePremiumHouse(this.id)) + houseUser.teleportInOrOutPremiumHouse(player, this); + this.getEditableBlocks().forEach(block -> { + block.getLocation().getBlock().setType(block.getDefaultType()); + block.getLocation().getBlock().setData(block.getDefaultData()); + }); + this.getTrashcans().stream().filter(PremiumHouseTrashcan::isOwned).forEach(trashCan -> { + trashCan.setOwned(false);//TODO Make sure this method updates database. + gtmUser.addPermits(5); + }); + this.getChests().forEach(PremiumHouseChest::clear); + Utils.insertLogLater(player.getUniqueId(), player.getName(), "sellPremiumHouseMethod", "SELL_PREMIUM_HOUSE", "Premium House ID: " + this.id,1,this.permits); + Bukkit.broadcastMessage(Lang.HOUSES.f(user.getColoredName(player) + " &7sold premium house " + "&a" + this.id + " &7for &3&l" + this.permits + " Permits&7!")); + Houses.getHousesManager().save(); + } + + public void removeOwner(Player player, HouseUser user) { + if (!Objects.equals(this.owner, player.getUniqueId())) { + player.sendMessage(Lang.HOUSES.f("&7You don't own premium house &a" + this.id + "&7!")); + return; + } + + if (!Houses.ENABLED) { + player.sendMessage(Lang.HOUSES.f("&cHouses is currently disabled, try again soon!")); + return; + } + + player.sendMessage(Lang.HOUSES.f("&7You no longer own premium house &a" + this.id + "&7!")); + this.removeOwner(true);//TODO Make sure this method updates database. + if (user.isInsidePremiumHouse(this.id)) + user.teleportInOrOutPremiumHouse(player, this); + } + + public void removeOwner(boolean clearGuests) { + this.owner = null; + this.ownerName = null; + if (clearGuests) + this.guests.clear(); + + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + PremiumHouseDAO.deleteHouseUsers(connection, this.uniqueIdentifier, true); + if (clearGuests) PremiumHouseDAO.deleteHouseUsers(connection, this.uniqueIdentifier, false); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + + this.updateSigns(); + } + + public void addGuest(Player sender, Player target, HouseUser user) { + if (!Objects.equals(this.owner, sender.getUniqueId())) { + sender.sendMessage(Utils.f(Lang.HOUSES + "&7You don't own this premium house!")); + return; + } + + if (Objects.equals(sender, target)) { + sender.sendMessage(Utils.f(Lang.HOUSES + "&7You can't add yourself as a guest!")); + return; + } + + if (this.isGuest(target.getUniqueId())) { + sender.sendMessage(Utils.f(Lang.HOUSES + "&7That player is already a guest of this premium house!")); + return; + } + + sender.sendMessage(Lang.HOUSES.f("&7You added &a" + target.getName() + "&7 as a guest to premium house &a" + this.id + '!')); + target.sendMessage(Lang.HOUSES.f("&a" + sender.getName() + "&7 added you a guest to premium house &a" + this.id + "&7!")); + this.addGuest(target);//TODO Make sure this method updates database. + } + + public void addGuest(Player player) { + this.guests.add(new PremiumHouseGuest(player.getUniqueId(), player.getName())); + + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + PremiumHouseDAO.addHouseGuest(connection, this.uniqueIdentifier, player.getUniqueId(), false); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } + + public void removeGuest(Player sender, Player target, HouseUser user) { + if (!Objects.equals(this.owner, sender.getUniqueId())) { + sender.sendMessage(Utils.f(Lang.HOUSES + "&7You don't own this premium house!")); + return; + } + + if (!this.isGuest(target.getUniqueId())) { + sender.sendMessage(Utils.f(Lang.HOUSES + "&7That player is not a guest of this premium house!")); + return; + } + + if (user.isInsidePremiumHouse(this.id)) + user.teleportInOrOutPremiumHouse(target, this); + + sender.sendMessage(Lang.HOUSES.f("&7You removed &a" + target.getName() + "&7 as a guest from premium house &a" + this.id + '!')); + target.sendMessage(Lang.HOUSES.f("&a" + sender.getName() + "&7 removed you as a guest from premium house &a" + this.id + "&7!")); + this.removeGuest(target.getUniqueId());//TODO Make sure this method updates database. + } + + public void removeGuest(Player sender, String guest) { + if (!Objects.equals(this.owner, sender.getUniqueId())) { + sender.sendMessage(Utils.f(Lang.HOUSES + "&7You don't own this premium house!")); + return; + } + + if (!this.isGuest(guest)) { + sender.sendMessage(Utils.f(Lang.HOUSES + "&7That player is not a guest of this premium house!")); + return; + } + + this.removeGuest(guest);//TODO Make sure this method updates database. + sender.sendMessage(Lang.HOUSES.f("&7You removed &a" + guest + "&7 as a guest from premium house &a" + this.id + "!&")); + } + + public void removeGuest(UUID uuid) { + this.guests.remove(this.getGuest(uuid)); + + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + PremiumHouseDAO.deleteHouseGuest(connection, this.uniqueIdentifier, uuid); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } + + public void removeGuest(String name) { + removeGuest(this.getGuest(name).getUuid()); + } + + public Collection<EditableBlock> getEditableBlocks() { + return this.editableBlocks; + } + + public Collection<PremiumHouseTrashcan> getTrashcans() { + return trashcans; + } + + public Optional<PremiumHouseTrashcan> getTrashcan(Location location) { + if (this.trashcans.isEmpty()) return Optional.empty(); + return this.trashcans.stream().filter(trashcan -> trashcan.getLocation().equals(location)).findFirst(); + } + + public void addTrashcan(PremiumHouseTrashcan trashcan) { + this.trashcans.add(trashcan); + } + + public void addTrashcan(int trashcanId, int houseId, Location location, boolean owned, Callback<PremiumHouseTrashcan> callback) { + ServerUtil.runTaskAsync(() -> { + PremiumHouseTrashcan block = new PremiumHouseTrashcan(-1, trashcanId, houseId, location, owned); + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + PremiumHouseDAO.addTrashcan(connection, this.uniqueIdentifier, block, new JSONHelper() + .put("id", trashcanId).put("loc", HouseUtils.locationToString(location)).put("owned", owned)); + } catch (SQLException e) { + e.printStackTrace(); + callback.call(null); + return; + } + + this.trashcans.add(block); + callback.call(block); + }); + } + + public void addEditableBlock(EditableBlock block) { + this.editableBlocks.add(block); + } + + public void addEditableBlock(Location location, Material material, byte data, Callback<EditableBlock> callback) { + ServerUtil.runTaskAsync(() -> { + EditableBlock block = new EditableBlock(-1, location, material, data); + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + PremiumHouseDAO.addBlock(connection, this.uniqueIdentifier, block, new JSONHelper() + .put("loc", HouseUtils.locationToString(location)).put("block_data", material.name() + "," + data)); + } catch (SQLException e) { + e.printStackTrace(); + callback.call(null); + return; + } + + this.editableBlocks.add(block); + callback.call(block); + }); + } +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/PremiumHouseChest.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/PremiumHouseChest.java new file mode 100644 index 0000000..63f0987 --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/PremiumHouseChest.java @@ -0,0 +1,77 @@ +package net.grandtheftmc.houses.houses; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.BlockState; +import org.bukkit.block.Chest; + +public class PremiumHouseChest { + + private int hotspotId; + + private final int chestId; + private final int houseId; + private Location loc1; + private Location loc2; + + public PremiumHouseChest(int hotspotId, int chestId, int houseId, Location loc1) { + this.hotspotId = hotspotId; + this.chestId = chestId; + this.houseId = houseId; + this.loc1 = loc1; + } + + public PremiumHouseChest(int hotspotId, int chestId, int houseId, Location loc1, Location loc2) { + this.hotspotId = hotspotId; + this.chestId = chestId; + this.houseId = houseId; + this.loc1 = loc1; + this.loc2 = loc2; + } + + public int getHotspotId() { + return hotspotId; + } + + public void setHotspotId(int hotspotId) { + this.hotspotId = hotspotId; + } + + public int getId() { + return this.chestId; + } + + public int getHouseId() { + return this.houseId; + } + + public Location getLoc1() { + return this.loc1; + } + + public void setLoc1(Location loc1) { + this.loc1 = loc1; + } + + public Location getLoc2() { + return this.loc2; + } + + public void setLoc2(Location loc2) { + this.loc2 = loc2; + } + + public void clear() { + BlockState state = this.getLoc1().getBlock().getState(); + if (state.getType() != Material.CHEST) return; + Chest chest = (Chest) state; + chest.getBlockInventory().clear(); + if (this.getLoc2() != null) { + state = this.getLoc2().getBlock().getState(); + if (state.getType() != Material.CHEST) return; + chest = (Chest) state; + chest.getBlockInventory().clear(); + } + } + +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/PremiumHouseDoor.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/PremiumHouseDoor.java new file mode 100644 index 0000000..5a0bea0 --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/PremiumHouseDoor.java @@ -0,0 +1,76 @@ +package net.grandtheftmc.houses.houses; + +import org.bukkit.Location; + +public class PremiumHouseDoor { + + private int hotspotId; + + private final int doorId; + private final int houseId; + private Location doorLocation; + private Location insideLocation; + private Location outsideLocation; + + public PremiumHouseDoor(int hotspotId, int doorId, int houseId) { + this.hotspotId = hotspotId; + this.doorId = doorId; + this.houseId = houseId; + } + + public PremiumHouseDoor(int hotspotId, int doorId, int houseId, Location doorLocation) { + this.hotspotId = hotspotId; + this.doorId = doorId; + this.houseId = houseId; + this.doorLocation = doorLocation; + } + + public PremiumHouseDoor(int hotspotId, int doorId, int houseId, Location doorLocation, Location insideLocation, Location outsideLocation) { + this.hotspotId = hotspotId; + this.doorId = doorId; + this.houseId = houseId; + this.doorLocation = doorLocation; + this.insideLocation = insideLocation; + this.outsideLocation = outsideLocation; + } + + public int getHotspotId() { + return hotspotId; + } + + public void setHotspotId(int hotspotId) { + this.hotspotId = hotspotId; + } + + public int getId() { + return this.doorId; + } + + public int getHouseId() { + return this.houseId; + } + + public Location getLocation() { + return this.doorLocation; + } + + public void setLocation(Location doorLocation) { + this.doorLocation = doorLocation; + } + + public Location getInsideLocation() { + return this.insideLocation; + } + + public void setInsideLocation(Location insideLocation) { + this.insideLocation = insideLocation; + } + + public Location getOutsideLocation() { + return this.outsideLocation; + } + + public void setOutsideLocation(Location outsideLocation) { + this.outsideLocation = outsideLocation; + } +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/PremiumHouseGuest.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/PremiumHouseGuest.java new file mode 100644 index 0000000..1f016d6 --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/PremiumHouseGuest.java @@ -0,0 +1,35 @@ +package net.grandtheftmc.houses.houses; + +import java.util.UUID; + +public class PremiumHouseGuest { + + private UUID uuid; + private String name; + + public PremiumHouseGuest(UUID uuid) { + this.uuid = uuid; + } + + public PremiumHouseGuest(UUID uuid, String name) { + this.uuid = uuid; + this.name = name; + } + + public UUID getUuid() { + return this.uuid; + } + + public void setUuid(UUID uuid) { + this.uuid = uuid; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/PremiumHouseTrashcan.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/PremiumHouseTrashcan.java new file mode 100644 index 0000000..d021a93 --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/houses/PremiumHouseTrashcan.java @@ -0,0 +1,69 @@ +package net.grandtheftmc.houses.houses; + +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.houses.HouseUtils; +import net.grandtheftmc.houses.JSONHelper; +import net.grandtheftmc.houses.dao.PremiumHouseDAO; +import org.bukkit.Location; + +import java.sql.Connection; +import java.sql.SQLException; + +public class PremiumHouseTrashcan { + + private int hotspotId; + + private final int trashcanId; + private final int houseId; + private boolean owned = false; + private Location location; + + public PremiumHouseTrashcan(int hotspotId, int trashcanId, int houseId, Location location, boolean owned) { + this.hotspotId = hotspotId; + this.trashcanId = trashcanId; + this.houseId = houseId; + this.location = location; + this.owned = owned; + } + + public int getHotspotId() { + return hotspotId; + } + + public void setHotspotId(int hotspotId) { + this.hotspotId = hotspotId; + } + + public int getId() { + return this.trashcanId; + } + + public int getHouseId() { + return this.houseId; + } + + public Location getLocation() { + return this.location; + } + + public void setLocation(Location location) { + this.location = location; + } + + public boolean isOwned() { + return this.owned; + } + + public void setOwned(boolean owned) { + this.owned = owned; + + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + PremiumHouseDAO.setTrashcanOwned(connection, this.hotspotId, new JSONHelper().put("id", this.trashcanId).put("loc", HouseUtils.locationToString(this.location)).put("owned", owned)); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/BreakBlock.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/BreakBlock.java new file mode 100644 index 0000000..7f6d2c3 --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/BreakBlock.java @@ -0,0 +1,44 @@ +package net.grandtheftmc.houses.listeners; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.houses.*; +import org.bukkit.Material; +import org.bukkit.block.BlockState; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; + +public class BreakBlock implements Listener { + + @EventHandler(priority = EventPriority.HIGH) + public void onBreak(BlockBreakEvent e) { + if (e.isCancelled()) + return; + BlockState block = e.getBlock().getState(); + if (block.getType() != Material.CHEST) + return; + HousesManager hm = Houses.getManager(); + Object[] houseAndChest = hm.getHouseAndChest(block.getLocation()); + if (houseAndChest == null) + return; + e.setCancelled(true); + Player player = e.getPlayer(); + if (houseAndChest[0] instanceof PremiumHouse) { + PremiumHouse house = (PremiumHouse) houseAndChest[0]; + PremiumHouseChest chest = (PremiumHouseChest) houseAndChest[1]; + if (player.hasPermission("houses.admin")) + player.sendMessage(Utils.f(Lang.HOUSES + "&7This PremiumHouseChest with ID &a" + chest.getId() + "&7 belongs to premium house &a" + house.getId() + + "&7! Please remove it with &3/hc remove &a<id>&7 before breaking it!")); + } + House house = (House) houseAndChest[0]; + HouseChest chest = (HouseChest) houseAndChest[1]; + if (player.hasPermission("houses.admin")) + player.sendMessage(Utils.f(Lang.HOUSES + "&7This HouseChest with ID &a" + chest.getId() + "&7 belongs to house &a" + house.getId() + + "&7! Please remove it with &3/hc remove &a<id>&7 before breaking it!")); + } + +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/Chat.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/Chat.java new file mode 100644 index 0000000..189bb5c --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/Chat.java @@ -0,0 +1,63 @@ +package net.grandtheftmc.houses.listeners; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.houses.PremiumHouse; +import net.grandtheftmc.houses.users.HouseUser; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.UUID; + +public class Chat implements Listener { + + @EventHandler(priority = EventPriority.LOW) + public void onChat(AsyncPlayerChatEvent e) { + Player player = e.getPlayer(); + UUID uuid = player.getUniqueId(); + String msg = e.getMessage(); + HouseUser user = Houses.getUserManager().getLoadedUser(uuid); + if (user.isAddingGuest()) { + e.setCancelled(true); + new BukkitRunnable() { + @Override + public void run() { + Player player = Bukkit.getPlayer(uuid); + if (player == null) + return; + + HouseUser user = Houses.getUserManager().getLoadedUser(uuid); + if ("quit".equalsIgnoreCase(msg)) { + player.sendMessage(Utils.f(Lang.HOUSES + "&7You quit adding a guest!")); + user.setMenuHouseId(user.getAddingGuest()); + user.setAddingGuest(-1); + MenuManager.openMenu(player, "guests"); + return; + } + + Player target = Bukkit.getPlayer(msg); + if (target == null) { + player.sendMessage(Utils.f(Lang.HOUSES + "&7That player is not online!")); + user.setMenuHouseId(user.getAddingGuest()); + user.setAddingGuest(-1); + MenuManager.openMenu(player, "guests"); + return; + } + + PremiumHouse house = Houses.getManager().getPremiumHouse(user.getAddingGuest()); + house.addGuest(player, target, user); + user.setMenuHouseId(user.getAddingGuest()); + user.setAddingGuest(-1); + MenuManager.openMenu(player, "guests"); + } + }.runTask(Houses.getInstance()); + } + } +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/Damage.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/Damage.java new file mode 100644 index 0000000..39910a9 --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/Damage.java @@ -0,0 +1,57 @@ +package net.grandtheftmc.houses.listeners; + +import com.j0ach1mmall3.wastedguns.api.events.explosives.ExplosionDamageEntityEvent; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.users.HouseUser; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; + +import java.util.ArrayList; +import java.util.Collection; + +public class Damage implements Listener { + + @EventHandler + public void onExplosionDamage(ExplosionDamageEntityEvent event) { + Collection<LivingEntity> remove = new ArrayList<>(); + event.getVictims().forEach(livingEntity -> { + if(livingEntity.getType() != EntityType.PLAYER) return; + Player target = (Player)livingEntity; + HouseUser houseUser = Houses.getUserManager().getLoadedUser(target.getUniqueId()); + if(houseUser.isInsidePremiumHouse() || houseUser.isInsideHouse()) { + remove.add(livingEntity); + } + }); + event.getVictims().removeAll(remove); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onDamage(EntityDamageEvent event) { + if (event.getEntity().getType() != EntityType.PLAYER) return; + Player player = (Player) event.getEntity(); + HouseUser user = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + if (user.isInsideHouse() || user.isInsidePremiumHouse()) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onEntityDamageEntity(EntityDamageByEntityEvent event) { + if (event.getEntity().getType() != EntityType.PLAYER) return; + if (event.getDamager().getType() != EntityType.PLAYER) return; + + HouseUser victim = Houses.getUserManager().getLoadedUser(event.getEntity().getUniqueId()); + HouseUser attacker = Houses.getUserManager().getLoadedUser(event.getEntity().getUniqueId()); + + if ((victim.isInsideHouse() || victim.isInsidePremiumHouse()) + || (attacker.isInsideHouse() || attacker.isInsidePremiumHouse())) { + event.setCancelled(true); + } + } +} \ No newline at end of file diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/Death.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/Death.java new file mode 100644 index 0000000..0d165a2 --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/Death.java @@ -0,0 +1,21 @@ +package net.grandtheftmc.houses.listeners; + +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.users.HouseUser; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.PlayerDeathEvent; + +public class Death implements Listener { + + @EventHandler + public void onDeath(PlayerDeathEvent e) { + Player player = e.getEntity(); + HouseUser user = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + if (user.isInsideHouse()) { + user.setInsideHouse(-1); + user.updateVisibility(player); + } + } +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/Interact.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/Interact.java new file mode 100644 index 0000000..cf4f61a --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/Interact.java @@ -0,0 +1,714 @@ +package net.grandtheftmc.houses.listeners; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.Collection; +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; + +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.houses.dao.HouseDAO; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.BlockState; +import org.bukkit.block.Chest; +import org.bukkit.block.Sign; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.Inventory; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.gtm.trashcan.TrashCanManager; +import net.grandtheftmc.houses.HouseUtils; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.houses.Blocks; +import net.grandtheftmc.houses.houses.EditableBlock; +import net.grandtheftmc.houses.houses.House; +import net.grandtheftmc.houses.houses.HouseChest; +import net.grandtheftmc.houses.houses.HouseDoor; +import net.grandtheftmc.houses.houses.HousesManager; +import net.grandtheftmc.houses.houses.PremiumHouse; +import net.grandtheftmc.houses.houses.PremiumHouseChest; +import net.grandtheftmc.houses.houses.PremiumHouseDoor; +import net.grandtheftmc.houses.houses.PremiumHouseTrashcan; +import net.grandtheftmc.houses.users.HouseUser; + +public class Interact implements Listener { + + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + protected final void onInteract(PlayerInteractEvent e) { + + if (e.getHand() != EquipmentSlot.HAND) { + return; + } + + Player player = e.getPlayer(); + UUID uuid = player.getUniqueId(); + User u = Core.getUserManager().getLoadedUser(uuid); + if (!u.hasEditMode()) return; + BlockState state = e.getClickedBlock() == null ? null : e.getClickedBlock().getState(); + HousesManager hm = Houses.getManager(); + HouseUser user = Houses.getUserManager().getLoadedUser(uuid); + + if (u.isAdmin() && user.isRemovingDoor() && state != null && state.getType() == Material.IRON_DOOR_BLOCK) { + e.setCancelled(true); + Block underneath = e.getClickedBlock().getRelative(BlockFace.DOWN); + if (underneath.getType() == Material.IRON_DOOR_BLOCK) + state = underneath.getState(); + Location loc = state.getLocation(); + Object[] houseAndDoor = hm.getHouseAndDoor(loc); + if (houseAndDoor == null) { + player.sendMessage(Utils.f(Lang.HOUSES + "&7This door doesn't belong to any house!")); + return; + } + if (houseAndDoor[0] instanceof PremiumHouse) { + PremiumHouse premiumHouse = (PremiumHouse) houseAndDoor[0]; + if (!premiumHouse.equals(user.getEditingPremiumHouse())) { + player.sendMessage(Lang.HOUSES + .f("&7This door does not belong to the house you are editing! It belongs to premium house &a" + + premiumHouse.getId() + "&7!")); + return; + } + PremiumHouseDoor door = (PremiumHouseDoor) houseAndDoor[1]; + premiumHouse.removeDoor(door); + player.sendMessage(Utils.f(Lang.HOUSES + "&7You removed a door with id &a" + door.getId() + + "&7 from premium house &a" + premiumHouse.getId() + "&7.")); + return; + } + House house = (House) houseAndDoor[0]; + if (!house.equals(user.getEditingHouse())) { + player.sendMessage(Utils.f( + Lang.HOUSES + "&7This door does not belong to the house you are editing! It belongs to house &a" + + house.getId() + "&7!")); + return; + } + HouseDoor door = (HouseDoor) houseAndDoor[1]; + house.removeDoor(door); + player.sendMessage(Utils.f(Lang.HOUSES + "&7You removed a door with id &a" + door.getId() + + "&7 from house &a" + house.getId() + "&7.")); + return; + } + + if (u.isAdmin() && (user.isAddingDoor() || user.isAddingPremiumDoor())) { + if (((user.isAddingDoor() && user.getAddingDoor().getLocation() == null) || (user.isAddingPremiumDoor() && user.getAddingPremiumDoor().getLocation() == null)) && state != null && state.getType() == Material.IRON_DOOR_BLOCK) { + e.setCancelled(true); + Block underneath = e.getClickedBlock().getRelative(BlockFace.DOWN); + if (underneath.getType() == Material.IRON_DOOR_BLOCK) + state = underneath.getState(); + Location loc = state.getLocation(); + Object[] houseAndDoor = hm.getHouseAndDoor(loc); + if (houseAndDoor != null) { + if (houseAndDoor[0] instanceof PremiumHouse) { + PremiumHouse house = (PremiumHouse) houseAndDoor[0]; + player.sendMessage(Utils.f(Lang.HOUSES + "&7This door is added to premium house &a" + house.getId() + "&7 already!")); + return; + } + House house = (House) houseAndDoor[0]; + player.sendMessage(Utils.f(Lang.HOUSES + "&7This door is added to house &a" + house.getId() + "&7 already!")); + return; + } + + if (user.isAddingPremiumDoor()) { + PremiumHouseDoor door = user.getAddingPremiumDoor(); + door.setLocation(state.getLocation()); + player.sendMessage(Utils + .f(Lang.HOUSES + "&7You set the door location for premium door &a" + door.getId() + "&7.")); + if (door.getLocation() != null && door.getInsideLocation() != null + && door.getOutsideLocation() != null) { + user.setAddingPremiumDoor(null); + player.sendMessage(Utils.f(Lang.HOUSES + "&7You have completed the setup for door &a" + door.getId() + "&7!")); + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + HouseDAO.updateDoor(connection, door.getHotspotId(), door.getId(), door.getLocation(), door.getInsideLocation(), door.getOutsideLocation()); + } catch (SQLException ex) { + ex.printStackTrace(); + } + }); + } + return; + } + + HouseDoor door = user.getAddingDoor(); + door.setLocation(state.getLocation()); + player.sendMessage(Utils.f(Lang.HOUSES + "&7You set the door location for door &a" + door.getId() + "&7.")); + if (door.getLocation() != null && door.getInsideLocation() != null && door.getOutsideLocation() != null) { + user.setAddingDoor(null); + player.sendMessage(Utils.f(Lang.HOUSES + "&7You have completed the setup for door &a" + door.getId() + "&7!")); + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + HouseDAO.updateDoor(connection, door.getHotspotId(), door.getId(), door.getLocation(), door.getInsideLocation(), door.getOutsideLocation()); + } catch (SQLException ex) { + ex.printStackTrace(); + } + }); + } + + return; + } + switch (e.getAction()) { + case LEFT_CLICK_AIR: + case LEFT_CLICK_BLOCK: { + e.setCancelled(true); + if (user.isAddingPremiumDoor()) { + PremiumHouseDoor door = user.getAddingPremiumDoor(); + door.setInsideLocation(player.getLocation()); + player.sendMessage(Utils.f(Lang.HOUSES + "&7You set the inside location for door &a" + door.getId() + "&7.")); + if (door.getLocation() != null && door.getInsideLocation() != null && door.getOutsideLocation() != null) { + user.setAddingPremiumDoor(null); + player.sendMessage(Utils.f(Lang.HOUSES + "&7You have completed the setup for door &a" + door.getId() + "&7!")); + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + HouseDAO.updateDoor(connection, door.getHotspotId(), door.getId(), door.getLocation(), door.getInsideLocation(), door.getOutsideLocation()); + } catch (SQLException ex) { + ex.printStackTrace(); + } + }); + } + return; + } + HouseDoor door = user.getAddingDoor(); + door.setInsideLocation(player.getLocation()); + player.sendMessage(Utils.f(Lang.HOUSES + "&7You set the inside location for door &a" + door.getId() + "&7.")); + if (door.getLocation() != null && door.getInsideLocation() != null && door.getOutsideLocation() != null) { + user.setAddingDoor(null); + player.sendMessage(Utils.f(Lang.HOUSES + "&7You have completed the setup for door &a" + door.getId() + "&7!")); + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + HouseDAO.updateDoor(connection, door.getHotspotId(), door.getId(), door.getLocation(), door.getInsideLocation(), door.getOutsideLocation()); + } catch (SQLException ex) { + ex.printStackTrace(); + } + }); + } + return; + } + case RIGHT_CLICK_AIR: + case RIGHT_CLICK_BLOCK: + e.setCancelled(true); + if (user.isAddingPremiumDoor()) { + PremiumHouseDoor door = user.getAddingPremiumDoor(); + door.setOutsideLocation(player.getLocation()); + player.sendMessage( + Utils.f(Lang.HOUSES + "&7You set the outside location for door &a" + door.getId() + "&7.")); + if (door.getLocation() != null && door.getInsideLocation() != null + && door.getOutsideLocation() != null) { + user.setAddingPremiumDoor(null); + player.sendMessage(Utils + .f(Lang.HOUSES + "&7You have completed the setup for door &a" + door.getId() + "&7!")); + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + HouseDAO.updateDoor(connection, door.getHotspotId(), door.getId(), door.getLocation(), door.getInsideLocation(), door.getOutsideLocation()); + } catch (SQLException ex) { + ex.printStackTrace(); + } + }); + } + return; + } + HouseDoor door = user.getAddingDoor(); + door.setOutsideLocation(player.getLocation()); + player.sendMessage( + Utils.f(Lang.HOUSES + "&7You set the outside location for door &a" + door.getId() + "&7.")); + if (door.getLocation() != null && door.getInsideLocation() != null + && door.getOutsideLocation() != null) { + user.setAddingDoor(null); + player.sendMessage( + Utils.f(Lang.HOUSES + "&7You have completed the setup for door &a" + door.getId() + "&7!")); + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + HouseDAO.updateDoor(connection, door.getHotspotId(), door.getId(), door.getLocation(), door.getInsideLocation(), door.getOutsideLocation()); + } catch (SQLException ex) { + ex.printStackTrace(); + } + }); + } + return; + default: + return; + } + } + + switch (e.getAction()) { + case RIGHT_CLICK_BLOCK: + if (user.isAddingBlocks()) { + PremiumHouse premiumHouse = user.getEditingPremiumHouse(); + if (!Blocks.getMaterials().contains(e.getClickedBlock().getType())) { + player.sendMessage(Lang.HOUSES.f("&7This block type cannot be added.")); + return; + } + boolean a = false; + for (EditableBlock editableBlock : premiumHouse.getEditableBlocks()) { + if (editableBlock.getLocation().getBlockX() == e.getClickedBlock().getLocation().getBlockX() + && editableBlock.getLocation().getBlockY() == e.getClickedBlock().getLocation().getBlockY() + && editableBlock.getLocation().getBlockZ() == e.getClickedBlock().getLocation().getBlockZ()) { + a = true; + } + } + if (a) { + player.sendMessage(Lang.HOUSES.f("&7Block has already been added!")); + } else { +// EditableBlock editableBlock = new EditableBlock(e.getClickedBlock().getLocation(), e.getClickedBlock().getType(), e.getClickedBlock().getData()); +// premiumHouse.getEditableBlocks().add(editableBlock); +// player.sendMessage(Lang.HOUSES.f("&7Block has been added!")); + + premiumHouse.addEditableBlock(e.getClickedBlock().getLocation(), e.getClickedBlock().getType(), e.getClickedBlock().getData(), result -> { + if (result == null) return; + + ServerUtil.runTask(() -> player.sendMessage(Lang.HOUSES.f("&7Block has been added!"))); + }); + } + return; + } else if (user.isRemovingBlocks()) { + PremiumHouse premiumHouse = user.getEditingPremiumHouse(); + EditableBlock editableBlock = null; + for (EditableBlock block : premiumHouse.getEditableBlocks()) { + if (block.getLocation().getBlockX() == e.getClickedBlock().getLocation().getBlockX() + && block.getLocation().getBlockY() == e.getClickedBlock().getLocation().getBlockY() + && block.getLocation().getBlockZ() == e.getClickedBlock().getLocation().getBlockZ()) { + editableBlock = block; + break; + } + } + if (editableBlock != null) { + premiumHouse.getEditableBlocks().remove(editableBlock); + player.sendMessage(Lang.HOUSES.f("&7Block has been removed.")); + } + return; + } + switch (state.getType()) { + case TRAPPED_CHEST: + case CHEST: { + Chest chestBlock = (Chest) state; + Location loc = chestBlock.getLocation(); + Object[] houseAndChest = hm.getHouseAndChest(loc); + if (user.isAddingChests()) { + e.setCancelled(true); + if (houseAndChest != null) { + if (houseAndChest[0] instanceof PremiumHouse) { + PremiumHouse premiumHouse = (PremiumHouse) houseAndChest[0]; + player.sendMessage(Utils.f(Lang.HOUSES + "&7This chest is added to premium house &a" + + premiumHouse.getId() + "&7 already!")); + return; + } + House house = (House) houseAndChest[0]; + player.sendMessage(Utils + .f(Lang.HOUSES + "&7This chest is added to house &a" + house.getId() + "&7 already!")); + return; + } + Block secondBlock = Utils.getSecondHalfChest(e.getClickedBlock()); + boolean isDub = secondBlock != null; + House house = user.getEditingHouse(); + if (house == null) { + PremiumHouse premiumHouse = user.getEditingPremiumHouse(); + if (premiumHouse == null) { + user.setAddingChests(false); + return; + } + +// PremiumHouseChest chest = premiumHouse.addChest(new PremiumHouseChest(premiumHouse.getUnusedChestId(), premiumHouse.getId(), +// chestBlock.getLocation(), isDub ? secondBlock.getState().getLocation() : null)); +// player.sendMessage(Utils.f(Lang.HOUSES + "&7You have added a" + (isDub ? " double" : "") + " chest with id &a" + chest.getId() + "&7 to premium house &a" + premiumHouse.getId() + "&7.")); + + premiumHouse.addChest(premiumHouse.getUnusedChestId(), premiumHouse.getId(), chestBlock.getLocation(), isDub ? secondBlock.getState().getLocation() : null, result -> { + if (result == null) return; + + ServerUtil.runTask(() -> player.sendMessage(Utils.f(Lang.HOUSES + "&7You have added a" + (isDub ? " double" : "") + " chest with id &a" + result.getId() + "&7 to premium house &a" + premiumHouse.getId() + "&7."))); + }); + return; + } + +// HouseChest chest = house.addChest(new HouseChest(house.getUnusedChestId(), house.getId(), +// chestBlock.getLocation(), isDub ? secondBlock.getState().getLocation() : null)); + + house.addChest(house.getUnusedChestId(), house.getId(), chestBlock.getLocation(), isDub ? secondBlock.getState().getLocation() : null, result -> { + if (result != null) { + ServerUtil.runTask(() -> player.sendMessage(Utils.f(Lang.HOUSES + "&7You have added a" + (isDub ? " double" : "") + " chest with id &a" + result.getId() + "&7 to house &a" + house.getId() + "&7."))); + } + }); + +// player.sendMessage(Utils.f(Lang.HOUSES + "&7You have added a" + (isDub ? " double" : "") +// + " chest with id &a" + chest.getId() + "&7 to house &a" + house.getId() + "&7.")); + return; + } else if (user.isRemovingChests()) { + e.setCancelled(true); + if (houseAndChest == null) { + player.sendMessage(Utils.f(Lang.HOUSES + "&7This chest does not belong to any house!")); + return; + } + if (houseAndChest[0] instanceof PremiumHouse) { + PremiumHouse premiumHouse = (PremiumHouse) houseAndChest[0]; + if (!premiumHouse.equals(user.getEditingPremiumHouse())) { + player.sendMessage(Utils.f(Lang.HOUSES + + "&7This chest does not belong to the house you are editing! It belongs to premium house &a" + + premiumHouse.getId() + "&7!")); + return; + } + PremiumHouseChest chest = (PremiumHouseChest) houseAndChest[1]; + premiumHouse.removeChest(chest); + player.sendMessage(Utils.f(Lang.HOUSES + "&7You removed a chest with id &a" + chest.getId() + + "&7 from premium house &a" + premiumHouse.getId() + "&7.")); + return; + } + House house = (House) houseAndChest[0]; + if (!house.equals(user.getEditingHouse())) { + player.sendMessage(Utils.f(Lang.HOUSES + + "&7This chest does not belong to the house you are editing! It belongs to house &a" + + house.getId() + "&7!")); + return; + } + HouseChest chest = (HouseChest) houseAndChest[1]; + house.removeChest(chest); + player.sendMessage(Utils.f(Lang.HOUSES + "&7You removed a chest with id &a" + chest.getId() + + "&7 from house &a" + house.getId() + "&7.")); + return; + } + return; + } + case DROPPER: { + Location loc = state.getLocation(); + if (user.getEditingPremiumHouse() == null) { + player.sendMessage(Lang.HOUSES.f("&7You must be editing a premium house!")); + return; + } + PremiumHouse premiumHouse = user.getEditingPremiumHouse(); + if (user.isAddingTrashcans()) { + for (PremiumHouseTrashcan trashcan : premiumHouse.getTrashcans()) { + if (trashcan.getLocation().equals(loc)) { + player.sendMessage(Lang.HOUSES.f("&cThis Trashcan has already been added!")); + return; + } + } + int trashcanId = premiumHouse.getTrashcans().size() + 1; +// PremiumHouseTrashcan trashcan = new PremiumHouseTrashcan(trashcanId, premiumHouse.getId(), loc, false); +// premiumHouse.getTrashcans().add(trashcan); +// player.sendMessage(Lang.HOUSES.f("&7Trashcan &a" + trashcanId + " &7has been added to premium house &a" + premiumHouse.getId() + "&7!")); + + premiumHouse.addTrashcan(trashcanId, premiumHouse.getId(), loc, false, result -> { + if (result == null) return; + + ServerUtil.runTask(() -> player.sendMessage(Lang.HOUSES.f("&7Trashcan &a" + trashcanId + " &7has been added to premium house &a" + premiumHouse.getId() + "&7!"))); + }); + + e.setCancelled(true); + } else if (user.isRemovingTrashcans()) { + boolean found = false; + for (PremiumHouseTrashcan trashcan : premiumHouse.getTrashcans()) { + if (trashcan.getLocation().equals(loc)) { + player.sendMessage(Lang.HOUSES.f("&7Trashcan &a" + trashcan.getId() + + " &7has been removed from premium house &a" + premiumHouse.getId() + "&7!")); + premiumHouse.getTrashcans().remove(trashcan); + found = true; + return; + } + } + if (!found) { + player.sendMessage(Lang.HOUSES.f("&cTrashcan is not registered.")); + } + e.setCancelled(true); + } + return; + } + case SIGN_POST: + case WALL_SIGN: + Sign signBlock = (Sign) state; + Location loc = signBlock.getLocation(); + if (user.isAddingSigns()) { + e.setCancelled(true); + House house = hm.getHouseFromSign(loc); + if (house != null) { + player.sendMessage(Utils + .f(Lang.HOUSES + "&7This sign is added to house &a" + house.getId() + "&7 already!")); + return; + } + PremiumHouse premiumHouse = hm.getPremiumHouseFromSign(loc); + if (premiumHouse != null) { + player.sendMessage(Utils.f(Lang.HOUSES + "&7This sign is added to premium house &a" + + premiumHouse.getId() + "&7 already!")); + return; + } + House h = user.getEditingHouse(); + if (h == null) { + PremiumHouse ph = user.getEditingPremiumHouse(); + if (ph == null) { + user.setAddingSigns(false); + return; + } +// ph.addSign(loc); +// player.sendMessage(Utils.f(Lang.HOUSES + "&7You have added a sign to premium house &a" +// + ph.getId() + "&7 at location &a" + Utils.blockLocationToString(loc) + "&7.")); + ph.addSign(loc, result -> { + if (result == null) return; + ServerUtil.runTask(() -> player.sendMessage(Utils.f(Lang.HOUSES + "&7You have added a sign to premium house &a" + ph.getId() + "&7 at location &a" + Utils.blockLocationToString(loc) + "&7."))); + }); + return; + } +// h.addSign(loc); +// player.sendMessage(Utils.f(Lang.HOUSES + "&7You have added a sign to house &a" + h.getId() +// + "&7 at location &a" + Utils.blockLocationToString(loc) + "&7.")); + + h.addSign(loc, result -> { + if (result == null) return; + ServerUtil.runTask(() -> player.sendMessage(Utils.f(Lang.HOUSES + "&7You have added a sign to house &a" + h.getId() + "&7 at location &a" + Utils.blockLocationToString(loc) + "&7."))); + }); + return; + } else if (user.isRemovingSigns()) { + e.setCancelled(true); + House house = hm.getHouseFromSign(loc); + PremiumHouse premiumHouse = hm.getPremiumHouseFromSign(loc); + + if (house == null) { + if (premiumHouse == null) { + player.sendMessage(Utils.f(Lang.HOUSES + "&7This sign does not belong to any house!")); + return; + } + if (!premiumHouse.equals(user.getEditingPremiumHouse())) { + player.sendMessage(Utils.f(Lang.HOUSES + + "&7This sign does not belong to the house you are editing! It belongs to premium house &a" + + premiumHouse.getId() + "&7!")); + return; + } + premiumHouse.removeSign(loc); + player.sendMessage(Utils + .f(Lang.HOUSES + "&7You removed a sign from premium house &a" + premiumHouse.getId() + + "&7 at location &a" + Utils.blockLocationToString(loc) + "&7.")); + return; + } + if (!house.equals(user.getEditingHouse())) { + player.sendMessage(Utils.f(Lang.HOUSES + + "&7This sign does not belong to the house you are editing! It belongs to house &a" + + house.getId() + "&7!")); + return; + } + house.removeSign(loc); + player.sendMessage(Utils.f(Lang.HOUSES + "&7You removed a sign from house &a" + house.getId() + + "&7 at location &a" + Utils.blockLocationToString(loc) + "&7.")); + return; + } + return; + + default: + break; + } + default: + break; + } + } + + @EventHandler + public void onOpenChest(PlayerInteractEvent e) { + if (e.isCancelled()) return; + if (e.getHand() != EquipmentSlot.HAND) return; + + Player player = e.getPlayer(); + UUID uuid = player.getUniqueId(); + BlockState state = e.getClickedBlock().getState(); + HousesManager hm = Houses.getManager(); + HouseUser user = Houses.getUserManager().getLoadedUser(uuid); + switch (e.getAction()) { + case RIGHT_CLICK_BLOCK: + switch (state.getType()) { + case TRAPPED_CHEST: + case CHEST: { + Chest chestBlock = (Chest) state; + Location loc = chestBlock.getLocation(); + Object[] houseAndChest = hm.getHouseAndChest(loc); + if (houseAndChest == null) { +// e.setCancelled(true); +// player.sendMessage(Utils.f(Lang.HOUSES + "&7This house is having issues loading (&ferr2937&7)!")); + return; + } + + if (houseAndChest[0] instanceof PremiumHouse) { + PremiumHouse house = (PremiumHouse) houseAndChest[0]; + if (!house.hasAccess(player, user)) { + e.setCancelled(true); + player.sendMessage(Utils.f(Lang.HOUSES + "&7You don't own this premium house!")); + return; + } + user.setOpenChest(houseAndChest[1]); + return; + } + House house = (House) houseAndChest[0]; + e.setCancelled(true); + + if(!user.isInsidePremiumHouse() && !user.isInsideHouse()) { + player.sendMessage(Lang.HOUSES.f("&cError opening chest, Leave your house and re-enter to try again!")); + return; + } + + HouseChest chest = (HouseChest) houseAndChest[1]; + + user.setLastChestId(chest == null ? -1 : chest.getId()); + user.setOpenChest(chest); + house.openChest(player, loc, user, chest); + return; + } + case IRON_DOOR_BLOCK: { + Block underneath = e.getClickedBlock().getRelative(BlockFace.DOWN); + if (underneath.getType() == Material.IRON_DOOR_BLOCK) + state = underneath.getState(); + Location loc = state.getLocation(); + Object[] houseAndDoor = hm.getHouseAndDoor(loc); + if (houseAndDoor == null) + return; + if (houseAndDoor[0] instanceof PremiumHouse) { + PremiumHouse house = (PremiumHouse) houseAndDoor[0]; + if (user.isTeleporting()) + return; + if (!house.hasAccess(player, user) || player.isSneaking()) { + HouseUtils.openPremiumHouseMenu(player, house, user); + return; + } + PremiumHouseDoor door = (PremiumHouseDoor) houseAndDoor[1]; + user.teleportInOrOutPremiumHouse(player, door); + return; + } + House house = (House) houseAndDoor[0]; + if (!user.ownsHouse(house.getId())) { + HouseUtils.openHouseMenu(player, house, user); + return; + } + if (user.isTeleporting()) + return; + if (player.isSneaking()) { + HouseUtils.openHouseMenu(player, house, user); + return; + } + HouseDoor door = (HouseDoor) houseAndDoor[1]; + user.teleportInOrOutHouse(player, door); + return; + } + case SIGN: + case SIGN_POST: + case WALL_SIGN: { + Sign signBlock = (Sign) state; + Location loc = signBlock.getLocation(); + House house = hm.getHouseFromSign(loc); + if (house != null) { + HouseUtils.openHouseMenu(player, house, user); + } + PremiumHouse premiumHouse = hm.getPremiumHouseFromSign(loc); + if (premiumHouse != null) { + HouseUtils.openPremiumHouseMenu(player, premiumHouse, user); + } + return; + } + case DROPPER: { + Location location = state.getLocation(); + if (!user.isInsidePremiumHouse()) return; + PremiumHouse premiumHouse = Houses.getHousesManager().getPremiumHouse(user.getInsidePremiumHouse()); + if (Objects.equals(premiumHouse.getOwner(), player.getUniqueId()) + || premiumHouse.isGuest(player.getUniqueId())) { + Optional<PremiumHouseTrashcan> trashcanOptional = premiumHouse.getTrashcan(location); + PremiumHouseTrashcan trashcan = null; + if (!trashcanOptional.isPresent()) { + int trashcanId = premiumHouse.getTrashcans().size() + 1; +// trashcan = new PremiumHouseTrashcan(trashcanId, premiumHouse.getId(), location, false); +// premiumHouse.getTrashcans().add(trashcan); + + premiumHouse.addTrashcan(trashcanId, premiumHouse.getId(), location, false, result -> { + if (result == null) return; + ServerUtil.runTask(() -> result.setOwned(true)); + }); + } else { + trashcan = trashcanOptional.get(); + } + + if (trashcan == null) return; + + user.setOpenTrashcan(trashcan); + e.setCancelled(true); + player.closeInventory(); + if (trashcan.isOwned()) { + TrashCanManager.openTrashCan(player); + } else { + MenuManager.openMenu(player, "buytrashcan"); + } + } else { + player.sendMessage(Lang.HOUSES.f("&7You do not have access to this trashcan!")); + } + return; + } + default: + break; + } + default: + break; + } + } + + @EventHandler + public void onClose(InventoryCloseEvent e) { + Player player = (Player) e.getPlayer(); + HouseUser houseUser = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + Inventory inv = e.getInventory(); + Collection<String> invNames = Arrays.asList("Trash Can", "Confirm Trashcan Purchase"); + if (e.getInventory().getType() != InventoryType.CHEST + || !invNames.contains(ChatColor.stripColor(inv.getTitle()))) + return; + houseUser.setOpenTrashcan(null); + } + + + @EventHandler + public void onInteractEntity(PlayerInteractEntityEvent e) { + Player player = e.getPlayer(); + HouseUser user = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + if (user.isInsideHouse() || user.isInsidePremiumHouse()) + e.setCancelled(true); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onBlockClick(PlayerInteractEvent event) { + Player player = event.getPlayer(); + if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return; + if (event.getClickedBlock() == null) return; + if (!Blocks.getMaterials().contains(event.getClickedBlock().getType())) return; + UUID uuid = player.getUniqueId(); + HouseUser houseUser = Houses.getUserManager().getLoadedUser(uuid); + if (!houseUser.isChangingBlocks()) return; + if (!houseUser.isInsidePremiumHouse()) return; + PremiumHouse premiumHouse = houseUser.getPremiumHouse(houseUser.getInsidePremiumHouse()); + if (!premiumHouse.getOwnerName().equalsIgnoreCase(player.getName())) return; + boolean a = false; + for (EditableBlock editableBlock : premiumHouse.getEditableBlocks()) { + if (editableBlock.getLocation().getBlockX() == event.getClickedBlock().getLocation().getBlockX() + && editableBlock.getLocation().getBlockY() == event.getClickedBlock().getLocation().getBlockY() + && editableBlock.getLocation().getBlockZ() == event.getClickedBlock().getLocation().getBlockZ()) { + a = true; + } + } + if (!a) { + player.sendMessage(Lang.HOUSES.f("&7This block cannot be changed!")); + } else { + houseUser.setEditingBlock(event.getClickedBlock()); + if (player.isSneaking() && houseUser.getLastUsedMaterial() != null) { + Blocks lastUsed = houseUser.getLastUsedMaterial(); + houseUser.getEditingBlock().setType(lastUsed.getType()); + houseUser.getEditingBlock().setData(lastUsed.getData()); + houseUser.setEditingBlock(null); + player.sendMessage(Lang.HOUSES.f("&7Block has been set to &a" + lastUsed.getType().name() + "&7!")); + return; + } + HouseUtils.openChangeBlocksMenu(player, premiumHouse, houseUser); + } + } +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/InventoryClose.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/InventoryClose.java new file mode 100644 index 0000000..b656e05 --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/InventoryClose.java @@ -0,0 +1,85 @@ +package net.grandtheftmc.houses.listeners; + +import java.util.Arrays; +import java.util.UUID; + +import org.bukkit.ChatColor; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; + +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.houses.House; +import net.grandtheftmc.houses.houses.HouseChest; +import net.grandtheftmc.houses.houses.HousesManager; +import net.grandtheftmc.houses.users.HouseUser; +import net.grandtheftmc.houses.users.UserHouse; +import net.grandtheftmc.houses.users.UserHouseChest; + +public class InventoryClose implements Listener { + + @EventHandler + public void onClose(InventoryCloseEvent e) { + Inventory inv = e.getInventory(); + if (inv.getType() != InventoryType.CHEST) + return; + Player player = (Player) e.getPlayer(); + UUID uuid = player.getUniqueId(); + String title = ChatColor.stripColor(inv.getTitle()).replace("Chest: ", ""); + String[] ids = title.split(","); + if (ids.length != 2) + return; + int houseId; + int chestId; + try { + houseId = Integer.parseInt(ids[0]); + chestId = Integer.parseInt(ids[1]); + } catch (NumberFormatException ex) { + return; + } + HousesManager hm = Houses.getManager(); + House house = hm.getHouse(houseId); + if (house == null) + return; + HouseChest chest = house.getChest(chestId); + if (chest == null) + return; + HouseUser user = Houses.getUserManager().getLoadedUser(uuid); + UserHouse userHouse = user.getUserHouse(houseId); + if (userHouse == null) + return; + UserHouseChest userChest = userHouse.getChest(chestId); + if (userChest == null || Arrays.equals(userChest.getContents(), inv.getContents())) + return; + userChest.setContents(inv.getContents()); + user.setOpenChest(null); + // userChest.updateContents(uuid); + Utils.playChestAnimation(player, chest.getLoc1(), false); + } + + @EventHandler + public void onChestClose(InventoryCloseEvent e) { + Inventory inv = e.getInventory(); + HumanEntity entity = e.getPlayer(); + + if (inv.getType() != InventoryType.CHEST) { + return; + } + + if (!(entity instanceof Player)) { + return; + } + + Player player = (Player) entity; + HouseUser user = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + + if (user.hasChestOpen()) { + user.setOpenChest(null); + } + } +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/InventoryInteract.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/InventoryInteract.java new file mode 100644 index 0000000..356ec3f --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/InventoryInteract.java @@ -0,0 +1,84 @@ +package net.grandtheftmc.houses.listeners; + +import org.bukkit.Location; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryDragEvent; +import org.bukkit.event.inventory.InventoryInteractEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; + +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.houses.House; +import net.grandtheftmc.houses.houses.HouseChest; +import net.grandtheftmc.houses.houses.HousesManager; +import net.grandtheftmc.houses.houses.PremiumHouse; +import net.grandtheftmc.houses.houses.PremiumHouseChest; +import net.grandtheftmc.houses.users.HouseUser; + +public class InventoryInteract implements Listener { + @EventHandler + private void onInventoryClick(InventoryClickEvent event) { + this.onInventoryInteract(event); + } + + @EventHandler + private void onInventoryDrag(InventoryDragEvent event) { + this.onInventoryInteract(event); + } + + @EventHandler + private void onInventoryInteract(InventoryInteractEvent event) { + Inventory inv = event.getInventory(); + HumanEntity entity = event.getWhoClicked(); + + if (inv.getType() != InventoryType.CHEST) { + return; + } + + if (!(entity instanceof Player)) { + return; + } + + if(inv.getLocation() == null) { + return; + } + + Player player = (Player) entity; + HousesManager hm = Houses.getManager(); + Object[] houseAndChest = hm.getHouseAndChest(new Location(inv.getLocation().getWorld(), inv.getLocation().getBlockX(), inv.getLocation().getBlockY(), inv.getLocation().getBlockZ())); + + if (houseAndChest == null || houseAndChest[0] == null || houseAndChest[1] == null) { + return; + } + + if (houseAndChest[0] instanceof PremiumHouse) { + this.managePremiumHouse(event, player, (PremiumHouse) houseAndChest[0], (PremiumHouseChest) houseAndChest[1]); + } else { + this.manageHouse(event, player, (House) houseAndChest[0], (HouseChest) houseAndChest[1]); + } + } + + private void managePremiumHouse(InventoryInteractEvent event, Player player, PremiumHouse house, PremiumHouseChest chest) { + HouseUser user = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + + if (user.hasChestOpen() && user.getOpenChest() == chest) { + return; + } + + event.setCancelled(true); + } + + private void manageHouse(InventoryInteractEvent event, Player player, House house, HouseChest chest) { + HouseUser user = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + + if (user.hasChestOpen() && user.getOpenChest() == chest) { + return; + } + + event.setCancelled(true); + } +} \ No newline at end of file diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/Join.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/Join.java new file mode 100644 index 0000000..6f78eaa --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/Join.java @@ -0,0 +1,20 @@ +package net.grandtheftmc.houses.listeners; + +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.users.HouseUser; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; + +public class Join implements Listener { + + @EventHandler + public void onJoin(PlayerJoinEvent e) { + Player player = e.getPlayer(); + HouseUser user = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + user.updateVisibility(player); + + user.loadChests((call) -> {}); + } +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/Leave.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/Leave.java new file mode 100644 index 0000000..c3850af --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/Leave.java @@ -0,0 +1,45 @@ +package net.grandtheftmc.houses.listeners; + +import net.grandtheftmc.houses.houses.House; +import net.grandtheftmc.houses.houses.PremiumHouse; +import net.grandtheftmc.houses.houses.PremiumHouseChest; +import net.grandtheftmc.houses.users.UserHouse; +import net.grandtheftmc.houses.users.UserHouseChest; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.potion.PotionEffectType; + +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.users.HouseUser; + +public class Leave implements Listener { + + @EventHandler + public void onLeave(PlayerQuitEvent e) { + Player player = e.getPlayer(); + HouseUser user = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + if (user.isTeleporting()) { + user.setTeleporting(false); + player.removePotionEffect(PotionEffectType.BLINDNESS); + } + if (user.isInsideHouse() || user.isInsidePremiumHouse()) { + player.teleport(GTM.getWarpManager().getSpawn().getLocation()); + } + + for(UserHouse userHouse : user.getHouses()) { + for(UserHouseChest chest : userHouse.getChests()) { + chest.updateContents(player.getUniqueId(), userHouse.getUniqueId()); + } + } + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onLeaveMonitor(PlayerQuitEvent e) { + Houses.getUserManager().unloadUser(e.getPlayer().getUniqueId()); + } + +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/Login.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/Login.java new file mode 100644 index 0000000..fffe688 --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/Login.java @@ -0,0 +1,43 @@ +package net.grandtheftmc.houses.listeners; + +import java.util.UUID; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerPreLoginEvent; +import org.bukkit.event.player.PlayerLoginEvent; +import org.bukkit.event.player.PlayerLoginEvent.Result; +import org.bukkit.plugin.java.JavaPlugin; + +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.users.HouseUser; + +public class Login implements Listener { + + public Login(JavaPlugin plugin) { + } + + @EventHandler + public void onAsyncLogin(AsyncPlayerPreLoginEvent e) { + HouseUser user = Houses.getUserManager().getLoadedUser(e.getUniqueId()); +// user.dataCheck(e.getName()); + if (!user.updateDataFromDb()) + e.disallow(org.bukkit.event.player.AsyncPlayerPreLoginEvent.Result.KICK_OTHER, "&cAn error occured while trying to fetch your data from the database. Please try again in a few seconds!"); + } + + @EventHandler(priority=EventPriority.MONITOR) + public void onLoginMonitor(PlayerLoginEvent e) { + Player player = e.getPlayer(); + UUID uuid = player.getUniqueId(); + HouseUser user = Houses.getUserManager().getLoadedUser(uuid); + + if (!user.hasUpdated()) + e.disallow(PlayerLoginEvent.Result.KICK_OTHER, Utils.f("&cThe server is still restarting! Please try again in a few seconds!")); + + if (e.getResult() != Result.ALLOWED) + Houses.getUserManager().unloadUser(uuid); + } +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/MenuListener.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/MenuListener.java new file mode 100644 index 0000000..7d0a528 --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/MenuListener.java @@ -0,0 +1,704 @@ +package net.grandtheftmc.houses.listeners; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.menus.Menu; +import net.grandtheftmc.core.menus.MenuClickEvent; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.menus.MenuOpenEvent; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.houses.*; +import net.grandtheftmc.houses.users.HouseUser; +import net.grandtheftmc.houses.users.UserHouse; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Color; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import java.util.*; + +public class MenuListener implements Listener { + + public void setPhoneDefaults(MenuOpenEvent e) { + ItemStack whiteGlass = Utils.createItem(Material.STAINED_GLASS_PANE, "&a"); + ItemStack grayGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a"); + ItemStack blackGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 15, "&a"); + ItemStack lightGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 8, "&a"); + + for (int i : new int[]{0, 8, 9, 17, 18, 26, 27, 35, 36, 44, 45, 53}) e.setItem(i, lightGlass); + for (int i : new int[]{1, 10, 19, 28, 37, 46, 7, 16, 25, 34, 43, 52}) + e.setItem(i, whiteGlass); + for (int i : new int[]{2, 3, 4, 5, 6}) + e.setItem(i, blackGlass); + for (int i : new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42, 47, 48, 49, 50, 51}) + e.setItem(i, grayGlass); + } + + public void setPhoneDefaults(Inventory inv) { + ItemStack whiteGlass = Utils.createItem(Material.STAINED_GLASS_PANE, "&a"); + ItemStack grayGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a"); + ItemStack blackGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 15, "&a"); + ItemStack lightGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 8, "&a"); + + for (int i : new int[]{0, 8, 9, 17, 18, 26, 27, 35, 36, 44, 45, 53}) inv.setItem(i, lightGlass); + for (int i : new int[]{1, 10, 19, 28, 37, 46, 7, 16, 25, 34, 43, 52}) + inv.setItem(i, whiteGlass); + for (int i : new int[]{2, 3, 4, 5, 6}) + inv.setItem(i, blackGlass); + for (int i : new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42, 47, 48, 49, 50, 51}) + inv.setItem(i, grayGlass); + } + + public void setConfirmDefaults(MenuOpenEvent e) { + this.setConfirmDefaults(e, "&a&lConfirm", "&c&lCancel"); + } + + public void setConfirmDefaults(MenuOpenEvent e, String confirmMessage, String cancelMessage) { + ItemStack whiteGlass = Utils.createItem(Material.STAINED_GLASS_PANE, "&a"); + ItemStack grayGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a"); + ItemStack blackGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 15, "&a"); + ItemStack greenGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 5, confirmMessage); + ItemStack redGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 14, cancelMessage); + ItemStack lightGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 8, "&a"); + + for (int i : new int[]{0, 8, 9, 17, 18, 26, 27, 35, 36, 44, 45, 53}) e.setItem(i, lightGlass); + for (int i : new int[]{1, 10, 19, 28, 37, 46, 7, 16, 25, 34, 43, 52}) + e.setItem(i, whiteGlass); + for (int i : new int[]{2, 3, 4, 5, 6}) + e.setItem(i, blackGlass); + for (int i : new int[]{13, 22, 31, 40, 49,}) + e.setItem(i, grayGlass); + for (int i : new int[]{11, 12, 20, 21, 29, 30, 38, 39, 47, 48}) + e.setItem(i, greenGlass); + for (int i : new int[]{14, 15, 23, 24, 32, 33, 41, 42, 50, 51}) + e.setItem(i, redGlass); + } + + @EventHandler + public void onMenuOpen(MenuOpenEvent e) { + Player player = e.getPlayer(); + UUID uuid = player.getUniqueId(); + Menu menu = e.getMenu(); + switch (menu.getName()) { + case "houses": { + this.setPhoneDefaults(e); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42, 47, 48, 49, 50, 51}; + HouseUser user = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + List<UserHouse> houses = user.getHouses(); + List<PremiumHouse> premiumHouses = user.getPremiumHousesAsGuest(); + Iterator<UserHouse> it = houses.iterator(); + Iterator<PremiumHouse> it2 = premiumHouses.iterator(); + int size = houses.size() + premiumHouses.size(); + int max = user.getMaxHouses(player, Core.getUserManager().getLoadedUser(uuid), GTM.getUserManager().getLoadedUser(uuid)); + for (int i = 0; i < 20; i++) { + PremiumHouse premiumHouse = it.hasNext() ? null : it2.hasNext() ? it2.next() : null; + UserHouse userHouse = it.hasNext() ? it.next() : null; + if (premiumHouse == null && userHouse == null) + break; + if (premiumHouse != null) { + e.setItem(slots[i], + Utils.addGlow(Utils.createItem(Material.IRON_DOOR, "&3&lPremium House: &a&l" + premiumHouse.getId(), + Arrays.asList("&7Permits: &a&l" + premiumHouse.getPermits(), "&7Chests: &a&l" + premiumHouse.getChests().size(), + "&7Owned by &a" + (player.getUniqueId().equals(premiumHouse.getOwner()) ? "me" : premiumHouse.getOwnerName()) + "&7.")))); + continue; + } + House house = Houses.getHousesManager().getHouse(userHouse.getId()); + e.setItem(slots[i], Utils.createItem(Material.IRON_DOOR, "&3&lHouse: &a&l" + house.getId(), + Arrays.asList("&7Price: &a$&l" + house.getPrice(), "&7Chests: &a&l" + house.getChests().size()))); + } + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the home page!")); + e.setItem(49, Utils.setArmorColor(Utils.createItem(Material.IRON_DOOR, "&3&lMy Houses", "&7Click on a house to open its menu!"), Color.fromRGB(102, 127, 51))); + if (size > 20) + e.setItem(50, Utils.createItem(Material.ARROW, "&3&lNext Page", "&7Page 2")); + e.setItem(51, Utils.createItem(Material.BOOK, "&3&lMax Houses: &a&l" + size + "&7/&a&l" + max, + size >= max ? "&7Go to &a" + Core.getSettings().getStoreLink() + "&7 to get access to more houses!" : "&7You can own &a" + (max - size) + "&7 more houses!")); + return; + } + case "house": { + HouseUser user = Houses.getUserManager().getLoadedUser(uuid); + int id = user.getMenuHouseId(); + House house = Houses.getManager().getHouse(id); + this.setPhoneDefaults(e); + e.setItem(11, Utils.createItem(Material.CHEST, "&3&lChests: &a&l" + house.getAmountOfChests())); + e.setItem(13, Utils.createItem(Material.PAPER, "&3&lPrice: &a$&l" + house.getPrice())); + e.setItem(15, Utils.createItem(Material.DARK_OAK_DOOR_ITEM, "&3&lDoors: &a&l" + house.getDoors().size())); + if (user.ownsHouse(house.getId())) + e.setItem(31, Utils.createItem(Material.INK_SACK, 1, "&c&lSell House", Collections.singletonList("&7Reward: &a$&l" + (house.getPrice() / 2)))); + else + e.setItem(31, Utils.createItem(Material.SLIME_BALL, "&a&lBuy House", Collections.singletonList("&7Price: &a$&l" + house.getPrice()))); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the houses menu!")); + e.setItem(49, Utils.createItem(Material.IRON_DOOR, "&3&lHouse: &a&l" + id, "&7A place to crash!")); + int size = user.getHouses().size() + user.getPremiumHousesAsGuest().size(); + int max = user.getMaxHouses(player, Core.getUserManager().getLoadedUser(uuid), GTM.getUserManager().getLoadedUser(uuid)); + e.setItem(51, Utils.createItem(Material.BOOK, "&3&lMax Houses: &a&l" + size + "&7/&a&l" + max, + size >= max ? "&7Go to &a" + Core.getSettings().getStoreLink() + "&7 to get access to more houses!" : "&7You can own &a" + (max - size) + "&7 more houses!")); + return; + } + case "premiumhouse": { + HouseUser user = Houses.getUserManager().getLoadedUser(uuid); + int id = user.getMenuHouseId(); + PremiumHouse house = Houses.getManager().getPremiumHouse(id); + this.setPhoneDefaults(e); + + e.setItem(11, Utils.createItem(Material.CHEST, "&3&lChests: &a&l" + house.getAmountOfChests())); + e.setItem(13, Utils.createItem(Material.PAINTING, "&3&lPermits: &a&l" + house.getPermits(), + "&7You have &a&l" + GTM.getUserManager().getLoadedUser(uuid).getPermits() + "&7 Permits!")); + e.setItem(15, Utils.createItem(Material.IRON_DOOR, "&3&lDoors: &a&l" + house.getDoors().size())); + if (!house.getEditableBlocks().isEmpty()) { + e.setItem(29, Utils.createItem(Material.SNOW_BLOCK, "&3&lCustomize House")); + } + if (!house.isOwned()) + e.setItem(31, Utils.createItem(Material.SLIME_BALL, "&a&lBuy House", Collections.singletonList("&7Price: &a&l" + house.getPermits() + " Permits"))); + else if (player.getUniqueId().equals(house.getOwner())) + e.setItem(31, Utils.createItem(Material.INK_SACK, 1, "&c&lSell House", Collections.singletonList("&7Reward: &a&l" + house.getPermits() + " Permits"))); + else + e.setItem(31, Utils.setSkullOwner(Utils.createItem(Material.SKULL_ITEM, "&3&lOwner: &a&l" + house.getOwnerName()), house.getOwnerName())); + e.setItem(33, Utils.createItem(Material.TRIPWIRE_HOOK, "&3&lView Guests")); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the houses menu!")); + e.setItem(49, Utils.createItem(Material.IRON_DOOR, "&3&lPremium House: &a&l" + id, "&7A place to crash!")); + int size = user.getHouses().size() + user.getPremiumHousesAsGuest().size(); + int max = user.getMaxHouses(player, Core.getUserManager().getLoadedUser(uuid), GTM.getUserManager().getLoadedUser(uuid)); + e.setItem(51, Utils.createItem(Material.BOOK, "&3&lMax Houses: &a&l" + size + "&7/&a" + max, + size >= max ? "&7Go to &a" + Core.getSettings().getStoreLink() + "&7 to get access to more houses!" : "&7You can own &a" + (max - size) + "&7 more houses!")); + return; + } + case "buyhouse": + this.setConfirmDefaults(e, "&a&lClick to buy this house!", "&c&lClick to cancel!"); + return; + case "sellhouse": + this.setConfirmDefaults(e, "&a&lClick to sell this house!", "&c&lClick to cancel!"); + return; + case "buypremiumhouse": + this.setConfirmDefaults(e, "&a&lClick to buy this premium house!", "&c&lClick to cancel!"); + return; + case "sellpremiumhouse": + this.setConfirmDefaults(e, "&a&lClick to sell this premium house!", "&c&lClick to cancel!"); + return; + case "guests": { + this.setPhoneDefaults(e); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42, 47, 48, 49, 50, 51}; + HouseUser user = Houses.getUserManager().getLoadedUser(uuid); + int id = user.getMenuHouseId(); + PremiumHouse house = Houses.getManager().getPremiumHouse(id); + List<PremiumHouseGuest> guests = house.getGuests(); + Iterator<PremiumHouseGuest> it = guests.iterator(); + for (int i = 0; i < 20; i++) { + if (!it.hasNext()) + break; + PremiumHouseGuest guest = it.next(); + e.setItem(slots[i], Utils.setSkullOwner(Utils.createItem(Material.SKULL_ITEM, 2, "&3&l" + guest.getName()), guest.getName())); + } + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the premium house menu!")); + if (house.isOwner(uuid)) { + e.setItem(49, Utils.createItem(Material.SLIME_BALL, "&a&lAdd Guest")); + e.setItem(51, Utils.createItem(Material.INK_SACK, 1, "&c&lRemove Guest")); + } + if (guests.size() > 20) + e.setItem(50, Utils.createItem(Material.ARROW, "&3&lNext Page", "&7Page 2")); + return; + } + case "removeguests": { + this.setPhoneDefaults(e); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42, 47, 48, 49, 50, 51}; + HouseUser user = Houses.getUserManager().getLoadedUser(uuid); + int id = user.getMenuHouseId(); + PremiumHouse house = Houses.getManager().getPremiumHouse(id); + List<PremiumHouseGuest> guests = house.getGuests(); + Iterator<PremiumHouseGuest> it = guests.iterator(); + for (int i = 0; i < 20; i++) { + if (!it.hasNext()) + break; + PremiumHouseGuest guest = it.next(); + e.setItem(slots[i], Utils.setSkullOwner(Utils.createItem(Material.SKULL_ITEM, 2, "&3&l" + guest.getName(), "&7Click to remove!"), guest.getName())); + } + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the premium house menu!")); + e.setItem(49, Utils.createItem(Material.SLIME_BALL, "&a&lAdd Guest")); + e.setItem(51, Utils.createItem(Material.INK_SACK, 1, "&c&lStop Removing Guests")); + if (guests.size() > 20) + e.setItem(50, Utils.createItem(Material.ARROW, "&3&lNext Page", "&7Page 2")); + return; + } + case "houseshelp": { + this.setPhoneDefaults(e); + e.setItem(11, Utils.createItem(Material.EMPTY_MAP, "&3&lWhat are houses?", "", "&7A house is a safezone where you can store items in chests.")); + e.setItem(12, Utils.createItem(Material.EMPTY_MAP, "&3&lCan I share my house with someone?", "", "&7Multiple people can buy the same house.", + "&7Inside of the house, everyone is invisible", "&7and the chests are unique to every owner.")); + e.setItem(13, Utils.createItem(Material.EMPTY_MAP, "&3&lWhat's so special about Premium Houses?", "", "&7The owner of a Premium House can add guests to it", + "&7who can also open the chests!")); + e.setItem(14, Utils.createItem(Material.EMPTY_MAP, "&3&lHow can I buy a Premium House?", "", "&7Premium Houses can only be purchased through donating.", + "&7Get House Permits at &a" + Core.getSettings().getStoreLink() + "&7", "&7to buy a Premium House!")); + e.setItem(15, Utils.createItem(Material.EMPTY_MAP, "&3&lHow many houses can I buy?", "", "&7Ranking up gets you access to more houses,", + "&7as well as getting a donor rank at &a" + Core.getSettings().getStoreLink() + "&7!")); + e.setItem(20, Utils.createItem(Material.EMPTY_MAP, "&3&lFor how long do I get to keep my house?", "", "&7After you buy it, you can keep it forever!")); + e.setItem(21, Utils.createItem(Material.EMPTY_MAP, "&3&lDo I get my money back when I sell a house?", "", "&7When you sell a house, you get back half of the price.", + "&7If you sell a Premium House, all of the Permits will get refunded!")); + e.setItem(22, Utils.createItem(Material.EMPTY_MAP, "&3&lCan I give my permits to someone else?", "", "&7No, you may not. Sorry!")); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the houses menu!")); + return; + } + case "editblocks": { + int count = -1; + for (Blocks material : Blocks.values()) { + if (count == 53) break; + count += 1; + ItemStack itemStack = new ItemStack(material.getType()); + itemStack.setDurability(material.getData()); + e.setItem(count, itemStack); + } + return; + } + case "buytrashcan": { + HouseUser user = Houses.getUserManager().getLoadedUser(uuid); + PremiumHouseTrashcan trashcan = user.getOpenTrashcan(); + PremiumHouse house = Houses.getHousesManager().getPremiumHouse(user.getInsidePremiumHouse()); + this.setPhoneDefaults(e); + + e.setItem(11, Utils.createItem(Material.CHEST, "&3&lChests: &a&l" + house.getAmountOfChests())); + e.setItem(13, Utils.createItem(Material.PAINTING, "&3&lPermits: &a&l" + house.getPermits(), + "&7You have &a&l" + GTM.getUserManager().getLoadedUser(uuid).getPermits() + "&7 Permits!")); + e.setItem(15, Utils.createItem(Material.IRON_DOOR, "&3&lDoors: &a&l" + house.getDoors().size())); + + e.setItem(31, Utils.createItem(Material.SLIME_BALL, "&a&lBuy Trashcan", Collections.singletonList("&7Price: &a&l5 Permits"))); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Close this menu")); + e.setItem(49, Utils.createItem(Material.DROPPER, "&3&lTrash Can: &a&l" + trashcan.getId(), "&7Sell your loot!")); + + int size = user.getHouses().size() + user.getPremiumHousesAsGuest().size(); + int max = user.getMaxHouses(player, Core.getUserManager().getLoadedUser(uuid), GTM.getUserManager().getLoadedUser(uuid)); + e.setItem(51, Utils.createItem(Material.BOOK, "&3&lMax Houses: &a&l" + size + "&7/&a" + max, + size >= max ? "&7Go to &a" + Core.getSettings().getStoreLink() + "&7 to get access to more houses!" : "&7You can own &a" + (max - size) + "&7 more houses!")); + return; + } + case "confirmtrashcanbuy": { + this.setConfirmDefaults(e, "&a&lClick to buy this Trash Can for 5 permits", "&c&lClick to cancel!"); + return; + } + default: + break; + } + } + + @EventHandler + public void onMenuClick(MenuClickEvent e) { + Player player = e.getPlayer(); + UUID uuid = player.getUniqueId(); + Menu menu = e.getMenu(); + ItemStack item = e.getItem(); + Inventory inv = e.getInv(); + HouseUser user = Houses.getUserManager().getLoadedUser(uuid); + switch (menu.getName()) { + case "houses": + if (item == null) + return; + switch (item.getType()) { + case REDSTONE: + MenuManager.openMenu(player, "phone"); + return; + case IRON_DOOR: + String s = ChatColor.stripColor(item.getItemMeta().getDisplayName()); + if ("Find House".equals(s)) + return; + if (s.startsWith("Premium House: ")) { + int id; + try { + id = Integer.parseInt(s.replace("Premium House: ", "")); + } catch (NumberFormatException e1) { + player.sendMessage(Utils.f(Lang.HOUSES + "&7That House ID is invalid!")); + return; + } + PremiumHouse house = Houses.getHousesManager().getPremiumHouse(id); + if (house == null) { + player.sendMessage(Lang.HOUSES.f("&7That premium house does not exist!")); + return; + } + user.setMenuHouseId(house.getId()); + MenuManager.openMenu(player, "premiumhouse"); + return; + } else if (s.startsWith("House: ")) { + int id; + try { + id = Integer.parseInt(s.replace("House: ", "")); + } catch (NumberFormatException ex) { + player.sendMessage(Utils.f(Lang.HOUSES + "&7That House ID is invalid!")); + return; + } + House house = Houses.getHousesManager().getHouse(id); + if (house == null) { + player.sendMessage(Lang.HOUSES.f("&7That house does not exist!")); + return; + } + user.setMenuHouseId(house.getId()); + MenuManager.openMenu(player, "house"); + return; + } + return; + case ARROW: + int page = Integer.parseInt(ChatColor.stripColor(item.getItemMeta().getLore().get(0)).replace("Page ", "")); + this.setPhoneDefaults(inv); + int[] slots = new int[]{10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, 33, 34, 37, 38, 39, 40, 41, 42, 43}; + List<UserHouse> houses = user.getHouses(); + List<PremiumHouse> premiumHouses = user.getPremiumHousesAsGuest(); + Iterator<UserHouse> it = houses.iterator(); + Iterator<PremiumHouse> it2 = premiumHouses.iterator(); + int size = houses.size() + premiumHouses.size(); + int max = user.getMaxHouses(player, Core.getUserManager().getLoadedUser(uuid), GTM.getUserManager().getLoadedUser(uuid)); + for (int i = 0; i < (page * 20); i++) { + PremiumHouse premiumHouse = it.hasNext() ? null : it2.hasNext() ? it2.next() : null; + UserHouse userHouse = it.hasNext() ? it.next() : null; + if (premiumHouse == null && userHouse == null) + break; + if (i < (page - 1) * 20) + continue; + if (premiumHouse != null) { + inv.setItem(slots[i - (page - 1) * 20], + Utils.addGlow(Utils.createItem(Material.IRON_DOOR, "&3&lPremium House: &a&l" + premiumHouse.getId(), + Arrays.asList("Permits: &a&l" + premiumHouse.getPermits(), "&7Chests: &a&l" + premiumHouse.getChests().size(), + "&7Owned by &a" + (player.getUniqueId().equals(premiumHouse.getOwner()) ? "me" : premiumHouse.getOwnerName()) + '.')))); + continue; + } + + House house = Houses.getHousesManager().getHouse(userHouse.getId()); + inv.setItem(slots[i - (page - 1) * 20], Utils.createItem(Material.IRON_DOOR, "&3&lHouse: &a&l" + house.getId(), + Arrays.asList("&7Price: &$a&l" + house.getPrice(), "&7Chests: &a&l" + house.getChests().size()))); + } + inv.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the home page!")); + if (page > 1) + inv.setItem(48, Utils.createItem(Material.ARROW, "&3llPrevious Page", "&7Page " + (page - 1))); + inv.setItem(49, Utils.setArmorColor(Utils.createItem(Material.IRON_DOOR, "&3&lMy Houses", "&7Click on a house to open its menu!"), Color.fromRGB(102, 127, 51))); + if ((houses.size() + premiumHouses.size()) > (20 * page)) + inv.setItem(50, Utils.createItem(Material.ARROW, "&3&lNext Page", "&7Page 2")); + inv.setItem(51, Utils.createItem(Material.BOOK, "&3&lMax Houses: &a&l" + size + "&7/&a" + max, + size >= max ? "&7Go to &a" + Core.getSettings().getStoreLink() + "&7 to get access to more houses!" : "&7You can own &a" + (max - size) + "&7 more houses!")); + return; + default: + return; + + } + case "house": + if (item == null) + return; + switch (item.getType()) { + case SLIME_BALL: + MenuManager.openMenu(player, "buyhouse"); + return; + case INK_SACK: + MenuManager.openMenu(player, "sellhouse"); + return; + case REDSTONE: + MenuManager.openMenu(player, "houses"); + default: + return; + } + case "editblocks": + if (item == null) return; + if (!user.isInsidePremiumHouse()) { + return; + } + if (user.getEditingBlock() == null) return; + if (!Blocks.getMaterials().contains(item.getType())) return; + user.getEditingBlock().setType(item.getType(), false); + user.getEditingBlock().setData(item.getData().getData()); + user.setEditingBlock(null); + player.sendMessage(Lang.HOUSES.f("&7Block has been set to &a" + item.getType().name() + "&7!")); + user.setLastUsedMaterial(Blocks.match(item.getType(), item.getData().getData())); + player.closeInventory(); + return; + case "premiumhouse": + if (item == null) + return; + switch (item.getType()) { + case SLIME_BALL: + MenuManager.openMenu(player, "buypremiumhouse"); + return; + case INK_SACK: + MenuManager.openMenu(player, "sellpremiumhouse"); + return; + case TRIPWIRE_HOOK: + MenuManager.openMenu(player, "guests"); + return; + case REDSTONE: + MenuManager.openMenu(player, "houses"); + return; + case SNOW_BLOCK: + PremiumHouse house = Houses.getHousesManager().getPremiumHouse(user.getMenuHouseId()); + if (!house.getOwnerName().equalsIgnoreCase(player.getName())) return; + if (!user.isInsidePremiumHouse()) { + user.teleportInOrOutPremiumHouse(player, house); + } + if (user.isChangingBlocks()) { + player.sendMessage(Lang.HOUSES.f("&7House Editing disabled")); + } else { + player.sendMessage(Core.getAnnouncer().getHeader()); + player.sendMessage(Lang.HOUSES.f("&7You are now editing your house, right click a block to begin!")); + player.sendMessage(Lang.HOUSES.f("&7SHIFT + Right click a block to automatically set it to your last used block" + + " (for quick changing)")); + player.sendMessage(Lang.HOUSES.f("&7Once you're finished, leave your house to disable house editing." + + " (You can also use your door GUI to disable it)")); + player.sendMessage(Core.getAnnouncer().getFooter()); + } + user.setChangingBlocks(!user.isChangingBlocks()); + return; + default: + return; + } + case "sellhouse": + if (item == null) + return; + switch (item.getType()) { + case STAINED_GLASS_PANE: + switch (item.getDurability()) { + case 5: + House house = Houses.getHousesManager().getHouse(user.getMenuHouseId()); + if (house == null) { + player.sendMessage(Lang.HOUSES.f("&7That house does not exist!")); + return; + } + house.sellHouse(player, GTM.getUserManager().getLoadedUser(uuid), user); + case 14: + MenuManager.openMenu(player, "house"); + return; + default: + return; + } + default: + return; + } + + case "buyhouse": + if (item == null) + return; + switch (item.getType()) { + case STAINED_GLASS_PANE: + switch (item.getDurability()) { + case 5: + House house = Houses.getHousesManager().getHouse(user.getMenuHouseId()); + if (house == null) { + player.sendMessage(Lang.HOUSES.f("&7That house does not exist!")); + return; + } + house.buyHouse(player, Core.getUserManager().getLoadedUser(uuid), GTM.getUserManager().getLoadedUser(uuid), user); + case 14: + MenuManager.openMenu(player, "house"); + return; + default: + return; + } + default: + return; + } + + case "sellpremiumhouse": + if (item == null) + return; + switch (item.getType()) { + case STAINED_GLASS_PANE: + switch (item.getDurability()) { + case 5: + PremiumHouse house = Houses.getHousesManager().getPremiumHouse(user.getMenuHouseId()); + house.sell(player, GTM.getUserManager().getLoadedUser(uuid), user); + case 14: + MenuManager.openMenu(player, "premiumhouse"); + return; + default: + return; + } + default: + return; + } + case "buypremiumhouse": + if (item == null) + return; + switch (item.getType()) { + case STAINED_GLASS_PANE: + switch (item.getDurability()) { + case 5: + PremiumHouse house = Houses.getHousesManager().getPremiumHouse(user.getMenuHouseId()); + house.buy(player, Core.getUserManager().getLoadedUser(uuid), GTM.getUserManager().getLoadedUser(uuid), user); + case 14: + MenuManager.openMenu(player, "premiumhouse"); + return; + default: + return; + } + default: + return; + } + case "guests": + if (item == null) + return; + switch (item.getType()) { + case ARROW: { + int page = Integer.parseInt(ChatColor.stripColor(item.getItemMeta().getLore().get(0)).replace("Page ", "")); + this.setPhoneDefaults(inv); + int[] slots = new int[]{10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, 33, 34, 37, 38, 39, 40, 41, 42, 43}; + PremiumHouse house = Houses.getManager().getPremiumHouse(user.getMenuHouseId()); + List<PremiumHouseGuest> guests = house.getGuests(); + Iterator<PremiumHouseGuest> it = guests.iterator(); + for (int i = 0; i < (page * 20); i++) { + if (!it.hasNext()) + break; + PremiumHouseGuest guest = it.next(); + if (i < (page - 1) * 20) + continue; + inv.setItem(slots[i - (page - 1) * 20], Utils.setSkullOwner(Utils.createItem(Material.SKULL_ITEM, 2, "&3&l" + guest.getName()), guest.getName())); + } + inv.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the premium house menu!")); + if (page > 1) + inv.setItem(48, Utils.createItem(Material.ARROW, "&3&lPrevious Page", "&7Page " + (page - 1))); + if (house.getOwner().equals(player.getUniqueId())) { + inv.setItem(49, Utils.createItem(Material.SLIME_BALL, "&a&lAdd Guest")); + inv.setItem(51, Utils.createItem(Material.INK_SACK, 1, "&c&lRemove Guest")); + } else + inv.setItem(49, Utils.setArmorColor(Utils.createItem(Material.TRIPWIRE_HOOK, "&3&lPremium House Guests", "&7Players that can access this house!"), + Color.fromRGB(102, 127, 51))); + if (guests.size() > (20 * page)) + inv.setItem(50, Utils.createItem(Material.ARROW, "&3&lNext Page", "&7Page 2")); + + return; + } + case SLIME_BALL: { + PremiumHouse house = Houses.getManager().getPremiumHouse(user.getMenuHouseId()); + if (house.isOwner(uuid)) + player.closeInventory(); + user.addGuest(player, house); + return; + } + case INK_SACK: + PremiumHouse house = Houses.getManager().getPremiumHouse(user.getMenuHouseId()); + if (house.getOwner().equals(user.getUUID())) + MenuManager.openMenu(player, "removeguests"); + else + player.sendMessage(Utils.f(Lang.HOUSES + "&7You don't own this house!")); + return; + case REDSTONE: + MenuManager.openMenu(player, "premiumhouse"); + return; + default: + return; + } + case "removeguests": + if (item == null) + return; + switch (item.getType()) { + case ARROW: { + int page = Integer.parseInt(ChatColor.stripColor(item.getItemMeta().getLore().get(0)).replace("Page ", "")); + this.setPhoneDefaults(inv); + int[] slots = new int[]{10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, 33, 34, 37, 38, 39, 40, 41, 42, 43}; + PremiumHouse house = Houses.getManager().getPremiumHouse(user.getMenuHouseId()); + List<PremiumHouseGuest> guests = house.getGuests(); + Iterator<PremiumHouseGuest> it = guests.iterator(); + for (int i = 0; i < (page * 20); i++) { + if (!it.hasNext()) + break; + PremiumHouseGuest guest = it.next(); + if (i < (page - 1) * 20) + continue; + inv.setItem(slots[i - (page - 1) * 20], + Utils.setSkullOwner(Utils.createItem(Material.SKULL_ITEM, 2, "&3&l" + guest.getName(), "&7Click to remove this guest!"), guest.getName())); + } + inv.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the premium house menu!")); + if (page > 1) + inv.setItem(48, Utils.createItem(Material.ARROW, "&3&lPrevious Page", "&7Page " + (page - 1))); + if (house.getOwner().equals(player.getUniqueId())) { + inv.setItem(49, Utils.createItem(Material.SLIME_BALL, "&a&lAdd Guest")); + inv.setItem(51, Utils.createItem(Material.INK_SACK, 1, "&c&lStop Removing Guests")); + } else + inv.setItem(49, Utils.setArmorColor(Utils.createItem(Material.TRIPWIRE_HOOK, "&3&lPremium House Guests", "&7Players that can access this house!"), + Color.fromRGB(102, 127, 51))); + if (guests.size() > (20 * page)) + inv.setItem(50, Utils.createItem(Material.ARROW, "&3&lNext Page", "&7Page 2")); + return; + } + case SLIME_BALL: { + PremiumHouse house = Houses.getManager().getPremiumHouse(user.getMenuHouseId()); + player.closeInventory(); + user.addGuest(player, house); + return; + } + case SKULL_ITEM: + PremiumHouse house = Houses.getHousesManager().getPremiumHouse(user.getMenuHouseId()); + String guest = ChatColor.stripColor(item.getItemMeta().getDisplayName()); + Player target = Bukkit.getPlayer(guest); + if (target == null) house.removeGuest(player, guest); + else + house.removeGuest(player, target, Houses.getUserManager().getLoadedUser(target.getUniqueId())); + MenuManager.openMenu(player, "removeguests"); + return; + case INK_SACK: + MenuManager.openMenu(player, "guests"); + return; + case REDSTONE: + MenuManager.openMenu(player, "guests"); + return; + default: + return; + + } + case "houseshelp": + if (item == null) return; + switch (item.getType()) { + case REDSTONE: + MenuManager.openMenu(player, "houses"); + return; + default: + break; + } + case "buytrashcan": + if (item == null) return; + switch (item.getType()) { + case SLIME_BALL: { + MenuManager.openMenu(player, "confirmtrashcanbuy"); + return; + } + case REDSTONE: + player.closeInventory(); + return; + default: + return; + } + case "confirmtrashcanbuy": { + if (item == null) return; + switch (item.getType()) { + case STAINED_GLASS_PANE: + switch (item.getDurability()) { + case 5: + if (user.getOpenTrashcan() == null) return; + GTMUser gtmUser = GTM.getUserManager().getLoadedUser(uuid); + PremiumHouseTrashcan trashcan = user.getOpenTrashcan(); + PremiumHouse premiumHouse = Houses.getHousesManager().getPremiumHouse(trashcan.getHouseId()); + if (!premiumHouse.getOwnerName().equalsIgnoreCase(player.getName())) { + player.sendMessage(Lang.HOUSES.f("&7Only the house owner may purchase house extensions!")); + return; + } + if (gtmUser.hasPermits(5)) { + gtmUser.takePermits(5); + trashcan.setOwned(true); + Houses.getHousesManager().save(); + Utils.insertLogLater(player.getUniqueId(), player.getName(), "confirmtrashcanbuyMenu", "BUY_TRASHCAN", "Premium House ID: " + trashcan.getHouseId(),1,5); + player.sendMessage(Lang.HOUSES.f("&7Trash Can purchased for &3&l5 permits&7!")); + } else { + player.sendMessage(Lang.HOUSES.f("&7You don't have the required 5 permits to purchase this!")); + } + player.closeInventory(); + return; + case 14: + MenuManager.openMenu(player, "buytrashcan"); + return; + default: + return; + } + default: + return; + } + } + } + } + +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/PetListener.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/PetListener.java new file mode 100644 index 0000000..c3c6373 --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/PetListener.java @@ -0,0 +1,35 @@ +package net.grandtheftmc.houses.listeners; + +/*import com.dsh105.echopet.compat.api.event.PetInteractEvent; +import com.dsh105.echopet.compat.api.event.PetTeleportEvent; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.houses.House; +import net.grandtheftmc.houses.houses.HouseDoor; +import net.grandtheftmc.houses.users.HouseUser; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler;*/ +import org.bukkit.event.Listener; + +public class PetListener implements Listener { + + /* @EventHandler + public void onTeleport(PetTeleportEvent e) { + Player player = e.getPet().getOwner(); + HouseUser houseUser = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + if (!houseUser.isInsideHouse()) return; + e.setCancelled(true); + House house = Houses.getHousesManager().getHouse(houseUser.getInsideHouse()); + if (house != null) { + HouseDoor door = house.getDoor(); + if (door != null) + e.setTo(door.getOutsideLocation()); + } + } + + @EventHandler + public void onPetInteract(PetInteractEvent e) { + Player player = e.getPet().getOwner(); + HouseUser houseUser = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + if (houseUser.isInsideHouse() || houseUser.isInsidePremiumHouse()) e.setCancelled(true); + }*/ +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/Teleport.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/Teleport.java new file mode 100644 index 0000000..7963b74 --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/Teleport.java @@ -0,0 +1,55 @@ +package net.grandtheftmc.houses.listeners; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.gtm.GTM; +import net.grandtheftmc.gtm.events.TPEvent; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.users.HouseUser; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerTeleportEvent; +import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; + +public class Teleport implements Listener { + + @EventHandler + public void onTeleport(PlayerTeleportEvent e) { + if (e.getCause() == TeleportCause.END_PORTAL) return; + Player player = e.getPlayer(); + HouseUser user = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + if (user.isInsideHouse()) { + user.setInsideHouse(-1); + user.updateVisibility(player); + } + if (user.isInsidePremiumHouse()) user.setInsidePremiumHouse(-1); + } + + @EventHandler + public void onTP(TPEvent e) { + if (e.getTarget() == null) + return; + Player player = e.getPlayer(); + GTMUser user = GTM.getUserManager().getLoadedUser(player.getUniqueId()); + switch (e.getType()) { + case TP_COMPLETE: + HouseUser targetUser = Houses.getUserManager().getLoadedUser(e.getTarget().getUniqueId()); + if (targetUser.isInsideHouse()) { + e.setTargetLocation( + Houses.getHousesManager().getHouse(targetUser.getInsideHouse()).getDoor().getOutsideLocation()); + } else if (targetUser.isInsidePremiumHouse()) { + e.setTargetLocation(Houses.getHousesManager().getPremiumHouse(targetUser.getInsidePremiumHouse()).getDoor() + .getOutsideLocation()); + } + return; + case PREMIUM_HOUSE_LEAVE: + case HOUSE_LEAVE: + user.setLastTeleport(); + break; + default: + break; + } + } + +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/WeaponShoot.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/WeaponShoot.java new file mode 100644 index 0000000..4425242 --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/listeners/WeaponShoot.java @@ -0,0 +1,22 @@ +package net.grandtheftmc.houses.listeners; + +import com.j0ach1mmall3.wastedguns.api.events.ranged.RangedWeaponShootEvent; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.users.HouseUser; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +public class WeaponShoot implements Listener { + + @EventHandler + public void rangedWeaponShoot(RangedWeaponShootEvent event) { + if (event.getLivingEntity().getType() != EntityType.PLAYER) return; + Player player = (Player) event.getLivingEntity(); + HouseUser houseUser = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + if (houseUser.isTeleporting()) { + event.setCancelled(true); + } + } +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/users/HouseUser.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/users/HouseUser.java new file mode 100644 index 0000000..f5eecae --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/users/HouseUser.java @@ -0,0 +1,756 @@ +package net.grandtheftmc.houses.users; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.util.Callback; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.events.TPEvent; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.houses.HouseUtils; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.dao.HouseDAO; +import net.grandtheftmc.houses.houses.*; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; +import java.util.stream.Collectors; + +public class HouseUser { + + private final UUID uuid; + private boolean hasUpdated; + private List<UserHouse> houses = new ArrayList<>(); + + private int insideHouse; + private int insidePremiumHouse; + private boolean teleporting; + + private House editingHouse; + private PremiumHouse editingPremiumHouse; + private boolean addingChests; + private boolean removingChests; + private HouseDoor addingDoor; + private PremiumHouseDoor addingPremiumDoor; + private boolean removingDoor; + private int addingGuest; + private boolean addingSigns; + private boolean removingSigns; + private boolean addingBlocks; + private boolean removingBlocks; + private boolean loadedChests = false; + + private int lastChestId = -1; + + private Object openChest; + + private PremiumHouseTrashcan openTrashcan; + private boolean addingTrashcans; + private boolean removingTrashcans; + + private int menuHouseId; + + private int maxHouses = -1; + + private Block editingBlock; + private boolean changingBlocks; + private Blocks lastUsedMaterial; + + public HouseUser(UUID uuid) { + this.uuid = uuid; + } + + public UUID getUUID() { + return this.uuid; + } + + public void dataCheck(String name) { + for (PremiumHouse house : Houses.getManager().getPremiumHouses()) { + if (house.isOwner(this.uuid)) + house.setOwnerName(name); + PremiumHouseGuest guest = house.getGuest(this.uuid); + if (guest != null) + guest.setName(name); + } + + String table = Core.name(); + +// Core.sql.update("update " + Core.name() + "_houses set name='" + name + "' where uuid='" + this.uuid + "';"); +// BaseDatabase.runCustomQuery("update " + Core.name() + "_houses set name='" + name + "' where uuid='" + this.uuid + "';"); + + //Not used. +// Core.sql.update("update " + Core.name() + " set name='ERROR' where name='" + name + "' and uuid!='" + this.uuid + "';"); + } + + public void loadChests(Callback<Boolean> callback) { + new BukkitRunnable() { + @Override public void run() { + boolean b = true; + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + + HouseDAO.getChestContent(connection, HouseUser.this, uuid); + +// try (PreparedStatement statement = connection.prepareStatement("select * from " + Core.name() + "_houses_chests where uuid='" + HouseUser.this.uuid + "' LIMIT 10000;")) { +// try (ResultSet result = statement.executeQuery()) { +// while (result.next()) { +// int id = result.getInt("houseId"); +// int chestId = result.getInt("chestId"); +// UserHouse userHouse = HouseUser.this.getUserHouse(id); +// if (userHouse == null) +// continue; +// UserHouseChest chest = userHouse.getChestOrNull(chestId); +// if (chest == null) { +// userHouse.addChest(new UserHouseChest(id, chestId, GTMUtils.fromBase64(result.getString("contents")))); +// } else { +// chest.setContents(GTMUtils.fromBase64(result.getString("contents"))); +// } +// } +// } +// } + } catch (SQLException e) { + e.printStackTrace(); + b = false; + } + +// try { +// ResultSet rs = Core.sql.query("select * from " + Core.name() + "_houses_chests where uuid='" + HouseUser.this.uuid + "' LIMIT 10000;"); +// // HousesChests(uuid varchar(255), houseId integer, chestId +// // integer, contents blob); +// while (rs.next()) { +// int id = rs.getInt("houseId"); +// int chestId = rs.getInt("chestId"); +// UserHouse userHouse = HouseUser.this.getUserHouse(id); +// if (userHouse == null) +// continue; +// UserHouseChest chest = userHouse.getChestOrNull(chestId); +// if (chest == null) { +// userHouse.addChest(new UserHouseChest(id, chestId, GTMUtils.fromBase64(rs.getString("contents")))); +// } else { +// chest.setContents(GTMUtils.fromBase64(rs.getString("contents"))); +// } +// } +// rs.close(); +// } catch (SQLException e) { +// e.printStackTrace(); +// b = false; +// } + + HouseUser.this.loadedChests = true; + callback.call(b); + } + }.runTaskAsynchronously(Core.getInstance()); + } + + public boolean updateDataFromDb() { + HousesManager hm = Houses.getHousesManager(); + this.houses = new ArrayList<>(); + boolean b = true; + + Optional<List<UserHouse>> optional = Optional.empty(); + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + optional = HouseDAO.loadUser(connection, hm, this.uuid); + } catch (SQLException e) { + e.printStackTrace(); + b = false; + } + + if (!optional.isPresent()) { + System.out.println("ERROR, OPTIONAL WASN'T PRESENT."); + } + else { + optional.get().stream().forEach(userHouse -> { + System.out.println("ID - " + userHouse.getId()); + this.houses.add(userHouse); + }); + } + +// try (Connection connection = BaseDatabase.getInstance().getConnection()) { +// try (PreparedStatement statement = connection.prepareStatement("select * from " + Core.name() + "_houses where uuid='" + this.uuid + "' LIMIT 500;")) { +// try (ResultSet result = statement.executeQuery()) { +// while (result.next()) { +// int id = result.getInt("houseId"); +// House house = hm.getHouse(id); +// if (house == null) +// continue; +// UserHouse userHouse = new UserHouse(this.uuid, house.getId()); +// this.houses.add(userHouse); +// } +// } +// } +// } catch (SQLException e) { +// e.printStackTrace(); +// b = false; +// } + +// try { +// ResultSet rs = Core.sql.query("select * from " + Core.name() + "_houses where uuid='" + this.uuid + "' LIMIT 500;"); +// while (rs.next()) { +// int id = rs.getInt("houseId"); +// House house = hm.getHouse(id); +// if (house == null) +// continue; +// UserHouse userHouse = new UserHouse(this.uuid, house.getId()); +// this.houses.add(userHouse); +// } +// rs.close(); +// } catch (SQLException e) { +// e.printStackTrace(); +// b = false; +// } + + this.hasUpdated = true; + return b; + } + + public int getMaxHouses(Player player, User user, GTMUser gtmUser) { + if (this.maxHouses >= 0) return this.maxHouses; + int amnt = gtmUser.getRank().getHouses() + HouseUtils.getHouses(user.getUserRank()); + for (int i = 20; i > 0; i--) + if (player.hasPermission("houses.own." + i)) { + amnt += i; + break; + } + for (int i = 20; i > 0; i--) + if (player.hasPermission("houses.extra." + i)) + amnt += i; + this.maxHouses = amnt; + return amnt; + } + + public boolean hasMaxHouses(Player player, User user, GTMUser gtmUser) { + return this.getMaxHouses(player, user, gtmUser) <= (this.houses.size() + this.getPremiumHouses().size()); + } + + public UserHouse getUserHouse(int id) { + for (UserHouse house : this.houses) + if (house.getId() == id) + return house; + return null; + } + + public UserHouse getUserHouseByUniqueId(int uniqueId) { + for (UserHouse house : this.houses) + if (house.getUniqueId() == uniqueId) + return house; + return null; + } + + public boolean ownsHouse(int id) { + return this.getUserHouse(id) != null; + } + + public List<UserHouse> getHouses() { + return this.houses; + } + + public List<UserHouse> getHouses(int start, int end) { + if (start < 0 || end > this.houses.size()) return this.houses; + return this.houses.subList(start, end); + } + + public PremiumHouse getPremiumHouse(int id) { + for (PremiumHouse house : this.getPremiumHouses()) + if (house.getId() == id) + return house; + return null; + } + + public boolean ownsPremiumHouse(int id) { + return this.getPremiumHouse(id) != null; + } + + public List<PremiumHouse> getPremiumHouses() { + return Houses.getManager().getPremiumHouses().stream().filter(house -> this.uuid.equals(house.getOwner())).collect(Collectors.toList()); + } + + public List<PremiumHouse> getPremiumHouses(int start, int end) { + if (start < 0 || end > this.getPremiumHouses().size()) { + return this.getPremiumHouses(); + } + return this.getPremiumHouses().subList(start, end); + } + + public List<PremiumHouse> getPremiumHousesAsGuest() { + return Houses.getManager().getPremiumHouses().stream().filter(house -> this.uuid.equals(house.getOwner()) || house.isGuest(this.uuid)).collect(Collectors.toList()); + } + + public List<PremiumHouse> getPremiumHousesOnlyAsGuest() { + return Houses.getManager().getPremiumHouses().stream().filter(house -> house.isGuest(this.uuid)).collect(Collectors.toList()); + } + + public boolean isInsideHouse() { + return this.insideHouse > 0; + } + + public boolean isInsideHouse(int id) { + return this.insideHouse == id; + } + + public int getInsideHouse() { + return this.insideHouse; + } + + public void setInsideHouse(int i) { + this.insideHouse = i; + } + + public boolean isInsidePremiumHouse() { + return this.insidePremiumHouse > 0; + } + + public boolean isInsidePremiumHouse(int id) { + return this.insidePremiumHouse == id; + } + + public int getInsidePremiumHouse() { + return this.insidePremiumHouse; + } + + public void setInsidePremiumHouse(int i) { + this.insidePremiumHouse = i; + } + + public boolean isTeleporting() { + return this.teleporting; + } + + public void setTeleporting(boolean b) { + this.teleporting = b; + } + + public void updateVisibility(Player player) { + // IF PLAYER IS IN NORMAL HOUSE -> CANT SEE ANYONE + // IF PLAYER IS NOT IN HOUSE -> CAN SEE EVERYONE THAT IS NOT IN A NORMAL + // HOUSE + HouseUserManager um = Houses.getUserManager(); + boolean viewInvisible = player.hasPermission("houses.viewinvisible"); + if (this.isInsideHouse()) + for (Player p : Bukkit.getOnlinePlayers()) { + if (!viewInvisible) player.hidePlayer(p); + if (!p.hasPermission("houses.viewinvisible")) p.hidePlayer(player); + } + else { + + for (Player p : Bukkit.getOnlinePlayers()) { + HouseUser u = um.getLoadedUser(p.getUniqueId()); + if (u.isInsideHouse()) { + if (!p.hasPermission("houses.viewinvisible")) + p.hidePlayer(player); + if (!viewInvisible) + player.hidePlayer(player); + } else { + p.showPlayer(player); + player.showPlayer(p); + } + } + } + } + + + public String getHousesString() { + String s = ""; + Iterator<UserHouse> it = this.houses.iterator(); + while (it.hasNext()) + s = s + it.next().getId() + (it.hasNext() ? "," : ""); + return s; + } + + public void teleportInOrOutHouse(Player player, House house) { + this.teleportInOrOutHouse(player, Core.getUserManager().getLoadedUser(player.getUniqueId()), house.getDoors().get(0)); + } + + public void teleportInOrOutHouse(Player player, HouseDoor door) { + this.teleportInOrOutHouse(player, Core.getUserManager().getLoadedUser(player.getUniqueId()), door); + } + + public void teleportInOrOutHouse(Player player, User user, House house) { + this.teleportInOrOutHouse(player, user, house.getDoors().get(0)); + } + + public void teleportInOrOutHouse(Player player, User user, HouseDoor door) { + UUID finalUUID = this.uuid; + int houseId = door.getHouseId(); + int doorId = door.getId(); + this.teleporting = true; + int cooldown = HouseUtils.getHouseDelay(user.getUserRank()); + player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, cooldown + 20, 0)); + player.sendMessage(Lang.HOUSES.f("&7" + (this.isInsideHouse() ? "Leaving" : "Entering") + " your house" + (cooldown < 20 ? "." : " in &a&l" + (cooldown / 20) + " &7seconds." + (user.isSpecial() ? "" : "Buy a rank to speed it up.")))); + new BukkitRunnable() { + @Override + public void run() { + Player player = Bukkit.getPlayer(finalUUID); + if (player == null) + return; + HouseUser user = Houses.getUserManager().getLoadedUser(finalUUID); + if (!user.isTeleporting()) + return; + House house = Houses.getManager().getHouse(houseId); + if (house == null) + return; + HouseDoor door = house.getDoor(doorId); + if (door == null) + door = house.getDoor(); + user.setTeleporting(false); + user.setInsidePremiumHouse(-1); + TPEvent e = new TPEvent(player, player, user.isInsideHouse() ? TPEvent.TPType.HOUSE_LEAVE : TPEvent.TPType.HOUSE_ENTER).call(); + if (e.isCancelled()) { + player.sendMessage(Lang.HOUSES.f(e.getCancelMessage())); + return; + } + Location tpLoc = user.isInsideHouse() ? door.getOutsideLocation() : door.getInsideLocation(); + user.setInsideHouse(user.isInsideHouse() ? -1 : houseId); + player.teleport(new Location(tpLoc.getWorld(), tpLoc.getX(), tpLoc.getY(), tpLoc.getZ(), player.getLocation().getYaw(), player.getLocation().getPitch()), TeleportCause.END_PORTAL); + HouseUser.this.updateVisibility(player); + if(!loadedChests) + loadChests((call) -> {}); + } + }.runTaskLater(Houses.getInstance(), cooldown); + } + + public void teleportInOrOutPremiumHouse(Player player, PremiumHouse house) { + this.teleportInOrOutPremiumHouse(player, house.getDoors().get(0)); + } + + public void teleportInOrOutPremiumHouse(Player player, PremiumHouseDoor door) { + UUID finalUUID = this.uuid; + int houseId = door.getHouseId(); + int doorId = door.getId(); + this.teleporting = true; + player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 30, 0)); + new BukkitRunnable() { + @Override + public void run() { + Player player = Bukkit.getPlayer(finalUUID); + if (player == null) + return; + HouseUser user = Houses.getUserManager().getLoadedUser(finalUUID); + if (!user.isTeleporting()) + return; + PremiumHouse house = Houses.getHousesManager().getPremiumHouse(houseId); + if (house == null) + return; + PremiumHouseDoor door = house.getDoor(doorId); + if (door == null) + door = house.getDoor(); + user.setTeleporting(false); + user.setInsideHouse(-1); + TPEvent e = new TPEvent(player, player, user.isInsideHouse() ? TPEvent.TPType.PREMIUM_HOUSE_LEAVE : TPEvent.TPType.PREMIUM_HOUSE_ENTER).call(); + if (e.isCancelled()) { + player.sendMessage(Lang.HOUSES.f(e.getCancelMessage())); + return; + } + player.playSound(player.getLocation(), + user.isInsidePremiumHouse() ? Sound.BLOCK_IRON_DOOR_CLOSE : Sound.BLOCK_IRON_DOOR_OPEN, + 1.0F, 1.0F); + Location tpLoc = user.isInsidePremiumHouse() ? door.getOutsideLocation() : door.getInsideLocation(); + user.setInsidePremiumHouse(user.isInsidePremiumHouse() ? -1 : houseId); + player.teleport(new Location(tpLoc.getWorld(), tpLoc.getX(), tpLoc.getY(), tpLoc.getZ(), player.getLocation().getYaw(), player.getLocation().getPitch()), TeleportCause.END_PORTAL); + HouseUser.this.updateVisibility(player); + if (!user.isInsidePremiumHouse()) { + if (user.isChangingBlocks()) { + player.sendMessage(Lang.HOUSES.f("&7House Editing disabled")); + user.setChangingBlocks(false); + } + } + } + }.runTaskLater(Houses.getInstance(), 12); + } + + public House getEditingHouse() { + return this.editingHouse; + } + + public void setEditingHouse(House editingHouse) { + this.editingHouse = editingHouse; + } + + public PremiumHouse getEditingPremiumHouse() { + return this.editingPremiumHouse; + } + + public void setEditingPremiumHouse(PremiumHouse editingPremiumHouse) { + this.editingPremiumHouse = editingPremiumHouse; + } + + public boolean isAddingChests() { + return this.addingChests; + } + + public void setAddingChests(boolean addingChests) { + this.addingChests = addingChests; + } + + public boolean isRemovingChests() { + return this.removingChests; + } + + public void setRemovingChests(boolean removingChests) { + this.removingChests = removingChests; + } + + public HouseDoor getAddingDoor() { + return this.addingDoor; + } + + public boolean isAddingDoor() { + return this.addingDoor != null; + } + + public void setAddingDoor(HouseDoor addingDoor) { + this.addingDoor = addingDoor; + } + + public PremiumHouseDoor getAddingPremiumDoor() { + return this.addingPremiumDoor; + } + + public boolean isAddingPremiumDoor() { + return this.addingPremiumDoor != null; + } + + public void setAddingPremiumDoor(PremiumHouseDoor addingPremiumDoor) { + this.addingPremiumDoor = addingPremiumDoor; + } + + public int getMenuHouseId() { + return this.menuHouseId; + } + + public void setMenuHouseId(int menuHouseId) { + this.menuHouseId = menuHouseId; + } + + public boolean isRemovingDoor() { + return this.removingDoor; + } + + public void setRemovingDoor(boolean removingDoor) { + this.removingDoor = removingDoor; + } + + public void addHouse(House house) { + List<UserHouseChest> chests = house.getChests().stream().map(chest -> new UserHouseChest(house.getId(), chest.getId())).collect(Collectors.toList()); + this.houses.add(new UserHouse(this.uuid, house.getUniqueIdentifier(), house.getId(), chests)); + int houseId = house.getId(); + UUID uuid = this.uuid; + + ServerUtil.runTaskAsync(() -> { + House h = Houses.getHousesManager().getHouse(houseId); + if (h == null) return; + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + HouseDAO.addUser(connection, house.getUniqueIdentifier(), uuid); + + for (HouseChest chest : house.getChests()) { + HouseDAO.addChestContent(connection, house.getUniqueIdentifier(), chest.getId(), uuid, null); + } + } catch (SQLException e) { + e.printStackTrace(); + } + }); + +// new BukkitRunnable() { +// @Override +// public void run() { +// House house = Houses.getHousesManager().getHouse(houseId); +// if (house == null) return; +// +// HouseDAO.addUser(connection, house.getUniqueIdentifier(), uuid); +// +// for (HouseChest chest : house.getChests()) { +//// BaseDatabase.runCustomQuery("insert into " + Core.name() + "_houses_chests(uuid,houseId,chestId) values ('" + uuid.toString() + "','" + house.getId() + "','" + chest.getId() + "');"); +// HouseDAO.addChestContent(connection, house.getUniqueIdentifier(), chest.getId(), uuid, null); +// } +// +// BaseDatabase.runCustomQuery("insert into " + Core.name() + "_houses(uuid,houseId) values ('" + uuid + "', " + house.getId() + ");"); +// +//// try { +//// +//// PreparedStatement statement = Core.sql.prepareStatement( +//// "insert into " + Core.name() + "_houses_chests(uuid,houseId,chestId) values (?,?,?);"); +//// for (HouseChest chest : house.getChests()) { +//// statement.setString(1, uuid.toString()); +//// statement.setInt(2, house.getId()); +//// statement.setInt(3, chest.getId()); +//// statement.executeUpdate(); +//// } +//// statement.close(); +//// } catch (SQLException e) { +//// e.printStackTrace(); +//// } +//// Core.sql.update("insert into " + Core.name() + "_houses(uuid,houseId) values ('" + uuid +//// + "', " + house.getId() + ");"); +// } +// }.runTaskAsynchronously(Houses.getInstance()); + } + + public void removeHouse(Player player, House house) { + UserHouse userHouse = this.getUserHouse(house.getId()); + this.houses.remove(userHouse); + if (this.isInsideHouse(house.getId())) + this.teleportInOrOutHouse(player, Core.getUserManager().getLoadedUser(player.getUniqueId()), house); +// Core.sql.updateAsyncLater("delete from " + Core.name() + "_houses_chests where uuid='" + this.uuid +// + "' and houseId=" + house.getId() + ';'); +// Core.sql.updateAsyncLater("delete from " + Core.name() + "_houses where uuid='" + this.uuid +// + "' and houseId=" + house.getId() + ';'); + + ServerUtil.runTaskAsync(() -> { +// BaseDatabase.runCustomQuery("delete from " + Core.name() + "_houses_chests where uuid='" + this.uuid + "' and houseId=" + house.getId() + ';'); +// BaseDatabase.runCustomQuery("delete from " + Core.name() + "_houses where uuid='" + this.uuid + "' and houseId=" + house.getId() + ';'); + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + HouseDAO.deleteOwner(connection, house.getUniqueIdentifier(), this.uuid); + //TODO Should delete from `gtm_house_chest` automatically. + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } + + public boolean hasUpdated() { + return this.hasUpdated; + } + + public void setHasUpdated(boolean hasUpdated) { + this.hasUpdated = hasUpdated; + } + + public void addGuest(Player sender, PremiumHouse house) { + if (!house.isOwner(this.uuid)) { + sender.sendMessage(Utils.f(Lang.HOUSES.f("&7You don't own this house!"))); + return; + } + + this.addingGuest = house.getId(); + sender.sendMessage(Lang.HOUSES.f("&7Please type the name of the player you want to add as a guest, or type &a\"quit\"&7 to quit!")); + } + + public int getAddingGuest() { + return this.addingGuest; + } + + public boolean isAddingGuest() { + return this.addingGuest > 0; + } + + public void setAddingGuest(int addingGuest) { + this.addingGuest = addingGuest; + } + + public boolean isAddingSigns() { + return this.addingSigns; + } + + public void setAddingSigns(boolean addingSigns) { + this.addingSigns = addingSigns; + } + + public boolean isRemovingSigns() { + return this.removingSigns; + } + + public void setRemovingSigns(boolean removingSigns) { + this.removingSigns = removingSigns; + } + + public Block getEditingBlock() { + return this.editingBlock; + } + + public void setEditingBlock(Block loc) { + this.editingBlock = loc; + } + + public boolean isAddingBlocks() { + return this.addingBlocks; + } + + public void setAddingBlocks(boolean a) { + this.addingBlocks = a; + } + + public boolean isRemovingBlocks() { + return removingBlocks; + } + + public void setRemovingBlocks(boolean removingBlocks) { + this.removingBlocks = removingBlocks; + } + + public boolean isChangingBlocks() { + return changingBlocks; + } + + public void setChangingBlocks(boolean changingBlocks) { + this.changingBlocks = changingBlocks; + } + + public Blocks getLastUsedMaterial() { + return lastUsedMaterial; + } + + public void setLastUsedMaterial(Blocks lastUsedMaterial) { + this.lastUsedMaterial = lastUsedMaterial; + } + + public boolean isAddingTrashcans() { + return addingTrashcans; + } + + public void setAddingTrashcans(boolean addingTrashcans) { + this.addingTrashcans = addingTrashcans; + } + + public boolean isRemovingTrashcans() { + return removingTrashcans; + } + + public void setRemovingTrashcans(boolean removingTrashcans) { + this.removingTrashcans = removingTrashcans; + } + + public PremiumHouseTrashcan getOpenTrashcan() { + return openTrashcan; + } + + public void setOpenTrashcan(PremiumHouseTrashcan openTrashcan) { + this.openTrashcan = openTrashcan; + } + + public int getLastChestId() { + return lastChestId; + } + + public void setLastChestId(int lastChestId) { + this.lastChestId = lastChestId; + } + + public void setOpenChest(Object openChest) { + this.openChest = openChest; + } + + public boolean hasChestOpen() { + return this.openChest != null; + } + + public Object getOpenChest() { + return this.openChest; + } +} + diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/users/HouseUserManager.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/users/HouseUserManager.java new file mode 100644 index 0000000..990f321 --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/users/HouseUserManager.java @@ -0,0 +1,34 @@ +package net.grandtheftmc.houses.users; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +public class HouseUserManager { + + private final List<HouseUser> loadedUsers = new ArrayList<>(); + + public List<HouseUser> getLoadedUsers() { + return this.loadedUsers; + } + + public boolean unloadUser(UUID uuid) { + if (uuid == null) + return false; + for (HouseUser user : this.loadedUsers.toArray(new HouseUser[this.loadedUsers.size()])) + if (uuid.equals(user.getUUID())) + return this.loadedUsers.remove(user); + return false; + } + + public HouseUser getLoadedUser(UUID uuid) { + if (uuid == null) return null; + for (HouseUser u : this.loadedUsers.toArray(new HouseUser[this.loadedUsers.size()])) + if (uuid.equals(u.getUUID())) + return u; + HouseUser user = new HouseUser(uuid); + this.loadedUsers.add(user); + return user; + } + +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/users/UserHouse.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/users/UserHouse.java new file mode 100644 index 0000000..e4ea492 --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/users/UserHouse.java @@ -0,0 +1,97 @@ +package net.grandtheftmc.houses.users; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.dao.HouseDAO; +import net.grandtheftmc.houses.houses.House; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +public class UserHouse { + + private int uniqueId; + private final UUID uuid; + private final int houseId; + private List<UserHouseChest> chests = new ArrayList<>(); + + public UserHouse(UUID uuid, int uniqueId, int houseId) { + this.uuid = uuid; + this.uniqueId = uniqueId; + this.houseId = houseId; + } + + public UserHouse(UUID uuid, int uniqueId, int houseId, List<UserHouseChest> chests) { + this.uuid = uuid; + this.uniqueId = uniqueId; + this.houseId = houseId; + this.chests = chests; + } + + public int getUniqueId() { + return uniqueId; + } + + public void setUniqueId(int uniqueId) { + this.uniqueId = uniqueId; + } + + public int getId() { + return this.houseId; + } + + public UserHouseChest getChestOrNull(int id) { + for (UserHouseChest chest : this.chests) + if (chest.getId() == id) + return chest; + return null; + } + + public UserHouseChest getChest(int id) { + for (UserHouseChest chest : this.chests) + if (chest.getId() == id) + return chest; + + House house = Houses.getHousesManager().getHouse(this.houseId); + if (house.getChest(id) != null) { + UserHouseChest chest = new UserHouseChest(this.houseId, id); + +// Core.sql.updateAsyncLater("insert into " + Core.name() + "_houses_chests(uuid,houseId,chestId) values ('" + this.uuid + "'," + this.houseId + ',' + id + ");"); + ServerUtil.runTaskAsync(() -> { +// BaseDatabase.runCustomQuery("insert into " + Core.name() + "_houses_chests(uuid,houseId,chestId) values ('" + this.uuid + "'," + this.houseId + ',' + id + ");"); + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + HouseDAO.addChestContent(connection, house.getUniqueIdentifier(), id, this.uuid, null); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + + this.chests.add(chest); + return chest; + } + return null; + } + + public void addChest(UserHouseChest chest) { + UserHouseChest old = this.getChestOrNull(chest.getId()); + if (old == null) this.chests.add(chest); + else old.setContents(chest.getContents()); + } + + public void removeChest(int id) { + this.chests.remove(this.getChest(id)); + } + + public void removeChests() { + this.chests.clear(); + } + + public List<UserHouseChest> getChests() { + return chests; + } +} diff --git a/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/users/UserHouseChest.java b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/users/UserHouseChest.java new file mode 100644 index 0000000..217494a --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/java/net/grandtheftmc/houses/users/UserHouseChest.java @@ -0,0 +1,81 @@ +package net.grandtheftmc.houses.users; + +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.dao.HouseDAO; +import net.grandtheftmc.houses.houses.House; +import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitRunnable; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.UUID; + +public class UserHouseChest { + + private final int houseId; + private final int chestId; + private ItemStack[] contents; + + public UserHouseChest(int houseId, int chestId) { + this.houseId = houseId; + this.chestId = chestId; + this.contents = new ItemStack[]{}; + } + + public UserHouseChest(int houseId, int chestId, ItemStack[] contents) { + this.houseId = houseId; + this.chestId = chestId; + this.contents = contents; + } + + public int getId() { + return this.chestId; + } + + public int getHouseId() { + return this.houseId; + } + + public ItemStack[] getContents() { + return this.contents; + } + + public void setContents(ItemStack[] i) { + this.contents = i; + } + + public void updateContents(UUID uuid, int uniqueId) { + ItemStack[] contents = this.contents; + new BukkitRunnable() { + @Override + public void run() { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { +// try (PreparedStatement statement = connection.prepareStatement("update " + Core.name() + "_houses_chests set contents=? where uuid=? and houseId=? and chestId=?;")) { +// statement.setString(1, GTMUtils.toBase64(contents)); +// statement.setString(2, uuid.toString()); +// statement.setInt(3, UserHouseChest.this.houseId); +// statement.setInt(4, UserHouseChest.this.chestId); +// statement.execute(); +// } + HouseDAO.updateChestContent(connection, uniqueId, chestId, uuid, contents); + } catch (SQLException e) { + e.printStackTrace(); + } + +// PreparedStatement ps = Core.sql.prepareStatement("update " + Core.name() + "_houses_chests set contents=? where uuid=? and houseId=? and chestId=?;"); +// try { +// ps.setString(1, GTMUtils.toBase64(contents)); +// ps.setString(2, uuid.toString()); +// ps.setInt(3, UserHouseChest.this.houseId); +// ps.setInt(4, UserHouseChest.this.chestId); +// ps.execute(); +// } catch (SQLException e) { +// e.printStackTrace(); +// } + } + }.runTaskAsynchronously(Houses.getInstance()); + + } + +} diff --git a/houses-master@c2d95d8e6a6/src/main/resources/houses.yml b/houses-master@c2d95d8e6a6/src/main/resources/houses.yml new file mode 100644 index 0000000..930620e --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/resources/houses.yml @@ -0,0 +1,13 @@ +'1': + price: 50000 + doors: + '1': + location: world,0,0,0 + insideLocation: world,0,0,0 + outsideLocation: world,0,0,0 + chests: + '1': + loc1: world,0,0,0 + '2': + loc1: world,0,0,0 + loc2: world,0,0,0 \ No newline at end of file diff --git a/houses-master@c2d95d8e6a6/src/main/resources/plugin.yml b/houses-master@c2d95d8e6a6/src/main/resources/plugin.yml new file mode 100644 index 0000000..8406e71 --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/resources/plugin.yml @@ -0,0 +1,20 @@ +name: Houses +version: 1.0 +description: Houses Plugin +author: Presidentx +main: net.grandtheftmc.houses.Houses +softdepend: [WorldEdit] +depend: [Core,GTM] +commands: + houses: + aliases: [h, house] + premiumhouses: + aliases: [ph, phouse, premh, premhouse, premiumhouse] + housedoor: + aliases: [hd, hdoor, housesdoor, housesdoors] + housechest: + aliases: [hc, hchest, houseschest, houseschests] + housesign: + aliases: [hs, hsign, housessign, housessigns] + housetrashcan: + aliases: [htc] \ No newline at end of file diff --git a/houses-master@c2d95d8e6a6/src/main/resources/premiumHouses.yml b/houses-master@c2d95d8e6a6/src/main/resources/premiumHouses.yml new file mode 100644 index 0000000..aadf300 --- /dev/null +++ b/houses-master@c2d95d8e6a6/src/main/resources/premiumHouses.yml @@ -0,0 +1,18 @@ +'1': + permits: 5 + doors: + '1': + location: world,0,0,0 + insideLocation: world,0,0,0 + outsideLocation: world,0,0,0 + chests: + '1': + loc1: world,0,0,0 + '2': + loc1: world,0,0,0 + loc2: world,0,0,0 + owner: some-random-uuid-dqsd + ownerName: An-Owner + guests: + some-other-uuid-dqsd: Other_faggot + some-faggot-samuri-dqsd: Samuri \ No newline at end of file diff --git a/hub-master@949a7e78421/.gitignore b/hub-master@949a7e78421/.gitignore new file mode 100644 index 0000000..ad7f541 --- /dev/null +++ b/hub-master@949a7e78421/.gitignore @@ -0,0 +1,8 @@ + +\.idea/ + +target/classes/ + +target/ + +*.iml \ No newline at end of file diff --git a/hub-master@949a7e78421/README.md b/hub-master@949a7e78421/README.md new file mode 100644 index 0000000..fdaec0e --- /dev/null +++ b/hub-master@949a7e78421/README.md @@ -0,0 +1 @@ +First commit. \ No newline at end of file diff --git a/hub-master@949a7e78421/pom.xml b/hub-master@949a7e78421/pom.xml new file mode 100644 index 0000000..43de6d0 --- /dev/null +++ b/hub-master@949a7e78421/pom.xml @@ -0,0 +1,119 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>net.grandtheftmc</groupId> + <artifactId>hub</artifactId> + <version>1.3.0</version> + <name>Hub</name> + + <repositories> + <repository> + <id>viaversion-repo</id> + <url>https://repo.viaversion.com</url> + </repository> + <repository> + <id>nexus-release</id> + <url>http://nexus.grandtheftmc.net/content/repositories/releases</url> + </repository> + </repositories> + + <distributionManagement> + <repository> + <id>nexus-release</id> + <name>Internal Releases</name> + <url>http://nexus.grandtheftmc.net/content/repositories/releases</url> + </repository> + <snapshotRepository> + <id>nexus-snapshot</id> + <name>Internal Snapshots</name> + <url>http://nexus.grandtheftmc.net/content/repositories/snapshots</url> + </snapshotRepository> + </distributionManagement> + + <dependencies> + <dependency> + <groupId>org.spigotmc.1.12</groupId> + <artifactId>spigot</artifactId> + <version>1.12.0</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>net.grandtheftmc</groupId> + <artifactId>core</artifactId> + <version>2.3.10</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>us.myles</groupId> + <artifactId>viaversion</artifactId> + <version>1.0.3</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.comphenix.protocol</groupId> + <artifactId>ProtocolLib</artifactId> + <version>1.0.0</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>net.grandtheftmc</groupId> + <artifactId>common</artifactId> + <version>1.1.2</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.inventivetalent</groupId> + <artifactId>mapmanager</artifactId> + <version>1.4.0</version> + <scope>provided</scope> + </dependency> + </dependencies> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <maven.compiler.source>1.8</maven.compiler.source> + <maven.compiler.target>1.8</maven.compiler.target> + </properties> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-shade-plugin</artifactId> + <configuration> + <finalName>Hub</finalName> + </configuration> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>shade</goal> + </goals> + </execution> + </executions> + </plugin> + + <!-- Nexus deploy --> + <plugin> + <groupId>org.sonatype.plugins</groupId> + <artifactId>nexus-staging-maven-plugin</artifactId> + <version>1.6.8</version> + <extensions>true</extensions> + <executions> + <execution> + <id>default-deploy</id> + <phase>deploy</phase> + <goals> + <goal>deploy</goal> + </goals> + </execution> + </executions> + <configuration> + <serverId>nexus</serverId> + <nexusUrl>http://nexus.grandtheftmc.net/</nexusUrl> + <skipStaging>true</skipStaging> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/Hub.java b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/Hub.java new file mode 100644 index 0000000..f16c04c --- /dev/null +++ b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/Hub.java @@ -0,0 +1,156 @@ +package net.grandtheftmc.hub; + +import net.grandtheftmc.ServerType; +import net.grandtheftmc.ServerTypeId; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Settings; +import net.grandtheftmc.core.alert.AlertManager; +import net.grandtheftmc.core.servers.menu.GTMTranzitMenu; +import net.grandtheftmc.core.servers.menu.TranzitMenu; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.hub.commands.SpawnCommand; +import net.grandtheftmc.hub.listeners.*; +import net.grandtheftmc.hub.patch.InventoryFillPatch; +import net.grandtheftmc.jedis.JedisChannel; +import net.grandtheftmc.jedis.JedisManager; +import net.grandtheftmc.jedis.message.ServerQueueNotifyMessage; +import org.bukkit.*; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.java.JavaPlugin; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class Hub extends JavaPlugin { + private static Hub instance; + private YamlConfiguration hubConfig; + private Collection<Location> spawnPoints; + private Location spawn; + private AlertsComponent alertsComponent; + private int progress = 0; + + private TranzitMenu tranzitMenu; + + public static Hub getInstance() { + return instance; + } + + public TranzitMenu getTranzitMenu() { + return tranzitMenu; + } + + @Override + public void onEnable() { + instance = this; + + this.load(); + this.alertsComponent = new AlertsComponent(Core.getInstance().getAlertManager()).onEnable(this); + + GTMTranzitMenu gtmTranzitMenu = new GTMTranzitMenu(); + this.tranzitMenu = new TranzitMenu(gtmTranzitMenu); + + Bukkit.getScheduler().runTaskTimer(Core.getInstance(), () -> { + tranzitMenu.rotate(); + tranzitMenu.refreshEdge(); + + gtmTranzitMenu.rotate(); + gtmTranzitMenu.refreshEdge(); + + if (progress == 3) { + tranzitMenu.refreshButtons(); + gtmTranzitMenu.refreshButtons(); + progress = 0; + return; + } + + progress++; + }, 60, 6); + + new PortalComponent(this).onEnable(this); + + this.registerCommands(); + this.registerListeners(); + } + + @Override + public void onDisable() { + Bukkit.getScheduler().cancelTasks(this); + this.unload(); + this.alertsComponent.onDisable(this); + } + + private void registerListeners() { + PluginManager pm = Bukkit.getPluginManager(); + pm.registerEvents(new Damage(), this); + pm.registerEvents(new Death(), this); + pm.registerEvents(new Drop(), this); + pm.registerEvents(new Interact(), this); + pm.registerEvents(new Join(), this); + pm.registerEvents(new Update(), this); + pm.registerEvents(new Chat(), this); + pm.registerEvents(new Move(), this); + pm.registerEvents(new PortalEnter(), this); + pm.registerEvents(new BlockPlace(), this); + + //Protocol Listeners + new InventoryFillPatch(); + } + + private void registerCommands() { + this.getCommand("spawn").setExecutor(new SpawnCommand()); + } + + public void load() { + this.spawnPoints = new ArrayList<>(); + this.hubConfig = Utils.loadConfig("hub"); + YamlConfiguration c = this.hubConfig; + this.spawn = Utils.teleportLocationFromString(c.getString("spawn")); + c.getStringList("spawnpoints").forEach(point -> { + this.spawnPoints.add(HubUtils.deserializeLocation(point)); + }); + this.loadSettings(); + } + + public void unload() { + List<String> points = new ArrayList<>(); + this.spawnPoints.forEach(point -> points.add(HubUtils.serializeLocation(point))); + this.hubConfig.set("spawnpoints", points); + Utils.saveConfig(this.hubConfig, "hub"); + } + + private void loadSettings() { + Settings settings = Core.getSettings(); + settings.setDefaultGameMode(GameMode.ADVENTURE); + settings.setUseEditMode(true); + settings.setJoinLeaveMessagesEnabled(false); + settings.setLoadCosmetics(true); + for (World world : Bukkit.getWorlds()) { + world.setGameRuleValue("commandBlockOutput", "false"); + world.setGameRuleValue("doDaylightCycle", "true"); + world.setGameRuleValue("doFireTick", "false"); + world.setGameRuleValue("doMobSpawning", "false"); + world.setGameRuleValue("doTileDrops", "false"); + world.setGameRuleValue("keepInventory", "false"); + world.setGameRuleValue("mobGriefing", "false"); + world.setGameRuleValue("naturalRegeneration", "true"); + world.setPVP(false); + world.setAutoSave(false); + world.setDifficulty(Difficulty.NORMAL); + world.setTime(18000); + settings.setStopChunkLoad(world.getName()); + settings.setStopHungerChange(world.getName()); + settings.setStopWeatherChange(world.getName()); + } + } + + public Location getSpawn() { + return this.spawn; + } + + public Collection<Location> getSpawnPoints() { + return this.spawnPoints; + } +} diff --git a/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/HubUtils.java b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/HubUtils.java new file mode 100644 index 0000000..9f4a866 --- /dev/null +++ b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/HubUtils.java @@ -0,0 +1,104 @@ +package net.grandtheftmc.hub; + +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.boards.Board; +import net.grandtheftmc.core.boards.BoardType; +import net.grandtheftmc.core.servers.Server; +import net.grandtheftmc.core.users.Pref; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.Utils; + +public final class HubUtils { + + private HubUtils() {} + + public static void giveItems(Player player) { + if (player == null) return; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + player.setHealth(20); + player.setMaxHealth(20); + player.setFoodLevel(20); + player.setGameMode(GameMode.SURVIVAL); + PlayerInventory inv = player.getInventory(); + inv.clear(); + player.getInventory().setHeldItemSlot(4); + // inv.setItem(0, Utils.createItem(Material.ENDER_CHEST, "&6&lCosmetics &7&lRight Click")); + inv.setItem(3, Utils.createItem(Material.COMPASS, "&e&lServer Warper &7&lRight Click")); + inv.setItem(5, Utils.createItem(Material.WATCH, "&d&lHub Warper &7&lRight Click")); + String b = user.getPref(Pref.PLAYERS_SHOWN) ? "&c&lHide" : "&a&lShow"; + inv.setItem(8, Utils.createItem(Material.REDSTONE_COMPARATOR, b + " Players &7&lRight Click")); + player.getActivePotionEffects().clear(); + inv.setArmorContents(null); + inv.setChestplate(new ItemStack(Material.ELYTRA)); + player.updateInventory(); + } + + public static void sendJoinMessage(Player p, User user) { + p.sendMessage(new String[]{"", "", "", "", "", "", "", "", ""}); + String[] header = Core.getAnnouncer().getHeader(); + if (header != null && header.length > 0) ; + p.sendMessage(Utils.f(Core.getAnnouncer().getHeader())); + p.sendMessage(new String[]{ + Utils.fc("Welcome, " + user.getColoredName(p) + "&r to the &7&l" + Core.getSettings().getNetworkShortName() + " &6&lHub&r!"), + Utils.fc("&e&l&oGTA in Minecraft!"), "", Utils.fc("&e&lSTORE &r&n" + Core.getSettings().getStoreLink()), + Utils.fc("&a&lSITE &r&n" + Core.getSettings().getWebsiteLink() + " "), "", Utils.fc("&7Use the &eserver warper&7 to play!")}); + String[] footer = Core.getAnnouncer().getFooter(); + if (footer != null && footer.length > 0) ; + p.sendMessage(Utils.f(Core.getAnnouncer().getFooter())); + } + + public static void updateBoard(Player player, User user) { + String rank = "No Rank"; + if (user.isSpecial()) + rank = user.getUserRank().getColoredNameBold(); + Board board = new Board("lobby", Core.getSettings().getType().getScoreboardHeader(), BoardType.KEY_VALUE); + if (Core.getSettings().isSister()) { + + int online = 0; + for (Server server : Core.getServerManager().getServers()) + online += server.getOnlinePlayers(); + board.addValue("d", "Players Online", online + ""); + + board.addValue("6", "Rank", rank); + board.addValue("6", "Server IP", Core.getSettings().getNetworkIP()); + } + else { + board.addValue("a", "Tokens", String.valueOf(user.getTokens())); + board.addValue("e", "Crowbars", String.valueOf(Math.max(user.getCrowbars(), 0))); + board.addValue("6", "Rank", rank); + board.addValue("6", "Server IP", Core.getSettings().getNetworkIP()); + //board.addValue("6", "Server IP", user.getjoin) + } + board.updateFor(player, user); + } + + public static String serializeLocation(Location location) { + String world = location.getWorld().getName(); + String x = String.valueOf(location.getX()); + String y = String.valueOf(location.getY()); + String z = String.valueOf(location.getZ()); + String yaw = String.valueOf(location.getYaw()); + String pitch = String.valueOf(location.getPitch()); + return world + ':' + x + ':' + y + ':' + z + ':' + yaw + ':' + pitch; + } + + public static Location deserializeLocation(String loc) { + String[] args = loc.split(":"); + World world = Bukkit.getWorld(args[0]); + double x = Double.valueOf(args[1]); + double y = Double.valueOf(args[2]); + double z = Double.valueOf(args[3]); + float yaw = Float.valueOf(args[4]); + float pitch = Float.valueOf(args[5]); + return new Location(world, x, y, z, yaw, pitch); + } +} diff --git a/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/Testing.java b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/Testing.java new file mode 100644 index 0000000..a2c0c3f --- /dev/null +++ b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/Testing.java @@ -0,0 +1,41 @@ +package net.grandtheftmc.hub; + +import java.util.Arrays; + +public class Testing { + + private static Integer[][] array = new Integer[5][5]; + private static int idk = 6; + + public static void main(String[] args) { + for (int i = 0; i < 5; i++) { + for (int x = 0; x < 5; x++) { + array[i][x] = i + 1; + } + } + + for (int i = 0; i < 5; i ++) { + + for (int x = 0; x < array.length; x++) { + System.out.println(Arrays.toString(array[x])); + } + + move(); + System.out.println(""); + } + } + + private static void move() { + Integer[][] temp = new Integer[array.length][array[0].length]; + for (int i = array.length - 1; i > 0; i--) { + temp[i - 1] = array[i]; + } + + for (int x = 0; x < array[array.length - 1].length; x++) { + temp[array.length - 1][x] = idk; + } + + idk += 1; + array = temp; + } +} diff --git a/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/commands/SpawnCommand.java b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/commands/SpawnCommand.java new file mode 100644 index 0000000..363f824 --- /dev/null +++ b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/commands/SpawnCommand.java @@ -0,0 +1,46 @@ +package net.grandtheftmc.hub.commands; + +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.hub.Hub; +import org.bukkit.Location; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class SpawnCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Utils.f("&cYou are not a player!")); + return true; + } + Player player = (Player) s; + if(args.length == 1) { + if(args[0].equalsIgnoreCase("add")) { + Hub.getInstance().getSpawnPoints().add(player.getLocation()); + player.sendMessage(player.getLocation().toString() + " added"); + } else if(args[0].equalsIgnoreCase("remove")) { + Location loc = getNearestLocation(player.getLocation()); + Hub.getInstance().getSpawnPoints().remove(loc); + player.sendMessage(loc.toString() + " removed"); + } + } else { + player.teleport(Hub.getInstance().getSpawn()); + player.sendMessage(Utils.f("&aYou were teleported to spawn!")); + } + return true; + } + + public static Location getNearestLocation(Location location) { + Location nearestLocation = null; + for(Location point : Hub.getInstance().getSpawnPoints()) { + if(nearestLocation == null || point.distance(location) < point.distance(location)) { + nearestLocation = point; + } + } + return nearestLocation; + } + +} diff --git a/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/AlertsComponent.java b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/AlertsComponent.java new file mode 100644 index 0000000..512a661 --- /dev/null +++ b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/AlertsComponent.java @@ -0,0 +1,268 @@ +package net.grandtheftmc.hub.listeners; + +import java.io.IOException; +import java.net.URL; +import java.util.HashMap; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; + +import javax.imageio.ImageIO; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.AsyncPlayerPreLoginEvent; +import org.bukkit.event.player.PlayerInteractAtEntityEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemStack; +import org.inventivetalent.mapmanager.MapManagerPlugin; +import org.inventivetalent.mapmanager.controller.MapController; +import org.inventivetalent.mapmanager.manager.MapManager; +import org.inventivetalent.mapmanager.wrapper.MapWrapper; + +import com.google.common.collect.Maps; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.alert.Alert; +import net.grandtheftmc.core.alert.AlertManager; +import net.grandtheftmc.core.util.Component; +import net.grandtheftmc.core.util.ImageRenderer; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.title.NMSTitle; +import net.grandtheftmc.hub.Hub; + +/** + * Created by Luke Bingham on 12/09/2017. + */ +public class AlertsComponent implements Component<AlertsComponent, Hub> { + + private final HashMap<UUID, Alert> userAlerts; + private final HashMap<Integer, MapData> renders; + private final AlertManager alertManager; + private final NMSTitle title; + + private final MapManager mapManager = ((MapManagerPlugin) Bukkit.getPluginManager().getPlugin("MapManager")).getMapManager(); + + public AlertsComponent(AlertManager alertManager) { + this.alertManager = alertManager; + this.userAlerts = Maps.newHashMap(); + this.renders = Maps.newHashMap(); + this.title = new NMSTitle(); + } + + @Override + public AlertsComponent onEnable(Hub plugin) { + Bukkit.getPluginManager().registerEvents(this, plugin); + log(true); + return this; + } + + @Override + public AlertsComponent onDisable(Hub plugin) { + this.userAlerts.clear(); + return this; + } + + @EventHandler + protected final void onPreJoin(AsyncPlayerPreLoginEvent event) { + if(event.getLoginResult() == AsyncPlayerPreLoginEvent.Result.ALLOWED) { + if(this.alertManager.getAlerts().size() > 0 && this.alertManager.getAvailableAlerts().size() > 0) { + this.alertManager.getAvailableAlertsForPlayer(event.getUniqueId(), alerts -> { + if(alerts.size() > 0) { + Alert alert = alerts.get(ThreadLocalRandom.current().nextInt(alerts.size())); + this.userAlerts.putIfAbsent(event.getUniqueId(), alert); + } + }); + } + } + } + + @EventHandler(priority = EventPriority.HIGH) + protected final void onPlayerJoin(PlayerJoinEvent event) { + if(event.getPlayer() == null) return; + UUID uuid = event.getPlayer().getUniqueId(); + if(this.userAlerts.containsKey(uuid)) { + Alert alert = this.userAlerts.get(uuid); + +// ItemStack map = new ItemStack(Material.MAP); +// MapMeta meta = (MapMeta) map.getItemMeta(); +// meta.setScaling(false); +// meta.setDisplayName(C.GREEN + C.BOLD + alert.getName()); +// map.setItemMeta(meta); + + +// MapView view = Bukkit.getMap(map.getDurability()); +// for (MapRenderer mapRenderer : view.getRenderers()) +// view.removeRenderer(mapRenderer); + + try { +// ImageRenderer renderer = null; + + MapData mapData; + if(!this.renders.containsKey(alert.getUniqueIdentifier())) { +// renderer = new ImageRenderer(alert.getImageUrl()); +// this.renders.put(alert.getUniqueIdentifier(), renderer); + MapWrapper mapWrapper = mapManager.wrapImage(ImageIO.read(new URL(alert.getImageUrl()))); + mapData = new MapData(mapManager.wrapImage(ImageIO.read(new URL(alert.getImageUrl()))), mapWrapper.getController()); + this.renders.putIfAbsent(alert.getUniqueIdentifier(), mapData); + } + else mapData = this.renders.get(alert.getUniqueIdentifier()); + +// view.addRenderer(renderer); + +// event.getPlayer().getInventory().setItem(4, map); +// event.getPlayer().updateInventory(); + + MapController controller = mapData.getController(); + controller.addViewer(event.getPlayer());//TODO Remove on join. + controller.sendContent(event.getPlayer()); + + ServerUtil.runTaskLater(() -> { + if(Bukkit.getPlayer(uuid) != null){ + controller.showInInventory(Bukkit.getPlayer(uuid), 4, true, alert.getName()); + //controller.showInInventory(Bukkit.getPlayer(uuid), 4, true); + } + }, 10); + + Location current = event.getPlayer().getLocation(); + current.setPitch(50); + event.getPlayer().teleport(current); + + this.alertManager.alertShown(event.getPlayer(), alert, aBoolean -> {}); + + } catch (IOException e) { + this.userAlerts.remove(uuid); + event.getPlayer().getInventory().setItem(4, new ItemStack(Material.AIR)); + event.getPlayer().updateInventory(); + e.printStackTrace(); + } + } + } + + @EventHandler + protected final void onLeave(PlayerQuitEvent event) { + if(event.getPlayer() == null) return; + if(this.userAlerts.containsKey(event.getPlayer().getUniqueId())) { + this.userAlerts.remove(event.getPlayer().getUniqueId()); + ImageRenderer.RENDERED_USERS.remove(event.getPlayer().getUniqueId()); + } + + for(MapData data : this.renders.values()) { + data.controller.removeViewer(event.getPlayer()); + } + } + + @EventHandler + protected final void onInteract(PlayerInteractEvent event) { +// if(event.getItem() == null) return; +// ItemStack item = event.getItem(); +// if(!item.hasItemMeta()) return; +// String name = ChatColor.stripColor(item.getItemMeta().getDisplayName()); +// +// for(Alert alert : this.userAlerts.values()) { +// if(alert == null) continue; +// if(alert.getName() == null || alert.getLink() == null) continue; +// if(alert.getName().equals(name)) { +// event.getPlayer().sendMessage(Lang.ALERTS.f(alert.getLink())); +// this.title.sendTitle(event.getPlayer(), "", Utils.f("&eClick the link in chat!"), 1, 1, 1); +// break; +// } +// } + + if(event.getHand() != EquipmentSlot.HAND) return; + if(event.getPlayer().getInventory().getHeldItemSlot() != 4) return; + + if(this.userAlerts.containsKey(event.getPlayer().getUniqueId())) { + Alert alert = this.userAlerts.get(event.getPlayer().getUniqueId()); + event.getPlayer().sendMessage(Lang.ALERTS.f(alert.getLink())); + NMSTitle.sendTitle(event.getPlayer(), "", Utils.f("&eClick the link in chat!"), 30, 20, 20); + } + } + + @EventHandler + protected final void onInteract(PlayerInteractAtEntityEvent event) { +// if(event.getHand() == EquipmentSlot.OFF_HAND) return; +// ItemStack item = event.getPlayer().getInventory().getItemInMainHand(); +// if(item == null || item.getType() != Material.MAP) return; +// if(!item.hasItemMeta()) return; +// String name = ChatColor.stripColor(item.getItemMeta().getDisplayName()); +// System.out.println(name); +// +// for(UUID uuid : this.userAlerts.keySet()) { +// +// if(alert == null) continue; +// if(alert.getName() == null) continue; +// if(alert.getName().equals(name)) { +// event.getPlayer().sendMessage(Lang.ALERTS.f(alert.getLink())); +// this.title.sendTitle(event.getPlayer(), "", Utils.f("&eClick the link in chat!"), 1, 1, 1); +// break; +// } +// } + + if(event.getHand() != EquipmentSlot.HAND) return; + if(event.getPlayer().getInventory().getHeldItemSlot() != 4) return; + + if(this.userAlerts.containsKey(event.getPlayer().getUniqueId())) { + Alert alert = this.userAlerts.get(event.getPlayer().getUniqueId()); + event.getPlayer().sendMessage(Lang.ALERTS.f(alert.getLink())); + NMSTitle.sendTitle(event.getPlayer(), "", Utils.f("&eClick the link in chat!"), 1, 1, 1); + } + } + +// private final Random random = new Random(); +// +// @EventHandler +// protected final void onMapInitialize(MapInitializeEvent event) { +// MapView mapView = event.getMap(); +// mapView.getRenderers().clear(); +// +// +// +// mapView.addRenderer(new Renderer()); +// } +// +// public class Renderer extends MapRenderer { +// @Override +// public void render(MapView mapView, MapCanvas mapCanvas, Player player) { +// for (int x = 25; x < 50; x++) { +// for (int y = 25; y < 50; y++) { +// mapCanvas.setPixel(x, y, MapPalette.RED); +// } +// } +// +// mapCanvas.drawText(15, 15, MinecraftFont.Font, player.getName()); +// +// byte[] dirs = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}, color = {0,1,2,3,4,5,6,7}; +// MapCursorCollection cursors = new MapCursorCollection(); +// for(int i = 0; i < 10; i++) { +// cursors.addCursor(random.nextInt(128), random.nextInt(128), dirs[random.nextInt(dirs.length)], color[random.nextInt(color.length)]); +// } +// +// mapCanvas.setCursors(cursors); +// } +// } + + public class MapData { + private final MapWrapper mapWrapper; + private final MapController controller; + + public MapData(MapWrapper mapWrapper, MapController controller) { + this.mapWrapper = mapWrapper; + this.controller = controller; + } + + public MapWrapper getMapWrapper() { + return mapWrapper; + } + + public MapController getController() { + return controller; + } + } +} diff --git a/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/BlockPlace.java b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/BlockPlace.java new file mode 100644 index 0000000..613bc43 --- /dev/null +++ b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/BlockPlace.java @@ -0,0 +1,17 @@ +package net.grandtheftmc.hub.listeners; + +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockPlaceEvent; + +public class BlockPlace implements Listener { + + @EventHandler(priority = EventPriority.HIGHEST) + public void blockPlaceEvent(BlockPlaceEvent event) { + if (!event.getPlayer().isOp()) { + event.setBuild(false); + event.setCancelled(true); + } + } +} diff --git a/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/Chat.java b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/Chat.java new file mode 100644 index 0000000..d133976 --- /dev/null +++ b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/Chat.java @@ -0,0 +1,37 @@ +package net.grandtheftmc.hub.listeners; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +public class Chat implements Listener { + private Map<String, Long> recentChats = new HashMap<>(); + + @EventHandler(priority = EventPriority.LOWEST) + public void onChat(AsyncPlayerChatEvent event) { + Player player = event.getPlayer(); + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (user.getUserRank() == UserRank.DEFAULT) { + if (recentChats.containsKey(player.getName())) { + if (recentChats.get(player.getName()) + TimeUnit.SECONDS.toMillis(2) >= System.currentTimeMillis()) { + player.sendMessage(Lang.HUB.f("&7You must wait a second before speaking again!")); + event.setCancelled(true); + } else { + recentChats.remove(player.getName()); + } + } else { + recentChats.put(player.getName(), System.currentTimeMillis()); + } + } + } +} \ No newline at end of file diff --git a/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/Damage.java b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/Damage.java new file mode 100644 index 0000000..7fa8074 --- /dev/null +++ b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/Damage.java @@ -0,0 +1,29 @@ + +package net.grandtheftmc.hub.listeners; + +import net.grandtheftmc.hub.Hub; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageEvent; + +public class Damage implements Listener { + + @EventHandler + public void onDamageByEntity(EntityDamageEvent event) { + if (!(event.getEntity() instanceof Player)) return; + event.getEntity().setFireTicks(0); + event.setCancelled(true); + switch (event.getCause()) { + case VOID: + case SUFFOCATION: + case CUSTOM: + event.getEntity().teleport(Hub.getInstance().getSpawn()); + break; + + default: + break; + } + } + +} diff --git a/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/Death.java b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/Death.java new file mode 100644 index 0000000..d05ffad --- /dev/null +++ b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/Death.java @@ -0,0 +1,18 @@ +package net.grandtheftmc.hub.listeners; + +import net.grandtheftmc.hub.Hub; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.PlayerDeathEvent; + +public class Death implements Listener { + + @EventHandler + public void onDeath(PlayerDeathEvent e) { + e.setDeathMessage(null); + Player player = e.getEntity(); + player.setHealth(20); + player.teleport(Hub.getInstance().getSpawn()); + } +} diff --git a/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/Drop.java b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/Drop.java new file mode 100644 index 0000000..5644ede --- /dev/null +++ b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/Drop.java @@ -0,0 +1,22 @@ +package net.grandtheftmc.hub.listeners; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.inventory.ItemStack; + +public class Drop implements Listener { + + @EventHandler(priority = EventPriority.MONITOR) + public void onDrop(PlayerDropItemEvent e) { + if (e.isCancelled()) e.setCancelled(false); + Player p = e.getPlayer(); + ItemStack item = e.getItemDrop().getItemStack().clone(); + item.setAmount(p.getInventory().getItemInMainHand().getAmount() + item.getAmount()); + e.getItemDrop().remove(); + p.getInventory().setItem(p.getInventory().getHeldItemSlot(), item); + p.updateInventory(); + } +} diff --git a/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/Interact.java b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/Interact.java new file mode 100644 index 0000000..bf70f35 --- /dev/null +++ b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/Interact.java @@ -0,0 +1,160 @@ +package net.grandtheftmc.hub.listeners; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.servers.Server; +import net.grandtheftmc.core.servers.ServerManager; +import net.grandtheftmc.core.users.Pref; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserManager; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.hub.Hub; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.Sign; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +public class Interact implements Listener { + private Map<String, Long> recentClicks = new HashMap<>(); + + @EventHandler + public void onInteract(PlayerInteractEvent event) { + UserManager um = Core.getUserManager(); + if (event.getAction() != Action.RIGHT_CLICK_AIR && event.getAction() != Action.RIGHT_CLICK_BLOCK) + return; + Player player = event.getPlayer(); + UUID uuid = player.getUniqueId(); + User user = Core.getUserManager().getLoadedUser(uuid); + ItemStack item = player.getInventory().getItemInMainHand(); + if (item != null) { + switch (item.getType()) { + case COMPASS: + if (!Core.getSettings().serverWarperEnabled()) + return; + event.setCancelled(true); +// MenuManager.openMenu(player, "serverwarper"); + Hub.getInstance().getTranzitMenu().openInventory(player); + return; + case WATCH: + if (!Core.getSettings().serverWarperEnabled()) + return; + event.setCancelled(true); + MenuManager.openMenu(player, "hubservers"); + return; + case BOOK: + return; + case ENDER_CHEST: + MenuManager.openMenu(player, "cosmetics"); + event.setCancelled(true); + return; + case REDSTONE_COMPARATOR: + if (recentClicks.containsKey(player.getName())) { + if (recentClicks.get(player.getName()) + TimeUnit.SECONDS.toMillis(3) >= System.currentTimeMillis()) { + player.sendMessage(Lang.HUB.f("&7You must wait before toggling this again!")); + event.setCancelled(true); + return; + } else { + recentClicks.put(player.getName(), System.currentTimeMillis()); + } + } else { + recentClicks.put(player.getName(), System.currentTimeMillis()); + } + if(user.getPref(Pref.PLAYERS_SHOWN)) { + player.sendMessage(Lang.PREFS.f("&7Players are now hidden")); + for (Player target : Bukkit.getOnlinePlayers()) { + User targetUser = Core.getUserManager().getLoadedUser(target.getUniqueId()); + if(targetUser.getPref(Pref.PLAYERS_SHOWN)) target.hidePlayer(player); + player.hidePlayer(target); + } + } else { + player.sendMessage(Lang.PREFS.f("&7Players are now shown")); + for (Player target : Bukkit.getOnlinePlayers()) { + User targetUser = Core.getUserManager().getLoadedUser(target.getUniqueId()); + if(targetUser.getPref(Pref.PLAYERS_SHOWN)) target.showPlayer(player); + player.showPlayer(target); + } + } + user.setPref(player, Pref.PLAYERS_SHOWN, !user.getPref(Pref.PLAYERS_SHOWN)); + ItemMeta meta = item.getItemMeta(); + String b = user.getPref(Pref.PLAYERS_SHOWN) ? "&c&lHide" : "&a&lShow"; + meta.setDisplayName(Utils.f(b + " Players &7&lRight Click")); + item.setItemMeta(meta); + event.setCancelled(true); + return; + case EXP_BOTTLE: + event.setCancelled(true); + player.updateInventory(); + MenuManager.openMenu(player, "rewards"); + return; + default: + break; + } + + } + Block block = event.getClickedBlock(); + if (block == null) return; + if (block.getType() == Material.WALL_SIGN) { + Sign sign = (Sign) block.getState(); + Server server = null; + ServerManager sm = Core.getServerManager(); + for (Server s : sm.getServers()) { + if (s.getJoinSigns().contains(sign.getLocation())) { + server = s; + break; + } + } + if (server == null) return; + if (server.needsRankToJoin() && server.getRankToJoin().isHigherThan(user.getUserRank())) { + player.sendMessage(Utils.f("&cSorry, this game is for " + server.getRankToJoin().getColoredNameBold() + + "&c and up only! Go to " + Core.getSettings().getStoreLink() + " to purchase a rank!")); + return; + } + + if (Objects.equals(server.getGameState(), "INGAME") && !user.isSpecial()) { + player.sendMessage(Utils.f( + "&cThis game is in progress! You must be &6&lVIP&c or above to spectate games! Go to " + Core.getSettings().getStoreLink() + " to purchase a rank!")); + return; + } else if (Objects.equals(server.getGameState(), "END")) { + player.sendMessage(Utils.f("&cThis game is ending! There is no point in joining now!")); + return; + } + + if (server.isFull() && (!user.isSpecial() || user.getUserRank() == UserRank.VIP)) { + player.sendMessage( + Utils.f("&cSorry, this server is full! You must be &a&lPREMIUM&c or up to join full games!")); + return; + } + player.sendMessage(Utils.f("&7Joining server &a&l" + server.getName().toUpperCase() + "&7...")); + sm.sendToServer(player, server.getName()); + } + } + + @EventHandler(ignoreCancelled = true) + protected final void onInventoryClick(InventoryClickEvent event) { + Player player = (Player) event.getWhoClicked(); + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (user == null) { + event.setCancelled(true); + return; + } + + if (!user.hasEditMode()) + event.setCancelled(true); + } +} \ No newline at end of file diff --git a/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/Join.java b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/Join.java new file mode 100644 index 0000000..808bb69 --- /dev/null +++ b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/Join.java @@ -0,0 +1,82 @@ +package net.grandtheftmc.hub.listeners; + +import java.util.Random; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.database.mutex.Mutexable; +import net.grandtheftmc.core.database.mutex.event.MutexLoadCompleteEvent; +import net.grandtheftmc.core.users.Pref; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.hub.Hub; +import net.grandtheftmc.hub.HubUtils; +import us.myles.ViaVersion.api.Via; + +public class Join implements Listener { + + @EventHandler + public void onJoin(PlayerJoinEvent e) { + + // grab event variables + Player player = e.getPlayer(); + + // see below method + } + + @EventHandler + public void onMutexLoadComplete(MutexLoadCompleteEvent event) { + + // grab event variables + Mutexable mutexable = event.getMutexable(); + if (mutexable instanceof User) { + User user = (User) mutexable; + + // make sure still online + Player player = Bukkit.getPlayer(user.getUUID()); + if (player != null) { + + HubUtils.sendJoinMessage(player, user); + HubUtils.giveItems(player); + HubUtils.updateBoard(player, user); + user.setPref(player, Pref.PLAYERS_SHOWN, true); + player.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, Integer.MAX_VALUE, 2)); + + if (Bukkit.getPluginManager().getPlugin("ViaVersion") != null) { + int playerVersion = Via.getAPI().getPlayerVersion(player.getUniqueId()); + if (playerVersion < 210) { + player.sendMessage(Lang.HEY.f("&7It appears you're using an older version of Minecraft. " + "It is highly recommended you use the latest Minecraft version for the best experience!")); + } + } + + if (Hub.getInstance().getSpawn() != null) { + if (Hub.getInstance().getSpawnPoints().isEmpty()) { + player.teleport(Hub.getInstance().getSpawn()); + return; + } + int size = Hub.getInstance().getSpawnPoints().size(); + player.teleport((Location) Hub.getInstance().getSpawnPoints().toArray()[new Random().nextInt(size)]); + } + } + } + } + + @EventHandler + public void onMove(PlayerMoveEvent event) { + Player player = event.getPlayer(); + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (!user.hasMoved()) { + user.setHasMoved(); + user.updateVisibility(player); + } + } +} diff --git a/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/Move.java b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/Move.java new file mode 100644 index 0000000..073fab8 --- /dev/null +++ b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/Move.java @@ -0,0 +1,25 @@ +package net.grandtheftmc.hub.listeners; + +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.util.Vector; + +public class Move implements Listener { + + @EventHandler + public void onPlayerMove(PlayerMoveEvent event) { + if(event.getFrom() == event.getTo()) return; + Player player = event.getPlayer(); + if (player.isGliding() && player.isSneaking()) { + double pitch = -event.getTo().getPitch(); + if (pitch < 10 || pitch > 90) return; + Vector vector = player.getLocation().getDirection(); + player.setVelocity(vector.multiply(1.6)); + player.getWorld().playSound(player.getLocation(), Sound.ENTITY_ARROW_SHOOT, 1.0F, 2.0F); + player.getInventory().getChestplate().setDurability((short) 0); + } + } +} diff --git a/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/PortalComponent.java b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/PortalComponent.java new file mode 100644 index 0000000..723feb9 --- /dev/null +++ b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/PortalComponent.java @@ -0,0 +1,187 @@ +package net.grandtheftmc.hub.listeners; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.BlockPosition; +import com.comphenix.protocol.wrappers.WrappedBlockData; +import net.grandtheftmc.core.util.Component; +import net.grandtheftmc.core.wrapper.packet.AbstractPacket; +import net.grandtheftmc.hub.Hub; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.util.Vector; + +import java.util.Random; + +public class PortalComponent implements Component<PortalComponent, Hub> { + + private CustomPlayServerBlockChange[][] positions; + private final Random random; + + public PortalComponent(JavaPlugin plugin) { + this.positions = new CustomPlayServerBlockChange[23][17]; + this.random = new Random(); + + Bukkit.getPluginManager().registerEvents(this, plugin); + + World world = Bukkit.getWorld("world"); + Location loc1 = new Location(world, 351.5, 134, -130.5); + Location loc2 = new Location(world, 337.5, 112, -130.5); + + int arr1 = -1; + for (int y = loc1.getBlockY(); y > loc2.getBlockY() - 1; y--) { + arr1++; + + int arr2 = -1; + for (int x = loc1.getBlockX(); x > loc2.getBlockX() - 1; x--) { + arr2++; + + boolean b = random.nextInt(2) == 1; + WrappedBlockData blockData = WrappedBlockData.createData(b ? Material.STAINED_GLASS : Material.STAINED_GLASS_PANE, b ? (random.nextBoolean() ? 5 : 13) : 8); + + CustomPlayServerBlockChange info = new CustomPlayServerBlockChange(); + info.setLocation(new BlockPosition(x, y, loc1.getBlockZ())); + info.setBlockData(blockData); + + this.positions[arr1][arr2] = info; + } + } + } + + @Override + public PortalComponent onEnable(Hub plugin) { + + //Scrolling portal effect +// Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, () -> { +// for (CustomPlayServerBlockChange[] array : this.positions) { +// for (CustomPlayServerBlockChange packet : array) { +// if (packet == null) continue; +// if (!packet.isVisible()) continue; +// +// for (Player player : Bukkit.getOnlinePlayers()) { +// packet.sendPacket(player); +// } +// } +// } +// +// moveDown(); +// }, 100, 1); + return this; + } + + private final Location loc1 = new Location(Bukkit.getWorld("world"), 351.5, 134, -131.5); + private final Location loc2 = new Location(Bukkit.getWorld("world"), 337.5, 112, -130.5); + private Location spawn = null; + + @EventHandler + protected final void onPlayerMove(PlayerMoveEvent event) { + Location loc = event.getTo(); +// if (event.getPlayer().getOpenInventory() != null) { +// if (event.getPlayer().getOpenInventory().getTopInventory() != null) { +// return; +// } +// } + + if (event.getFrom().getBlockX() == event.getTo().getBlockX() && event.getFrom().getBlockY() == event.getTo().getBlockY() && event.getFrom().getBlockZ() == event.getTo().getBlockZ()) return; + + if ((loc.getBlockX() <= loc1.getBlockX() && loc.getBlockX() >= loc2.getBlockX()) && + (loc.getBlockY() <= loc1.getBlockY() && loc.getBlockY() >= loc2.getBlockY()) && + (Math.abs(loc.getBlockZ()) <= Math.abs(loc1.getBlockZ()) && Math.abs(loc.getBlockZ()) >= Math.abs(loc2.getBlockZ()))) { + Hub.getInstance().getTranzitMenu().openInventory(event.getPlayer()); + + if (spawn == null) { + spawn = ((Location) Hub.getInstance().getSpawnPoints().toArray()[0]).clone(); + } + + Vector to = spawn.toVector().subtract(loc.toVector()).normalize(); + to.setY(to.getY() + 1); + + event.getPlayer().setVelocity(to); + } + } + + private void moveDown() { + CustomPlayServerBlockChange[][] temp = new CustomPlayServerBlockChange[this.positions.length][this.positions[0].length]; + + for (int i = this.positions.length - 1; i > 0; i--) { + temp[i - 1] = this.positions[i]; + } + + for (int x = 0; x < this.positions[this.positions.length - 1].length; x++) { + CustomPlayServerBlockChange blockChange = this.positions[0][x]; + if (blockChange == null) continue; + + boolean b = random.nextInt(2) == 1; + blockChange.setBlockData(WrappedBlockData.createData(b ? Material.STAINED_GLASS : Material.STAINED_GLASS_PANE, b ? (random.nextBoolean() ? 5 : 13) : 8)); + + temp[this.positions.length - 1][x] = blockChange; + } + + this.positions = temp; + } + + /** + * This is a Wrapped block change packet, + * I have a custom one for visibility option. + */ + private static class CustomPlayServerBlockChange extends AbstractPacket { + public static final PacketType TYPE; + private boolean existing; + + public CustomPlayServerBlockChange() { + super(new PacketContainer(TYPE), TYPE); + this.handle.getModifier().writeDefaults(); + } + + public CustomPlayServerBlockChange(PacketContainer packet) { + super(packet, TYPE); + } + + public BlockPosition getLocation() { + return (BlockPosition)this.handle.getBlockPositionModifier().read(0); + } + + public void setLocation(BlockPosition value) { + this.handle.getBlockPositionModifier().write(0, value); + } + + public Location getBukkitLocation(World world) { + return this.getLocation().toVector().toLocation(world); + } + + public WrappedBlockData getBlockData() { + return (WrappedBlockData)this.handle.getBlockData().read(0); + } + + public void setBlockData(WrappedBlockData value) { + this.handle.getBlockData().write(0, value); + } + + public boolean isExisting() { + return existing; + } + + public void setExisting(boolean existing) { + this.existing = existing; + } + + public boolean isVisible() { + World world = Bukkit.getWorld("world"); + Location loc = getBukkitLocation(world); + Block block = world.getBlockAt(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + boolean b = block.getType() == Material.STAINED_GLASS || block.getType() == Material.STAINED_GLASS_PANE; + return b; + } + + static { + TYPE = PacketType.Play.Server.BLOCK_CHANGE; + } + } +} diff --git a/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/PortalEnter.java b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/PortalEnter.java new file mode 100644 index 0000000..e0b0ea5 --- /dev/null +++ b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/PortalEnter.java @@ -0,0 +1,23 @@ +package net.grandtheftmc.hub.listeners; + +import net.grandtheftmc.core.menus.MenuManager; +import org.bukkit.Sound; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityPortalEnterEvent; +import org.bukkit.event.inventory.InventoryType; + +public class PortalEnter implements Listener { + + @EventHandler + public void playerPortalEvent(EntityPortalEnterEvent event) { + if (event.getEntityType() != EntityType.PLAYER) return; + Player player = (Player) event.getEntity(); + if (player.getOpenInventory() != null && player.getOpenInventory().getType() == InventoryType.CHEST) return; + player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1F, 1F); + player.setVelocity(player.getLocation().getDirection().setY(2).multiply(-1)); + MenuManager.openMenu(player, "serverwarper"); + } +} diff --git a/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/Update.java b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/Update.java new file mode 100644 index 0000000..387dfbd --- /dev/null +++ b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/listeners/Update.java @@ -0,0 +1,41 @@ +package net.grandtheftmc.hub.listeners; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.events.UpdateEvent; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.hub.HubUtils; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +public class Update implements Listener { + + @EventHandler + public void onUpdate(UpdateEvent e) { + Player player = e.getPlayer(); + switch (e.getReason()) { + case BOARD: + case BUCKS: + case TOKENS: + case RANK: + HubUtils.updateBoard(player, Core.getUserManager().getLoadedUser(player.getUniqueId())); + break; + case PREF: + switch (e.getPref()) { + case PLAYERS_SHOWN: + User u = Core.getUserManager().getLoadedUser(player.getUniqueId()); + u.setLastPlayersToggle(System.currentTimeMillis()); + u.updateVisibility(player); + break; + case USE_SCOREBOARD: + HubUtils.updateBoard(player, Core.getUserManager().getLoadedUser(player.getUniqueId())); + break; + default: + break; + } + break; + default: + break; + } + } +} diff --git a/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/patch/InventoryFillPatch.java b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/patch/InventoryFillPatch.java new file mode 100644 index 0000000..2e1571d --- /dev/null +++ b/hub-master@949a7e78421/src/main/java/net/grandtheftmc/hub/patch/InventoryFillPatch.java @@ -0,0 +1,60 @@ +package net.grandtheftmc.hub.patch; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.events.ListeningWhitelist; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.events.PacketListener; +import com.comphenix.protocol.injector.GamePhase; +import net.grandtheftmc.hub.Hub; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +/** + * Created by Luke Bingham on 12/08/2017. + */ +public class InventoryFillPatch implements PacketListener { + + public InventoryFillPatch() { + ProtocolLibrary.getProtocolManager().addPacketListener(this); + } + + @Override + public void onPacketSending(PacketEvent packetEvent) { + PacketContainer packet = packetEvent.getPacket(); + Player player = packetEvent.getPlayer(); + + if(packet.getType().equals(PacketType.Play.Server.WINDOW_ITEMS)) { + packet.getItemListModifier().read(0).forEach(item -> { + if(item.getTypeId() == 386) { + item.setType(Material.AIR); + packetEvent.setCancelled(true); + } + }); + } + } + + @Override + public void onPacketReceiving(PacketEvent packetEvent) { + //Nothing here. + } + + @Override + public ListeningWhitelist getSendingWhitelist() { + return ListeningWhitelist.newBuilder().normal().gamePhase(GamePhase.PLAYING).types( + PacketType.Play.Server.WINDOW_ITEMS + ).build(); + } + + @Override + public ListeningWhitelist getReceivingWhitelist() { + return ListeningWhitelist.EMPTY_WHITELIST; + } + + @Override + public Plugin getPlugin() { + return Hub.getInstance(); + } +} diff --git a/hub-master@949a7e78421/src/main/resources/hub.yml b/hub-master@949a7e78421/src/main/resources/hub.yml new file mode 100644 index 0000000..0812e6f --- /dev/null +++ b/hub-master@949a7e78421/src/main/resources/hub.yml @@ -0,0 +1,4 @@ +spawn: world,0,0,0,0,0 + +spawnpoints: +- world:0:0:0:0:0 \ No newline at end of file diff --git a/hub-master@949a7e78421/src/main/resources/plugin.yml b/hub-master@949a7e78421/src/main/resources/plugin.yml new file mode 100644 index 0000000..1cdaef0 --- /dev/null +++ b/hub-master@949a7e78421/src/main/resources/plugin.yml @@ -0,0 +1,11 @@ + name: Hub + version: 1.0 + description: Hub + author: Presidentx + main: net.grandtheftmc.hub.Hub + depend: [Core, MapManager] + commands: + spawn: + description: Teleport to the spawn point + usage: /spawn + default: true diff --git a/vice-master@f8937e1dbf1/.gitignore b/vice-master@f8937e1dbf1/.gitignore new file mode 100644 index 0000000..ad7f541 --- /dev/null +++ b/vice-master@f8937e1dbf1/.gitignore @@ -0,0 +1,8 @@ + +\.idea/ + +target/classes/ + +target/ + +*.iml \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/README.md b/vice-master@f8937e1dbf1/README.md new file mode 100644 index 0000000..fdaec0e --- /dev/null +++ b/vice-master@f8937e1dbf1/README.md @@ -0,0 +1 @@ +First commit. \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/chests/abandoned_mineshaft.json b/vice-master@f8937e1dbf1/loot_tables/chests/abandoned_mineshaft.json new file mode 100644 index 0000000..d3b0e2e --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/chests/abandoned_mineshaft.json @@ -0,0 +1,276 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:golden_apple", + "weight": 20 + }, + { + "type": "item", + "name": "minecraft:golden_apple", + "weight": 1, + "functions": [ + { + "function": "set_data", + "data": 1 + } + ] + }, + { + "type": "item", + "name": "minecraft:name_tag", + "weight": 30 + }, + { + "type": "item", + "name": "minecraft:book", + "weight": 10, + "functions": [ + { + "function": "enchant_randomly" + } + ] + }, + { + "type": "item", + "name": "minecraft:iron_pickaxe", + "weight": 5 + }, + { + "type": "empty", + "weight": 5 + } + ] + }, + { + "rolls": { + "min": 2, + "max": 4 + }, + "entries": [ + { + "type": "item", + "name": "minecraft:iron_ingot", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 5 + } + } + ], + "weight": 10 + }, + { + "type": "item", + "name": "minecraft:gold_ingot", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 3 + } + } + ], + "weight": 5 + }, + { + "type": "item", + "name": "minecraft:redstone", + "functions": [ + { + "function": "set_count", + "count": { + "min": 4, + "max": 9 + } + } + ], + "weight": 5 + }, + { + "type": "item", + "name": "minecraft:dye", + "functions": [ + { + "function": "set_data", + "data": 4 + }, + { + "function": "set_count", + "count": { + "min": 4, + "max": 9 + } + } + ], + "weight": 5 + }, + { + "type": "item", + "name": "minecraft:diamond", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 2 + } + } + ], + "weight": 3 + }, + { + "type": "item", + "name": "minecraft:coal", + "functions": [ + { + "function": "set_count", + "count": { + "min": 3, + "max": 8 + } + } + ], + "weight": 10 + }, + { + "type": "item", + "name": "minecraft:bread", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 3 + } + } + ], + "weight": 15 + }, + { + "type": "item", + "name": "minecraft:melon_seeds", + "functions": [ + { + "function": "set_count", + "count": { + "min": 2, + "max": 4 + } + } + ], + "weight": 10 + }, + { + "type": "item", + "name": "minecraft:pumpkin_seeds", + "functions": [ + { + "function": "set_count", + "count": { + "min": 2, + "max": 4 + } + } + ], + "weight": 10 + }, + { + "type": "item", + "name": "minecraft:beetroot_seeds", + "functions": [ + { + "function": "set_count", + "count": { + "min": 2, + "max": 4 + } + } + ], + "weight": 10 + } + ] + }, + { + "rolls": 3, + "entries": [ + { + "type": "item", + "name": "minecraft:rail", + "functions": [ + { + "function": "set_count", + "count": { + "min": 4, + "max": 8 + } + } + ], + "weight": 20 + }, + { + "type": "item", + "name": "minecraft:golden_rail", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 4 + } + } + ], + "weight": 5 + }, + { + "type": "item", + "name": "minecraft:detector_rail", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 4 + } + } + ], + "weight": 5 + }, + { + "type": "item", + "name": "minecraft:activator_rail", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 4 + } + } + ], + "weight": 5 + }, + { + "type": "item", + "name": "minecraft:torch", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 16 + } + } + ], + "weight": 15 + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/chests/desert_pyramid.json b/vice-master@f8937e1dbf1/loot_tables/chests/desert_pyramid.json new file mode 100644 index 0000000..235911f --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/chests/desert_pyramid.json @@ -0,0 +1,235 @@ +{ + "pools": [ + { + "rolls": { + "min": 2, + "max": 4 + }, + "entries": [ + { + "type": "item", + "name": "minecraft:diamond", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 3 + } + } + ], + "weight": 5 + }, + { + "type": "item", + "name": "minecraft:iron_ingot", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 5 + } + } + ], + "weight": 15 + }, + { + "type": "item", + "name": "minecraft:gold_ingot", + "functions": [ + { + "function": "set_count", + "count": { + "min": 2, + "max": 7 + } + } + ], + "weight": 15 + }, + { + "type": "item", + "name": "minecraft:emerald", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 3 + } + } + ], + "weight": 15 + }, + { + "type": "item", + "name": "minecraft:bone", + "functions": [ + { + "function": "set_count", + "count": { + "min": 4, + "max": 6 + } + } + ], + "weight": 25 + }, + { + "type": "item", + "name": "minecraft:spider_eye", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 3 + } + } + ], + "weight": 25 + }, + { + "type": "item", + "name": "minecraft:rotten_flesh", + "functions": [ + { + "function": "set_count", + "count": { + "min": 3, + "max": 7 + } + } + ], + "weight": 25 + }, + { + "type": "item", + "name": "minecraft:saddle", + "weight": 20 + }, + { + "type": "item", + "name": "minecraft:iron_horse_armor", + "weight": 15 + }, + { + "type": "item", + "name": "minecraft:golden_horse_armor", + "weight": 10 + }, + { + "type": "item", + "name": "minecraft:diamond_horse_armor", + "weight": 5 + }, + { + "type": "item", + "name": "minecraft:book", + "weight": 20, + "functions": [ + { + "function": "enchant_randomly" + } + ] + }, + { + "type": "item", + "name": "minecraft:golden_apple", + "weight": 20 + }, + { + "type": "item", + "name": "minecraft:golden_apple", + "weight": 2, + "functions": [ + { + "function": "set_data", + "data": 1 + } + ] + }, + { + "type": "empty", + "weight": 15 + } + ] + }, + { + "rolls": 4, + "entries": [ + { + "type": "item", + "name": "minecraft:bone", + "weight": 10, + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 8 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:gunpowder", + "weight": 10, + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 8 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:rotten_flesh", + "weight": 10, + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 8 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:string", + "weight": 10, + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 8 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:sand", + "weight": 10, + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 8 + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/chests/end_city_treasure.json b/vice-master@f8937e1dbf1/loot_tables/chests/end_city_treasure.json new file mode 100644 index 0000000..892f3c0 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/chests/end_city_treasure.json @@ -0,0 +1,162 @@ +{ + "pools": [ + { + "rolls": { + "min": 2, + "max": 6 + }, + "entries": [ + { + "type": "item", + "name": "minecraft:diamond", + "weight": 5, + "functions": [ + { + "function": "set_count", + "count": { + "min": 2, + "max": 7 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:iron_ingot", + "weight": 10, + "functions": [ + { + "function": "set_count", + "count": { + "min": 4, + "max": 8 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:gold_ingot", + "weight": 15, + "functions": [ + { + "function": "set_count", + "count": { + "min": 2, + "max": 7 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:emerald", + "weight": 2, + "functions": [ + { + "function": "set_count", + "count": { + "min": 2, + "max": 6 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:beetroot_seeds", + "weight": 5, + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 10 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:saddle", + "weight": 3 + }, + { + "type": "item", + "name": "minecraft:iron_horse_armor", + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:golden_horse_armor", + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:diamond_horse_armor", + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:diamond_pickaxe", + "weight": 3, + "functions": [ + { + "function": "enchant_with_levels", + "treasure": true, + "levels": { + "min": 20, + "max": 39 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:diamond_shovel", + "weight": 3, + "functions": [ + { + "function": "enchant_with_levels", + "treasure": true, + "levels": { + "min": 20, + "max": 39 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:iron_pickaxe", + "weight": 3, + "functions": [ + { + "function": "enchant_with_levels", + "treasure": true, + "levels": { + "min": 20, + "max": 39 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:iron_shovel", + "weight": 3, + "functions": [ + { + "function": "enchant_with_levels", + "treasure": true, + "levels": { + "min": 20, + "max": 39 + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/chests/igloo_chest.json b/vice-master@f8937e1dbf1/loot_tables/chests/igloo_chest.json new file mode 100644 index 0000000..5121be6 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/chests/igloo_chest.json @@ -0,0 +1,93 @@ +{ + "pools": [ + { + "rolls": { + "min": 2, + "max": 8 + }, + "entries": [ + { + "type": "item", + "name": "minecraft:apple", + "weight": 15, + "functions": [ + { + "function": "minecraft:set_count", + "count": { + "min": 1, + "max": 3 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:coal", + "weight": 15, + "functions": [ + { + "function": "minecraft:set_count", + "count": { + "min": 1, + "max": 4 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:gold_nugget", + "weight": 10, + "functions": [ + { + "function": "minecraft:set_count", + "count": { + "min": 1, + "max": 3 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:stone_axe", + "weight": 2 + }, + { + "type": "item", + "name": "minecraft:rotten_flesh", + "weight": 10 + }, + { + "type": "item", + "name": "minecraft:emerald", + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:wheat", + "weight": 10, + "functions": [ + { + "function": "minecraft:set_count", + "count": { + "min": 2, + "max": 3 + } + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:golden_apple", + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/chests/jungle_temple.json b/vice-master@f8937e1dbf1/loot_tables/chests/jungle_temple.json new file mode 100644 index 0000000..d308cff --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/chests/jungle_temple.json @@ -0,0 +1,128 @@ +{ + "pools": [ + { + "rolls": { + "min": 2, + "max": 6 + }, + "entries": [ + { + "type": "item", + "name": "minecraft:diamond", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 3 + } + } + ], + "weight": 3 + }, + { + "type": "item", + "name": "minecraft:iron_ingot", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 5 + } + } + ], + "weight": 10 + }, + { + "type": "item", + "name": "minecraft:gold_ingot", + "functions": [ + { + "function": "set_count", + "count": { + "min": 2, + "max": 7 + } + } + ], + "weight": 15 + }, + { + "type": "item", + "name": "minecraft:emerald", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 3 + } + } + ], + "weight": 2 + }, + { + "type": "item", + "name": "minecraft:bone", + "functions": [ + { + "function": "set_count", + "count": { + "min": 4, + "max": 6 + } + } + ], + "weight": 20 + }, + { + "type": "item", + "name": "minecraft:rotten_flesh", + "functions": [ + { + "function": "set_count", + "count": { + "min": 3, + "max": 7 + } + } + ], + "weight": 16 + }, + { + "type": "item", + "name": "minecraft:saddle", + "weight": 3 + }, + { + "type": "item", + "name": "minecraft:iron_horse_armor", + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:golden_horse_armor", + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:diamond_horse_armor", + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:book", + "weight": 1, + "functions": [ + { + "function": "enchant_with_levels", + "levels": 30, + "treasure": true + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/chests/jungle_temple_dispenser.json b/vice-master@f8937e1dbf1/loot_tables/chests/jungle_temple_dispenser.json new file mode 100644 index 0000000..38c0e62 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/chests/jungle_temple_dispenser.json @@ -0,0 +1,26 @@ +{ + "pools": [ + { + "rolls": { + "min": 1, + "max": 2 + }, + "entries": [ + { + "type": "item", + "name": "minecraft:arrow", + "functions": [ + { + "function": "set_count", + "count": { + "min": 2, + "max": 7 + } + } + ], + "weight": 30 + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/chests/nether_bridge.json b/vice-master@f8937e1dbf1/loot_tables/chests/nether_bridge.json new file mode 100644 index 0000000..f345149 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/chests/nether_bridge.json @@ -0,0 +1,107 @@ +{ + "pools": [ + { + "rolls": { + "min": 2, + "max": 4 + }, + "entries": [ + { + "type": "item", + "name": "minecraft:diamond", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 3 + } + } + ], + "weight": 5 + }, + { + "type": "item", + "name": "minecraft:iron_ingot", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 5 + } + } + ], + "weight": 5 + }, + { + "type": "item", + "name": "minecraft:gold_ingot", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 3 + } + } + ], + "weight": 15 + }, + { + "type": "item", + "name": "minecraft:flint_and_steel", + "weight": 5 + }, + { + "type": "item", + "name": "minecraft:nether_wart", + "functions": [ + { + "function": "set_count", + "count": { + "min": 3, + "max": 7 + } + } + ], + "weight": 5 + }, + { + "type": "item", + "name": "minecraft:saddle", + "weight": 10 + }, + { + "type": "item", + "name": "minecraft:golden_horse_armor", + "weight": 8 + }, + { + "type": "item", + "name": "minecraft:iron_horse_armor", + "weight": 5 + }, + { + "type": "item", + "name": "minecraft:diamond_horse_armor", + "weight": 3 + }, + { + "type": "item", + "name": "minecraft:obsidian", + "functions": [ + { + "function": "set_count", + "count": { + "min": 2, + "max": 4 + } + } + ], + "weight": 2 + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/chests/simple_dungeon.json b/vice-master@f8937e1dbf1/loot_tables/chests/simple_dungeon.json new file mode 100644 index 0000000..087e170 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/chests/simple_dungeon.json @@ -0,0 +1,264 @@ +{ + "pools": [ + { + "rolls": { + "min": 1, + "max": 3 + }, + "entries": [ + { + "type": "item", + "name": "minecraft:saddle", + "weight": 20 + }, + { + "type": "item", + "name": "minecraft:golden_apple", + "weight": 15 + }, + { + "type": "item", + "name": "minecraft:golden_apple", + "weight": 2, + "functions": [ + { + "function": "set_data", + "data": 1 + } + ] + }, + { + "type": "item", + "name": "minecraft:record_13", + "weight": 15 + }, + { + "type": "item", + "name": "minecraft:record_cat", + "weight": 15 + }, + { + "type": "item", + "name": "minecraft:name_tag", + "weight": 20 + }, + { + "type": "item", + "name": "minecraft:golden_horse_armor", + "weight": 10 + }, + { + "type": "item", + "name": "minecraft:iron_horse_armor", + "weight": 15 + }, + { + "type": "item", + "name": "minecraft:diamond_horse_armor", + "weight": 5 + }, + { + "type": "item", + "name": "minecraft:book", + "weight": 10, + "functions": [ + { + "function": "enchant_randomly" + } + ] + } + ] + }, + { + "rolls": { + "min": 1, + "max": 4 + }, + "entries": [ + { + "type": "item", + "name": "minecraft:iron_ingot", + "weight": 10, + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 4 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:gold_ingot", + "weight": 5, + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 4 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:bread", + "weight": 20 + }, + { + "type": "item", + "name": "minecraft:wheat", + "weight": 20, + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 4 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:bucket", + "weight": 10 + }, + { + "type": "item", + "name": "minecraft:redstone", + "weight": 15, + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 4 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:coal", + "weight": 15, + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 4 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:melon_seeds", + "functions": [ + { + "function": "set_count", + "count": { + "min": 2, + "max": 4 + } + } + ], + "weight": 10 + }, + { + "type": "item", + "name": "minecraft:pumpkin_seeds", + "functions": [ + { + "function": "set_count", + "count": { + "min": 2, + "max": 4 + } + } + ], + "weight": 10 + }, + { + "type": "item", + "name": "minecraft:beetroot_seeds", + "functions": [ + { + "function": "set_count", + "count": { + "min": 2, + "max": 4 + } + } + ], + "weight": 10 + } + ] + }, + { + "rolls": 3, + "entries": [ + { + "type": "item", + "name": "minecraft:bone", + "weight": 10, + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 8 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:gunpowder", + "weight": 10, + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 8 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:rotten_flesh", + "weight": 10, + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 8 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:string", + "weight": 10, + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 8 + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/chests/spawn_bonus_chest.json b/vice-master@f8937e1dbf1/loot_tables/chests/spawn_bonus_chest.json new file mode 100644 index 0000000..455107c --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/chests/spawn_bonus_chest.json @@ -0,0 +1,160 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:stone_axe", + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:wooden_axe", + "weight": 3 + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:stone_pickaxe", + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:wooden_pickaxe", + "weight": 3 + } + ] + }, + { + "rolls": 3, + "entries": [ + { + "type": "item", + "name": "minecraft:apple", + "weight": 5, + "functions": [ + { + "function": "minecraft:set_count", + "count": { + "min": 1, + "max": 2 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:bread", + "weight": 3, + "functions": [ + { + "function": "minecraft:set_count", + "count": { + "min": 1, + "max": 2 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:fish", + "weight": 3, + "functions": [ + { + "function": "minecraft:set_data", + "data": 1 + }, + { + "function": "minecraft:set_count", + "count": { + "min": 1, + "max": 2 + } + } + ] + } + ] + }, + { + "rolls": 4, + "entries": [ + { + "type": "item", + "name": "minecraft:stick", + "weight": 10, + "functions": [ + { + "function": "minecraft:set_count", + "count": { + "min": 1, + "max": 12 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:planks", + "weight": 10, + "functions": [ + { + "function": "minecraft:set_count", + "count": { + "min": 1, + "max": 12 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:log", + "weight": 10, + "functions": [ + { + "function": "minecraft:set_count", + "count": { + "min": 1, + "max": 3 + } + }, + { + "function": "minecraft:set_data", + "data": { + "min": 0, + "max": 3 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:log2", + "weight": 10, + "functions": [ + { + "function": "minecraft:set_count", + "count": { + "min": 1, + "max": 3 + } + }, + { + "function": "minecraft:set_data", + "data": { + "min": 0, + "max": 1 + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/chests/stronghold_corridor.json b/vice-master@f8937e1dbf1/loot_tables/chests/stronghold_corridor.json new file mode 100644 index 0000000..80f6087 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/chests/stronghold_corridor.json @@ -0,0 +1,143 @@ +{ + "pools": [ + { + "rolls": { + "min": 2, + "max": 3 + }, + "entries": [ + { + "type": "item", + "name": "minecraft:ender_pearl", + "weight": 10 + }, + { + "type": "item", + "name": "minecraft:diamond", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 3 + } + } + ], + "weight": 3 + }, + { + "type": "item", + "name": "minecraft:iron_ingot", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 5 + } + } + ], + "weight": 10 + }, + { + "type": "item", + "name": "minecraft:gold_ingot", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 3 + } + } + ], + "weight": 5 + }, + { + "type": "item", + "name": "minecraft:redstone", + "functions": [ + { + "function": "set_count", + "count": { + "min": 4, + "max": 9 + } + } + ], + "weight": 5 + }, + { + "type": "item", + "name": "minecraft:bread", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 3 + } + } + ], + "weight": 15 + }, + { + "type": "item", + "name": "minecraft:apple", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 3 + } + } + ], + "weight": 15 + }, + { + "type": "item", + "name": "minecraft:iron_pickaxe", + "weight": 5 + }, + { + "type": "item", + "name": "minecraft:golden_apple", + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:saddle", + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:iron_horse_armor", + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:golden_horse_armor", + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:diamond_horse_armor", + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:book", + "weight": 1, + "functions": [ + { + "function": "enchant_with_levels", + "levels": 30, + "treasure": true + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/chests/stronghold_crossing.json b/vice-master@f8937e1dbf1/loot_tables/chests/stronghold_crossing.json new file mode 100644 index 0000000..3ae1faf --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/chests/stronghold_crossing.json @@ -0,0 +1,113 @@ +{ + "pools": [ + { + "rolls": { + "min": 1, + "max": 4 + }, + "entries": [ + { + "type": "item", + "name": "minecraft:iron_ingot", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 5 + } + } + ], + "weight": 10 + }, + { + "type": "item", + "name": "minecraft:gold_ingot", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 3 + } + } + ], + "weight": 5 + }, + { + "type": "item", + "name": "minecraft:redstone", + "functions": [ + { + "function": "set_count", + "count": { + "min": 4, + "max": 9 + } + } + ], + "weight": 5 + }, + { + "type": "item", + "name": "minecraft:coal", + "functions": [ + { + "function": "set_count", + "count": { + "min": 3, + "max": 8 + } + } + ], + "weight": 10 + }, + { + "type": "item", + "name": "minecraft:bread", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 3 + } + } + ], + "weight": 15 + }, + { + "type": "item", + "name": "minecraft:apple", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 3 + } + } + ], + "weight": 15 + }, + { + "type": "item", + "name": "minecraft:iron_pickaxe", + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:book", + "weight": 1, + "functions": [ + { + "function": "enchant_with_levels", + "levels": 30, + "treasure": true + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/chests/stronghold_library.json b/vice-master@f8937e1dbf1/loot_tables/chests/stronghold_library.json new file mode 100644 index 0000000..1805bb6 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/chests/stronghold_library.json @@ -0,0 +1,62 @@ +{ + "pools": [ + { + "rolls": { + "min": 2, + "max": 10 + }, + "entries": [ + { + "type": "item", + "name": "minecraft:book", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 3 + } + } + ], + "weight": 20 + }, + { + "type": "item", + "name": "minecraft:paper", + "functions": [ + { + "function": "set_count", + "count": { + "min": 2, + "max": 7 + } + } + ], + "weight": 20 + }, + { + "type": "item", + "name": "minecraft:map", + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:compass", + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:book", + "weight": 10, + "functions": [ + { + "function": "enchant_with_levels", + "levels": 30, + "treasure": true + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/chests/village_blacksmith.json b/vice-master@f8937e1dbf1/loot_tables/chests/village_blacksmith.json new file mode 100644 index 0000000..b8421fb --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/chests/village_blacksmith.json @@ -0,0 +1,135 @@ +{ + "pools": [ + { + "rolls": { + "min": 3, + "max": 8 + }, + "entries": [ + { + "type": "item", + "name": "minecraft:diamond", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 3 + } + } + ], + "weight": 3 + }, + { + "type": "item", + "name": "minecraft:iron_ingot", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 5 + } + } + ], + "weight": 10 + }, + { + "type": "item", + "name": "minecraft:gold_ingot", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 3 + } + } + ], + "weight": 5 + }, + { + "type": "item", + "name": "minecraft:bread", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 3 + } + } + ], + "weight": 15 + }, + { + "type": "item", + "name": "minecraft:apple", + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 3 + } + } + ], + "weight": 15 + }, + { + "type": "item", + "name": "minecraft:iron_pickaxe", + "weight": 5 + }, + { + "type": "item", + "name": "minecraft:obsidian", + "functions": [ + { + "function": "set_count", + "count": { + "min": 3, + "max": 7 + } + } + ], + "weight": 5 + }, + { + "type": "item", + "name": "minecraft:sapling", + "functions": [ + { + "function": "set_count", + "count": { + "min": 3, + "max": 7 + } + } + ], + "weight": 5 + }, + { + "type": "item", + "name": "minecraft:saddle", + "weight": 3 + }, + { + "type": "item", + "name": "minecraft:iron_horse_armor", + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:golden_horse_armor", + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:diamond_horse_armor", + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/chests/woodland_mansion.json b/vice-master@f8937e1dbf1/loot_tables/chests/woodland_mansion.json new file mode 100644 index 0000000..12a6de7 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/chests/woodland_mansion.json @@ -0,0 +1,254 @@ +{ + "pools": [ + { + "rolls": { + "min": 1, + "max": 3 + }, + "entries": [ + { + "type": "item", + "name": "minecraft:lead", + "weight": 20 + }, + { + "type": "item", + "name": "minecraft:golden_apple", + "weight": 15 + }, + { + "type": "item", + "name": "minecraft:golden_apple", + "weight": 2, + "functions": [ + { + "function": "set_data", + "data": 1 + } + ] + }, + { + "type": "item", + "name": "minecraft:record_13", + "weight": 15 + }, + { + "type": "item", + "name": "minecraft:record_cat", + "weight": 15 + }, + { + "type": "item", + "name": "minecraft:name_tag", + "weight": 20 + }, + { + "type": "item", + "name": "minecraft:diamond_hoe", + "weight": 15 + }, + { + "type": "item", + "name": "minecraft:book", + "weight": 10, + "functions": [ + { + "function": "enchant_randomly" + } + ] + } + ] + }, + { + "rolls": { + "min": 1, + "max": 4 + }, + "entries": [ + { + "type": "item", + "name": "minecraft:iron_ingot", + "weight": 10, + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 4 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:gold_ingot", + "weight": 5, + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 4 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:bread", + "weight": 20 + }, + { + "type": "item", + "name": "minecraft:wheat", + "weight": 20, + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 4 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:bucket", + "weight": 10 + }, + { + "type": "item", + "name": "minecraft:redstone", + "weight": 15, + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 4 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:coal", + "weight": 15, + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 4 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:melon_seeds", + "functions": [ + { + "function": "set_count", + "count": { + "min": 2, + "max": 4 + } + } + ], + "weight": 10 + }, + { + "type": "item", + "name": "minecraft:pumpkin_seeds", + "functions": [ + { + "function": "set_count", + "count": { + "min": 2, + "max": 4 + } + } + ], + "weight": 10 + }, + { + "type": "item", + "name": "minecraft:beetroot_seeds", + "functions": [ + { + "function": "set_count", + "count": { + "min": 2, + "max": 4 + } + } + ], + "weight": 10 + } + ] + }, + { + "rolls": 3, + "entries": [ + { + "type": "item", + "name": "minecraft:bone", + "weight": 10, + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 8 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:gunpowder", + "weight": 10, + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 8 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:rotten_flesh", + "weight": 10, + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 8 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:string", + "weight": 10, + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 8 + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/empty.json b/vice-master@f8937e1dbf1/loot_tables/empty.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/empty.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/bat.json b/vice-master@f8937e1dbf1/loot_tables/entities/bat.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/bat.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/blaze.json b/vice-master@f8937e1dbf1/loot_tables/entities/blaze.json new file mode 100644 index 0000000..78be797 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/blaze.json @@ -0,0 +1,35 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:blaze_rod", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 1 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ], + "conditions": [ + { + "condition": "killed_by_player" + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/cave_spider.json b/vice-master@f8937e1dbf1/loot_tables/entities/cave_spider.json new file mode 100644 index 0000000..d0f7a8f --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/cave_spider.json @@ -0,0 +1,61 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:string", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:spider_eye", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": -1, + "max": 1 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ], + "conditions": [ + { + "condition": "killed_by_player" + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/chicken.json b/vice-master@f8937e1dbf1/loot_tables/entities/chicken.json new file mode 100644 index 0000000..f771d3b --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/chicken.json @@ -0,0 +1,61 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:feather", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:chicken", + "weight": 1, + "functions": [ + { + "function": "furnace_smelt", + "conditions": [ + { + "condition": "entity_properties", + "entity": "this", + "properties": { + "on_fire": true + } + } + ] + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/cow.json b/vice-master@f8937e1dbf1/loot_tables/entities/cow.json new file mode 100644 index 0000000..14839a6 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/cow.json @@ -0,0 +1,68 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:leather", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:beef", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 3 + } + }, + { + "function": "furnace_smelt", + "conditions": [ + { + "condition": "entity_properties", + "entity": "this", + "properties": { + "on_fire": true + } + } + ] + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/creeper.json b/vice-master@f8937e1dbf1/loot_tables/entities/creeper.json new file mode 100644 index 0000000..ba3bac4 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/creeper.json @@ -0,0 +1,30 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:gunpowder", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/donkey.json b/vice-master@f8937e1dbf1/loot_tables/entities/donkey.json new file mode 100644 index 0000000..2c87ecc --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/donkey.json @@ -0,0 +1,29 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:leather", + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/elder_guardian.json b/vice-master@f8937e1dbf1/loot_tables/entities/elder_guardian.json new file mode 100644 index 0000000..8e74cab --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/elder_guardian.json @@ -0,0 +1,120 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:prismarine_shard", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:fish", + "weight": 3, + "functions": [ + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + }, + { + "function": "furnace_smelt", + "conditions": [ + { + "condition": "entity_properties", + "entity": "this", + "properties": { + "on_fire": true + } + } + ] + } + ] + }, + { + "type": "item", + "name": "minecraft:prismarine_crystals", + "weight": 2, + "functions": [ + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + }, + { + "type": "empty", + "weight": 1 + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:sponge", + "weight": 1, + "functions": [ + { + "function": "set_data", + "data": 1 + } + ] + } + ], + "conditions": [ + { + "condition": "killed_by_player" + } + ] + }, + { + "conditions": [ + { + "condition": "killed_by_player" + }, + { + "condition": "random_chance_with_looting", + "chance": 0.025, + "looting_multiplier": 0.01 + } + ], + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "minecraft:gameplay/fishing/fish", + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/ender_dragon.json b/vice-master@f8937e1dbf1/loot_tables/entities/ender_dragon.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/ender_dragon.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/enderman.json b/vice-master@f8937e1dbf1/loot_tables/entities/enderman.json new file mode 100644 index 0000000..67bc046 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/enderman.json @@ -0,0 +1,30 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:ender_pearl", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 1 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/endermite.json b/vice-master@f8937e1dbf1/loot_tables/entities/endermite.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/endermite.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/evocation_illager.json b/vice-master@f8937e1dbf1/loot_tables/entities/evocation_illager.json new file mode 100644 index 0000000..ddcfd0b --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/evocation_illager.json @@ -0,0 +1,44 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:totem_of_undying" + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:emerald", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 1 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ], + "conditions": [ + { + "condition": "killed_by_player" + } + ] + } + ] +} diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/ghast.json b/vice-master@f8937e1dbf1/loot_tables/entities/ghast.json new file mode 100644 index 0000000..ebf4b0e --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/ghast.json @@ -0,0 +1,56 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:ghast_tear", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 1 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:gunpowder", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/giant.json b/vice-master@f8937e1dbf1/loot_tables/entities/giant.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/giant.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/guardian.json b/vice-master@f8937e1dbf1/loot_tables/entities/guardian.json new file mode 100644 index 0000000..e14b3ac --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/guardian.json @@ -0,0 +1,99 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:prismarine_shard", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:fish", + "weight": 2, + "functions": [ + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + }, + { + "function": "furnace_smelt", + "conditions": [ + { + "condition": "entity_properties", + "entity": "this", + "properties": { + "on_fire": true + } + } + ] + } + ] + }, + { + "type": "item", + "name": "minecraft:prismarine_crystals", + "weight": 2, + "functions": [ + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + }, + { + "type": "empty", + "weight": 1 + } + ] + }, + { + "conditions": [ + { + "condition": "killed_by_player" + }, + { + "condition": "random_chance_with_looting", + "chance": 0.025, + "looting_multiplier": 0.01 + } + ], + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "minecraft:gameplay/fishing/fish", + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/horse.json b/vice-master@f8937e1dbf1/loot_tables/entities/horse.json new file mode 100644 index 0000000..2c87ecc --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/horse.json @@ -0,0 +1,29 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:leather", + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/husk.json b/vice-master@f8937e1dbf1/loot_tables/entities/husk.json new file mode 100644 index 0000000..593a80c --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/husk.json @@ -0,0 +1,60 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:rotten_flesh", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + }, + { + "conditions": [ + { + "condition": "killed_by_player" + }, + { + "condition": "random_chance_with_looting", + "chance": 0.025, + "looting_multiplier": 0.01 + } + ], + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:iron_ingot", + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:carrot", + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:potato", + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/iron_golem.json b/vice-master@f8937e1dbf1/loot_tables/entities/iron_golem.json new file mode 100644 index 0000000..d79d75b --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/iron_golem.json @@ -0,0 +1,42 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:red_flower", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:iron_ingot", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 3, + "max": 5 + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/llama.json b/vice-master@f8937e1dbf1/loot_tables/entities/llama.json new file mode 100644 index 0000000..2c87ecc --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/llama.json @@ -0,0 +1,29 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:leather", + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/magma_cube.json b/vice-master@f8937e1dbf1/loot_tables/entities/magma_cube.json new file mode 100644 index 0000000..b2035db --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/magma_cube.json @@ -0,0 +1,30 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:magma_cream", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": -2, + "max": 1 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/mule.json b/vice-master@f8937e1dbf1/loot_tables/entities/mule.json new file mode 100644 index 0000000..2c87ecc --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/mule.json @@ -0,0 +1,29 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:leather", + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/mushroom_cow.json b/vice-master@f8937e1dbf1/loot_tables/entities/mushroom_cow.json new file mode 100644 index 0000000..14839a6 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/mushroom_cow.json @@ -0,0 +1,68 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:leather", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:beef", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 3 + } + }, + { + "function": "furnace_smelt", + "conditions": [ + { + "condition": "entity_properties", + "entity": "this", + "properties": { + "on_fire": true + } + } + ] + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/ocelot.json b/vice-master@f8937e1dbf1/loot_tables/entities/ocelot.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/ocelot.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/parrot.json b/vice-master@f8937e1dbf1/loot_tables/entities/parrot.json new file mode 100644 index 0000000..4d0c212 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/parrot.json @@ -0,0 +1,30 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:feather", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/pig.json b/vice-master@f8937e1dbf1/loot_tables/entities/pig.json new file mode 100644 index 0000000..7247911 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/pig.json @@ -0,0 +1,42 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:porkchop", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 3 + } + }, + { + "function": "furnace_smelt", + "conditions": [ + { + "condition": "entity_properties", + "entity": "this", + "properties": { + "on_fire": true + } + } + ] + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/polar_bear.json b/vice-master@f8937e1dbf1/loot_tables/entities/polar_bear.json new file mode 100644 index 0000000..09f02ef --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/polar_bear.json @@ -0,0 +1,59 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:fish", + "weight": 3, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + }, + { + "function": "set_data", + "data": 0 + } + ] + }, + { + "type": "item", + "name": "minecraft:fish", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + }, + { + "function": "set_data", + "data": 1 + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/rabbit.json b/vice-master@f8937e1dbf1/loot_tables/entities/rabbit.json new file mode 100644 index 0000000..f7bc3e4 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/rabbit.json @@ -0,0 +1,88 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:rabbit_hide", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 1 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:rabbit", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 1 + } + }, + { + "function": "furnace_smelt", + "conditions": [ + { + "condition": "entity_properties", + "entity": "this", + "properties": { + "on_fire": true + } + } + ] + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + }, + { + "conditions": [ + { + "condition": "killed_by_player" + }, + { + "condition": "random_chance_with_looting", + "chance": 0.1, + "looting_multiplier": 0.03 + } + ], + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:rabbit_foot", + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/sheep.json b/vice-master@f8937e1dbf1/loot_tables/entities/sheep.json new file mode 100644 index 0000000..a567656 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/sheep.json @@ -0,0 +1,42 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:mutton", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 2 + } + }, + { + "function": "furnace_smelt", + "conditions": [ + { + "condition": "entity_properties", + "entity": "this", + "properties": { + "on_fire": true + } + } + ] + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/sheep/black.json b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/black.json new file mode 100644 index 0000000..71c38e9 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/black.json @@ -0,0 +1,30 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:wool", + "weight": 1, + "functions": [ + { + "function": "minecraft:set_data", + "data": 15 + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "minecraft:entities/sheep", + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/sheep/blue.json b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/blue.json new file mode 100644 index 0000000..b1d4ba5 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/blue.json @@ -0,0 +1,30 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:wool", + "weight": 1, + "functions": [ + { + "function": "minecraft:set_data", + "data": 11 + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "minecraft:entities/sheep", + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/sheep/brown.json b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/brown.json new file mode 100644 index 0000000..a74e0ec --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/brown.json @@ -0,0 +1,30 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:wool", + "weight": 1, + "functions": [ + { + "function": "minecraft:set_data", + "data": 12 + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "minecraft:entities/sheep", + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/sheep/cyan.json b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/cyan.json new file mode 100644 index 0000000..b9e1cff --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/cyan.json @@ -0,0 +1,30 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:wool", + "weight": 1, + "functions": [ + { + "function": "minecraft:set_data", + "data": 9 + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "minecraft:entities/sheep", + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/sheep/gray.json b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/gray.json new file mode 100644 index 0000000..dcc0559 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/gray.json @@ -0,0 +1,30 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:wool", + "weight": 1, + "functions": [ + { + "function": "minecraft:set_data", + "data": 7 + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "minecraft:entities/sheep", + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/sheep/green.json b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/green.json new file mode 100644 index 0000000..6761903 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/green.json @@ -0,0 +1,30 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:wool", + "weight": 1, + "functions": [ + { + "function": "minecraft:set_data", + "data": 13 + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "minecraft:entities/sheep", + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/sheep/light_blue.json b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/light_blue.json new file mode 100644 index 0000000..8663d87 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/light_blue.json @@ -0,0 +1,30 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:wool", + "weight": 1, + "functions": [ + { + "function": "minecraft:set_data", + "data": 3 + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "minecraft:entities/sheep", + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/sheep/lime.json b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/lime.json new file mode 100644 index 0000000..c92be36 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/lime.json @@ -0,0 +1,30 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:wool", + "weight": 1, + "functions": [ + { + "function": "minecraft:set_data", + "data": 5 + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "minecraft:entities/sheep", + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/sheep/magenta.json b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/magenta.json new file mode 100644 index 0000000..f687521 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/magenta.json @@ -0,0 +1,30 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:wool", + "weight": 1, + "functions": [ + { + "function": "minecraft:set_data", + "data": 2 + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "minecraft:entities/sheep", + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/sheep/orange.json b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/orange.json new file mode 100644 index 0000000..e3a8de9 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/orange.json @@ -0,0 +1,30 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:wool", + "weight": 1, + "functions": [ + { + "function": "minecraft:set_data", + "data": 1 + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "minecraft:entities/sheep", + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/sheep/pink.json b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/pink.json new file mode 100644 index 0000000..93aea36 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/pink.json @@ -0,0 +1,30 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:wool", + "weight": 1, + "functions": [ + { + "function": "minecraft:set_data", + "data": 6 + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "minecraft:entities/sheep", + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/sheep/purple.json b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/purple.json new file mode 100644 index 0000000..ac85e9b --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/purple.json @@ -0,0 +1,30 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:wool", + "weight": 1, + "functions": [ + { + "function": "minecraft:set_data", + "data": 10 + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "minecraft:entities/sheep", + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/sheep/red.json b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/red.json new file mode 100644 index 0000000..df6239d --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/red.json @@ -0,0 +1,30 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:wool", + "weight": 1, + "functions": [ + { + "function": "minecraft:set_data", + "data": 14 + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "minecraft:entities/sheep", + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/sheep/silver.json b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/silver.json new file mode 100644 index 0000000..26b14c1 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/silver.json @@ -0,0 +1,30 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:wool", + "weight": 1, + "functions": [ + { + "function": "minecraft:set_data", + "data": 8 + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "minecraft:entities/sheep", + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/sheep/white.json b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/white.json new file mode 100644 index 0000000..12856c3 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/white.json @@ -0,0 +1,30 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:wool", + "weight": 1, + "functions": [ + { + "function": "minecraft:set_data", + "data": 0 + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "minecraft:entities/sheep", + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/sheep/yellow.json b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/yellow.json new file mode 100644 index 0000000..4a775ad --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/sheep/yellow.json @@ -0,0 +1,30 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:wool", + "weight": 1, + "functions": [ + { + "function": "minecraft:set_data", + "data": 4 + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "minecraft:entities/sheep", + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/shulker.json b/vice-master@f8937e1dbf1/loot_tables/entities/shulker.json new file mode 100644 index 0000000..43abeff --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/shulker.json @@ -0,0 +1,20 @@ +{ + "pools": [ + { + "conditions": [ + { + "condition": "random_chance_with_looting", + "chance": 0.5, + "looting_multiplier": 0.0625 + } + ], + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:shulker_shell" + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/silverfish.json b/vice-master@f8937e1dbf1/loot_tables/entities/silverfish.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/silverfish.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/skeleton.json b/vice-master@f8937e1dbf1/loot_tables/entities/skeleton.json new file mode 100644 index 0000000..630df5b --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/skeleton.json @@ -0,0 +1,56 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:arrow", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:bone", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/skeleton_horse.json b/vice-master@f8937e1dbf1/loot_tables/entities/skeleton_horse.json new file mode 100644 index 0000000..a998e9e --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/skeleton_horse.json @@ -0,0 +1,30 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:bone", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/slime.json b/vice-master@f8937e1dbf1/loot_tables/entities/slime.json new file mode 100644 index 0000000..0e2ebe8 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/slime.json @@ -0,0 +1,30 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:slime_ball", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/snowman.json b/vice-master@f8937e1dbf1/loot_tables/entities/snowman.json new file mode 100644 index 0000000..270433e --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/snowman.json @@ -0,0 +1,23 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:snowball", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 15 + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/spider.json b/vice-master@f8937e1dbf1/loot_tables/entities/spider.json new file mode 100644 index 0000000..d0f7a8f --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/spider.json @@ -0,0 +1,61 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:string", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:spider_eye", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": -1, + "max": 1 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ], + "conditions": [ + { + "condition": "killed_by_player" + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/squid.json b/vice-master@f8937e1dbf1/loot_tables/entities/squid.json new file mode 100644 index 0000000..4d7926f --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/squid.json @@ -0,0 +1,34 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:dye", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 3 + } + }, + { + "function": "set_data", + "data": 0 + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/stray.json b/vice-master@f8937e1dbf1/loot_tables/entities/stray.json new file mode 100644 index 0000000..9501595 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/stray.json @@ -0,0 +1,92 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:arrow", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:bone", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:tipped_arrow", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 1 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + }, + "limit": 1 + }, + { + "function": "set_nbt", + "tag": "{Potion:\"minecraft:slowness\"}" + } + ] + } + ], + "conditions": [ + { + "condition": "killed_by_player" + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/vex.json b/vice-master@f8937e1dbf1/loot_tables/entities/vex.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/vex.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/villager.json b/vice-master@f8937e1dbf1/loot_tables/entities/villager.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/villager.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/vindication_illager.json b/vice-master@f8937e1dbf1/loot_tables/entities/vindication_illager.json new file mode 100644 index 0000000..0a03c37 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/vindication_illager.json @@ -0,0 +1,35 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:emerald", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 1 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ], + "conditions": [ + { + "condition": "killed_by_player" + } + ] + } + ] +} diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/witch.json b/vice-master@f8937e1dbf1/loot_tables/entities/witch.json new file mode 100644 index 0000000..d7d47bb --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/witch.json @@ -0,0 +1,159 @@ +{ + "pools": [ + { + "rolls": { + "min": 1, + "max": 3 + }, + "entries": [ + { + "type": "item", + "name": "minecraft:glowstone_dust", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:sugar", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:redstone", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:spider_eye", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:glass_bottle", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:gunpowder", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:stick", + "weight": 2, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/wither_skeleton.json b/vice-master@f8937e1dbf1/loot_tables/entities/wither_skeleton.json new file mode 100644 index 0000000..04d18fb --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/wither_skeleton.json @@ -0,0 +1,82 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:coal", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": -1, + "max": 1 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:bone", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + }, + { + "conditions": [ + { + "condition": "killed_by_player" + }, + { + "condition": "random_chance_with_looting", + "chance": 0.025, + "looting_multiplier": 0.01 + } + ], + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:skull", + "weight": 1, + "functions": [ + { + "function": "set_data", + "data": 1 + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/wolf.json b/vice-master@f8937e1dbf1/loot_tables/entities/wolf.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/wolf.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/zombie.json b/vice-master@f8937e1dbf1/loot_tables/entities/zombie.json new file mode 100644 index 0000000..593a80c --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/zombie.json @@ -0,0 +1,60 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:rotten_flesh", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + }, + { + "conditions": [ + { + "condition": "killed_by_player" + }, + { + "condition": "random_chance_with_looting", + "chance": 0.025, + "looting_multiplier": 0.01 + } + ], + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:iron_ingot", + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:carrot", + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:potato", + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/zombie_horse.json b/vice-master@f8937e1dbf1/loot_tables/entities/zombie_horse.json new file mode 100644 index 0000000..12669bf --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/zombie_horse.json @@ -0,0 +1,30 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:rotten_flesh", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/zombie_pigman.json b/vice-master@f8937e1dbf1/loot_tables/entities/zombie_pigman.json new file mode 100644 index 0000000..5d31ee1 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/zombie_pigman.json @@ -0,0 +1,76 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:rotten_flesh", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 1 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:gold_nugget", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 1 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + }, + { + "conditions": [ + { + "condition": "killed_by_player" + }, + { + "condition": "random_chance_with_looting", + "chance": 0.025, + "looting_multiplier": 0.01 + } + ], + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:gold_ingot", + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/entities/zombie_villager.json b/vice-master@f8937e1dbf1/loot_tables/entities/zombie_villager.json new file mode 100644 index 0000000..593a80c --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/entities/zombie_villager.json @@ -0,0 +1,60 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:rotten_flesh", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 0, + "max": 2 + } + }, + { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + } + ] + } + ] + }, + { + "conditions": [ + { + "condition": "killed_by_player" + }, + { + "condition": "random_chance_with_looting", + "chance": 0.025, + "looting_multiplier": 0.01 + } + ], + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:iron_ingot", + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:carrot", + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:potato", + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/gameplay/fishing.json b/vice-master@f8937e1dbf1/loot_tables/gameplay/fishing.json new file mode 100644 index 0000000..c345821 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/gameplay/fishing.json @@ -0,0 +1,27 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "minecraft:gameplay/fishing/junk", + "weight": 10, + "quality": -2 + }, + { + "type": "loot_table", + "name": "minecraft:gameplay/fishing/treasure", + "weight": 5, + "quality": 2 + }, + { + "type": "loot_table", + "name": "minecraft:gameplay/fishing/fish", + "weight": 85, + "quality": -1 + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/gameplay/fishing/fish.json b/vice-master@f8937e1dbf1/loot_tables/gameplay/fishing/fish.json new file mode 100644 index 0000000..3376910 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/gameplay/fishing/fish.json @@ -0,0 +1,53 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:fish", + "functions": [ + { + "function": "set_data", + "data": 0 + } + ], + "weight": 60 + }, + { + "type": "item", + "name": "minecraft:fish", + "functions": [ + { + "function": "set_data", + "data": 1 + } + ], + "weight": 25 + }, + { + "type": "item", + "name": "minecraft:fish", + "functions": [ + { + "function": "set_data", + "data": 2 + } + ], + "weight": 2 + }, + { + "type": "item", + "name": "minecraft:fish", + "functions": [ + { + "function": "set_data", + "data": 3 + } + ], + "weight": 13 + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/loot_tables/gameplay/fishing/junk.json b/vice-master@f8937e1dbf1/loot_tables/gameplay/fishing/junk.json new file mode 100644 index 0000000..7d0eba6 --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/gameplay/fishing/junk.json @@ -0,0 +1,98 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:leather_boots", + "weight": 10, + "functions": [ + { + "function": "set_damage", + "damage": { + "min": 0, + "max": 0.90 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:leather", + "weight": 10 + }, + { + "type": "item", + "name": "minecraft:bone", + "weight": 10 + }, + { + "type": "item", + "name": "minecraft:potion", + "weight": 10, + "functions": [ + { + "function": "set_nbt", + "tag": "{Potion:\"minecraft:water\"}" + } + ] + }, + { + "type": "item", + "name": "minecraft:string", + "weight": 5 + }, + { + "type": "item", + "name": "minecraft:fishing_rod", + "weight": 2, + "functions": [ + { + "function": "set_damage", + "damage": { + "min": 0, + "max": 0.90 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:bowl", + "weight": 10 + }, + { + "type": "item", + "name": "minecraft:stick", + "weight": 5 + }, + { + "type": "item", + "name": "minecraft:dye", + "weight": 1, + "functions": [ + { + "function": "set_data", + "data": 0 + }, + { + "function": "set_count", + "count": 10 + } + ] + }, + { + "type": "item", + "name": "minecraft:tripwire_hook", + "weight": 10 + }, + { + "type": "item", + "name": "minecraft:rotten_flesh", + "weight": 10 + } + ] + } + ] +} diff --git a/vice-master@f8937e1dbf1/loot_tables/gameplay/fishing/treasure.json b/vice-master@f8937e1dbf1/loot_tables/gameplay/fishing/treasure.json new file mode 100644 index 0000000..eb443fa --- /dev/null +++ b/vice-master@f8937e1dbf1/loot_tables/gameplay/fishing/treasure.json @@ -0,0 +1,74 @@ +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:waterlily", + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:name_tag", + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:saddle", + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:bow", + "weight": 1, + "functions": [ + { + "function": "set_damage", + "damage": { + "min": 0, + "max": 0.25 + } + }, + { + "function": "enchant_with_levels", + "levels": 30, + "treasure": true + } + ] + }, + { + "type": "item", + "name": "minecraft:fishing_rod", + "weight": 1, + "functions": [ + { + "function": "set_damage", + "damage": { + "min": 0, + "max": 0.25 + } + }, + { + "function": "enchant_with_levels", + "levels": 30, + "treasure": true + } + ] + }, + { + "type": "item", + "name": "minecraft:book", + "weight": 1, + "functions": [ + { + "function": "enchant_with_levels", + "levels": 30, + "treasure": true + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/pom.xml b/vice-master@f8937e1dbf1/pom.xml new file mode 100644 index 0000000..ed44196 --- /dev/null +++ b/vice-master@f8937e1dbf1/pom.xml @@ -0,0 +1,220 @@ +<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>net.grandtheftmc</groupId> + <artifactId>vice</artifactId> + <version>1.1.0</version> + <name>Vice</name> + + <repositories> + <repository> + <id>paperspigot-repo</id> + <url>https://repo.destroystokyo.com/repository/maven-public/</url> + </repository> + <repository> + <id>dmulloy2-repo</id> + <url>http://repo.dmulloy2.net/nexus/repository/public/</url> + </repository> + <repository> + <id>jitpack.io</id> + <url>https://jitpack.io</url> + </repository> + <repository> + <id>worldedit-repo</id> + <url>http://maven.sk89q.com/repo/</url> + </repository> + <repository> + <id>viaversion-repo</id> + <url>https://repo.viaversion.com</url> + </repository> + <repository> + <id>central</id> + <name>Central Repository</name> + <url>http://repo.maven.apache.org/maven2</url> + <layout>default</layout> + <snapshots> + <enabled>false</enabled> + </snapshots> + </repository> + <repository> + <id>everything</id> + <url>http://repo.citizensnpcs.co</url> + </repository> + <repository> + <id>nexus-release</id> + <url>https://nexus.grandtheftmc.net/content/repositories/releases/</url> + </repository> + </repositories> + + <distributionManagement> + <repository> + <id>nexus-release</id> + <name>Internal Releases</name> + <url>https://nexus.grandtheftmc.net/content/repositories/releases/</url> + </repository> + <snapshotRepository> + <id>nexus-snapshot</id> + <name>Internal Snapshots</name> + <url>https://nexus.grandtheftmc.net/content/repositories/snapshots/</url> + </snapshotRepository> + </distributionManagement> + + <dependencies> + <dependency> + <groupId>org.spigotmc.1.12</groupId> + <artifactId>spigot</artifactId> + <version>1.12.0</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>de.slikey</groupId> + <artifactId>EffectLib</artifactId> + <version>5.2</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.sk89q.worldedit</groupId> + <artifactId>worldedit-bukkit</artifactId> + <version>LATEST</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.sk89q.worldguard</groupId> + <artifactId>worldguard-bukkit</artifactId> + <version>6.2.1</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.sk89q</groupId> + <artifactId>worldedit</artifactId> + <version>6.1.7.3</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>us.myles</groupId> + <artifactId>viaversion</artifactId> + <version>1.0.3</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.comphenix.protocol</groupId> + <artifactId>ProtocolLib-API</artifactId> + <version>4.2.1</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.github.j0ach1mmall3</groupId> + <artifactId>JLib</artifactId> + <version>1.10.0</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>net.grandtheftmc</groupId> + <artifactId>wastedguns</artifactId> + <version>1.1.1</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>net.grandtheftmc</groupId> + <artifactId>wastedvehicles</artifactId> + <version>1.0.3.rewrite</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>net.grandtheftmc</groupId> + <artifactId>wastedcops</artifactId> + <version>1.0.1</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.gmail.filoghost.holographicdisplays</groupId> + <artifactId>HolographicDisplays</artifactId> + <version>1.0.0</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>net.grandtheftmc</groupId> + <artifactId>core</artifactId> + <version>2.3.7.2</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.massivecraft</groupId> + <artifactId>Cartels</artifactId> + <version>1.7.1</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>net.citizensnpcs</groupId> + <artifactId>citizensapi</artifactId> + <version>2.0.22</version> + <scope>provided</scope> + </dependency> + <!--<dependency>--> + <!--<groupId>mkremins</groupId>--> + <!--<artifactId>fanciful</artifactId>--> + <!--<version>0.4.0-SNAPSHOT</version>--> + <!--<scope>compile</scope>--> + <!--<exclusions>--> + <!--<exclusion>--> + <!--<artifactId>gson</artifactId>--> + <!--<groupId>com.google.code.gson</groupId>--> + <!--</exclusion>--> + <!--</exclusions>--> + <!--</dependency>--> + </dependencies> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <maven.compiler.source>1.8</maven.compiler.source> + <maven.compiler.target>1.8</maven.compiler.target> + </properties> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-shade-plugin</artifactId> + <configuration> + <finalName>Vice</finalName> + <artifactSet> + <excludes> + <exclude>us.myles:*:*:*</exclude> + </excludes> + </artifactSet> + </configuration> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>shade</goal> + </goals> + </execution> + </executions> + </plugin> + + <!-- Nexus deploy --> + <plugin> + <groupId>org.sonatype.plugins</groupId> + <artifactId>nexus-staging-maven-plugin</artifactId> + <version>1.6.8</version> + <extensions>true</extensions> + <executions> + <execution> + <id>default-deploy</id> + <phase>deploy</phase> + <goals> + <goal>deploy</goal> + </goals> + </execution> + </executions> + <configuration> + <serverId>nexus</serverId> + <nexusUrl>http://nexus.grandtheftmc.net/</nexusUrl> + <skipStaging>true</skipStaging> + </configuration> + </plugin> + </plugins> + </build> +</project> \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/Vice.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/Vice.java new file mode 100644 index 0000000..6020994 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/Vice.java @@ -0,0 +1,716 @@ +package net.grandtheftmc.vice; + +import java.util.logging.Level; + +import org.bukkit.Bukkit; +import org.bukkit.Chunk; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.java.JavaPlugin; + +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.ProtocolManager; +import com.massivecraft.factions.Factions; + +import de.slikey.effectlib.EffectManager; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Settings; +import net.grandtheftmc.core.casino.CoreCasino; +import net.grandtheftmc.core.casino.slot.SlotMachine; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.resourcepack.RSPack_1_12; +import net.grandtheftmc.core.resourcepack.ResourcePack; +import net.grandtheftmc.core.resourcepack.ResourcePackManager; +import net.grandtheftmc.core.util.NMSVersion; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.util.title.NMSTitle; +import net.grandtheftmc.guns.GTMGuns; +import net.grandtheftmc.vice.areas.AreaManager; +import net.grandtheftmc.vice.combatlog.CombatLogManager; +import net.grandtheftmc.vice.commands.AmmoCommand; +import net.grandtheftmc.vice.commands.AntiAuraCommand; +import net.grandtheftmc.vice.commands.AreaCommand; +import net.grandtheftmc.vice.commands.BackpackCommand; +import net.grandtheftmc.vice.commands.BackupCommand; +import net.grandtheftmc.vice.commands.BaltopCommand; +import net.grandtheftmc.vice.commands.BondsCommand; +import net.grandtheftmc.vice.commands.BribeCommand; +import net.grandtheftmc.vice.commands.CheatCodeCommand; +import net.grandtheftmc.vice.commands.ChunkUnloadCommand; +import net.grandtheftmc.vice.commands.ClearCommand; +import net.grandtheftmc.vice.commands.CopCommand; +import net.grandtheftmc.vice.commands.CoreNPCCommand; +import net.grandtheftmc.vice.commands.DrugCheckCommand; +import net.grandtheftmc.vice.commands.FeedCommand; +import net.grandtheftmc.vice.commands.FixCommand; +import net.grandtheftmc.vice.commands.HomeCommand; +import net.grandtheftmc.vice.commands.KillCommand; +import net.grandtheftmc.vice.commands.LotteryCommand; +import net.grandtheftmc.vice.commands.MoneyCommand; +import net.grandtheftmc.vice.commands.PayCommand; +import net.grandtheftmc.vice.commands.PrestigeCommand; +import net.grandtheftmc.vice.commands.RTPCommand; +import net.grandtheftmc.vice.commands.RankupCommand; +import net.grandtheftmc.vice.commands.ResetCommand; +import net.grandtheftmc.vice.commands.ResetStatsCommand; +import net.grandtheftmc.vice.commands.ResourcePackCommand; +import net.grandtheftmc.vice.commands.SellCommand; +import net.grandtheftmc.vice.commands.SkinCommand; +import net.grandtheftmc.vice.commands.SkinsCommand; +import net.grandtheftmc.vice.commands.SpawnCommand; +import net.grandtheftmc.vice.commands.SpectatorCommand; +import net.grandtheftmc.vice.commands.SpeedCommand; +import net.grandtheftmc.vice.commands.StackCommand; +import net.grandtheftmc.vice.commands.StatsCommand; +import net.grandtheftmc.vice.commands.TeleportCommand; +import net.grandtheftmc.vice.commands.TokenShopCommand; +import net.grandtheftmc.vice.commands.TopKillersCommand; +import net.grandtheftmc.vice.commands.TpaCommand; +import net.grandtheftmc.vice.commands.VehicleCommand; +import net.grandtheftmc.vice.commands.ViceAdminCommand; +import net.grandtheftmc.vice.commands.ViceRankCommand; +import net.grandtheftmc.vice.commands.ViceRanksCommand; +import net.grandtheftmc.vice.commands.WarpCommand; +import net.grandtheftmc.vice.commands.ZoneCommand; +import net.grandtheftmc.vice.display.DisplayManager; +import net.grandtheftmc.vice.dropship.DropShipManager; +import net.grandtheftmc.vice.drugs.DrugCommand; +import net.grandtheftmc.vice.drugs.DrugComponent; +import net.grandtheftmc.vice.drugs.DrugManager; +import net.grandtheftmc.vice.drugs.events.listener.DrugListener; +import net.grandtheftmc.vice.drugs.events.listener.DrugPlacementListener; +import net.grandtheftmc.vice.durability.DurabilityListener; +import net.grandtheftmc.vice.holidays.HolidayManager; +import net.grandtheftmc.vice.hologram.HologramManager; +import net.grandtheftmc.vice.items.BackpackManager; +import net.grandtheftmc.vice.items.GameItemCommand; +import net.grandtheftmc.vice.items.ItemManager; +import net.grandtheftmc.vice.items.KitCommand; +import net.grandtheftmc.vice.items.ShopCommand; +import net.grandtheftmc.vice.items.ShopManager; +import net.grandtheftmc.vice.listeners.ArmorEquip; +import net.grandtheftmc.vice.listeners.BlockDispense; +import net.grandtheftmc.vice.listeners.BlockPlace; +import net.grandtheftmc.vice.listeners.BreakBlock; +import net.grandtheftmc.vice.listeners.ChangeWorld; +import net.grandtheftmc.vice.listeners.Chat; +import net.grandtheftmc.vice.listeners.ChunkLoad; +import net.grandtheftmc.vice.listeners.CommandPreProcess; +import net.grandtheftmc.vice.listeners.CraftItem; +import net.grandtheftmc.vice.listeners.Damage; +import net.grandtheftmc.vice.listeners.Death; +import net.grandtheftmc.vice.listeners.Dispense; +import net.grandtheftmc.vice.listeners.Drop; +import net.grandtheftmc.vice.listeners.Enchant; +import net.grandtheftmc.vice.listeners.FoodChange; +import net.grandtheftmc.vice.listeners.Interact; +import net.grandtheftmc.vice.listeners.InventoryClick; +import net.grandtheftmc.vice.listeners.InventoryOpen; +import net.grandtheftmc.vice.listeners.InventoryPickupItem; +import net.grandtheftmc.vice.listeners.ItemBreak; +import net.grandtheftmc.vice.listeners.ItemComponent; +import net.grandtheftmc.vice.listeners.ItemSpawn; +import net.grandtheftmc.vice.listeners.ItemStack; +import net.grandtheftmc.vice.listeners.JetpackFuelUse; +import net.grandtheftmc.vice.listeners.Join; +import net.grandtheftmc.vice.listeners.Leave; +import net.grandtheftmc.vice.listeners.Login; +import net.grandtheftmc.vice.listeners.MenuListener; +import net.grandtheftmc.vice.listeners.MobSpawn; +import net.grandtheftmc.vice.listeners.Move; +import net.grandtheftmc.vice.listeners.PetListener; +import net.grandtheftmc.vice.listeners.Pickup; +import net.grandtheftmc.vice.listeners.PlayerEnterZone; +import net.grandtheftmc.vice.listeners.PlayerLeaveZone; +import net.grandtheftmc.vice.listeners.PortalEnter; +import net.grandtheftmc.vice.listeners.RenameComponent; +import net.grandtheftmc.vice.listeners.SmeltItem; +import net.grandtheftmc.vice.listeners.SwapHandItems; +import net.grandtheftmc.vice.listeners.Teleport; +import net.grandtheftmc.vice.listeners.UpdateListener; +import net.grandtheftmc.vice.listeners.VehicleUse; +import net.grandtheftmc.vice.listeners.VoteReward; +import net.grandtheftmc.vice.listeners.WeaponShoot; +import net.grandtheftmc.vice.listeners.WeaponUse; +import net.grandtheftmc.vice.lootcrates.CrateManager; +import net.grandtheftmc.vice.lootcrates.LootCrateCommand; +import net.grandtheftmc.vice.machine.MachineManager; +import net.grandtheftmc.vice.pickers.PickerCommand; +import net.grandtheftmc.vice.pickers.PickerManager; +import net.grandtheftmc.vice.redstone.RedstoneManager; +import net.grandtheftmc.vice.season.SeasonManager; +import net.grandtheftmc.vice.tasks.Lottery; +import net.grandtheftmc.vice.tasks.TaskManager; +import net.grandtheftmc.vice.users.AntiAfkTimer; +import net.grandtheftmc.vice.users.ViceUser; +import net.grandtheftmc.vice.users.ViceUserDAO; +import net.grandtheftmc.vice.users.ViceUserManager; +import net.grandtheftmc.vice.users.npcs.MachineNPC; +import net.grandtheftmc.vice.users.npcs.SkinsNPC; +import net.grandtheftmc.vice.users.npcs.TaxiNPC; +import net.grandtheftmc.vice.users.npcs.TrashCanManager; +import net.grandtheftmc.vice.users.npcs.shopnpc.ShopNPC; +import net.grandtheftmc.vice.users.storage.BooleanStorageType; +import net.grandtheftmc.vice.weapon.WeaponRegistry; +import net.grandtheftmc.vice.weapon.skins.WeaponSkinManager; +import net.grandtheftmc.vice.world.WorldManager; + +public class Vice extends JavaPlugin { + + private static DrugManager drugManager; + private static Vice instance; + private static ViceUserManager um; + private static TaskManager tm; + private static BackpackManager bam; + private static WorldManager worldm; + private static ItemManager im; + private static ShopManager sm; + private static CrateManager cm; + private static TrashCanManager tcm; + private static Lottery lottery; + private static HolidayManager hm; + private static GTMGuns wg; + private static com.j0ach1mmall3.wastedvehicles.Main wv; + private static CombatLogManager clm; + private static ProtocolManager pm; + private MachineManager machineManager; + private static ViceSettings settings; + private static EffectManager effectLib; + private static Factions cartels; + private static PickerManager pim; + private static WeaponSkinManager wsm; + private CoreCasino<Vice> coreCasino; + private HologramManager hologramManager; + private SeasonManager seasonManager; + private DisplayManager displayManager; + private AreaManager areaManager; + + public static boolean WEAPON_SKINS_FEATURE_FLAG = false; + +// private TagManager<Vice> tagManager; + + + public static WorldManager getWorldManager() { + return worldm; + } + + public static CombatLogManager getCombatLogManager() { + return clm; + } + + public static Vice getInstance() { + return instance; + } + + public MachineManager getMachineManager() { + return machineManager; + } + + public static ViceUserManager getUserManager() { + return um; + } + + public static EffectManager getEffectLib() { + return effectLib; + } + + public static TaskManager getTaskManager() { + return tm; + } + + public static BackpackManager getBackpackManager() { + return bam; + } + + public static ItemManager getItemManager() { + return im; + } + + public static ViceSettings getSettings() { + return settings; + } + + public static ShopManager getShopManager() { + return sm; + } + + public static CrateManager getCrateManager() { + return cm; + } + + public static ProtocolManager getProtocolManager() { + return pm; + } + + public static HolidayManager getHolidayManager() { + return hm; + } + + public static DrugManager getDrugManager() { + return drugManager; + } + + public static WeaponSkinManager getWeaponSkinManager() { + return wsm; + } + + public static Factions getCartels() { + if (cartels == null) cartels = Factions.getInstance(); + return cartels; + } + + + public static TrashCanManager getTrashCanManager() { + return tcm; + } + + public static GTMGuns getWastedGuns() { + return wg; + } + + public static com.j0ach1mmall3.wastedvehicles.Main getWastedVehicles() { + return wv; + } + + public static Lottery getLottery() { + return lottery; + } + + public static PickerManager getPickerManager() { + return pim; + } + + public static ResourcePackManager getResourcePackManager() { + return Core.resourcePackManager; + } + + public static void log(Level level, String message) { + System.out.println("[Vice][" + level.toString() + "] " + message); + } + + public static void log(String message) { + log(Level.INFO, message); + } + + public static void error(String message) { + log(Level.SEVERE, message); + } + + public DisplayManager getDisplayManager() { + return this.displayManager; + } + + public SeasonManager getSeasonManager() { + return this.seasonManager; + } + + public AreaManager getAreaManager() { + return this.areaManager; + } + + @Override + public void onEnable() { + + // TODO remove + System.out.println("[Vice] Test."); + + instance = this; + settings = new ViceSettings(); + this.load(); + this.loadDependencies(); + effectLib = new EffectManager(this); + um = new ViceUserManager(); + tm = new TaskManager(); + drugManager = new DrugManager(); + drugManager.start(); + im = new ItemManager(); + drugManager.loadDrugRecipes(); + bam = new BackpackManager(); + sm = new ShopManager(); + cm = new CrateManager(); + lottery = new Lottery(); + hm = new HolidayManager(); + wsm = new WeaponSkinManager(); + worldm = new WorldManager(); + worldm.load(); + clm = new CombatLogManager(); + clm.load(); + tcm = new TrashCanManager(); + pm = ProtocolLibrary.getProtocolManager(); + this.pim = new PickerManager(); +// this.tagManager = new TagManager<Vice>(this, NMSVersion.MC_1_12).onEnable(this); +// new CartelsComponent(this, this.tagManager); +// new NametagComponent(this, this.tagManager); + Core.resourcePackManager = new ResourcePackManager(this, new RSPack_1_12(), new NMSTitle()); + Core.resourcePackManager.setResourcePack(NMSVersion.UNKNOWN, new ResourcePack("http://cdn.grandtheftmc.net/VICE-2.0.8-1.11.zip", "27D482BCBAB4431CEAD764728543B42F")); + Core.resourcePackManager.setResourcePack(NMSVersion.MC_1_12_2, new ResourcePack("http://cdn.grandtheftmc.net/VICE-2.0.8-1.11.zip", "27D482BCBAB4431CEAD764728543B42F")); + Core.resourcePackManager.setResourcePack(NMSVersion.MC_1_12_1, new ResourcePack("http://cdn.grandtheftmc.net/VICE-2.0.8-1.11.zip", "27D482BCBAB4431CEAD764728543B42F")); + Core.resourcePackManager.setResourcePack(NMSVersion.MC_1_12, new ResourcePack("http://cdn.grandtheftmc.net/VICE-2.0.8-1.11.zip", "27D482BCBAB4431CEAD764728543B42F")); + Core.resourcePackManager.setResourcePack(NMSVersion.MC_1_11_2, new ResourcePack("http://cdn.grandtheftmc.net/VICE-2.0.8-1.11.zip", "27D482BCBAB4431CEAD764728543B42F")); + Core.resourcePackManager.setResourcePack(NMSVersion.MC_1_11, new ResourcePack("http://cdn.grandtheftmc.net/VICE-2.0.8-1.11.zip", "27D482BCBAB4431CEAD764728543B42F")); + Core.resourcePackManager.setResourcePack(NMSVersion.MC_1_10, new ResourcePack("http://cdn.grandtheftmc.net/VICE-2.0.8-1.10.zip", "33862C9199CFFB217D6808EFE06392DB")); + Core.resourcePackManager.setResourcePack(NMSVersion.MC_1_9_4, new ResourcePack("http://cdn.grandtheftmc.net/VICE-2.0.8-1.10.zip", "33862C9199CFFB217D6808EFE06392DB")); + Core.resourcePackManager.setResourcePack(NMSVersion.MC_1_9_2, new ResourcePack("http://cdn.grandtheftmc.net/VICE-2.0.8-1.10.zip", "33862C9199CFFB217D6808EFE06392DB")); + Core.resourcePackManager.setResourcePack(NMSVersion.MC_1_9_1, new ResourcePack("http://cdn.grandtheftmc.net/VICE-2.0.8-1.10.zip", "33862C9199CFFB217D6808EFE06392DB")); + Core.resourcePackManager.setResourcePack(NMSVersion.MC_1_9, new ResourcePack("http://cdn.grandtheftmc.net/VICE-2.0.8-1.10.zip", "33862C9199CFFB217D6808EFE06392DB")); + + this.coreCasino = new CoreCasino<Vice>(this, new NMSTitle(), NMSVersion.MC_1_12); + + ServerUtil.runTaskLater(() -> { + coreCasino.addGame(new SlotMachine(coreCasino, new Location(Bukkit.getWorld("spawn"), 131, 77.1875, 173.5, 0f, 0f))); + coreCasino.addGame(new SlotMachine(coreCasino, new Location(Bukkit.getWorld("spawn"), 144, 77.1875, 173.5, 0f, 0f))); + + coreCasino.enabledAllGames(); + }, 15*20); + + Bukkit.getScheduler().runTaskTimer(this, new AntiAfkTimer(), 0, 20*60*10); + + new WeaponRegistry(wg.getWeaponManager()); + + this.hologramManager = new HologramManager(this); + this.displayManager = new DisplayManager(this, this.hologramManager); + this.seasonManager = new SeasonManager(this, this.hologramManager); + + this.areaManager = new AreaManager(this); + + this.machineManager = new MachineManager(this); +// new GunTestingListener().onEnable(this); //TODO: TESTING. + new DrugComponent(this); + new DropShipManager(this, this.areaManager, im); + new RedstoneManager(); + + this.registerCommands(); + this.registerListeners(); + + // Utils.startEnchantmentShineRemover(pm, this); + + //EventCatcher +// detector.addListener((plugin, event) -> { +// log(event.getEventName() + " cancelled by: " + plugin.getName()); +// }); + + World spawn = Bukkit.getWorld("spawn"); + Core.getNPCManager().registerCoreNPC(new ShopNPC(new Location(spawn, 91, 79, 214.5))); + Core.getNPCManager().registerCoreNPC(new MachineNPC(this.machineManager, new Location(spawn, 159, 77, 217))); + Core.getNPCManager().registerCoreNPC(new TaxiNPC(new Location(spawn, 137.5, 77, 230.5))); + + if(WEAPON_SKINS_FEATURE_FLAG) { + Core.getNPCManager().registerCoreNPC(new SkinsNPC(new Location(spawn, -325.5, 25, 206.5))); + } + + for (World world : Bukkit.getWorlds()) { + world.setGameRuleValue("announceAdvancements", "false"); + if (world.getName().equals("world")) { + for (Chunk chunk : world.getLoadedChunks()) { + chunk.unload(); + } + } + } + } + + private void loadDependencies() { + PluginManager plm = Bukkit.getPluginManager(); + Plugin wastedGunsPlugin = plm.getPlugin("WastedGuns"); + if (wastedGunsPlugin == null) { + log("Error while enabling WastedGuns dependency. Is it installed?"); + } else { + wg = (GTMGuns) wastedGunsPlugin; + } + Plugin wastedVehiclesPlugin = plm.getPlugin("WastedVehicles"); + if (wastedVehiclesPlugin == null) { + log("Error while enabling WastedVehicles dependency. Is it installed?"); + } else { + wv = (com.j0ach1mmall3.wastedvehicles.Main) wastedVehiclesPlugin; + } + } + + @Override + public void onDisable() { + Bukkit.getScheduler().cancelTasks(this); + + this.seasonManager.onDisable(this); + this.hologramManager.onDisable(this); + this.machineManager.onDisable(this); + +// this.tagManager.onDisable(this); + for (Player player : Bukkit.getOnlinePlayers()) { + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + user.setBooleanToStorage(BooleanStorageType.KICKED, true); + if (user.isInCombat()) user.setLastTag(-1); + Vice.getUserManager().unloadUser(player.getUniqueId()); + } + + this.save(); + this.coreCasino.removeAllGames(); + } + + private void registerListeners() { + PluginManager pm = Bukkit.getPluginManager(); + pm.registerEvents(new Death(), this); + pm.registerEvents(new ItemStack(), this); + pm.registerEvents(new Login(), this); + pm.registerEvents(new Leave(), this); + pm.registerEvents(new MenuListener(), this); + pm.registerEvents(new Join(this.hologramManager), this); + pm.registerEvents(new Pickup(), this); + pm.registerEvents(new WeaponUse(), this); + pm.registerEvents(new Drop(), this); + pm.registerEvents(new Interact(), this); + pm.registerEvents(new Chat(), this); + pm.registerEvents(new InventoryClick(), this); + pm.registerEvents(new InventoryOpen(), this); + pm.registerEvents(new BlockDispense(), this); + pm.registerEvents(new BackpackManager(), this); + pm.registerEvents(new UpdateListener(), this); + pm.registerEvents(new Move(), this); + pm.registerEvents(new Damage(), this); + pm.registerEvents(new ChangeWorld(), this); + pm.registerEvents(new FoodChange(), this); + pm.registerEvents(new VehicleUse(), this); + pm.registerEvents(new PetListener(), this); + pm.registerEvents(new ItemBreak(), this); + pm.registerEvents(new BreakBlock(), this); + pm.registerEvents(new WeaponShoot(), this); + pm.registerEvents(new SwapHandItems(), this); + pm.registerEvents(new DrugListener(), this); + pm.registerEvents(new DrugPlacementListener(), this); +// pm.registerEvents(new ResourcePack(), this); +// pm.registerEvents(new FireListener(), this); + pm.registerEvents(new VoteReward(), this); + pm.registerEvents(new CraftItem(), this); + pm.registerEvents(new SmeltItem(), this); + pm.registerEvents(new Enchant(), this); + pm.registerEvents(new DurabilityListener(), this); + pm.registerEvents(new InventoryPickupItem(), this); + pm.registerEvents(new CommandPreProcess(), this); + pm.registerEvents(new ArmorEquip(), this); + pm.registerEvents(new BlockPlace(), this); + pm.registerEvents(new ChunkLoad(), this); + pm.registerEvents(new Dispense(), this); + pm.registerEvents(new MobSpawn(), this); + pm.registerEvents(new JetpackFuelUse(), this); + pm.registerEvents(new Teleport(), this); + pm.registerEvents(new JetpackFuelUse(), this); + pm.registerEvents(new PlayerEnterZone(), this); + pm.registerEvents(new PlayerLeaveZone(), this); + pm.registerEvents(new PortalEnter(), this); + pm.registerEvents(new ItemSpawn(), this); + pm.registerEvents(tcm, this); + new HomeCommand(); + new PrestigeCommand(); + new CoreNPCCommand(this.machineManager); + // new LogoutCommand(); + new ItemComponent(); + new RenameComponent(this); + + this.getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord"); + } + + private void registerCommands() { + this.getCommand("ammo").setExecutor(new AmmoCommand()); + this.getCommand("feed").setExecutor(new FeedCommand()); + this.getCommand("lootcrate").setExecutor(new LootCrateCommand()); + this.getCommand("spawn").setExecutor(new SpawnCommand()); + this.getCommand("warp").setExecutor(new WarpCommand()); + this.getCommand("viceadmin").setExecutor(new ViceAdminCommand()); + this.getCommand("gameitem").setExecutor(new GameItemCommand()); + this.getCommand("kit").setExecutor(new KitCommand()); + this.getCommand("shop").setExecutor(new ShopCommand()); + this.getCommand("vicerank").setExecutor(new ViceRankCommand()); + this.getCommand("money").setExecutor(new MoneyCommand()); + new BaltopCommand(); + this.getCommand("pay").setExecutor(new PayCommand()); + this.getCommand("rankup").setExecutor(new RankupCommand()); + this.getCommand("tpa").setExecutor(new TpaCommand()); + this.getCommand("tpahere").setExecutor(new TpaCommand()); + this.getCommand("tpaccept").setExecutor(new TpaCommand()); + this.getCommand("tpdeny").setExecutor(new TpaCommand()); + this.getCommand("bonds").setExecutor(new BondsCommand()); + this.getCommand("kill").setExecutor(new KillCommand()); + this.getCommand("suicide").setExecutor(new KillCommand()); + this.getCommand("picker").setExecutor(new PickerCommand()); + this.getCommand("vehicle").setExecutor(new VehicleCommand()); + this.getCommand("backpack").setExecutor(new BackpackCommand()); + this.getCommand("bribe").setExecutor(new BribeCommand()); + this.getCommand("reset").setExecutor(new ResetCommand()); + this.getCommand("tokenshop").setExecutor(new TokenShopCommand()); + this.getCommand("antiaura").setExecutor(new AntiAuraCommand()); + this.getCommand("clear").setExecutor(new ClearCommand()); + this.getCommand("fix").setExecutor(new FixCommand()); +// this.getCommand("near").setExecutor(new NearCommand()); Not wanted on vice. + this.getCommand("teleport").setExecutor(new TeleportCommand()); + this.getCommand("spectator").setExecutor(new SpectatorCommand()); + this.getCommand("backup").setExecutor(new BackupCommand()); + this.getCommand("resetstats").setExecutor(new ResetStatsCommand()); + this.getCommand("lottery").setExecutor(new LotteryCommand()); + this.getCommand("speed").setExecutor(new SpeedCommand()); + this.getCommand("chunkunload").setExecutor(new ChunkUnloadCommand()); + this.getCommand("topkillers").setExecutor(new TopKillersCommand()); + this.getCommand("stats").setExecutor(new StatsCommand()); + this.getCommand("drugs").setExecutor(new DrugCommand()); + this.getCommand("resourcepack").setExecutor(new ResourcePackCommand()); + this.getCommand("drugcheck").setExecutor(new DrugCheckCommand()); + this.getCommand("viceranks").setExecutor(new ViceRanksCommand()); + this.getCommand("stack").setExecutor(new StackCommand()); + this.getCommand("cop").setExecutor(new CopCommand()); + this.getCommand("rtp").setExecutor(new RTPCommand()); + this.getCommand("area").setExecutor(new AreaCommand(this)); + new CheatCodeCommand(); + new ZoneCommand(); + new SellCommand(); + + if(WEAPON_SKINS_FEATURE_FLAG) { + new SkinCommand(); + new SkinsCommand(); + } + } + + private void load() { + this.setupTables(); + settings.setPlayerCacheConfig(Utils.loadConfig("playercache")); + settings.setViceConfig(Utils.loadConfig("vice")); + settings.setWarpsConfig(Utils.loadConfig("warps")); + settings.setItemsConfig(Utils.loadConfig("items")); + settings.setKitsConfig(Utils.loadConfig("kits")); + settings.setLootConfig(Utils.loadConfig("loot")); + settings.setLootCratesConfig(Utils.loadConfig("lootcrates")); + settings.setLotteryConfig(Utils.loadConfig("lottery")); + settings.setDrugBlocksConfig(Utils.loadConfig("drugblocks")); + settings.setDrugDealersConfig(Utils.loadConfig("drugdealers")); + settings.setPickersConfig(Utils.loadConfig("pickers")); + settings.setUpgradeContainersConfig(Utils.loadConfig("upgradedcontainers")); + settings.setHomesConfig(Utils.loadConfig("homes")); + settings.setZoneConfig(Utils.loadConfig("zones")); + YamlConfiguration c = settings.getViceConfig(); + settings.setMap(c.getString("map")); + this.loadMenus(); + this.loadSettings(); + settings.setOneElevenRespack("http://cdn.grandtheftmc.net/VICE-2.0.8-1.11.zip"); + settings.setOneElevenHash("27D482BCBAB4431CEAD764728543B42F"); + settings.setOneTenRespack("http://cdn.grandtheftmc.net/VICE-2.0.8-1.10.zip"); + settings.setOneTenHash("33862C9199CFFB217D6808EFE06392DB"); + } + + public void reload() { + this.load(); + im.loadItems(); + im.loadKits(); + cm.loadCrates(); + worldm.load(); + lottery.loadConfig(); + } + + public void save() { + im.saveItems(); + cm.saveCrates(); + im.saveKits(); + worldm.save(); + // lottery.saveConfig(); + this.drugManager.stop(); + effectLib.dispose(); + pim.save(); + clm.save(); + } + + public void setupTables() { + // TODO redo this shit +// Core.sql.updateAsyncLater("CREATE TABLE IF NOT EXISTS " + Core.name() + "(uuid varchar(40) NOT NULL, name varchar(17) NOT NULL, rank varchar(255) DEFAULT 'HOBO', copRank varchar(366) DEFAULT NULL, kills int(11) default 0, deaths int(11) default 0, money double default 0, killStreak int(11) default 0, bonds int(11) default 0, backpackContents longtext, kitExpiries varchar(255), houses varchar(255), gang varchar(255), gangRank varchar(255) NOT NULL DEFAULT 'member', jailTimer int(11) DEFAULT -1, jailCop varchar(255) default NULL, jailCopName varchar(255) default NULL, personalVehicle varchar(255), cheatcodes BLOB, PRIMARY KEY (uuid))"); + ServerUtil.runTaskAsync(() -> { + ViceUserDAO.createTable(); + ViceUserDAO.managePlaytime(); + }); + +// new BukkitRunnable() { +// @Override +// public void run() { +// try (ResultSet rs = Core.sql.query("select * from " + Core.name() + " LIMIT 1;")) { +// ResultSetMetaData metaData = rs.getMetaData(); +// List<String> columns = new ArrayList<>(); +// +// for (int i = 1; i <= metaData.getColumnCount(); i++) +// columns.add(metaData.getColumnName(i).toLowerCase()); +// +// if (!columns.contains("playtime")) +// Core.sql.updateAsyncLater("ALTER TABLE " + Core.name() + " ADD COLUMN playtime BIGINT(20) NOT NULL DEFAULT 0;"); +// +// for (AmmoType type : AmmoType.values()) +// if (!type.isInInventory() && !columns.contains(type.toString().toLowerCase())) +// Core.sql.update("alter table " + Core.name() + " add column " + type.toString().toLowerCase() + " int(11) default 0;"); +// +// for (VehicleProperties vehicle : Vice.getWastedVehicles().getBabies().getVehicleProperties()) { +// if (!columns.contains(vehicle.getIdentifier().toLowerCase())) +// Core.sql.update("alter table " + Core.name() + " add column " + vehicle.getIdentifier().toLowerCase() + " BOOLEAN not null default 0;"); +// +// if (!columns.contains(vehicle.getIdentifier().toLowerCase() + ":info")) +// Core.sql.update("alter table " + Core.name() + " add column `" + vehicle.getIdentifier().toLowerCase() + ":info` VARCHAR(255);"); +// } +// rs.close(); +// } catch (SQLException e) { +// Core.error("Error while altering " + Core.name() + " table: "); +// e.printStackTrace(); +// } +// } +// }.runTaskAsynchronously(this); + } + + private void loadMenus() { + MenuManager.addMenu("phone", 54, "&7&lPhone"); + + MenuManager.addMenu("account", 54, "&d&lMy Account"); + MenuManager.addMenu("ranks", 54, "&a&lRanks"); + MenuManager.addMenu("vicestats", 54, "&d&lStats"); + MenuManager.addMenu("prefs", 54, "&5&lPreferences"); + MenuManager.addMenu("contacts", 54, "&6&lContacts"); + + MenuManager.addMenu("kits", 54, "&b&lKits"); + + MenuManager.addMenu("taxi", 54, "&e&lTaxi Service"); + MenuManager.addMenu("taxiplayers", 54, "&e&lTaxi Service: Players"); + MenuManager.addMenu("taxihouses", 54, "&e&lTaxi Service: &3&lHouses"); + MenuManager.addMenu("taxiotherplayers", 54, "&e&lPick up a player!"); + MenuManager.addMenu("taxiwarps", 54, "&e&lTaxi Service: Warps"); + + MenuManager.addMenu("ammopouch", 36, "&c&lAmmo Pouch"); + + MenuManager.addMenu("jail", 54, "&c&lJail"); + + MenuManager.addMenu("property", 54, "&2&lProperty"); + MenuManager.addMenu("vehicles", 54, "&4&lVehicles"); + MenuManager.addMenu("vehicleshop", 54, "&4&lVehicle Shop"); + MenuManager.addMenu("buyvehicle", 54, "&4&lBuy Vehicle Shop"); + MenuManager.addMenu("sellvehicle", 54, "&4&lSell Vehicle"); + MenuManager.addMenu("repairvehicle", 54, "&4&lRepair Vehicle"); + MenuManager.addMenu("personalvehicle", 54, "&4&lPersonal Vehicle"); + MenuManager.addMenu("mechanic", 54, "&4&lMechanic"); + + MenuManager.addMenu("cheatcodes", 54, "&2&lCheat Codes"); + MenuManager.addMenu("choose_villager_type", 54, "&2&lChoose The Villager's Job"); + + MenuManager.addMenu("armorupgrade", 54, "&b&lArmor Upgrade"); + + MenuManager.addMenu("lottery", 54, "&e&lLottery"); + + MenuManager.addMenu("drugdealer", 54, "&c&lDrug Dealer"); + + } + + private void loadSettings() { + Settings settings = Core.getSettings(); + settings.setDefaultGameMode(GameMode.SURVIVAL); + settings.setPetsVulnerable(true); + settings.setServerWarperEnabled(false); + settings.setTokenShopEnabled(true); + settings.setCanOpenChests(true); + settings.setCanInteractInventory(true); + settings.setLoadCosmetics(true); + settings.setCanCraft(true); + //World plots = Bukkit.getWorld(Vice.getSettings().getPlotsWorld()); + //plots.setPVP(false); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/ViceSettings.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/ViceSettings.java new file mode 100644 index 0000000..aace7b7 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/ViceSettings.java @@ -0,0 +1,214 @@ +package net.grandtheftmc.vice; + +import org.bukkit.configuration.file.YamlConfiguration; + +public class ViceSettings { + private YamlConfiguration viceConfig; + private YamlConfiguration warpsConfig; + private YamlConfiguration bountiesConfig; + private YamlConfiguration itemsConfig; + private YamlConfiguration kitsConfig; + private YamlConfiguration lootConfig; + private YamlConfiguration lootCratesConfig; + private YamlConfiguration barrelsConfig; + private YamlConfiguration lotteryConfig; + private YamlConfiguration drugDealersConfig; + private YamlConfiguration drugBlocksConfig; + private YamlConfiguration viceShopMenuConfig; + private YamlConfiguration pickersConfig; + private YamlConfiguration homesConfig; + private YamlConfiguration upgradeContainersConfig; + private YamlConfiguration playerCacheConfig; + private YamlConfiguration zoneConfig; + + private String oneTenRespack; + private String oneTenHash; + + private String oneElevenRespack; + private String oneElevenHash; + + private String map; + + public YamlConfiguration getZoneConfig() { + return zoneConfig; + } + + public void setZoneConfig(YamlConfiguration zoneConfig) { + this.zoneConfig = zoneConfig; + } + + public YamlConfiguration getPlayerCacheConfig() { + return playerCacheConfig; + } + + public void setPlayerCacheConfig(YamlConfiguration playerCacheConfig) { + this.playerCacheConfig = playerCacheConfig; + } + + public void setHomesConfig(YamlConfiguration homesConfig) { + this.homesConfig = homesConfig; + } + + public YamlConfiguration getHomesConfig() { + return homesConfig; + } + + public void setViceShopMenuConfig(YamlConfiguration viceShopMenuConfig) { + this.viceShopMenuConfig = viceShopMenuConfig; + } + + public void setUpgradeContainersConfig(YamlConfiguration upgradeContainersConfig) { + this.upgradeContainersConfig = upgradeContainersConfig; + } + + public YamlConfiguration getUpgradeContainersConfig() { + return upgradeContainersConfig; + } + + public YamlConfiguration getViceShopMenuConfig() { + return viceShopMenuConfig; + } + + public YamlConfiguration getDrugBlocksConfig() { + return drugBlocksConfig; + } + + public YamlConfiguration getDrugDealerConfig() { + return null; + }//todo: added to allow jar to file + + public void setDrugDealerConfig(YamlConfiguration c) { + } + + public void setDrugBlocksConfig(YamlConfiguration drugBlocksConfig) { + this.drugBlocksConfig = drugBlocksConfig; + } + + public YamlConfiguration getDrugDealersConfig() { + return drugDealersConfig; + } + + public void setDrugDealersConfig(YamlConfiguration drugDealersConfig) { + this.drugDealersConfig = drugDealersConfig; + } + + public YamlConfiguration getViceConfig() { + return this.viceConfig; + } + + public void setViceConfig(YamlConfiguration viceConfig) { + this.viceConfig = viceConfig; + } + + public YamlConfiguration getWarpsConfig() { + return this.warpsConfig; + } + + public void setWarpsConfig(YamlConfiguration warpsConfig) { + this.warpsConfig = warpsConfig; + } + + public YamlConfiguration getBountiesConfig() { + return this.bountiesConfig; + } + + public void setBountiesConfig(YamlConfiguration bountiesConfig) { + this.bountiesConfig = bountiesConfig; + } + + public YamlConfiguration getItemsConfig() { + return this.itemsConfig; + } + + public void setItemsConfig(YamlConfiguration itemsConfig) { + this.itemsConfig = itemsConfig; + } + + public YamlConfiguration getKitsConfig() { + return this.kitsConfig; + } + + public void setKitsConfig(YamlConfiguration kitsConfig) { + this.kitsConfig = kitsConfig; + } + + public YamlConfiguration getBarrelsConfig() { + return this.barrelsConfig; + } + + public void setBarrelsConfig(YamlConfiguration barrelsConfig) { + this.barrelsConfig = barrelsConfig; + } + + public String getMap() { + return this.map; + } + + public void setMap(String map) { + this.map = map; + } + + public YamlConfiguration getLootCratesConfig() { + return this.lootCratesConfig; + } + + public void setLootCratesConfig(YamlConfiguration lootCratesConfig) { + this.lootCratesConfig = lootCratesConfig; + } + + public YamlConfiguration getLootConfig() { + return this.lootConfig; + } + + public void setLootConfig(YamlConfiguration lootConfig) { + this.lootConfig = lootConfig; + } + + public YamlConfiguration getLotteryConfig() { + return this.lotteryConfig; + } + + public void setLotteryConfig(YamlConfiguration lotteryConfig) { + this.lotteryConfig = lotteryConfig; + } + + public String getOneElevenRespack() { + return oneElevenRespack; + } + + public String getOneElevenHash() { + return oneElevenHash; + } + + public String getOneTenRespack() { + return oneTenRespack; + } + + public String getOneTenHash() { + return oneTenHash; + } + + public void setOneElevenRespack(String oneElevenRespack) { + this.oneElevenRespack = oneElevenRespack; + } + + public void setOneElevenHash(String oneElevenHash) { + this.oneElevenHash = oneElevenHash; + } + + public void setOneTenRespack(String oneTenRespack) { + this.oneTenRespack = oneTenRespack; + } + + public void setOneTenHash(String oneTenHash) { + this.oneTenHash = oneTenHash; + } + + public YamlConfiguration getPickersConfig() { + return this.pickersConfig; + } + + public void setPickersConfig(YamlConfiguration pickersConfig) { + this.pickersConfig = pickersConfig; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/ViceUtils.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/ViceUtils.java new file mode 100644 index 0000000..7b85e2f --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/ViceUtils.java @@ -0,0 +1,916 @@ +package net.grandtheftmc.vice; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.WrappedDataWatcher; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.boards.Board; +import net.grandtheftmc.core.boards.BoardType; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.users.Pref; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.items.GameItem; +import net.grandtheftmc.vice.items.Schedule; +import net.grandtheftmc.vice.users.ViceRank; +import net.grandtheftmc.vice.users.ViceUser; +import net.grandtheftmc.vice.utils.ReflectionUtil; +import net.grandtheftmc.vice.world.warps.Warp; +import org.bukkit.*; +import org.bukkit.block.Block; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.io.BukkitObjectInputStream; +import org.bukkit.util.io.BukkitObjectOutputStream; +import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder; + +import java.io.*; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.text.NumberFormat; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.Month; +import java.time.ZoneId; +import java.util.*; +import java.util.concurrent.ThreadLocalRandom; +import java.util.logging.Level; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +public final class ViceUtils { + + public static final String HEADER = Utils.f( + " &7&l▀&d&l▄&7&l▀&d&l▄&7&l▀&d&l▄&7&l▀&d&l▄&7&l▀&d&l▄&7&l▀&d&l▄&7&l▀&d&l▄&7&l▀&d&l▄&7&l▀&d&l▄&7&l▀&d&l▄&7&l▀&d&l▄&7&l▀&d&l▄&7&l▀&d&l▄&7&l▀&d&l▄&7&l▀&d&l▄&7&l▀"); + public static final String FOOTER = Utils.f( + " &7&l▄&d&l▀&7&l▄&d&l▀&7&l▄&d&l▀&7&l▄&d&l▀&7&l▄&d&l▀&7&l▄&d&l▀&7&l▄&d&l▀&7&l▄&d&l▀&7&l▄&d&l▀&7&l▄&d&l▀&7&l▄&d&l▀&7&l▄&d&l▀&7&l▄&d&l▀&7&l▄&d&l▀&7&l▄&d&l▀&7&l▄"); + + private ViceUtils() { + } + + public static Material getSeedVersionOfMaterial(Material material) { + String sMat = material + "_SEEDS"; + return Material.getMaterial(sMat) == null ? material : Material.getMaterial(sMat); + } + + public static ViceUser getViceUser(Player player) { + return Vice.getUserManager().getLoadedUser(player.getUniqueId()); + } + + public static User getUser(Player player) { + return Core.getUserManager().getLoadedUser(player.getUniqueId()); + } + + public static UserRank getRank(Player player) { + return Core.getUserManager().getLoadedUser(player.getUniqueId()).getUserRank(); + } + + public static void updateBoard(Player player, ViceUser viceUser) { + updateBoard(player, Core.getUserManager().getLoadedUser(player.getUniqueId()), viceUser); + } + + public static boolean canPlantOn(Material plant, Material block){ + switch (plant){ + case CARROT_ITEM: + case POTATO_ITEM: + case SEEDS: + case BEETROOT_SEEDS: + case MELON_SEEDS: + case PUMPKIN_SEEDS: + return block==Material.SOIL; + case NETHER_STALK: + return block== Material.SOUL_SAND; + case SUGAR_CANE: + return block== Material.DIRT || block== Material.SAND; + case CACTUS: + return block== Material.SAND; + } + return true; + } + + public static void updateBoard(Player player, User user, ViceUser viceUser) { + if (!user.getPref(Pref.USE_SCOREBOARD) || user.isInTutorial()) { + player.setScoreboard(Bukkit.getScoreboardManager().getNewScoreboard()); + return; + } + Board board = new Board("vice", "&d&lVice&7&lMC", BoardType.LIST); + board.addLine("&a&lMoney"); + board.addLine(' ' + Utils.formatMoney(viceUser.getMoney())); + board.addLine("&a"); + if (viceUser.isCop()) { + board.addLine("&3&lCop Rank"); + board.addLine(' ' + viceUser.getCopRank().getName()); + } else { + ViceRank rank = viceUser.getRank(); + ViceRank next = rank.getNext(); + int cost = next == null ? 0 : next.getPrice(); + board.addLine(Utils.f("&e&lRank Info")); + board.addLine(Utils.f(" &7Current: &r" + viceUser.getRank())); + if (next != null) { + board.addLine(Utils.f(" &7Next: &r" + next.getColoredName())); + board.addLine(Utils.f(" &7Cost: &r" + Utils.formatMoney(next.getPrice()))); + board.addLine(Utils.f(viceUser.hasMoney(cost) ? " &7Use &a/rankup&7 to progress!" : " &7Progress: &r" + (100 * Utils.round(viceUser.getMoney() / cost)) + "%")); + } + } + board.addLine(Utils.f("&b")); + board.addLine(Utils.f("&6&lServer IP")); + board.addLine(Utils.f(" mc-gtm.net")); + board.updateFor(player, Core.getUserManager().getLoadedUser(player.getUniqueId())); + } + + public static void removeBoard(Player player) { + player.setScoreboard(Bukkit.getScoreboardManager().getNewScoreboard()); + } + + public static String getWantedLevelStars(int i) { + String[] wantedLevels = new String[]{"✩✩✩✩✩", "✮✩✩✩✩", "✮✮✩✩✩", "✮✮✮✩✩", "✮✮✮✮✩", "✮✮✮✮✮"}; + return wantedLevels[i]; + } + + public static void giveGameItems(Player player) { + ItemStack phone = Utils.createItem(Material.WATCH, "&7&lPhone"); + ItemStack bp = Utils.createItem(Material.CHEST, "&6&lBackpack"); + ItemStack ammoPouch = Utils.createItem(Material.CHEST, "&c&lAmmo Pouch"); + Inventory inv = player.getInventory(); + if (!inv.contains(phone)) + if (inv.getItem(8) == null) + inv.setItem(8, phone); + else + inv.addItem(phone); + if(!inv.contains(bp)) + inv.setItem(17, bp); + if(!inv.contains(ammoPouch)) + inv.setItem(16, ammoPouch); + } + + + + public static boolean isPhone(ItemStack item) { + return item != null && Objects.equals(item, Utils.createItem(Material.WATCH, "&7&lPhone")); + } + + public static String getMessageKilledBy(String name) { + String[] msges = new String[]{"Shanked by " + name, "Rekt by " + name, "Killed by " + name, + name + " killed you", name + " clapped yo ass", name + " killed you"}; + return msges[Utils.getRandom().nextInt(msges.length)]; + } + + public static void sendJoinMessage(Player p, User u) { + p.sendMessage(new String[]{"", "", "", "", "", "", "", "", "", "", Utils.f(HEADER), "", + Utils.fc("Welcome, " + u.getColoredName(p) + "&r to &d&lVice&7&lMC&r! "), + Utils.fc("&e&l&oDrug Cartels in Minecraft! "), "", Utils.fc("&e&lSTORE &r&nstore.grandtheftmc.net"), + Utils.fc("&a&lSITE &r&ngrandtheftmc.net "), "", Utils.fc("&7Use &a/tutorial&7 to get started!"), + "", Utils.f(FOOTER), ""}); + + } + + public static List<ViceUser> getCops() { + return Vice.getUserManager().getLoadedUsers().stream().filter(ViceUser::isCop).collect(Collectors.toList()); + } + + public static Map<ViceUser, Integer> sort(Map<ViceUser, Integer> unsortMap) { + List<Map.Entry<ViceUser, Integer>> list = new LinkedList<>(unsortMap.entrySet()); + list.sort(Comparator.comparing(obj -> obj.getValue())); + Map<ViceUser, Integer> sortedMap = new LinkedHashMap<>(); + for (Map.Entry<ViceUser, Integer> entry : list) { + sortedMap.put(entry.getKey(), entry.getValue()); + } + return sortedMap; + } + + public static List<Player> getJailedPlayers() { + List<Player> players = new ArrayList<>(); + for (Player p : Bukkit.getOnlinePlayers()) { + ViceUser viceUser = Vice.getUserManager().getLoadedUser(p.getUniqueId()); + if (viceUser.isArrested()) { + players.add(p); + } + } + return players; + } + + public static String toBase64(ItemStack[] array) { + if (array == null) + return null; + try { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + try (BukkitObjectOutputStream dataOutput = new BukkitObjectOutputStream(outputStream)) { + + dataOutput.writeInt(array.length); + for (ItemStack stack : array) + dataOutput.writeObject(stack); + dataOutput.close(); + } + return Base64Coder.encodeLines(outputStream.toByteArray()); + } catch (Exception e) { + Vice.getInstance().getLogger().log(Level.ALL, "Error while serializing items!"); + e.printStackTrace(); + return null; + } + } + + public static ItemStack[] fromBase64(String data) { + if (data == null) + return new ItemStack[0]; + try { + ByteArrayInputStream inputStream = new ByteArrayInputStream(Base64Coder.decodeLines(data)); + ItemStack[] array; + try (BukkitObjectInputStream dataInput = new BukkitObjectInputStream(inputStream)) { + array = new ItemStack[dataInput.readInt()]; + // Read the serialized inventory + for (int i = 0; i < array.length; i++) + array[i] = (ItemStack) dataInput.readObject(); + + dataInput.close(); + } + return array; + } catch (Exception e) { + Vice.getInstance().getLogger().log(Level.ALL, "Error while deserializing items: " + data); + e.printStackTrace(); + return new ItemStack[0]; + } + } + + public static int getGangMembers(UserRank userRank) { + switch (userRank) { + case DEFAULT: + return 0; + case VIP: + return 2; + case PREMIUM: + return 5; + case ELITE: + return 10; + case SPONSOR: + return 15; + default: + return 20; + } + } + + private final static List<String> DEFAULT_ITEMS = new ArrayList<>(Arrays.asList("Phone", "Backpack", "Ammo Pouch")); + public static boolean isDefaultPlayerItem(ItemStack is) { + return is!=null && is.hasItemMeta() && is.getItemMeta().hasDisplayName() && DEFAULT_ITEMS.contains(ChatColor.stripColor(is.getItemMeta().getDisplayName())); + } + + public static String upperCaseFirst(String s) { + return s.substring(0, 1).toUpperCase() + s.substring(1, s.length()).toLowerCase(); + } + + public static int getTimeInJailForDrugs(Player player) { // IN SECONDS + Map<Schedule, Integer> drugs = new HashMap<>(); + for (ItemStack item : player.getInventory().getContents()) { + GameItem gameItem = Vice.getItemManager().getItem(item); + if (gameItem != null && gameItem.isScheduled()) { + Schedule s = gameItem.getSchedule(); + drugs.put(s, drugs.getOrDefault(s, 0) + item.getAmount()); + } + } + int i = drugs.entrySet().stream().mapToInt(entry -> (int) (getTimeInJail(entry.getValue()) * entry.getKey().getJailMultiplier())).sum(); + return i > 900 ? 900 : i; + } + + private static int getTimeInJail(int drugs) { // IN SECONDS + if (drugs <= 64) + return 60; + if (drugs <= 256) + return 120; + if (drugs <= 512) + return 180; + return 300; + } + + public static int getCopMoney(int wl) { + return new int[]{0, 2000, 5000, 10000, 20000, 50000}[wl]; + } + + public static int getFeedDelay(UserRank rank) {// IN SECONDS + switch (rank) { + case DEFAULT: + return 1800; + case VIP: + return 900; + case PREMIUM: + return 600; + case ELITE: + return 300; + case SPONSOR: + return 180; + default: + return 120; + } + + } + public static int getFixHandDelay(UserRank rank) {// IN SECONDS + switch (rank) { + case DEFAULT: + return 60*60; + case VIP: + return 60*30; + case PREMIUM: + return 60*20; + case ELITE: + return 60*15; + case SPONSOR: + return 60*10; + case SUPREME: + return 60*5; + default: + return 60*5; + } + + } + + public static boolean isTool(Material mat) { + String s = mat.toString(); + return s.contains("SPADE") || s.contains("PICKAXE") || s.contains("AXE") || s.contains("HOE"); + } + + public static boolean isArmorPiece(Material mat) { + String s = mat.toString(); + return s.contains("LEGGINGS") || s.contains("BOOTS") || s.contains("HELMET") || s.contains("CHESTPLATE"); + } + + public static int getFixAllDelay(UserRank rank) {// IN SECONDS + switch (rank) { + default: + return 60*60*24; + } + + } + + public static int getSetHomes(ViceRank rank) { + switch (rank) { + case JUNKIE: + case FALCON: + case THUG: + case DEALER: + return 0; + case GROWER: + case SMUGGLER: + case CHEMIST: + case DRUGLORD: + return 2; + default: + return 3; + } + } + + public static int getSetHomes(UserRank rank) { + switch (rank) { + case DEFAULT: + return 1; + case VIP: + return 2; + case PREMIUM: + return 4; + case ELITE: + return 7; + case SPONSOR: + return 12; + default: + return 20; + } + } + + public static int getBackpackRows(UserRank rank) { + switch (rank) { + case DEFAULT: + return 2; + case VIP: + return 3; + case PREMIUM: + return 5; + case ELITE: + return 7; + case SPONSOR: + return 9; + default: + return 11; + } + } + + public static int getStartingMoney(UserRank rank) { + switch (rank) { + case DEFAULT: + return 5000; + case VIP: + return 100000; + case PREMIUM: + return 250000; + case ELITE: + return 500000; + case SPONSOR: + return 1000000; + default: + return 2000000; + } + } + + public static int getStartingBonds(UserRank rank) { + switch (rank) { + case DEFAULT: + case VIP: + case PREMIUM: + case ELITE: + return 0; + case SPONSOR: + return 5; + default: + return 10; + } + } + + + public static int getFreeLotteryTickets(UserRank userRank) { + switch (userRank) { + case DEFAULT: + return 0; + case VIP: + return 1; + case PREMIUM: + return 2; + case ELITE: + return 5; + case SPONSOR: + return 10; + default: + return 20; + } + } + + public static int getWarpDelay(UserRank userRank) { + switch (userRank) { + case DEFAULT: + return 15; + case VIP: + return 12; + case PREMIUM: + return 10; + case ELITE: + return 8; + case SPONSOR: + return 6; + default: + return 5; + } + } + + public static int getNearRange(UserRank rank) { + switch (rank) { + case VIP: + return 50; + case PREMIUM: + return 75; + case ELITE: + return 100; + case SPONSOR: + return 125; + case SUPREME: + return 150; + default: + return 100; + } + } + + public static int getStackDelay(UserRank rank) { + switch (rank) { + case HELPOP: + case MOD: + case SRMOD: + case ADMIN: + return 30; + case DEV: + case MANAGER: + case OWNER: + return 1; + default: + return 60; + } + } + + public static double getDrugSellModifier(UserRank rank){ + switch (rank) { + case DEFAULT: + return 1; + case VIP: + return 1.05; + case PREMIUM: + return 1.1; + case ELITE: + return 1.2; + case SPONSOR: + return 1.3; + case SUPREME: + return 1.5; + default: + return 1.5; + } + } + + /* + * public static String serialize(ItemStack[] a) { StringBuilder b = new + * StringBuilder(); for (int i = 0; i < a.length; i++) { if (i > 0) + * b.append(","); ItemStack items = a[i]; try { + * b.append(StreamSerializer.getDefault().serializeItemStack(items)); } catch + * (Exception e) { b.append("null"); System.out.println( + * "Error while serializing an items (" + i + "): " + + * e.getCause().getMessage()); } } return b.toString(); } + * + * public static ItemStack[] deserialize(String s) { if (s == null || + * s.length() == 0) return new ItemStack[0]; String[] a = s.split(","); + * ItemStack[] array = new ItemStack[a.length]; for (int i = 0; i < + * a.length; i++) { try { array[i] = + * StreamSerializer.getDefault().deserializeItemStack(a[i]); } catch + * (Exception e) { array[i] = null; System.out.println( + * "Error while deserializing an items (" + i + "): " + e.getMessage()); } } + * return array; } + */ + + public static boolean isValidURL(String string) { + String urlRegex = "^((https?|ftp)://|(www|ftp)\\.)?[a-z0-9-]+(\\.[a-z0-9-]+)+([/?].*)?$"; + Pattern p = Pattern.compile(urlRegex); + Matcher m = p.matcher(string); + return m.find(); + } + + public static double getCrossProduct(LivingEntity livingEntity, Location target) { + if (livingEntity.getWorld() != target.getWorld()) return 10000; + Location head = livingEntity.getLocation(); + org.bukkit.util.Vector look = livingEntity.getLocation().getDirection().normalize(); + org.bukkit.util.Vector direction = head.subtract(target).toVector().normalize(); + org.bukkit.util.Vector cp = direction.crossProduct(look); + return cp.length(); + } + + public static String serializeLocation(Location location) { + if (location == null) + return null; + String world = location.getWorld() == null ? null : location.getWorld().getName(); + String x = String.valueOf(location.getX()); + String y = String.valueOf(location.getY()); + String z = String.valueOf(location.getZ()); + String yaw = String.valueOf(location.getYaw()); + String pitch = String.valueOf(location.getPitch()); + return world + '@' + x + '@' + y + '@' + z + '@' + yaw + '@' + pitch; + } + + public static Optional<Location> deserializeLocation(String loc) { + String[] args = loc.split("@"); + World world = Bukkit.getWorld(args[0]); + double x = Double.valueOf(args[1]); + double y = Double.valueOf(args[2]); + double z = Double.valueOf(args[3]); + float yaw = Float.valueOf(args[4]); + float pitch = Float.valueOf(args[5]); + Location location = new Location(world, x, y, z, yaw, pitch); + return Optional.ofNullable(location); + } + + public static String convertItemStackToJson(ItemStack itemStack) { + Class<?> craftItemStackClazz = ReflectionUtil.getOBCClass("inventory.CraftItemStack"); + Method asNMSCopyMethod = ReflectionUtil.getMethod(craftItemStackClazz, "asNMSCopy", ItemStack.class); + Class<?> nmsItemStackClazz = ReflectionUtil.getNMSClass("ItemStack"); + Class<?> nbtTagCompoundClazz = ReflectionUtil.getNMSClass("NBTTagCompound"); + Method saveNmsItemStackMethod = ReflectionUtil.getMethod(nmsItemStackClazz, "save", nbtTagCompoundClazz); + + Object nmsNbtTagCompoundObj; + Object nmsItemStackObj; + Object itemAsJsonObject; + + try { + nmsNbtTagCompoundObj = nbtTagCompoundClazz.newInstance(); + nmsItemStackObj = asNMSCopyMethod.invoke(null, itemStack); + itemAsJsonObject = saveNmsItemStackMethod.invoke(nmsItemStackObj, nmsNbtTagCompoundObj); + } catch (Throwable t) { + return null; + } + + return itemAsJsonObject.toString(); + } + + public static double getRecentTPS() { + return 20; + } + + public static void moneylog(Player sender, Player target, double amount) { + NumberFormat formatter = NumberFormat.getCurrencyInstance(); + String fileName = new SimpleDateFormat("MM-dd-yy").format(new Date()); + File file = new File("vicelogs/moneylog_" + fileName + ".txt"); + try { + if (!file.isFile() || !file.exists()) + file.createNewFile(); + } catch (IOException exception) { + exception.printStackTrace(); + } + String date = new SimpleDateFormat("MM/dd/yy - h:mm a").format(new Date()); + try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file, true))) { + bufferedWriter.write(date + " - " + sender.getName() + " sent " + formatter.format(amount) + " to " + target.getName() + '\n'); + bufferedWriter.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static void log(String logName, String msg) { + String fileName = new SimpleDateFormat("MM-dd-yy").format(new Date()); + File file = new File("Vicelogs/" + logName + '_' + fileName + ".txt"); + try { + if (!file.isFile() || !file.exists()) { + file.createNewFile(); + } + String date = new SimpleDateFormat("MM/dd/yy - h:mm a").format(new Date()); + FileWriter fileWriter = new FileWriter(file, true); + try (BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)) { + bufferedWriter.write(date + " - " + msg + '\n'); + } + } catch (IOException exception) { + exception.printStackTrace(); + } + } + + public static GameItem getRandomGameItem() { + List<GameItem> gameItems = Vice.getItemManager().getItems().stream().filter(gameItem -> gameItem.getType() == GameItem.ItemType.ITEMSTACK || gameItem.getType() == GameItem.ItemType.WEAPON).collect(Collectors.toList()); + return gameItems.get(ThreadLocalRandom.current().nextInt(gameItems.size())); + } + + public static Warp getNearestWarp(Location location) { + Warp nearestWarp = null; + for (Warp warp : Vice.getWorldManager().getWarpManager().getWarps()) { + if (warp.getLocation().getWorld() != location.getWorld()) continue; + if (nearestWarp == null || + warp.getLocation().distance(location) < nearestWarp.getLocation().distance(location)) { + nearestWarp = warp; + } + } + return nearestWarp; + } + + public static Map<String, Integer> getTopKillers(int count) { + Map<String, Integer> topKillers = new HashMap<>(); +// try { +// ResultSet resultSet = Core.getSQL().query("SELECT * FROM " + Core.name() + " ORDER BY kills DESC LIMIT " + count + ';'); +// while (resultSet.next()) { +// topKillers.put(resultSet.getString("name"), resultSet.getInt("kills")); +// } +// resultSet.close(); +// } catch (Exception ignored) { +// } + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM " + Core.name() + " ORDER BY kills DESC LIMIT " + count + ';')) { + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + topKillers.put(result.getString("name"), result.getInt("kills")); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + + return topKillers; + } + + public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) { + return map.entrySet() + .stream() + .sorted(Map.Entry.comparingByValue(Collections.reverseOrder())) + .collect(Collectors.toMap( + Map.Entry::getKey, + Map.Entry::getValue, + (e1, e2) -> e1, + LinkedHashMap::new + )); + } + + public static boolean isInteger(String s) { + try { + Integer.parseInt(s); + } catch (NumberFormatException e) { + return false; + } + return true; + } + + public static void spawnTinyArmorStand(Location location, String username, String title) { + ArmorStand armorStand = (ArmorStand) location.getWorld().spawnEntity(location, EntityType.ARMOR_STAND); + armorStand.setSmall(true); + armorStand.setBasePlate(false); + ItemStack skull = Utils.createItem(Material.SKULL_ITEM, 3, Utils.f(username)); + SkullMeta meta = (SkullMeta) skull.getItemMeta(); + meta.setOwner(username); + skull.setItemMeta(meta); + armorStand.setHelmet(skull); + armorStand.setCustomNameVisible(true); + armorStand.setCustomName(Utils.f(title)); + } + + public static void sendGlow(Player player, Player target, long time) { + PacketContainer packet = Vice.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_METADATA); + packet.getIntegers().write(0, target.getEntityId()); + WrappedDataWatcher watcher = new WrappedDataWatcher(); + WrappedDataWatcher.Serializer serializer = WrappedDataWatcher.Registry.get(Byte.class); + watcher.setEntity(target); + watcher.setObject(0, serializer, (byte) 0x40); + packet.getWatchableCollectionModifier().write(0, watcher.getWatchableObjects()); + try { + Vice.getProtocolManager().sendServerPacket(player, packet); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + new BukkitRunnable() { + @Override + public void run() { + removeGlow(player, target); + } + }.runTaskLaterAsynchronously(Vice.getInstance(), time); + } + + public static void removeGlow(Player player, Player target) { + PacketContainer packet = Vice.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_METADATA); + packet.getIntegers().write(0, target.getEntityId()); + WrappedDataWatcher watcher = new WrappedDataWatcher(); + WrappedDataWatcher.Serializer serializer = WrappedDataWatcher.Registry.get(Byte.class); + watcher.setEntity(target); + watcher.setObject(0, serializer, (byte) 0x0); + packet.getWatchableCollectionModifier().write(0, watcher.getWatchableObjects()); + try { + Vice.getProtocolManager().sendServerPacket(player, packet); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + } + + public static Month getMonth() { + return LocalDate.now(ZoneId.systemDefault()).getMonth(); + + } + + public static int getDay() { + return LocalDate.now(ZoneId.systemDefault()).getDayOfMonth(); + } + + public static ChatColor randomColor() { + int a = ThreadLocalRandom.current().nextInt(16); + switch (a) { + case 1: + return ChatColor.GREEN; + case 2: + return ChatColor.DARK_GREEN; + case 3: + return ChatColor.BLUE; + case 4: + return ChatColor.DARK_RED; + case 5: + return ChatColor.DARK_PURPLE; + case 6: + return ChatColor.GOLD; + case 7: + return ChatColor.GRAY; + case 8: + return ChatColor.DARK_GRAY; + case 9: + return ChatColor.DARK_BLUE; + case 10: + return ChatColor.GREEN; + case 11: + return ChatColor.AQUA; + case 12: + return ChatColor.RED; + case 13: + return ChatColor.LIGHT_PURPLE; + case 14: + return ChatColor.YELLOW; + default: + return ChatColor.AQUA; + } + } + +// public static CoreNPC createNPC(Location location, String uuid, String displayName) { +// GameProfile prof; +// try { +// prof = new ProfileBuilder(displayName).applySkin(UUID.fromString(uuid)).build(); +// } catch (SkinLookupException e) { +// e.printStackTrace(); +// return null; +// } +// +// try { +// CoreNPC npc = new CoreNPC_1_12_R1(location, UUID.randomUUID().toString(), prof); +// npc.setArmour(); +// npc.spawn(); +// return npc; +// } catch (DuplicateIdentifierException e) { +// e.printStackTrace(); +// return null; +// } +// } + + /* Property example: + skin18488.getProperties().put("textures", new Property( + "textures", + "eyJ0aW1lc3RhbXAiOjE0OTk2OTMzMDMzODEsInByb2ZpbGVJZCI6IjQzYTgzNzNkNjQyOTQ1MTBhOWFhYjMwZjViM2NlYmIzIiwicHJvZmlsZU5hbWUiOiJTa3VsbENsaWVudFNraW42Iiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS82ZDg2NmFmYmZiNGFkMDE4YWYzZDUzY2M3ZjMyMmFlNzUwYTUyZjQ3OTNkNzg5YTcxNTI1YmJlZmRlOTI4M2MifX19", + "HLaxBLtNoquUFZNH4OTD/C1lGgTgYsde5qVp3Qm6cIAUZISG3KPIG/Rd53NupJgbYVe/lgA/QlnxjJ8QvpWhZOT9qPCVicAUHKGk5lVZGx3zTgf0DYHgNwd++lYFIHzFzke5VGtrd4DRtev/NplmO3KJ7orRbNFWwL1HqI9OQQNH/6cE6WKz3ecfohdwhA9E2LsL3Tljr4b3Q5heK5Q5WdSsTa7GCX/sxSFp8XHqedQEMWMc2Q72dXlGuiJ3+9HVu8XTzfE30sCYUdXk4CkZ5lWaL2M521lsve+c+gbfDXakZzmcAXd1E11sGEzrGnsr/78KMSie6u/noRFFb5lgGN3scQogRClHgHNql25S0o5QW6NWnwHEd5+fOfcpRZq45XW57aj0qTZLxZpWrn6mWddZHs5OWJ99wChsUj6Tj3Z+rtptHBqEBdj4Cd33zFT6B9Os3GveEpDx1MOV+dG6l6zBVdWy5Sg1oGJxQlYbLy5/FesYIXLXpkK9sU1mPQFmNg2YlF9j87bo8PHU6GngN6fqA+xwlEaLYVkaRkbaQMwD8eotTWKJRFyAEkCnjOBeOG/bQKpIbRfJ+k/N9/K18oUoazd6dnEtDVOogQTVvQPxlV8iZO08GwCfbBJBZzIijw7CPc7RkreFeye0hhfUjuFpSPDkqarccINA0C0d+VE=")); + */ + public static void createNPC(Location location, String uuid, String displayName, com.mojang.authlib.properties.Property texture) { +// GameProfile prof; +// try { +// prof = new ProfileBuilder(displayName).applySkin(UUID.fromString(uuid)).build(); +// } catch (SkinLookupException e) { +// e.printStackTrace(); +// return; +// } +// +// try { +// GameProfile skin18488 = new GameProfile(UUID.fromString(uuid), displayName); +// skin18488.getProperties().put("textures", texture); +// +// CoreNPC npc = new CoreNPC(location, UUID.randomUUID().toString(), skin18488); +// npc.setArmour(); +// npc.setHeadRotation(0F); +// npc.spawn(); +// } catch (DuplicateIdentifierException e) { +// e.printStackTrace(); +// } + } + public static boolean isInSpawnRange(Player player, double range) { + return Vice.getWorldManager().getWarpManager().getSpawn() != null && Vice.getWorldManager().getWarpManager().getSpawn().getLocation().distance(player.getLocation()) < range; +} + + public static boolean ascendLevel(Player player) { + Location pos = player.getLocation(); + int x = pos.getBlockX(); + int y = Math.max(0, pos.getBlockY()); + int z = pos.getBlockZ(); + World world = pos.getWorld(); + + byte free = 0; + byte spots = 0; + while (y <= 256 + 2) { + if (world.getBlockAt(x, y, z).isEmpty()) { + free += 1; + } else { + free = 0; + } + if (free == 2) { + spots += 1; + if (spots == 2) { + Block block = world.getBlockAt(x, y - 2, z); + int type = block.getTypeId(); + if ((type == 10) || (type == 11)) { + return false; + } + + player.teleport(new Location(world, pos.getX(), y - 1, pos.getZ(), pos.getYaw(), pos.getPitch())); + return true; + } + } + y++; + } + return false; + } + + public static boolean descendLevel(Player player) { + Location pos = player.getLocation(); + int x = pos.getBlockX(); + int y = Math.max(0, pos.getBlockY() - 1); + int z = pos.getBlockZ(); + World world = pos.getWorld(); + + byte free = 0; + while (y >= 1) { + if (world.getBlockAt(x, y, z).isEmpty()) { + free += 1; + } else { + free = 0; + } + if (free == 2) { + while (y >= 0) { + Block block = world.getBlockAt(x, y, z); + int type = block.getTypeId(); + if ((type != 0) && (type != 10) && (type != 11)) { + player.teleport(new Location(world, pos.getX(), y + 1, pos.getZ(), pos.getYaw(), pos.getPitch())); + return true; + } + y--; + } + return false; + } + y--; + } + return false; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/AreaManager.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/AreaManager.java new file mode 100644 index 0000000..d47c6a0 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/AreaManager.java @@ -0,0 +1,301 @@ +package net.grandtheftmc.vice.areas; + +import com.google.common.collect.Sets; +import com.massivecraft.factions.integration.Worldguard; +import com.sk89q.worldedit.BlockVector; +import com.sk89q.worldguard.bukkit.WorldGuardPlugin; +import com.sk89q.worldguard.protection.flags.BooleanFlag; +import com.sk89q.worldguard.protection.managers.RegionManager; +import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion; +import com.sk89q.worldguard.protection.regions.ProtectedRegion; +import net.grandtheftmc.core.util.Component; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.areas.builder.AreaBuilder; +import net.grandtheftmc.vice.areas.dao.AreaDAO; +import net.grandtheftmc.vice.areas.listeners.AreaBuilderListener; +import net.grandtheftmc.vice.areas.listeners.AreaListener; +import net.grandtheftmc.vice.areas.obj.Area; +import net.grandtheftmc.vice.areas.obj.AreaUser; +import net.grandtheftmc.vice.areas.tasks.AreaUpdater; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.Chest; +import org.bukkit.block.DoubleChest; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.scheduler.BukkitTask; + +import java.util.Arrays; +import java.util.List; +import java.util.Set; +import java.util.UUID; + +public class AreaManager implements Component<AreaManager, Vice>{ + + private final Vice plugin; + private BukkitTask updateTask; + + private Set<AreaUser> areaUsers; + private Set<Area> areas; + private Set<AreaBuilder> builders; + + private final AreaListener areaListener; + private final AreaBuilderListener areaBuilderListener; + + public AreaManager(Vice plugin) { + this.plugin = plugin; + + this.areaUsers = Sets.newConcurrentHashSet(); + this.areas = Sets.newHashSet(); + this.builders = Sets.newConcurrentHashSet(); + + this.areaListener = new AreaListener(plugin, this); + this.areaBuilderListener = new AreaBuilderListener(plugin, this); + + updateTask = Bukkit.getScheduler().runTaskTimer(plugin, new AreaUpdater(this), 20L, 20L); + + Vice.getCrateManager().getCrates().clear(); + Vice.getCrateManager().saveCrates(); + + WorldGuardPlugin worldguard = WorldGuardPlugin.inst(); + ServerUtil.runTaskAsync(() -> { + Set<Area> set = AreaDAO.loadBySeason(plugin.getSeasonManager().getCurrentSeason().getNumber()); + for (Area a : set) { + RegionManager manager = worldguard.getRegionManager(a.getWorld()); + + ProtectedRegion region = null; + boolean exists = manager.hasRegion(a.getName()); + if (!exists) region = new ProtectedCuboidRegion(a.getName(), new BlockVector(a.getMaxX(), a.getWorld().getMaxHeight(), a.getMaxZ()), new BlockVector(a.getMinX(), 1, a.getMinZ())); + else region = manager.getRegion(a.getName()); + + if (region != null) { + region.setFlag(new BooleanFlag("build"), true); + region.setFlag(new BooleanFlag("entity-item-frame-destroy"), true); + region.setFlag(new BooleanFlag("vehicle-place"), true); + region.setFlag(new BooleanFlag("creeper-explosion"), true); + region.setFlag(new BooleanFlag("enderdragon-block-damage"), true); + region.setFlag(new BooleanFlag("ghast-fireball"), true); + region.setFlag(new BooleanFlag("other-explosion"), true); + region.setFlag(new BooleanFlag("fire-spread"), true); + region.setFlag(new BooleanFlag("enderman-grief"), true); + region.setFlag(new BooleanFlag("entity-painting-destroy"), true); + region.setFlag(new BooleanFlag("entity-item-frame-destroy"), true); + region.setFlag(new BooleanFlag("leaf-decay"), true); + + if (!exists) { + manager.addRegion(region); + System.out.println("Region created: " + a.getName()); + } + } + + this.areas.add(a); + + + ServerUtil.runTask(() -> { + for (int x = a.getRealMinX(); x < a.getRealMaxX(); x++) { + for (int z = a.getRealMinZ(); z < a.getRealMaxZ(); z++) { + for (int y = 0; y < a.getWorld().getMaxHeight(); y++) { + + Block block = a.getWorld().getBlockAt(x, y, z); + if (block.getType() != Material.CHEST) continue; + if (block.getState() == null) continue; + if (!(block.getState() instanceof Chest)) continue; + if (block.getState() instanceof DoubleChest) continue; + + a.addChest((Chest) block.getState()); + Vice.getCrateManager().addCrate(block.getState().getLocation()); + System.out.println("Added chest(" + a.getChests().size() + ") for Area: " + a.getName()); + } + } + } + }); + } + }); + } + + @Override + public AreaManager onDisable(Vice plugin) { + this.updateTask.cancel(); + return this; + } + + /** + * Returns a new Area object based on the given info + * @param name + * @param c1 + * @param c2 + * @return + */ + public Area createArea(String name, Location c1, Location c2) { + return new Area( + (areas.size() + 1), + plugin.getSeasonManager().getCurrentSeason().getNumber(), + name, + c1.getWorld().getName(), + c1.getBlockX(), + c2.getBlockX(), + c1.getBlockZ(), + c2.getBlockZ()); + } + + /** + * Returns a new AreaBuilder object based on the given info + * @param name + * @param creator + * @return + */ + public AreaBuilder createBuilder(String name, UUID creator) { + return new AreaBuilder( + name, + creator + ); + } + + /** + * Returns a new Area object from the given AreaBuilder object + * @param builder + * @return + */ + public Area convertBuilderToArea(AreaBuilder builder) { + return createArea(builder.getName(), builder.getCorner1(), builder.getCorner2()); + } + + /** + * Returns true if the given UUID is currently are the given Area + * @param uuid + * @param area + * @return + */ + public boolean isAt(UUID uuid, Area area) { + AreaUser user = getUserByUUID(uuid); + + if(user == null || user.getCurrent() == -1) return false; + + int resultId = user.getCurrent(); + int id = area.getID(); + + return resultId == id; + } + + /** + * Returns true if the given UUID is building an Area + * @param uuid + * @return + */ + public boolean isBuilding(UUID uuid) { + return getBuilderByUserUUID(uuid) != null; + } + + /** + * Returns an Area object matching the given ID + * @param id + * @return + */ + public Area getAreaById(int id) { + return areas.stream().filter(area -> area.getID() == id).findFirst().orElse(null); + } + + /** + * Returns an Area object matching the given name + * @param name + * @return + */ + public Area getAreaByName(String name) { + return areas.stream().filter(area -> area.getName().equalsIgnoreCase(name)).findFirst().orElse(null); + } + + /** + * Returns an AreaUser object matching the given UUID + * @param uuid + * @return + */ + public AreaUser getUserByUUID(UUID uuid) { + return areaUsers.stream().filter(user -> user.getUUID().equals(uuid)).findFirst().orElse(null); + } + + /** + * Returns an AreaBuilder object matching the given Area Creator UUID + * @param uuid + * @return + */ + public AreaBuilder getBuilderByUserUUID(UUID uuid) { + return builders.stream().filter(builder -> builder.getCreator().equals(uuid)).findFirst().orElse(null); + } + + /** + * Returns a fancy claiming stick in the form of an ItemStack + * @return + */ + public ItemStack getAreaClaimStick() { + ItemStack item = new ItemStack(Material.STICK); + ItemMeta meta = item.getItemMeta(); + + meta.setDisplayName(ChatColor.GOLD + "Area Claiming Stick"); + meta.setLore(Arrays.asList( + ChatColor.BLUE + "Step 1" + ChatColor.WHITE + ": Left-click the first corner of the claim", + ChatColor.BLUE + "Step 2" + ChatColor.WHITE + ": Right-click the second corner of the claim", + ChatColor.BLUE + "Step 3" + ChatColor.WHITE + ": Left-click while sneaking to confirm the claim", + ChatColor.DARK_RED + "Optional" + ChatColor.WHITE + ": Right-click the air while sneaking to clear claim selection")); + + item.setItemMeta(meta); + + return item; + } + + /** + * Inefficiently sends perimeter block changes to the given player + * @param player + */ + public void drawNearby(Player player) { + final Location location = player.getLocation(); + Set<Location> toRefresh = Sets.newHashSet(); + + int areaColor = 1; + + for (Area area : areas) { + if (!area.getWorld().equals(player.getWorld())) continue; + + for (int i = location.getBlockY() - 2; i < location.getBlockY() + 5; i++) { + List<Location> perimeter = area.getPerimeter(area.getWorld().getUID(), i); + + for (Location blocks : perimeter) { + if (blocks.distance(location) > 40 || blocks.getBlock().getType().equals(Material.AIR)) continue; + + player.sendBlockChange(blocks, Material.WOOL, (byte)areaColor); + toRefresh.add(blocks); + } + } + + areaColor++; + } + + // Refreshing the blockstate 15 seconds later + ServerUtil.runTaskLater(() -> toRefresh.forEach(refreshedBlock -> refreshedBlock.getBlock().getState().update()), 15 * 20L); + } + + public Set<AreaUser> getAreaUsers() { + return this.areaUsers; + } + + public Set<Area> getAreas() { + return this.areas; + } + + public Set<AreaBuilder> getBuilders() { + return this.builders; + } + + public AreaListener getAreaListener() { + return this.areaListener; + } + + public AreaBuilderListener getAreaBuilderListener() { + return this.areaBuilderListener; + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/builder/AreaBuilder.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/builder/AreaBuilder.java new file mode 100644 index 0000000..31b1107 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/builder/AreaBuilder.java @@ -0,0 +1,42 @@ +package net.grandtheftmc.vice.areas.builder; + +import org.bukkit.Location; + +import java.util.UUID; + +public class AreaBuilder { + + private String name; + private UUID creator; + private Location c1, c2; + + public AreaBuilder(String name, UUID creator) { + this.name = name; + this.creator = creator; + } + + public String getName() { + return this.name; + } + + public UUID getCreator() { + return this.creator; + } + + public Location getCorner1() { + return this.c1; + } + + public Location getCorner2() { + return this.c2; + } + + public void setCorner1(Location location) { + this.c1 = location; + } + + public void setCorner2(Location location) { + this.c2 = location; + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/dao/AreaDAO.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/dao/AreaDAO.java new file mode 100644 index 0000000..72abfa0 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/dao/AreaDAO.java @@ -0,0 +1,175 @@ +package net.grandtheftmc.vice.areas.dao; + +import com.google.common.collect.Sets; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.areas.obj.Area; + +import java.sql.*; +import java.util.Set; + +public class AreaDAO { + + /* + Create: + CREATE TABLE IF NOT EXISTS area (id INT NOT NULL AUTO_INCREMENT,season INT NOT NULL,name VARCHAR(36) NOT NULL,world VARCHAR(16) NOT NULL,min_x INT NOT NULL,max_x INT NOT NULL,min_z INT NOT NULL,max_z INT NOT NULL,PRIMARY KEY (id)); + */ + + /** + * Insert the area in to the database + * Updates the Area ID upon completion + * @param area + * @return + */ + public static boolean insert(Area area) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO `area` (`season`,`name`,`world`,`min_x`,`max_x`,`min_z`,`max_z`) VALUES(?,?,?,?,?,?,?);", Statement.RETURN_GENERATED_KEYS)) { + statement.setInt(1, area.getSeason()); + statement.setString(2, area.getName()); + statement.setString(3, area.getWorld().getName()); + statement.setInt(4, area.getMinX()); + statement.setInt(5, area.getMaxX()); + statement.setInt(6, area.getMinZ()); + statement.setInt(7, area.getMaxZ()); + + statement.executeUpdate(); + + try (ResultSet result = statement.getGeneratedKeys()) { + if (result.next()) { + area.setID(result.getInt(1)); + Vice.log("[AreaDAO] Updated area '" + area.getName() + "' ID to " + area.getID()); + + return true; + } + + Vice.error("[AreaDAO] Failed to find generated ID in 'insert' on Area: " + area.getName()); + return false; + } + } + } catch (SQLException e) { + Vice.error("[AreaDAO] Failed to execute 'insert' on Area: " + area.getName()); + e.printStackTrace(); + + return false; + } + } + + /** + * Delete the area by ID from the database + * @param id + * @return + */ + public static boolean delete(int id) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("DELETE FROM `area` WHERE `id`=?;")) { + statement.setInt(1, id); + + statement.execute(); + + return true; + } + } catch (SQLException e) { + Vice.error("[AreaDAO] Failed to execute 'delete' on Area: " + id); + e.printStackTrace(); + + return false; + } + } + + /** + * Update the name of the given area by ID in the database to the newly given name + * @param id + * @param newName + * @return + */ + public static boolean updateName(int id, String newName) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `area` SET `name`=? WHERE `id`=?;")) { + statement.setString(1, newName); + statement.setInt(2, id); + + statement.execute(); + + return true; + } + } catch (SQLException e) { + Vice.error("[AreaDAO] Failed to execute 'updateName' on Area: " + id); + e.printStackTrace(); + + return false; + } + } + + /** + * Loads all seasons, regardless of season + * @return + */ + public static Set<Area> loadAll() { + Set<Area> areas = Sets.newHashSet(); + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM `area`;")) { + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + int id = result.getInt("id"); + int season = result.getInt("season"); + String name = result.getString("name"); + String world = result.getString("world"); + int x1 = result.getInt("min_x"); + int x2 = result.getInt("max_x"); + int z1 = result.getInt("min_z"); + int z2 = result.getInt("max_z"); + + areas.add(new Area(id, season, name, world, x1, x2, z1, z2)); + } + + Vice.log("Loaded " + areas.size() + " Areas"); + return areas; + } + } + } catch (SQLException e) { + Vice.error("[AreaDAO] Failed to execute 'loadAll'"); + e.printStackTrace(); + + return areas; + } + } + + /** + * Loads all areas for a specific season + * @param season + * @return + */ + public static Set<Area> loadBySeason(int season) { + Set<Area> areas = Sets.newHashSet(); + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM `area` WHERE `season`=?;")) { + statement.setInt(1, season); + + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + int id = result.getInt("id"); + String name = result.getString("name"); + String world = result.getString("world"); + int x1 = result.getInt("min_x"); + int x2 = result.getInt("max_x"); + int z1 = result.getInt("min_z"); + int z2 = result.getInt("max_z"); + + areas.add(new Area(id, season, name, world, x1, x2, z1, z2)); + } + + Vice.log("Loaded " + areas.size() + " Areas"); + return areas; + } + } + } catch (SQLException e) { + Vice.error("[AreaDAO] Failed to execute 'loadBySeason(" + season + ")'"); + e.printStackTrace(); + + return areas; + } + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/dao/DiscoveryDAO.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/dao/DiscoveryDAO.java new file mode 100644 index 0000000..4327022 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/dao/DiscoveryDAO.java @@ -0,0 +1,136 @@ +package net.grandtheftmc.vice.areas.dao; + +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.vice.Vice; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +public class DiscoveryDAO { + + /** + * Inserts the given values to the Discovery table + */ + public static boolean insert(UUID uuid, int season, int area) { + String id = uuid.toString().replaceAll("-", ""); + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO `discovery` (`uuid`,`season`,`area`) VALUES(UNHEX(?),?,?);")) { + statement.setString(1, id); + statement.setInt(2, season); + statement.setInt(3, area); + + statement.execute(); + + return true; + } + } catch (SQLException e) { + Vice.error("[DiscoveryDAO] Failed to execute 'insert'"); + e.printStackTrace(); + + return false; + } + } + + /** + * Removes all discoveries which match the given area ID + * @param area + * @return + */ + public static boolean deleteByArea(int area) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("DELETE FROM `discovery` WHERE `area`=?;")) { + statement.setInt(1, area); + + statement.execute(); + + return true; + } + } catch (SQLException e) { + Vice.error("[DiscoveryDAO] Failed to execute 'deleteByArea'"); + e.printStackTrace(); + + return false; + } + } + + /** + * Returns a Map containing all areas ever discovered by the given UUID + * Map<Season #, Set<Area ID>> + * @param uuid + * @return + */ + public static Map<Integer, Set<Integer>> getAllByUUID(UUID uuid) { + Map<Integer, Set<Integer>> areas = Maps.newHashMap(); + String id = uuid.toString().replaceAll("-", ""); + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM `discovery` WHERE `uuid`=HEX(?);")) { + statement.setString(1, id); + + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + int season = result.getInt("season"); + int area = result.getInt("area"); + + if (areas.containsKey(season)) { + areas.get(season).add(area); + } else { + Set<Integer> newSet = Sets.newHashSet(); + newSet.add(area); + areas.put(season, newSet); + } + } + + return areas; + } + } + } catch (SQLException e) { + Vice.error("[DiscoveryDAO] Failed to execute 'getAllByUUID'"); + e.printStackTrace(); + + return areas; + } + } + + /** + * Returns a set containing all areas discovered by the given UUID during the given season + * @param uuid + * @param season + * @return + */ + public static Set<Integer> getSeasonByUUID(UUID uuid, int season) { + Set<Integer> areas = Sets.newHashSet(); + String id = uuid.toString().replaceAll("-", ""); + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM `discovery` WHERE `uuid`=UNHEX(?) AND `season`=?;")) { + statement.setString(1, id); + statement.setInt(2, season); + + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + int area = result.getInt("area"); + + areas.add(area); + } + + return areas; + } + } + } catch (SQLException e) { + Vice.error("[DiscoveryDAO] Failed to execute 'getSeasonByUUID'"); + e.printStackTrace(); + + return areas; + } + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/events/AreaEnterEvent.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/events/AreaEnterEvent.java new file mode 100644 index 0000000..962547f --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/events/AreaEnterEvent.java @@ -0,0 +1,36 @@ +package net.grandtheftmc.vice.areas.events; + +import net.grandtheftmc.vice.areas.obj.Area; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class AreaEnterEvent extends Event { + + private static final HandlerList handlers = new HandlerList(); + private final Player player; + private final Area area; + + public AreaEnterEvent(final Player player, final Area area) { + this.player = player; + this.area = area; + } + + public static final HandlerList getHandlerList() { + return handlers; + } + + @Override + public final HandlerList getHandlers() { + return handlers; + } + + public final Player getPlayer() { + return this.player; + } + + public final Area getArea() { + return this.area; + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/events/AreaLeaveEvent.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/events/AreaLeaveEvent.java new file mode 100644 index 0000000..0730bcd --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/events/AreaLeaveEvent.java @@ -0,0 +1,36 @@ +package net.grandtheftmc.vice.areas.events; + +import net.grandtheftmc.vice.areas.obj.Area; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class AreaLeaveEvent extends Event { + + private static final HandlerList handlers = new HandlerList(); + private final Player player; + private final Area area; + + public AreaLeaveEvent(final Player player, final Area area) { + this.player = player; + this.area = area; + } + + public static final HandlerList getHandlerList() { + return handlers; + } + + @Override + public final HandlerList getHandlers() { + return handlers; + } + + public final Player getPlayer() { + return this.player; + } + + public final Area getArea() { + return this.area; + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/listeners/AreaBuilderListener.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/listeners/AreaBuilderListener.java new file mode 100644 index 0000000..487b72b --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/listeners/AreaBuilderListener.java @@ -0,0 +1,141 @@ +package net.grandtheftmc.vice.areas.listeners; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.areas.AreaManager; +import net.grandtheftmc.vice.areas.builder.AreaBuilder; +import net.grandtheftmc.vice.areas.dao.AreaDAO; +import net.grandtheftmc.vice.areas.obj.Area; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.ItemStack; + +public class AreaBuilderListener implements Listener { + + private final AreaManager areaManager; + + public AreaBuilderListener(Vice plugin, AreaManager areaManager) { + this.areaManager = areaManager; + + Bukkit.getPluginManager().registerEvents(this, plugin); + } + + /** + * Removes player from area builders upon disconnecting + * @param event + */ + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + Player player = event.getPlayer(); + AreaBuilder builder = areaManager.getBuilderByUserUUID(player.getUniqueId()); + + if (builder == null) return; + + areaManager.getBuilders().remove(builder); + + for (ItemStack contents : player.getInventory()) { + if (contents == null || !contents.getType().equals(Material.STICK)) continue; + + if (!contents.hasItemMeta() || !contents.getItemMeta().getDisplayName().equals(areaManager.getAreaClaimStick().getItemMeta().getDisplayName())) continue; + + player.getInventory().remove(contents); + } + } + + /** + * Handles the claiming interactions + * @param event + */ + @EventHandler + public void onPlayerInteract(PlayerInteractEvent event) { + Player player = event.getPlayer(); + Action action = event.getAction(); + Block clickedBlock = event.getClickedBlock(); + ItemStack hand = player.getInventory().getItemInMainHand(); + + if (hand == null || !hand.getType().equals(Material.STICK)) return; + + if (!areaManager.isBuilding(player.getUniqueId())) return; + + AreaBuilder builder = areaManager.getBuilderByUserUUID(player.getUniqueId()); + + event.setCancelled(true); + + if (action.equals(Action.LEFT_CLICK_AIR) && player.isSneaking()) { + if (builder.getCorner1() == null || builder.getCorner2() == null) { + player.sendMessage(Lang.VICE.f("&cYou have not set both corners yet")); + return; + } + + Area area = areaManager.convertBuilderToArea(builder); + + areaManager.getAreas().add(area); + areaManager.getBuilders().remove(builder); + + ServerUtil.runTaskAsync(() -> AreaDAO.insert(area)); + + player.sendMessage(Lang.VICE.f("&aArea has been created")); + player.getInventory().setItemInMainHand(null); + + boolean drawNearby = false; + + for(Area areas : areaManager.getAreas()) { + if (!areas.isOverlapping(area.getMinX(), area.getMaxX(), area.getMinZ(), area.getMaxZ(), area.getWorld().getName()) || areas.getID() == area.getID()) continue; + + player.sendMessage(Lang.VICE.f("&cWarning! This area is overlapping &6" + areas.getName())); + drawNearby = true; + } + + if(drawNearby) { + areaManager.drawNearby(player); + + player.sendMessage(Lang.VICE.f("&eNearby areas have been temporarily drawn on your screen")); + } + } + + if (action.equals(Action.LEFT_CLICK_BLOCK)) { + builder.setCorner1(clickedBlock.getLocation()); + player.sendMessage(Lang.VICE.f("&aCorner #1 has been updated")); + return; + } + + if (action.equals(Action.RIGHT_CLICK_BLOCK)) { + builder.setCorner2(clickedBlock.getLocation()); + player.sendMessage(Lang.VICE.f("&aCorner #2 has been updated")); + return; + } + + if (action.equals(Action.RIGHT_CLICK_AIR)) { + builder.setCorner1(null); + builder.setCorner2(null); + player.sendMessage(Lang.VICE.f("&eArea claims have been reset")); + } + } + + @EventHandler + public void onPlayerDropItem(PlayerDropItemEvent event) { + Player player = event.getPlayer(); + ItemStack item = event.getItemDrop().getItemStack(); + + if (!item.getType().equals(Material.STICK)) return; + + if (!item.hasItemMeta() || !item.getItemMeta().getDisplayName().equals(areaManager.getAreaClaimStick().getItemMeta().getDisplayName())) return; + + event.getItemDrop().setItemStack(null); + + if (areaManager.isBuilding(player.getUniqueId())) { + areaManager.getBuilders().remove(areaManager.getBuilderByUserUUID(player.getUniqueId())); + player.sendMessage(Lang.VICE.f("&eYou are no longer creating this area")); + } + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/listeners/AreaListener.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/listeners/AreaListener.java new file mode 100644 index 0000000..79ffac2 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/listeners/AreaListener.java @@ -0,0 +1,89 @@ +package net.grandtheftmc.vice.areas.listeners; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.areas.AreaManager; +import net.grandtheftmc.vice.areas.dao.DiscoveryDAO; +import net.grandtheftmc.vice.areas.events.AreaEnterEvent; +import net.grandtheftmc.vice.areas.events.AreaLeaveEvent; +import net.grandtheftmc.vice.areas.obj.Area; +import net.grandtheftmc.vice.areas.obj.AreaUser; +import net.grandtheftmc.vice.utils.TitleBuilder; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerPreLoginEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +import java.util.Set; +import java.util.UUID; + +public class AreaListener implements Listener { + + private final Vice plugin; + private final AreaManager areaManager; + + public AreaListener(Vice plugin, AreaManager areaManager) { + this.plugin = plugin; + this.areaManager = areaManager; + + Bukkit.getPluginManager().registerEvents(this, plugin); + } + + @EventHandler + public void onPlayerLogin(AsyncPlayerPreLoginEvent event) { + UUID uuid = event.getUniqueId(); + + Set<Integer> discoveries = DiscoveryDAO.getSeasonByUUID(uuid, plugin.getSeasonManager().getCurrentSeason().getNumber()); + AreaUser user = new AreaUser(uuid, discoveries); + + areaManager.getAreaUsers().add(user); + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + AreaUser user = areaManager.getUserByUUID(event.getPlayer().getUniqueId()); + areaManager.getAreaUsers().remove(user); + } + + @EventHandler + public void onPlayerEnterArea(AreaEnterEvent event) { + Player player = event.getPlayer(); + Area area = event.getArea(); + AreaUser user = areaManager.getUserByUUID(player.getUniqueId()); + + user.setCurrent(area.getID()); + + if (!user.hasVisited(area.getID())) { + user.getVisited().add(area.getID()); + ServerUtil.runTaskAsync(() -> DiscoveryDAO.insert(player.getUniqueId(), plugin.getSeasonManager().getCurrentSeason().getNumber(), area.getID())); + + new TitleBuilder() + .setTitleText(ChatColor.LIGHT_PURPLE + area.getName().replace("_", " ")) + .setSubTitleText(ChatColor.GOLD + "You found a hidden area!") + .setDuration(3) + .setFadeIn(1) + .setFadeOut(1) + .send(player); + } + + player.sendMessage(Lang.VICE.f("&dEntering&f: &6" + area.getName().replace("_", " "))); + } + + @EventHandler + public void onPlayerLeaveArea(AreaLeaveEvent event) { + Player player = event.getPlayer(); + Area area = event.getArea(); + AreaUser user = areaManager.getUserByUUID(player.getUniqueId()); + + user.setCurrent(-1); + + player.sendMessage(Lang.VICE.f("&dLeaving&f: &6" + area.getName().replace("_", " "))); + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/obj/Area.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/obj/Area.java new file mode 100644 index 0000000..c4a057d --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/obj/Area.java @@ -0,0 +1,182 @@ +package net.grandtheftmc.vice.areas.obj; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.block.Chest; + +import java.util.Arrays; +import java.util.List; +import java.util.Set; +import java.util.UUID; + +public class Area { + + private int id; + private final int season; + private final String name; + private final String worldName; + private final int xMin, xMax, zMin, zMax; + private final Set<Chest> chests; + + public Area(int id, int season, String name, String worldName, int x1, int x2, int z1, int z2) { + this.id = id; + this.season = season; + this.name = name; + this.worldName = worldName; + this.xMin = Math.min(x1, x2); + this.xMax = Math.max(x1, x2); + this.zMin = Math.min(z1, z2); + this.zMax = Math.max(z1, z2); + + this.chests = Sets.newHashSet(); + } + + /** + * Returns true if the given values are inside this area + * @param x + * @param z + * @param world + * @param isEntity + * @return + */ + public boolean isInside(double x, double z, String world, boolean isEntity) { + if(this.worldName == null || !this.worldName.equals(world)) return false; + + int xMin = getMinX(); int xMax = getMaxX(); int zMin = getMinZ(); int zMax = getMaxZ(); + + if(isEntity) { + ++xMax; + ++zMax; + } + + return x >= xMin && x <= xMax && z >= zMin && z <= zMax; + } + + /** + * Returns true if the given values overlap this area + * @param x1 + * @param x2 + * @param z1 + * @param z2 + * @param world + * @return + */ + public boolean isOverlapping(int x1, int x2, int z1, int z2, String world) { + if(this.worldName == null || !this.worldName.equals(world)) return false; + + double[] values = new double[2]; + + values[0] = x1; + values[1] = x2; + + Arrays.sort(values); + + if(getMinX() > values[1] || getMaxX() < values[0]) return false; + + values[0] = z1; + values[1] = z2; + + Arrays.sort(values); + + return !(getMinZ() > values[1]) && !(getMaxZ() < values[0]); + } + + /** + * Returns a list containing every block location surrounding the perimeter of an Area on the given Y level + * @param world + * @param y + * @return + */ + public List<Location> getPerimeter(UUID world, int y) { + List<Location> result = Lists.newArrayList(); + + for(int x = getMinX(); x <= getMaxX(); x++) { + for(int z = getMinZ(); z <= getMaxZ(); z++) { + + if(x == getMinX() || x == getMaxX() || z == getMinZ() || z == getMaxZ()) + result.add(new Location(Bukkit.getWorld(world), x, y, z)); + + } + } + + return result; + } + + public int getID() { + return this.id; + } + + public int getSeason() { + return this.season; + } + + public String getName() { + return this.name; + } + + public World getWorld() { + if (this.worldName == null) return null; + return Bukkit.getWorld(this.worldName); + } + + public int getMinX() { + return this.xMin; + } + + public int getMaxX() { + return this.xMax; + } + + public int getMinZ() { + return this.zMin; + } + + public int getMaxZ() { + return this.zMax; + } + + public Set<Chest> getChests() { + return chests; + } + + public void setID(int newId) { + this.id = newId; + } + + public void addChest(Chest chest) { + this.chests.add(chest); + } + + public AreaType getAreaType() { +// return this.chests.size() >= 30 ? AreaType.TOWN : AreaType.VILLAGE; + return this.getName().contains("_") ? AreaType.TOWN : AreaType.VILLAGE; + } + + public static enum AreaType { + TOWN, VILLAGE, + ; + } + + public static enum DropType { + MAJOR, MINOR, DEFAULT, ; + } + + public int getRealMinX() { + return this.xMin <= this.xMax ? this.xMin : this.xMax; + } + + public int getRealMaxX() { + return this.xMax >= this.xMin ? this.xMax : this.xMin; + } + + public int getRealMinZ() { + return this.zMin <= this.zMax ? this.zMin : this.zMax; + } + + public int getRealMaxZ() { + return this.zMax >= this.zMin ? this.zMax : this.zMin; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/obj/AreaUser.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/obj/AreaUser.java new file mode 100644 index 0000000..4053aac --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/obj/AreaUser.java @@ -0,0 +1,37 @@ +package net.grandtheftmc.vice.areas.obj; + +import java.util.Set; +import java.util.UUID; + +public class AreaUser { + + private UUID uuid; + private int current; + private Set<Integer> visited; + + public AreaUser(UUID uuid, Set<Integer> visited) { + this.uuid = uuid; + this.current = -1; // -1 is considered none + this.visited = visited; + } + + public UUID getUUID() { + return this.uuid; + } + + public int getCurrent() { + return this.current; + } + + public Set<Integer> getVisited() { + return this.visited; + } + + public boolean hasVisited(int areaId) { + return visited.contains(areaId); + } + + public void setCurrent(int id) { + this.current = id; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/tasks/AreaUpdater.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/tasks/AreaUpdater.java new file mode 100644 index 0000000..10feebf --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/areas/tasks/AreaUpdater.java @@ -0,0 +1,45 @@ +package net.grandtheftmc.vice.areas.tasks; + +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.vice.areas.AreaManager; +import net.grandtheftmc.vice.areas.events.AreaEnterEvent; +import net.grandtheftmc.vice.areas.events.AreaLeaveEvent; +import net.grandtheftmc.vice.areas.obj.Area; +import org.bukkit.Bukkit; + +import java.util.UUID; + +public class AreaUpdater implements Runnable { + + private final AreaManager areaManager; + + public AreaUpdater(AreaManager areaManager) { + this.areaManager = areaManager; + } + + @Override + public void run() { + Bukkit.getOnlinePlayers().forEach(player -> { + UUID uuid = player.getUniqueId(); + String world = player.getLocation().getWorld().getName(); + int x = player.getLocation().getBlockX(); + int z = player.getLocation().getBlockZ(); + + ServerUtil.runTaskAsync(() -> { + for(Area area : areaManager.getAreas()) { + if (!area.isInside(x, z, world, true)) { + + if (areaManager.isAt(uuid, area)) + ServerUtil.runTask(() -> Bukkit.getPluginManager().callEvent(new AreaLeaveEvent(player, area))); + + continue; + } + + if (!areaManager.isAt(uuid, area)) + ServerUtil.runTask(() -> Bukkit.getPluginManager().callEvent(new AreaEnterEvent(player, area))); + } + }); + }); + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/combatlog/CombatLogManager.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/combatlog/CombatLogManager.java new file mode 100644 index 0000000..8c90ef6 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/combatlog/CombatLogManager.java @@ -0,0 +1,128 @@ +package net.grandtheftmc.vice.combatlog; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.combatlog.task.DespawnTask; +import net.grandtheftmc.vice.users.ViceUser; +import net.grandtheftmc.vice.users.storage.BooleanStorageType; +import net.grandtheftmc.vice.world.ViceSelection; +import net.grandtheftmc.vice.world.ZoneFlag; +import org.bukkit.Material; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.NPC; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; + +import java.util.*; + +/** + * Created by Timothy Lampen on 2017-08-14. + */ +public class CombatLogManager { + private HashMap<NPC, CombatLogger> combatNPCs = new HashMap<>(); + private List<CombatLogger> destroyedNPCs = new ArrayList<>(); + + + public void spawnNPC(Player player, boolean fromSpawn) { + spawnNPC(player, fromSpawn, false); + } + + public void spawnNPC(Player player, boolean fromSpawn, boolean overrideKickCheck) { + ViceUser viceUser = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if(fromSpawn) { + List<ViceSelection> selections = Vice.getWorldManager().getZones(player.getLocation()); + if(selections.stream().anyMatch(selection -> selection.getFlags().contains(ZoneFlag.COP_CANT_ARREST))) + return; + } + if(!overrideKickCheck && viceUser.getBooleanFromStorage(BooleanStorageType.KICKED)) { + return; + } + List<ItemStack> contents = new ArrayList<>(); + for(ItemStack is : player.getInventory().getContents()) { + if(is==null || is.getType()== Material.AIR || is.getType()==Material.WATCH) + continue; + if(ViceUtils.isDefaultPlayerItem(is)) + continue; + if(fromSpawn/* && (Vice.getItemManager().getItem(is)==null || !Vice.getItemManager().getItem(is).isScheduled())*/)//don't spawn an npc if the player is at spawn. + continue; + contents.add(is); + } + if(contents.size()==0) { + return; + } + NPC npc = (NPC) player.getWorld().spawnEntity(player.getLocation(), EntityType.VILLAGER); + npc.setCustomName(Utils.f(user.getUserRank().getColor() + player.getName() + "&7's Combat NPC &e15&7)")); + npc.setCustomNameVisible(true); + npc.setAI(false); + npc.setMetadata("loggedplayer", new FixedMetadataValue(Vice.getInstance(), player.getUniqueId().toString())); + combatNPCs.put(npc, new CombatLogger(player.getUniqueId(), contents, fromSpawn)); + new DespawnTask(npc, Utils.f(user.getUserRank().getColor() + player.getName())).runTaskTimer(Vice.getInstance(), 0, 20); + } + + public NPC getSpawnedNPCFromPlayer(UUID uuid){ + Optional<Map.Entry<NPC, CombatLogger>> log = this.combatNPCs.entrySet().stream().filter(entry -> entry.getValue().getUUID().equals(uuid)).findFirst(); + return log.map(Map.Entry::getKey).orElse(null); + } + + public void removeNPC(NPC villager) { + if(combatNPCs.containsKey(villager)) + combatNPCs.remove(villager); + } + + public List<ItemStack> getPlayerInventory(NPC npc){ + if(this.combatNPCs.containsKey(npc)) + return this.combatNPCs.get(npc).getContents(); + return null; + } + + public void addDestroyedNPC(NPC npc){ + this.destroyedNPCs.add(this.combatNPCs.get(npc)); + } + + public void clearRemovedItems(UUID uuid) { + Optional<CombatLogger> log = this.destroyedNPCs.stream().filter(logger -> logger.getUUID().equals(uuid)).findFirst(); + log.ifPresent(combatLogger -> this.destroyedNPCs.remove(combatLogger)); + } + + public Optional<CombatLogger> getDestroyedCombatLogger(UUID uuid){ + return this.destroyedNPCs.stream().filter(log -> log.getUUID().equals(uuid)).findFirst(); + } + + public void load(){ + YamlConfiguration config = Vice.getSettings().getPlayerCacheConfig(); + if(config.getConfigurationSection("")==null) + return; + for(String sUUID : config.getConfigurationSection("").getKeys(false)) { + if(config.contains(sUUID + ".destroyed-npcs")) { + this.destroyedNPCs.add(new CombatLogger(UUID.fromString(sUUID), null, config.getBoolean(sUUID + ".destroyed-npcs"))); + } + } + } + + public void save(){ + combatNPCs.keySet().forEach(Entity::remove); + + YamlConfiguration config = Vice.getSettings().getPlayerCacheConfig(); + if(config.getConfigurationSection("")!=null) { + for (String sUUID : config.getConfigurationSection("").getKeys(false)) { + config.set(sUUID + ".destroyed-npcs", null); + } + } + Utils.saveConfig(config, "playercache"); + for(CombatLogger log : destroyedNPCs){ + config.set(log.getUUID().toString() + ".destroyed-npcs", log.isFromSpawn()); + } + Utils.saveConfig(config, "playercache"); + } + + public Set<NPC> getCombatLogNPCs() { + return this.combatNPCs.keySet(); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/combatlog/CombatLogger.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/combatlog/CombatLogger.java new file mode 100644 index 0000000..490a02f --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/combatlog/CombatLogger.java @@ -0,0 +1,33 @@ +package net.grandtheftmc.vice.combatlog; + +import org.bukkit.inventory.ItemStack; + +import java.util.List; +import java.util.UUID; + +/** + * Created by Timothy Lampen on 2017-08-17. + */ +public class CombatLogger { + private final UUID uuid; + private final boolean fromSpawn; + private final List<ItemStack> contents; + + public CombatLogger(UUID uuid, List<ItemStack> contents, boolean fromSpawn) { + this.uuid = uuid; + this.fromSpawn = fromSpawn; + this.contents = contents; + } + + public List<ItemStack> getContents() { + return contents; + } + + public UUID getUUID() { + return uuid; + } + + public boolean isFromSpawn() { + return fromSpawn; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/combatlog/task/DespawnTask.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/combatlog/task/DespawnTask.java new file mode 100644 index 0000000..2b1cf64 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/combatlog/task/DespawnTask.java @@ -0,0 +1,35 @@ +package net.grandtheftmc.vice.combatlog.task; + +import net.grandtheftmc.vice.Vice; +import net.md_5.bungee.api.ChatColor; +import org.bukkit.entity.NPC; +import org.bukkit.entity.Player; +import org.bukkit.entity.Villager; +import org.bukkit.scheduler.BukkitRunnable; + +/** + * Created by Timothy Lampen on 2017-08-14. + */ +public class DespawnTask extends BukkitRunnable{ + + private final NPC villager; + private int counter = 15; + private final String name; + public DespawnTask(NPC villager, String name){ + this.villager = villager; + this.name =name; + } + + @Override + public void run() { + if(villager.isDead() || !villager.isValid() || counter==0) { + Vice.getCombatLogManager().removeNPC(villager); + villager.remove(); + cancel(); + return; + } + else + villager.setCustomName(name + ChatColor.GRAY + "'s Combat NPC (" + ChatColor.YELLOW + counter + ChatColor.GRAY + ")"); + counter--; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/AmmoCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/AmmoCommand.java new file mode 100644 index 0000000..2582544 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/AmmoCommand.java @@ -0,0 +1,152 @@ +package net.grandtheftmc.vice.commands; + +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.items.AmmoType; +import net.grandtheftmc.vice.users.ViceUser; + +public class AmmoCommand implements CommandExecutor { + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!s.hasPermission("command.ammo")) { + s.sendMessage(Lang.NOPERM.toString()); + return true; + } + if (args.length == 0) { + s.sendMessage(Utils.f("&c/ammo types")); + s.sendMessage(Utils.f("&c/ammo balance <player> <type>")); + s.sendMessage(Utils.f("&c/ammo give <player> <type> <amount>")); + s.sendMessage(Utils.f("&c/ammo take <player> <type> <amount>")); + return true; + } + switch (args[0].toLowerCase()) { + case "types": { + sendAmmoTypes(s); + return true; + } + case "balance": { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/ammo balance <player> <type>")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player == null) { + s.sendMessage(Lang.AMMO.f("&7That player is not online!")); + return true; + } + AmmoType type = AmmoType.getAmmoType(args[2]); + if (type == null) { + s.sendMessage(Lang.AMMO.f("&7That AmmoType does not exist!")); + sendAmmoTypes(s); + return true; + } + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + s.sendMessage(Lang.AMMO.f("&a" + player.getName() + "&7 has &a&l" + user.getAmmo(type) + ' ' + + type.getGameItem().getDisplayName() + "&7!")); + return true; + } + case "give": { + if (args.length != 4) { + s.sendMessage(Utils.f("&c/ammo give <player> <type> <amount>")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player == null) { + s.sendMessage(Lang.AMMO.f("&7That player is not online!")); + return true; + } + AmmoType type = AmmoType.getAmmoType(args[2]); + if (type == null) { + s.sendMessage(Lang.AMMO.f("&7That AmmoType does not exist!")); + sendAmmoTypes(s); + return true; + } + int amnt; + try { + amnt = Integer.parseInt(args[3]); + } catch (NumberFormatException e) { + s.sendMessage(Lang.AMMO.f("&7The amount must be a number!")); + return true; + } + if (amnt <= 0) { + s.sendMessage(Lang.AMMO.f("&7The amount must be positive!")); + return true; + } + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + user.addAmmo(type, amnt); + s.sendMessage(Lang.AMMO.f("&7You gave &a&l" + amnt + ' ' + type.getGameItem().getDisplayName() + "&7 to &a" + + player.getName() + "&7!")); + player.sendMessage(Lang.AMMO.f("&7You were given &a&l" + amnt + ' ' + type.getGameItem().getDisplayName() + + "&7 by &a" + s.getName() + "&7!")); + return true; + } + case "take": + if (args.length != 3) { + s.sendMessage(Utils.f("&c/ammo take <player> <type> <amount>")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player == null) { + s.sendMessage(Lang.AMMO.f("&7That player is not online!")); + return true; + } + AmmoType type = AmmoType.getAmmoType(args[2]); + if (type == null) { + s.sendMessage(Lang.AMMO.f("&7That AmmoType does not exist!")); + sendAmmoTypes(s); + return true; + } + int amnt; + try { + amnt = Integer.parseInt(args[3]); + } catch (NumberFormatException e) { + s.sendMessage(Lang.AMMO.f("&7The amount must be a number!")); + return true; + } + if (amnt <= 0) { + s.sendMessage(Lang.AMMO.f("&7The amount must be positive!")); + return true; + } + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + if (!user.hasAmmo(type, amnt)) + amnt = user.getAmmo(type); + user.removeAmmo(type, amnt); + s.sendMessage(Lang.AMMO.f("&7You took &c&l" + amnt + ' ' + type.getGameItem().getDisplayName() + + "&7 from &a" + player.getName() + "&7!")); + player.sendMessage(Lang.AMMO.f("&c&l" + amnt + ' ' + type.getGameItem().getDisplayName() + + "&7 was taken from you by &a" + s.getName() + "&7!")); + return true; + default: + s.sendMessage(Utils.f("&c/ammo types")); + s.sendMessage(Utils.f("&c/ammo balance <player> <type>")); + s.sendMessage(Utils.f("&c/ammo give <player> <type> <amount>")); + s.sendMessage(Utils.f("&c/ammo take <player> <type> <amount>")); + return true; + } + } + + private String ammoTypes = null; + + private void sendAmmoTypes(CommandSender sender) { + if (ammoTypes == null) { + StringBuilder b = new StringBuilder("&7"); + for (AmmoType type : AmmoType.getTypes()) { + b.append(type).append("(").append(type.getGameItemName()).append("),"); + } + if (b.toString().endsWith(",")) { + b.setLength(b.length() - 1); + } + ammoTypes = b.toString(); + } + + sender.sendMessage(ammoTypes); + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/AntiAuraCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/AntiAuraCommand.java new file mode 100644 index 0000000..edb6c09 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/AntiAuraCommand.java @@ -0,0 +1,75 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Lang; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.TextComponent; +import org.apache.commons.lang.StringUtils; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.*; + +public class AntiAuraCommand implements CommandExecutor { + + //Checking for existance, hashsets are faster + public static final Set<String> TOGGLED_PLAYERS = new HashSet<>(); + + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (!s.hasPermission("antiaura.admin")) return false; + if (args.length == 0) { + s.sendMessage(Lang.ANTIAURA.f("&7/antiaura toggle")); + return false; + } + if (!(s instanceof Player)) { + if (args.length >= 1 && Objects.equals("notify", args[0])) { + this.notify(StringUtils.join(new ArrayList<>(Arrays.asList(args).subList(1, args.length)), " ")); + } else { + s.sendMessage(Lang.NOTPLAYER.s()); + } + return true; + } + Player player = (Player) s; + if (args.length >= 1) { + if ("toggle".equalsIgnoreCase(args[0])) { + if (TOGGLED_PLAYERS.contains(player.getName())) { + player.sendMessage(Lang.ANTIAURA.f("&7AntiAura notifications disabled.")); + TOGGLED_PLAYERS.remove(player.getName()); + } else { + player.sendMessage(Lang.ANTIAURA.f("&7AntiAura notifications enabled.")); + TOGGLED_PLAYERS.add(player.getName()); + } + } + } + return true; + } + + public void notify(String msg) { + for (String string : TOGGLED_PLAYERS) { + Player player; + if ((player = Bukkit.getPlayer(string)) != null) { + Player target = Bukkit.getPlayer(msg.split(" ")[0]); + if (target.isSprinting() && target.getInventory().getItemInMainHand().getType() == Material.DIAMOND_HOE + || "spawn".equals(target.getWorld().getName())) { + return; + } + + TextComponent component = new TextComponent(Lang.ANTIAURA.f("&7 " + msg)); + component.setColor(ChatColor.GRAY); + if (target != null) { + component.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/tp " + target.getName())); + component.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, + new ComponentBuilder("Click to teleport to " + target.getDisplayName()).create())); + } + player.spigot().sendMessage(component); + } + } + } +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/AreaCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/AreaCommand.java new file mode 100644 index 0000000..8ff0877 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/AreaCommand.java @@ -0,0 +1,123 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.areas.dao.AreaDAO; +import net.grandtheftmc.vice.areas.dao.DiscoveryDAO; +import net.grandtheftmc.vice.areas.obj.Area; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class AreaCommand implements CommandExecutor { + + private final Vice plugin; + + public AreaCommand(Vice plugin) { + this.plugin = plugin; + } + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof Player)) return true; + + Player player = (Player) s; + + if (!player.hasPermission("command.area")) { + s.sendMessage(Lang.NOPERM.toString()); + + return true; + } + + if (args.length < 2) { + s.sendMessage(Utils.f("&c/area create <name>")); + s.sendMessage(Utils.f("&c/area delete <name>")); + + return true; + } + + /* + Create + */ + if (args[0].equalsIgnoreCase("create")) { + if (plugin.getAreaManager().isBuilding(player.getUniqueId())) { + s.sendMessage(Lang.VICE.f("&cYou are already creating an Area")); + return true; + } + + StringBuilder areaName = new StringBuilder(); + + for (int i = 1; i < args.length; i++) + areaName.append(args[i]).append(" "); + + plugin.getAreaManager().getBuilders().add(plugin.getAreaManager().createBuilder(areaName.toString().trim(), player.getUniqueId())); + player.getInventory().setItemInMainHand(plugin.getAreaManager().getAreaClaimStick()); + + s.sendMessage(Lang.VICE.f("&aYou are now building '" + areaName.toString().trim() + "'")); + + return true; + } + + /* + Delete + */ + if (args[0].equalsIgnoreCase("delete")) { + StringBuilder areaName = new StringBuilder(); + + for (int i = 1; i < args.length; i++) + areaName.append(args[i]).append(" "); + + Area area = plugin.getAreaManager().getAreaByName(areaName.toString().trim()); + + if (area == null) { + s.sendMessage(Lang.VICE.f("&cArea not found")); + return true; + } + + plugin.getAreaManager().getAreas().remove(area); + + ServerUtil.runTaskAsync(() -> { + AreaDAO.delete(area.getID()); + DiscoveryDAO.deleteByArea(area.getID()); + }); + + plugin.getAreaManager().getAreaUsers().forEach(user -> { + if (user.getCurrent() == area.getID()) user.setCurrent(-1); + if (user.hasVisited(area.getID())) user.getVisited().remove(area.getID()); + }); + + s.sendMessage(Lang.VICE.f("&eYou have deleted '" + area.getName() + "'")); + + return true; + } + + /* + Cancel + */ + if (args[0].equalsIgnoreCase("cancel")) { + if (!plugin.getAreaManager().isBuilding(player.getUniqueId())) { + s.sendMessage(Lang.VICE.f("&cYou are not building an Area")); + return true; + } + + StringBuilder areaName = new StringBuilder(); + + for (int i = 1; i < args.length; i++) + areaName.append(args[i]).append(" "); + + plugin.getAreaManager().getBuilders().remove(plugin.getAreaManager().getBuilderByUserUUID(player.getUniqueId())); + + s.sendMessage(Lang.VICE.f("&eYou are no longer building '" + areaName.toString().trim() + "'")); + + return true; + } + + s.sendMessage(Utils.f("&c/area create <name>")); + s.sendMessage(Utils.f("&c/area delete <name>")); + + return false; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/BackpackCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/BackpackCommand.java new file mode 100644 index 0000000..5421dbd --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/BackpackCommand.java @@ -0,0 +1,66 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.ViceUser; +import net.grandtheftmc.vice.users.storage.BooleanStorageType; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryView; + +import java.util.Objects; + +public class BackpackCommand implements CommandExecutor { + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (args.length == 0 || !s.hasPermission("backpack.admin")) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + Player player = (Player) s; + Vice.getBackpackManager().openBackpack(player); + return true; + } + Player player = (Player) s; + if (Bukkit.getPlayer(args[0]) != null) { + Player target = Bukkit.getPlayer(args[0]); + if (target.getOpenInventory() != null && Objects.equals("Backpack", ChatColor.stripColor(target.getOpenInventory().getTitle()))) { + target.getOpenInventory().close(); + } + Inventory backpack = Vice.getBackpackManager().getBackpack(target, true); + player.openInventory(backpack); + Vice.getUserManager().getLoadedUser(target.getUniqueId()).setBooleanToStorage(BooleanStorageType.BACKPACK_OPEN, true); + return true; + } + switch (args[0]) { + case "reset": + if (args.length != 2) { + s.sendMessage(Utils.f("&c/backpack reset <player>")); + return true; + } + Player target = Bukkit.getPlayer(args[1]); + if (target == null) { + return true; + } + InventoryView inv = target.getOpenInventory(); + if (inv != null + && Objects.equals("Backpack", ChatColor.stripColor(inv.getTitle()))) + target.closeInventory(); + ViceUser targetViceUser = Vice.getUserManager().getLoadedUser(target.getUniqueId()); + targetViceUser.setBackpackContents(null); + s.sendMessage(Utils.f("&7You cleared the backpack of player &a" + target.getName() + "&7!")); + target.sendMessage(Utils.f("&a" + player.getName() + "&7 cleared your backpack.")); + return true; + default: + s.sendMessage(Utils.f("&c/backpack reset <player>")); + return true; + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/BackupCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/BackupCommand.java new file mode 100644 index 0000000..36d4ed7 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/BackupCommand.java @@ -0,0 +1,70 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.CopRank; +import net.grandtheftmc.vice.users.TaxiTarget; +import net.grandtheftmc.vice.users.ViceUser; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.Objects; + +/** + * Created by Liam on 9/12/2016. + */ +public class BackupCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command cmd, String lbl, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + Player player = (Player) s; + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + if (args.length == 0) { + if (user.hasRequestedBackup()) { + s.sendMessage(Lang.COP_MODE.f("&7You have already called " + (user.isCop() ? "for backup" : "the police") + "! Please wait &c&l" + Utils.timeInMillisToText(user.getTimeUntilBackupRequestExpires()) + "&7 to request backup again!")); + return true; + } + player.sendMessage(Lang.COP_MODE.f("&7You have called " + (user.isCop() ? "for backup" : "the police") + "! A message has been sent to all officers, and they can teleport to you for 1 minute!")); + user.setLastBackupRequest(System.currentTimeMillis()); + for (ViceUser u : Vice.getUserManager().getLoadedUsers()) { + if (u.isCop()) { + Player p = Bukkit.getPlayer(u.getUUID()); + if (!Objects.equals(player, p)) + p.spigot().sendMessage(new ComponentBuilder(Lang.COP_MODE.f((user.isCop() ? "&3&lCop " : "&7Citizen ") + Core.getUserManager().getLoadedUser(player.getUniqueId()).getColoredName(player))).append(" is requesting " + (user.isCop() ? "backup" : "police assistance") + "! Teleport: ").color(net.md_5.bungee.api.ChatColor.GRAY). + append(" [ACCEPT] ").color(net.md_5.bungee.api.ChatColor.GREEN).bold(true).event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/backup " + player.getName())).create()); + } + } + return true; + } + if (!user.isCop()) { + s.sendMessage(Lang.COP_MODE.f("&7You must be a " + CopRank.COP.getColoredNameBold() + "&7 to provide backup!")); + return true; + } + Player target = Bukkit.getPlayer(args[0]); + if (target == null) { + player.sendMessage(Lang.COP_MODE.f("&7That player is not online!")); + return true; + } + ViceUser targetUser = Vice.getUserManager().getLoadedUser(target.getUniqueId()); + if (target.getGameMode() == GameMode.SPECTATOR || !targetUser.hasRequestedBackup()) { + player.sendMessage(Lang.COP_MODE.f("&7That player has not requested backup!")); + return true; + } + Vice.getWorldManager().getWarpManager().warp(player, Core.getUserManager().getLoadedUser(player.getUniqueId()), user, new TaxiTarget(target), 0, -1); + target.sendMessage(Lang.COP_MODE.f("&7" + Core.getUserManager().getLoadedUser(player.getUniqueId()).getColoredName(player) + "&7 has accepted your " + (user.isCop() ? "backup" : "police assistance") + " request.")); + return true; + } + +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/BaltopCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/BaltopCommand.java new file mode 100644 index 0000000..d5f4529 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/BaltopCommand.java @@ -0,0 +1,68 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.commands.CoreCommand; +import net.grandtheftmc.core.util.Callback; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.ViceUserDAO; +import net.grandtheftmc.vice.utils.MapUtil; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; + +/** + * Created by Luke Bingham on 26/08/2017. + */ +public class BaltopCommand extends CoreCommand<Player> { + + public BaltopCommand() { + super( + "baltop", + "Shows the baltop for money", + "moneytop", "balancetop" + ); + } + + @Override + public void execute(Player sender, String[] strings) { + UUID uuid = sender.getUniqueId(); + new BukkitRunnable() { + @Override public void run() { + getTopBalance(10, results -> new BukkitRunnable() { + @Override + public void run() { + Player player = Bukkit.getPlayer(uuid); + if (player == null) return; + player.sendMessage( Lang.MONEY.f("&7Money Top:")); + + int i = 0; + for (String key : results.keySet()) { + i++; + player.sendMessage(Utils.f("&a#&l" + (i) + "&7: &r" + key + "&7 &a" + Utils.formatMoney(results.get(key)))); + } + } + }.runTask(Vice.getInstance())); + } + }.runTaskAsynchronously(Vice.getInstance()); + } + + private void getTopBalance(int amount, Callback<LinkedHashMap<String, Double>> callback) { + LinkedHashMap<String, Double> results = new LinkedHashMap<>(); + + Optional<Object[][]> optional = ViceUserDAO.getBalanceTop(amount); + if(!optional.isPresent()) return; + + for(int i = 0; i < optional.get().length; i++) { + results.put((String)optional.get()[i][0], (double)optional.get()[i][1]); + } + + callback.call(results); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/BondsCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/BondsCommand.java new file mode 100644 index 0000000..f46d6b1 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/BondsCommand.java @@ -0,0 +1,249 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.users.UserDAO; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.ViceUser; +import net.grandtheftmc.vice.users.ViceUserDAO; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Optional; +import java.util.UUID; + +public class BondsCommand implements CommandExecutor { + + + @Override + public boolean onCommand(CommandSender s, Command cmd, String label, String[] args) { + if (s instanceof Player && !s.hasPermission("command.bonds")) { + Player player = (Player) s; + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + player.sendMessage(Utils.f("&aYou have &c" + user.getBonds() + " &abonds")); + return true; + } + if (args.length == 0) { + s.sendMessage(Utils.f("&c/bonds <balance> name")); + s.sendMessage(Utils.f("&c/bonds <set/give/take> <name> <amnt>")); + return true; + } + switch (args[0].toLowerCase()) { + case "balance": { + if (args.length != 2) { + s.sendMessage(Utils.f("&c/bonds <balance> name")); + return true; + } + Player player = Bukkit.getPlayerExact(args[1]); + if (player == null) { + UUID senderUUID = s instanceof Player ? ((Player) s).getUniqueId() : null; + s.sendMessage(Utils.f("&cThat player isn't online, so please wait while the bonds are pulled from the database.")); + new BukkitRunnable() { + @Override + public void run() { + + Optional<Object[]> optional = ViceUserDAO.getBondAndName(args[1]); + if(!optional.isPresent()) return; + +// ResultSet rs = Core.getSQL().query("select name,bonds from " + Core.name() + " where name='" + args[1] + "';"); + String name = (String) optional.get()[0]; + int bonds = (int) optional.get()[1]; +// try { +// if (rs.next()) { +// name = rs.getString("name"); +// bonds = rs.getInt("bonds"); +// rs.close(); +// } else { +// rs.close(); +// return; +// } +// } catch (SQLException e) { +// e.printStackTrace(); +// } + String finalName = name; + int finalBonds = bonds; + new BukkitRunnable() { + @Override + public void run() { + (senderUUID == null ? Bukkit.getConsoleSender() : Bukkit.getPlayer(senderUUID)).sendMessage(Utils.f("&a " + finalName + " has " + finalBonds + " Bonds.")); + } + }.runTask(Vice.getInstance()); + } + }.runTaskAsynchronously(Vice.getInstance()); + return true; + } + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + s.sendMessage(Utils.f("&a" + player.getName() + " has " + user.getBonds() + " Bonds.")); + return true; + } + case "set": { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/bonds <set/give/take> <name> <amnt>")); + return true; + } + int amnt; + try { + amnt = Integer.parseInt(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f("&cThe amount must be a number!")); + return true; + } + if (amnt < 0) { + s.sendMessage(Utils.f("&cThe amount must be bigger than 0!")); + return true; + } + Player player = Bukkit.getPlayerExact(args[1]); + if (player == null) { + s.sendMessage(Utils.f("&cThat player isn't online, so hold on a second while the bonds are forcibly updated in the database.")); + ServerUtil.runTaskAsync(() -> ViceUserDAO.setBonds(args[1], amnt)); +// Core.getSQL().updateAsyncLater("update " + Core.name() + " set bonds=" + amnt + " where name='" + args[1] + "';"); + new BukkitRunnable() { + @Override + public void run() { + UUID uuid = UserDAO.getUuidByName(args[1]); + +// ResultSet rs = Core.getSQL().query("select uuid,lastname from users where lastname='" + args[1] + "';"); +// UUID uuid = null; +// String name = args[1]; +// try { +// if (rs.next()) { +// uuid = UUID.fromString(rs.getString("uuid")); +// name = rs.getString("lastname"); +// } +// rs.close(); +// } catch (SQLException e) { +// e.printStackTrace(); +// } + if (uuid == null) Core.log("Error while logging setBondsCommand for uuid " + uuid + ", name " + args[1] + ", amnt " + amnt); + else Utils.insertLog(uuid, args[1], "setBondsCommand", "BONDS", amnt + " Bonds", amnt, 0); + + } + }.runTaskAsynchronously(Core.getInstance()); + return true; + } + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + user.setBonds(amnt); + User u = Core.getUserManager().getLoadedUser(player.getUniqueId()); + u.insertLog(player, "setBondsCommand", "BONDS", amnt + " Bonds", amnt, 0); + s.sendMessage(Utils.f("&a" + player.getName() + " now has " + user.getBonds() + " bonds!")); + return true; + } + case "give": { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/houses bonds <set/give/take> <name> <amnt>")); + return true; + } + int amnt; + try { + amnt = Integer.parseInt(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f("&cThe amount must be a number!")); + return true; + } + if (amnt < 0) { + s.sendMessage(Utils.f("&cThe amount must be bigger than 0!")); + return true; + } + Player player = Bukkit.getPlayerExact(args[1]); + if (player == null) { + s.sendMessage(Utils.f("&cThat player isn't online, so hold on a second while the bonds are forcibly updated in the database.")); +// Core.getSQL().updateAsyncLater("update " + Core.name() + " set bonds=bonds+" + amnt + " where name='" + args[1] + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.addBonds(args[1], amnt)); + + new BukkitRunnable() { + @Override public void run() { + UUID uuid = UserDAO.getUuidByName(args[1]); +// ResultSet rs = Core.getSQL().query("select uuid,lastname from users where lastname='" + args[1] + "';"); +// UUID uuid = null; +// String name = args[1]; +// try { +// if (rs.next()) { +// uuid = UUID.fromString(rs.getString("uuid")); +// name = rs.getString("lastname"); +// } +// rs.close(); +// } catch (SQLException e) { +// e.printStackTrace(); +// } + if (uuid == null) { + Core.log("Error while logging giveBondsCommand for uuid " + uuid + ", name " + args[1] + ", amnt " + amnt); + } else + Utils.insertLog(uuid, args[1], "giveBondsCommand", "BONDS", amnt + " Bonds", amnt, 0); + + } + }.runTaskAsynchronously(Core.getInstance()); + return true; + } + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + user.giveBonds(amnt); + User u = Core.getUserManager().getLoadedUser(player.getUniqueId()); + u.insertLog(player, "giveBondsCommand", "BONDS", amnt + " Bonds", amnt, 0); + s.sendMessage(Utils.f("&a" + player.getName() + " now has " + user.getBonds() + " bonds!")); + + return true; + } + case "take": + if (args.length != 3) { + s.sendMessage(Utils.f("&c/houses bonds <set/give/take> <name> <amnt>")); + return true; + } + int amnt; + try { + amnt = Integer.parseInt(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f("&cThe amount must be a number!")); + return true; + } + if (amnt < 0) { + s.sendMessage(Utils.f("&cThe amount must be bigger than 0!")); + return true; + } + Player player = Bukkit.getPlayerExact(args[1]); + if (player == null) { + s.sendMessage(Utils.f("&cThat player isn't online, so hold on a second while the bonds are forcibly updated in the database.")); +// Core.getSQL().updateAsyncLater("update " + Core.name() + " set bonds=bonds-" + amnt + " where name='" + args[1] + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.takeBonds(args[1], amnt)); + + new BukkitRunnable() { + @Override + public void run() { + UUID uuid = UserDAO.getUuidByName(args[1]); +// ResultSet rs = Core.getSQL().query("select uuid,lastname from users where lastname='" + args[1] + "';"); +// UUID uuid = null; +// String name = args[1]; +// try { +// if (rs.next()) { +// uuid = UUID.fromString(rs.getString("uuid")); +// name = rs.getString("lastname"); +// } +// rs.close(); +// } catch (SQLException e) { +// e.printStackTrace(); +// } + if (uuid == null) { + Core.log("Error while logging takeBondsCommand for uuid " + uuid + ", name " + args[1] + ", amnt " + -amnt); + } else + Utils.insertLog(uuid, args[1], "takeBondsCommand", "BONDS", -amnt + " Bonds", -amnt, 0); + + } + }.runTaskAsynchronously(Core.getInstance()); + return true; + } + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + user.takeBonds(amnt); + User u = Core.getUserManager().getLoadedUser(player.getUniqueId()); + u.insertLog(player, "takeBondsCommand", "BONDS", amnt + " Bonds", -amnt, 0); + s.sendMessage(Utils.f("&a" + player.getName() + " now has " + user.getBonds() + " bonds!")); + return true; + } + return true; + } +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/BribeCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/BribeCommand.java new file mode 100644 index 0000000..a3666bd --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/BribeCommand.java @@ -0,0 +1,143 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.users.ViceUser; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +/** + * Created by Liam on 11/10/2016. + */ +public class BribeCommand implements CommandExecutor { + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + Player player = (Player) s; + if (args.length == 0) { + s.sendMessage(Lang.BRIBE.f("&7Help Command")); + s.sendMessage(Utils.f("&3/bribe &a<amount>&7 - Send a bribe offer to the cop who arrested you!")); + s.sendMessage(Utils.f("&3/bribe accept &a<prisoner>&7 - Accept the bribe of a prisoner you arrested!")); + s.sendMessage(Utils.f("&3/bribe deny &a<prisoner>&7 - Deny the bribe of a prisoner you arrested!")); + return true; + } + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + switch (args[0]) { + case "accept": { + if (!user.isCop()) { + player.sendMessage(Lang.BRIBE.f("&7You need to be in &3&lCOP Mode&7 to accept bribes!")); + return true; + } + if (args.length != 2) { + player.sendMessage(Lang.BRIBE.f("&7Please specify the prisoner of whom you would like to accept the bribe!")); + return true; + } + Player prisoner = Bukkit.getPlayer(args[1]); + ViceUser prisonerUser = prisoner == null ? null : Vice.getUserManager().getLoadedUser(prisoner.getUniqueId()); + if (prisoner == null || !prisonerUser.isArrested()) { + player.sendMessage(Lang.BRIBE.f("&7That player is not in jail!")); + return true; + } + if (prisonerUser.getJailTimer() <= 5) { + player.sendMessage(Lang.BRIBE.f("&7That prisoner is already being released!")); + return true; + } + if (prisonerUser.getBribe() <= 0) { + player.sendMessage(Lang.BRIBE.f("&7That prisoner has not sent a bribe offer to you! You can negotiate with them using &a\"/msg " + prisoner.getName() + "\"&7!")); + return true; + } + if (!prisonerUser.hasMoney(prisonerUser.getBribe())) { + player.sendMessage(Lang.BRIBE.f("&7That prisoner does not have enough money to pay for his bribe!")); + return true; + } + double bribe = prisonerUser.getBribe(); + prisonerUser.takeMoney(bribe); + user.addMoney(bribe); + prisonerUser.setBribe(0); + prisonerUser.setJailTimer(5); + ViceUtils.updateBoard(prisoner, prisonerUser); + ViceUtils.updateBoard(player, user); + player.sendMessage(Lang.BRIBE.f("&7You accepted a bribe of &a$&l" + bribe + "&7 from &e&l" + prisoner.getName() + "&7!")); + prisoner.sendMessage(Lang.BRIBE.f("&3&l" + player.getName() + "&7 accepted your bribe of &a$&l" + bribe + "&7!")); + return true; + } + case "deny": + if (!user.isCop()) { + player.sendMessage(Lang.BRIBE.f("&7You need to be in &3&lCOP Mode&7 to accept bribes!")); + return true; + } + if (args.length != 2) { + player.sendMessage(Lang.BRIBE.f("&7Please specify the prisoner of whom you would like to accept the bribe!")); + return true; + } + Player prisoner = Bukkit.getPlayer(args[1]); + ViceUser prisonerUser = prisoner == null ? null : Vice.getUserManager().getLoadedUser(prisoner.getUniqueId()); + if (prisoner == null || !prisonerUser.isArrested()) { + player.sendMessage(Lang.BRIBE.f("&7That player is not in jail!")); + return true; + } + if (prisonerUser.getJailTimer() <= 5) { + player.sendMessage(Lang.BRIBE.f("&7That prisoner is already being released!")); + return true; + } + if (prisonerUser.getBribe() <= 0) { + player.sendMessage(Lang.BRIBE.f("&7That prisoner has not sent a bribe offer to you! You can negotiate with them using &a\"/msg " + prisoner.getName() + "\"&7!")); + return true; + } + double bribe = prisonerUser.getBribe(); + player.sendMessage(Lang.BRIBE.f("&7You denied a bribe of &a$&l" + bribe + "&7 from &e&l" + prisoner.getName() + "&7! You can negotiate with them using &a\"/msg " + prisoner.getName() + "\"&7!")); + player.sendMessage(Lang.BRIBE.f("&3&l" + player.getName() + "&7 denied your bribe of &a$&l" + bribe + "&7! You can negotiate with them using &a\"/msg " + prisoner.getName() + "\"&7!")); + return true; + default: + if (!user.isArrested()) { + player.sendMessage(Lang.BRIBE.f("&7You are not in jail!")); + return true; + } + if (user.getJailTimer() < 5) { + player.sendMessage(Lang.BRIBE.f("&7You are already being released!")); + return true; + } + Player cop = Bukkit.getPlayer(user.getJailCop()); + ViceUser copUser = cop == null ? null : Vice.getUserManager().getLoadedUser(cop.getUniqueId()); + if (cop == null || !copUser.isCop()) { + player.sendMessage(Lang.BRIBE.f("&7The cop who arrested you (&3&l" + user.getJailCopName() + "&7) is off duty!")); + return true; + } + double amnt; + try { + amnt = Double.parseDouble(args[0]); + } catch (NumberFormatException e) { + player.sendMessage(Lang.BRIBE.f("&7The amount must be a number! (double)")); + return true; + } + if (amnt < 5000) { + player.sendMessage(Lang.BRIBE.f("&7Bribes must be at least &a$&l5,000!")); + return true; + } + if (user.getBribe() * 1.05 > amnt) { + player.sendMessage(Lang.BRIBE.f("&7You must raise the bribe by at least &a&l5%&7 of &a$&l" + user.getBribe() + "&7 (&a$&l" + (user.getBribe() * 1.05) + "&7)!")); + return true; + } + if (!user.hasMoney(amnt)) { + player.sendMessage(Lang.BRIBE.f("&7You don't have &c$&l" + amnt + "&7! Please enter a valid number or type &a\"quit\"&7!")); + return true; + } + user.setBribe(amnt); + player.sendMessage(Lang.BRIBE.f("&7You sent a bribe offer of &a$&l" + amnt + "&7 to &3&l" + cop.getName() + "&7. You can negotiate with them using &a\"/msg " + cop.getName() + "\"&7!")); + cop.spigot().sendMessage(new ComponentBuilder(Lang.BRIBE.f("&7A bribe offer of &a$&l" + amnt + "&7 was sent to you by &3&l" + player.getName() + "&7!")).append(" [ACCEPT] ").color(ChatColor.GREEN).bold(true).event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/bribe accept " + player.getName())).append("[DENY]").color(ChatColor.DARK_RED).bold(true).event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/bribe deny " + player.getName())).create()); + return true; + } + + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/CheatCodeCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/CheatCodeCommand.java new file mode 100644 index 0000000..21352e7 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/CheatCodeCommand.java @@ -0,0 +1,198 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.commands.CoreCommand; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.State; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.dao.CheatCodeDAO; +import net.grandtheftmc.vice.users.CheatCode; +import net.grandtheftmc.vice.users.CheatCodeState; +import net.grandtheftmc.vice.users.ViceUser; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import java.sql.Blob; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +/** + * Created by Timothy Lampen on 8/24/2017. + */ +public class CheatCodeCommand extends CoreCommand<CommandSender> { + + public CheatCodeCommand() { + super("cheatcode", "edit a player's unlocked cheat codes", "cc", "cheatcodes"); + } + + @Override + public void execute(CommandSender sender, String[] args) { + if(args.length==0) { + if(!(sender instanceof Player) || Core.getUserManager().getLoadedUser(((Player)sender).getUniqueId()).getUserRank().isHigherThan(UserRank.ADMIN)) { + sender.sendMessage(Utils.f("&e/cheatcode give <player> <cheatcode> &7- gives a certain player a PERM new cheatcode")); + sender.sendMessage(Utils.f("&e/cheatcode remove <player> <cheatcode> &7- removes a cheatcode from a player")); + sender.sendMessage(Utils.f("&e/cheatcode view <player> &7- view a player's cheatcodes")); + sender.sendMessage(Utils.f("&e/cheatcode list &7- lists all avaliable cheat codes.")); + sender.sendMessage(Utils.f("&e/cheatcode <cheatcode> &7- toggle / activate the specific cheatcode.")); + } + else { + sender.sendMessage(Utils.f("&e/cheatcode <cheatcode> &7- toggle / activate the specific cheatcode.")); + sender.sendMessage(Utils.f("&e/cheatcode list &7- lists all avaliable cheat codes.")); + } + return; + } + if(args.length==1) { + for (CheatCode code : CheatCode.values()) { + if (args[0].equalsIgnoreCase(code.toString())) { + if (!(sender instanceof Player)) { + sender.sendMessage(Lang.NOTPLAYER.f("")); + return; + } + Player player = (Player) sender; + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + code.activate(Core.getUserManager().getLoadedUser(player.getUniqueId()), user, player, user.getCheatCodeState(code)); + return; + } + } + } + switch (args[0]) { + case "remove": { + if(sender instanceof Player && !Core.getUserManager().getLoadedUser(((Player)sender).getUniqueId()).getUserRank().isHigherThan(UserRank.ADMIN)) { + sender.sendMessage(Lang.NOPERM.f("")); + return; + } + Player target = Bukkit.getPlayer(args[1]); + if(target==null) { + sender.sendMessage(Lang.CHEAT_CODES.f("&7Cannot find the player &a" + args[1])); + return; + } + if (args.length != 3) { + sender.sendMessage(Lang.CHEAT_CODES.f("&c/cheatcode remove <player> <cheatcode>")); + return; + } + Optional<CheatCode> optCode = Arrays.stream(CheatCode.values()).filter(c -> c.toString().equalsIgnoreCase(args[2])).findFirst(); + if (!optCode.isPresent()) { + sender.sendMessage(Lang.CHEAT_CODES.f("&cUnable to find cheatcode with name &e" + args[2])); + return; + } + ViceUser user = Vice.getUserManager().getLoadedUser(target.getUniqueId()); + Core.getUserManager().getLoadedUser(target.getUniqueId()).insertLog(target,"takeCheatCodeCommand","CHEATCODE", optCode.get().toString(),1,0); + user.setCheatCodeState(optCode.get(), new CheatCodeState(State.LOCKED, false)); + target.sendMessage(Lang.CHEAT_CODES.f("&7The cheatcode &e" + optCode.get() + " &7has been removed from your account.")); + sender.sendMessage(Lang.CHEAT_CODES.f("&7You have removed the cheatcode &e" + optCode.get() + " &7from &b" + target.getName() + "&7's account.")); + break; + } + case "give": { + if(sender instanceof Player && !Core.getUserManager().getLoadedUser(((Player)sender).getUniqueId()).getUserRank().isHigherThan(UserRank.ADMIN)) { + sender.sendMessage(Lang.NOPERM.f("")); + return; + } + Player target = Bukkit.getPlayer(args[1]); + if(target==null) { + sender.sendMessage(Lang.CHEAT_CODES.f("&7Cannot find the player &a" + args[1])); + return; + } + if (args.length != 3) { + sender.sendMessage(Lang.CHEAT_CODES.f("&c/cheatcode give <player> <cheatcode>")); + return; + } + Optional<CheatCode> optCode = Arrays.stream(CheatCode.values()).filter(c -> c.toString().equalsIgnoreCase(args[2])).findFirst(); + if (!optCode.isPresent()) { + sender.sendMessage(Lang.CHEAT_CODES.f("&cUnable to find cheatcode with name &e" + args[2])); + return; + } + ViceUser user = Vice.getUserManager().getLoadedUser(target.getUniqueId()); + switch (optCode.get()) { + case STACK: + Core.getPermsManager().addPerm(target.getUniqueId(), "command.stack"); + break; + case FIXALL: + Core.getPermsManager().addPerm(target.getUniqueId(), "command.fix.all"); + break; + case FIXHAND: + Core.getPermsManager().addPerm(target.getUniqueId(), "command.fix.hand"); + break; + + } + Core.getUserManager().getLoadedUser(target.getUniqueId()).insertLog(target,"giveCheatCodeCommand","CHEATCODE", optCode.get().toString(),1,0); + user.setCheatCodeState(optCode.get(), new CheatCodeState(optCode.get().getDefaultState(), true)); + sender.sendMessage(Lang.CHEAT_CODES.f("&7You have given &b" + target.getName() + " &7the cheatcode &e" + optCode.get().toString() + "&7!")); + target.sendMessage(Lang.CHEAT_CODES.f("&7You have reiceved the cheatcode &e" + optCode.get().toString() + "&7, go into the kit menu located on your phone to toggle the effects.")); + break; + } + case "view": { + if(sender instanceof Player && !Core.getUserManager().getLoadedUser(((Player)sender).getUniqueId()).getUserRank().isHigherThan(UserRank.ADMIN)) { + sender.sendMessage(Lang.NOPERM.f("")); + return; + } + if(args.length !=2) { + sender.sendMessage(Utils.f("&e/cheatcode view <player>")); + return; + } + Player target = Bukkit.getPlayer(args[1]); + if (target == null) { + new BukkitRunnable() { + @Override + public void run() { + int counter = 0; + Optional<HashMap<CheatCode, CheatCodeState>> optional = CheatCodeDAO.getCheatCodes(args[1]); + if(!optional.isPresent()) { + sender.sendMessage(Lang.CHEAT_CODES.f("&cAn error occurred.")); + return; + } + + counter = optional.get().size(); + + if(counter == 0) { + sender.sendMessage(Lang.CHEAT_CODES.f("&cThat player cannot be found!")); + } + else { + sender.sendMessage(Utils.f("&7Player's Cheat Codes:")); + for(Map.Entry<CheatCode, CheatCodeState> entry : optional.get().entrySet()) { + sender.sendMessage(Utils.f("&2&l" + entry.getKey() + "&7: State: " + (entry.getValue().getState()==State.ON ? "&a " : "&c ") + entry.getValue().getState() + "&7, Purchased: " + (entry.getValue().isPurchased() ? "&atrue" : "&cfalse"))); + } + } + } + }.runTaskAsynchronously(Vice.getInstance()); + return; + } + ViceUser user = Vice.getUserManager().getLoadedUser(target.getUniqueId()); + sender.sendMessage(Utils.f("&7Player's Cheat Codes:")); + for(Map.Entry<CheatCode, CheatCodeState> entry : user.getCheatCodes().entrySet()) { + sender.sendMessage(Utils.f("&2&l" + entry.getKey() + "&7: State: " + (entry.getValue().getState()==State.ON ? "&a " : "&c ") + entry.getValue().getState() + "&7, Purchased: " + (entry.getValue().isPurchased() ? "&atrue" : "&cfalse"))); + } + break; + } + + case "list": { + StringBuilder sb = new StringBuilder("&7Cheat Codes:"); + Arrays.stream(CheatCode.values()).forEach(code -> sb.append(" &a" + code.toString() + "&7,")); + sb.deleteCharAt(sb.length()-1); + sender.sendMessage(Utils.f(sb.toString())); + break; + } + default: { + if(!(sender instanceof Player) || Core.getUserManager().getLoadedUser(((Player)sender).getUniqueId()).getUserRank().isHigherThan(UserRank.ADMIN)) { + sender.sendMessage(Utils.f("&e/cheatcode give <player> <cheatcode> &7- gives a certain player a new cheatcode")); + sender.sendMessage(Utils.f("&e/cheatcode remove <player> <cheatcode> &7- removes a cheatcode from a player")); + sender.sendMessage(Utils.f("&e/cheatcode view <player> &7- view a player's cheatcodes")); + sender.sendMessage(Utils.f("&e/cheatcode list &7- lists all avaliable cheat codes.")); + sender.sendMessage(Utils.f("&e/cheatcode <cheatcode> &7- toggle / activate the specific cheatcode.")); + } + else { + sender.sendMessage(Utils.f("&e/cheatcode <cheatcode> &7- toggle / activate the specific cheatcode.")); + sender.sendMessage(Utils.f("&e/cheatcode list &7- lists all avaliable cheat codes.")); + } + break; + } + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/ChunkUnloadCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/ChunkUnloadCommand.java new file mode 100644 index 0000000..9ff092b --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/ChunkUnloadCommand.java @@ -0,0 +1,47 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import org.bukkit.Chunk; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; + +import java.util.Arrays; +import java.util.Collection; +import java.util.stream.Collectors; + +public class ChunkUnloadCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.VICE.f("&cYou are not a player!")); + return true; + } + Player player = (Player)s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if(!user.isRank(UserRank.DEV)) { + player.sendMessage(Lang.VICE.f("&7You don't have permission to use this command.")); + return true; + } + Collection<Chunk> chunks = Arrays + .stream(player.getWorld().getLoadedChunks()) + .collect(Collectors.toList()); + for(Chunk chunk : player.getWorld().getLoadedChunks()) { + for(Entity entity : chunk.getEntities()) { + if (entity.getType() == EntityType.PLAYER) { + chunks.remove(chunk); + break; + } + } + } + chunks.forEach(Chunk::unload); + return true; + } +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/ClearCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/ClearCommand.java new file mode 100644 index 0000000..94f7bd3 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/ClearCommand.java @@ -0,0 +1,40 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.ViceUtils; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class ClearCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!s.hasPermission("command.clear")) { + s.sendMessage(Utils.f("&cYou do not have permission to execute this command!")); + return true; + } + if (!(s instanceof Player)) { + s.sendMessage(Lang.VICE.f("&cYou are not a player!")); + return true; + } + Player player; + if (args.length == 0) { + player = (Player) s; + } else { + if (Bukkit.getPlayer(args[0]) == null) { + s.sendMessage(Lang.VICE.f("&cThat player is not online!")); + return true; + } else { + player = Bukkit.getPlayer(args[0]); + } + } + player.getInventory().iterator().forEachRemaining(itemStack -> player.getInventory().remove(itemStack)); + player.sendMessage(Lang.VICE.f("&7Your inventory has been cleared!")); + ViceUtils.giveGameItems(player); + return true; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/CopCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/CopCommand.java new file mode 100644 index 0000000..8384ec7 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/CopCommand.java @@ -0,0 +1,201 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.users.CopRank; +import net.grandtheftmc.vice.users.ViceUser; +import net.grandtheftmc.vice.users.ViceUserDAO; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; + +/** + * Created by Liam on 3/07/2017. + */ +public class CopCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command cmd, String lbl, String[] args) { + if (args.length == 0) { + s.sendMessage(Utils.f("&3/cop&7 set <player> <copRank> - Set the player's cop rank")); + s.sendMessage(Utils.f("&3/cop&7 promote <player> - Promotes the player to a higher Cop Rank")); + s.sendMessage(Utils.f("&3/cop&7 resign - Resigns your current position")); + s.sendMessage(Utils.f("&3/cop&7 list - Lists all avaliable online and offline cops")); + s.sendMessage(Utils.f("&3/cop&7 fire <player> - Fire the player from being a Cop")); + return true; + } + switch (args[0].toLowerCase()) { + case "list": { + new BukkitRunnable() { + @Override + public void run() { + HashMap<String, CopRank> onlineCops = new HashMap<>(); + for(Player player : Bukkit.getOnlinePlayers()) { + ViceUser viceUser = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + if(viceUser.getCopRank()!=null) { + onlineCops.put(player.getName(), viceUser.getCopRank()); + } + } + HashMap<String, CopRank> offlineCops = new HashMap<>(); +// ResultSet rs = Core.sql.prepareStatement("SELECT * from " + Core.name() + " WHERE copRank IS NOT NULL;").executeQuery(); +// while (rs.next()) { +// String name = rs.getString("name"); +// if(onlineCops.containsKey(name)) +// continue; +// CopRank rank = CopRank.getRankOrNull(rs.getString("copRank")); +// offlineCops.put(name, rank); +// } + + ViceUserDAO.getCops(onlineCops, offlineCops); + + List<Map.Entry<String,CopRank>> sortedOnline = sortMapByCopRankValueDescending(onlineCops); + List<Map.Entry<String,CopRank>> sortedOffline = sortMapByCopRankValueDescending(offlineCops); + s.sendMessage(Lang.COP.f("&a&lONLINE COPS:")); + sortedOnline.forEach(entry -> {s.sendMessage(Utils.f(ChatColor.GREEN + entry.getKey() + " &7: &3" + entry.getValue()));}); + s.sendMessage(Lang.COP.f("&4&lOFFLINE COPS:")); + sortedOffline.forEach(entry -> {s.sendMessage(Utils.f(ChatColor.RED + entry.getKey() + " &7: &3" + entry.getValue()));}); + } + }.runTaskAsynchronously(Vice.getInstance()); + return true; + } + case "resign": { + if(!(s instanceof Player)) { + s.sendMessage(Lang.COP.f("&7You have to be a player to execute this command!")); + return false; + } + Player player = (Player)s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + ViceUser viceUser = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + if(viceUser.getCopRank()!=CopRank.WARDEN) { + viceUser.setCopRank(null, player, user); + s.sendMessage(Lang.COP.f("&7You have resigned as a cop. Thank you for your support with our police force.")); + ViceUtils.updateBoard(player, viceUser); + return true; + } + + new BukkitRunnable() { + @Override + public void run() { + int counter = ViceUserDAO.countCops(CopRank.WARDEN); + + if(counter>=2) { + viceUser.setCopRank(null, player, user); + ViceUtils.updateBoard(player, viceUser); + s.sendMessage(Lang.COP.f("&7You have resigned as a warden. Thank you for your support with our police force.")); + } + else { + s.sendMessage(Lang.COP.f("&7You cannot resign as there are no other wardens to take your place!")); + } + } + }.runTaskAsynchronously(Vice.getInstance()); + return true; + } + case "set": { + if (!senderHasPerms(s)) { + s.sendMessage(Lang.NOPERM.s()); + return false; + } + if (args.length != 3) { + s.sendMessage(Utils.f("&c/cop set <player> <copRank>")); + return false; + } + Player player = Bukkit.getPlayer(args[1]); + if (player == null) { + s.sendMessage(Lang.COPS.f("&7That player is not online!")); + return false; + } + ViceUser viceUser = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + CopRank copRank = CopRank.getRankOrNull(args[2]); + if (copRank == null) { + String msg = Lang.COPS + "&7There is no Cop Rank with the name &3" + args[2] + "&7! Valid ranks: "; + for (CopRank r : CopRank.values()) + msg = msg + "&3" + r.getColoredNameBold() + "&7, "; + if (msg.endsWith("&7, ")) + msg = msg.substring(0, msg.length() - 4); + msg += "&7."; + s.sendMessage(Utils.f(msg)); + return true; + } + ViceUtils.updateBoard(player, viceUser); + viceUser.setCopRank(copRank, player, Core.getUserManager().getLoadedUser(player.getUniqueId())); + s.sendMessage(Lang.COPS.f("&7You set &3&l" + player.getName() + "&7 to " + copRank.getColoredNameBold() + "&7!")); + player.sendMessage(Lang.COPS.f("&7You have been set to " + copRank.getColoredNameBold() + "&7 by &3&l" + s.getName() + "&7!")); + return true; + } + case "promote": { + if (!senderHasPerms(s)) { + s.sendMessage(Lang.NOPERM.s()); + return false; + } + if (args.length != 2) { + s.sendMessage(Utils.f("&c/cop promote <player>")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player == null) { + s.sendMessage(Lang.COPS.f("&7That player is not online!")); + return true; + } + ViceUser viceUser = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + CopRank copRank = viceUser.isCop() ? viceUser.getCopRank().getNext() : CopRank.COP; + viceUser.setCopRank(copRank, player, Core.getUserManager().getLoadedUser(player.getUniqueId())); + ViceUtils.updateBoard(player, viceUser); + s.sendMessage(Lang.COPS.f("&7You promoted &3&l" + player.getName() + "&7 to " + copRank.getColoredNameBold() + "&7!")); + player.sendMessage(Lang.COPS.f("&7You have been promoted to " + copRank.getColoredNameBold() + "&7 by &3&l" + s.getName() + "&7!")); + return true; + } + case "fire": + if (!senderHasPerms(s)) { + s.sendMessage(Lang.NOPERM.s()); + return true; + } + if (args.length != 2) { + s.sendMessage(Utils.f("&c/cop fire <player>")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player == null) { + s.sendMessage(Lang.COPS.f("&7That player is not online!")); + return true; + } + ViceUser viceUser = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + viceUser.setCopRank(null, player, Core.getUserManager().getLoadedUser(player.getUniqueId())); + ViceUtils.updateBoard(player, viceUser); + s.sendMessage(Lang.COPS.f("&7You fired &3&l" + player.getName() + "&7 from the police force!")); + player.sendMessage(Lang.COPS.f("&7You have been fired from the police force by &3&l" + s.getName() + "&7!")); + return true; + } + return true; + } + + private boolean senderHasPerms(CommandSender sender) { + if(sender instanceof Player) { + Player player = (Player)sender; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + ViceUser viceUser = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + return user.isAdmin() && viceUser.getCopRank() == CopRank.WARDEN; + } + return true; + } + + private List<Map.Entry<String,CopRank>> sortMapByCopRankValueDescending(Map<String,CopRank> map) { + List<Map.Entry<String,CopRank>> sortedEntries = new ArrayList<>(map.entrySet()); + + Collections.sort(sortedEntries, (e1, e2) -> e2.getValue().compareTo(e1.getValue())); + + return sortedEntries; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/CoreNPCCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/CoreNPCCommand.java new file mode 100644 index 0000000..6f3c5ca --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/CoreNPCCommand.java @@ -0,0 +1,68 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.commands.CoreCommand; +import net.grandtheftmc.vice.machine.MachineManager; +import net.grandtheftmc.vice.users.npcs.MachineNPC; +import net.grandtheftmc.vice.users.npcs.shopnpc.ShopNPC; +import net.grandtheftmc.vice.users.npcs.TaxiNPC; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +/** + * Created by Timothy Lampen on 1/14/2018. + */ +public class CoreNPCCommand extends CoreCommand<Player> { + + private final MachineManager machineManager; + + public CoreNPCCommand(MachineManager machineManager) { + super("corenpc", "commands dealing with corenpcs"); + this.machineManager = machineManager; + } + + @Override + public void execute(Player player, String[] args) { + if(!player.isOp()) { + player.sendMessage(Lang.NOPERM.f("")); + return; + } + + if(args.length==0) { + player.sendMessage(Lang.GTM.f("&7Avaliable NPCs: ")); + player.sendMessage(Utils.f("&aTaxi&7- Opens the taxi menu")); + player.sendMessage(Utils.f("&aShop &7- Opens a food shop menu")); + player.sendMessage(Utils.f("&aMachine &7- NPC for trading machine shards")); + player.sendMessage(Lang.GTM.f("&c/corenpc delete &7- Removes the nearby entity (please stand within 1 block)")); + player.sendMessage(Lang.GTM.f("&c/corenpc spawn <npc>")); + return; + } + + if(args.length==1){ + switch (args[0].toLowerCase()) { + case "delete": + case "remove": + for(Entity e : player.getNearbyEntities(2,2,2)) + Core.getNPCManager().deleteNPC(e); + player.sendMessage(Lang.GTM.f("&cYou have removed nearby npcs.")); + break; + } + return; + } + + switch (args[1].toLowerCase()) { + case "shop": + new ShopNPC(player.getLocation()); + break; + case "machine": + new MachineNPC(this.machineManager, player.getLocation()); + break; + case "taxi": + new TaxiNPC(player.getLocation()); + break; + + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/DrugCheckCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/DrugCheckCommand.java new file mode 100644 index 0000000..b2dabbe --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/DrugCheckCommand.java @@ -0,0 +1,33 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Lang; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; + +/** + * Created by Timothy Lampen on 2017-04-22. + */ +public class DrugCheckCommand implements CommandExecutor { + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (args.length != 1) { + sender.sendMessage(Lang.DRUGS.f("&7Syntax Error: /drugcheck <player>")); + return false; + } + Player target = Bukkit.getPlayer(args[0]); + if (target == null) { + sender.sendMessage(Lang.DRUGS.f("&7Error: The specified player is not online.")); + return false; + } + sender.sendMessage(Lang.DRUGS.f("&7Current potion effect portfolio for " + target.getName())); + for (PotionEffect pe : target.getActivePotionEffects()) { + sender.sendMessage(ChatColor.GREEN + pe.getType().getName() + ChatColor.BLUE + " : " + ChatColor.GREEN + pe.getAmplifier() + 1 + ChatColor.BLUE + " : " + ChatColor.GREEN + pe.getDuration() / 20 + "s"); + } + return true; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/FeedCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/FeedCommand.java new file mode 100644 index 0000000..55d7501 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/FeedCommand.java @@ -0,0 +1,58 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.State; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.users.CheatCode; +import net.grandtheftmc.vice.users.ViceUser; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + + +public class FeedCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + /* if (args.length > 0 && s.hasPermission("command.feed.others")) { + player = Bukkit.getPlayer(args[0]); + if (player == null) { + s.sendMessage(Lang.VICE.f("&7That player is not online!")); + return true; + } + player.setFoodLevel(20); + player.setSaturation(20); + s.sendMessage(Lang.VICE.f("&7You fed &a" + player.getName() + "&7!")); + return true; + }*/ + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + Player player = (Player) s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + ViceUser viceUser = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + if (viceUser.getCheatCodeState(CheatCode.FEED).getState()== State.LOCKED) { + player.sendMessage(Lang.CHEAT_CODES.f(CheatCode.FEED.getLockedLore())); + return true; + } + + if(user.isOnCooldown("feed_command")) { + player.sendMessage(Lang.CHEAT_CODES.f("&7You must wait &a" + Utils.timeInSecondsToText(user.getCooldownTimeLeft("feed_command"), C.RED, C.RED, C.GRAY) + " &7before using this cheatcode again!")); + return true; + } + + user.addCooldown("feed_command", ViceUtils.getFeedDelay(user.getUserRank()), false, true); + player.setFoodLevel(20); + player.setSaturation(20); + player.sendMessage(Lang.VICE.f("&7You fed yourself!")); + return true; + + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/FixCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/FixCommand.java new file mode 100644 index 0000000..6f3c2b2 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/FixCommand.java @@ -0,0 +1,131 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.State; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.durability.DurabilityItems; +import net.grandtheftmc.vice.users.CheatCode; +import net.grandtheftmc.vice.users.ViceUser; +import net.grandtheftmc.vice.utils.DurabilityUtil; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.TimeUnit; + +public class FixCommand implements CommandExecutor { + private final List<Material> repairableItems = Arrays.asList( +// Material.LEATHER_CHESTPLATE, +// Material.CHAINMAIL_CHESTPLATE, Material.IRON_CHESTPLATE, +// Material.GOLD_CHESTPLATE, Material.DIAMOND_CHESTPLATE, +// Material.LEATHER_BOOTS, Material.LEATHER_LEGGINGS, +// Material.LEATHER_CHESTPLATE, Material.LEATHER_HELMET, +// Material.DIAMOND_HELMET, Material.ELYTRA + + Material.WOOD_PICKAXE, Material.STONE_PICKAXE,Material.GOLD_PICKAXE,Material.IRON_PICKAXE,Material.DIAMOND_PICKAXE, + Material.WOOD_SPADE, Material.STONE_SPADE,Material.GOLD_SPADE,Material.IRON_SPADE,Material.DIAMOND_SPADE, + Material.WOOD_AXE, Material.STONE_AXE,Material.GOLD_AXE,Material.IRON_AXE,Material.DIAMOND_AXE, + Material.WOOD_HOE, Material.STONE_HOE,Material.GOLD_HOE,Material.IRON_HOE,Material.DIAMOND_HOE + ); + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + Player player = (Player) s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + ViceUser viceUser = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + if (args.length == 0 || args.length == 1 && "hand".equalsIgnoreCase(args[0])) { + if(viceUser.getCheatCodeState(CheatCode.FIXHAND).getState()== State.LOCKED) { + player.sendMessage(Lang.CHEAT_CODES.f(CheatCode.FIXHAND.getLockedLore())); + return false; + } + if(user.isOnCooldown("fix_hand_command")) { + player.sendMessage(Lang.CHEAT_CODES.f("&7You must wait &a" + Utils.timeInSecondsToText(user.getCooldownTimeLeft("fix_hand_command"), C.RED, C.RED, C.GRAY) + " &7before using this cheatcode again!")); + return false; + } + ItemStack item = player.getInventory().getItemInMainHand(); + + Optional<DurabilityItems> durabilityItem = DurabilityUtil.getDurabilityItem(item); + + if(this.repairableItems.contains(item.getType()) || durabilityItem.isPresent()) { + + if (durabilityItem.isPresent()) { + ItemStack newRepaired = repairDurability(item); + player.getInventory().setItem(player.getInventory().getHeldItemSlot(), newRepaired); + } else { + item.setDurability((short)0); + } + + player.sendMessage(Lang.VICE.f("&7You have repaired your " + (item.getItemMeta().getDisplayName() == null ? item.getType().name().toLowerCase().replace("_", "") : item.getItemMeta().getDisplayName()) + "&7!")); + user.addCooldown("fix_hand_command", ViceUtils.getFixHandDelay(user.getUserRank()), false, true); + } else { + player.sendMessage(Lang.VICE.f("&7That item may not be repaired.")); + } + return true; + } else if(args.length == 1 && "all".equalsIgnoreCase(args[0])) { + if(viceUser.getCheatCodeState(CheatCode.FIXALL).getState()== State.LOCKED) { + player.sendMessage(Lang.CHEAT_CODES.f(CheatCode.FIXALL.getLockedLore())); + return false; + } + if(user.isOnCooldown("fix_all_command")) { + player.sendMessage(Lang.CHEAT_CODES.f("&7You must wait &a" + Utils.timeInSecondsToText(user.getCooldownTimeLeft("fix_all_command"), C.RED, C.RED, C.GRAY) + " &7before using this cheatcode again!")); + return false; + } + for(ItemStack item : player.getInventory().getContents()) { + if(item == null) continue; + if(!this.repairableItems.contains(item.getType())) continue; + item.setDurability((short)0); + } + player.sendMessage(Lang.VICE.f("&7You have repaired all damaged items in your inventory!")); + user.addCooldown("fix_all_command", ViceUtils.getFixAllDelay(user.getUserRank()), false, true); + } else { + player.sendMessage(Lang.VICE.f("&7/fix hand - fixes the item in your hand.")); + player.sendMessage(Lang.VICE.f("&7/fix all - fixes all the items in your inventory.")); + return true; + } + return true; + + } + + private ItemStack repairDurability(ItemStack item) { + + Optional<DurabilityItems> durabilityItems = DurabilityUtil.getDurabilityItem(item); + + if (item == null || !durabilityItems.isPresent()) { + return null; + } + + if (item.getItemMeta() != null && !item.getItemMeta().isUnbreakable()) { + ItemMeta itemMeta = item.getItemMeta(); + itemMeta.setUnbreakable(true); + itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE); + item.setItemMeta(itemMeta); + } + + DurabilityItems durabilityItem = durabilityItems.get(); + + ItemStack newArmour = DurabilityUtil.setDurability(item, durabilityItem.getMaximumDurability()); + DurabilityUtil.setDurabilityLore(newArmour, durabilityItem.getMaximumDurability(), durabilityItem); + + return newArmour; + } +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/HomeCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/HomeCommand.java new file mode 100644 index 0000000..b65c6ca --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/HomeCommand.java @@ -0,0 +1,125 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.commands.CoreCommand; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.users.TaxiTarget; +import net.grandtheftmc.vice.users.ViceUser; +import net.grandtheftmc.vice.utils.LocationUtil; +import org.bukkit.ChatColor; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.entity.Player; + +/** + * Created by Timothy Lampen on 2017-08-11. + */ +public class HomeCommand extends CoreCommand<Player> { + + + public HomeCommand() { + super("home", "sets / changes predefined homes for players", "vicesethome", "vicedelhome"); + } + + @Override + public void execute(Player player, String[] args) { + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + UserRank rank = Core.getUserManager().getLoadedUser(player.getUniqueId()).getUserRankNonTrial(); + if (args.length == 0) { + player.sendMessage(ChatColor.GRAY + "Your " + rank.getColoredNameBold() + ChatColor.GRAY + " and " + user.getRank().getColoredNameBold() + ChatColor.GRAY + " ranks allows you to set " + ChatColor.YELLOW + ChatColor.BOLD + ((ViceUtils.getSetHomes(rank) + ViceUtils.getSetHomes(user.getRank())) - user.getHomes().size()) + ChatColor.GRAY + " more home(s)"); + player.sendMessage(ChatColor.YELLOW + "/home set <name> " + ChatColor.GRAY + "- sets your current location to a home"); + player.sendMessage(ChatColor.YELLOW + "/home delete <name> " + ChatColor.GRAY + "- deletes one of your existing homes"); + player.sendMessage(ChatColor.YELLOW + "/home <name> " + ChatColor.GRAY + "- teleports you to the predefined location"); + player.sendMessage(ChatColor.YELLOW + "/home list " + ChatColor.GRAY + "- lists all of your current homes"); + return; + } + + if(player.getGameMode() != GameMode.SURVIVAL) { + player.sendMessage(Lang.VICE.f("&cYou cannot do this command unless you are in survival!")); + return; + } + + if (args.length == 1) {//theyre teleporting + String id = args[0].toLowerCase(); + switch (args[0].toLowerCase()) { + case "list": { + StringBuilder sb = new StringBuilder("&7Your homes: "); + int counter = 1; + for (String homeName : user.getHomes().keySet()) { + if (counter == user.getHomes().size()) { + sb.append("&e").append(homeName).append("&7."); + } else { + sb.append("&e").append(homeName).append("&7, "); + } + counter++; + } + player.sendMessage(Lang.VICE.f(sb.toString())); + break; + } + default: { + if (user.getHomeLocation(id) != null) { + if (user.isInCombat()) { + player.sendMessage(Lang.COMBATTAG.f("&7You cannot issue this command while in combat!")); + return; + } + + Location destination = user.getHomeLocation(id); + Vice.getWorldManager().getWarpManager().warp(player, Core.getUserManager().getLoadedUser(player.getUniqueId()), user, new TaxiTarget(LocationUtil.isBlockUnsafe(destination.getWorld(), destination.getBlockX(), destination.getBlockY(), destination.getBlockZ()) ? LocationUtil.getSafeDestination(destination) : destination)); + } + + else { + player.sendMessage(Lang.VICE.f("&7You don't have a home named &e" + id)); + } + break; + } + } + } else if (args.length == 2) { + String id = args[1].toLowerCase(); + switch (args[0].toLowerCase()) { + + case "add": + case "set": { + if (user.getHomes().size() >= (ViceUtils.getSetHomes(rank) + ViceUtils.getSetHomes(user.getRank()))) { + player.sendMessage(Lang.VICE.f("&7You already have the maximum amount of homes!")); + return; + } + + if (Core.getWorldManager().usesEditMode(player.getWorld().getName())) { + player.sendMessage(Lang.VICE.f("&7You cannot set your home in this world!")); + return; + } + + user.setHomeLocation(id, player.getLocation()); + player.sendMessage(Lang.VICE.f("&7You have created a new home named &e" + id + " &7at your current location.")); + break; + } + + case "remove": + case "delete": { + if (!user.removeHomeLocation(id)) { + player.sendMessage(Lang.VICE.f("&7You don't have a home named &e" + id)); + break; + } + + player.sendMessage(Lang.VICE.f("&7You have deleted your home named &e" + id)); + break; + } + default: { + player.sendMessage(ChatColor.RED + "Your " + rank.getColoredNameBold() + ChatColor.RED + " rank(s) allows you to set " + ChatColor.YELLOW + (ViceUtils.getSetHomes(rank) + ViceUtils.getSetHomes(user.getRank())) + ChatColor.RED + " homes"); + player.sendMessage(ChatColor.RED + "/home set <name> - sets your current location to a home"); + player.sendMessage(ChatColor.RED + "/home delete <name> - deletes one of your existing homes"); + player.sendMessage(ChatColor.RED + "/home <name> - teleports to the predefined location"); + break; + } + } + } else { + player.sendMessage(ChatColor.RED + "Your " + rank.getColoredNameBold() + ChatColor.RED + " rank(s) allows you to set " + ChatColor.YELLOW + (ViceUtils.getSetHomes(rank) + ViceUtils.getSetHomes(user.getRank())) + ChatColor.RED + " homes"); + player.sendMessage(ChatColor.RED + "/home set <name> - sets your current location to a home"); + player.sendMessage(ChatColor.RED + "/home delete <name> - deletes one of your existing homes"); + player.sendMessage(ChatColor.RED + "/home <name> - teleports to the predefined location"); + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/KillCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/KillCommand.java new file mode 100644 index 0000000..7079e1f --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/KillCommand.java @@ -0,0 +1,55 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class KillCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (args.length == 0 || "suicide".equalsIgnoreCase(lbl)) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.VICE.f("&cYou are not a player!")); + return true; + } + Player player = (Player) s; + if (Vice.getUserManager().getLoadedUser(player.getUniqueId()).isArrested()) { + player.sendMessage(Lang.JAIL.f("&7You can't kill yourself in jail!")); + return true; + } + player.getActivePotionEffects().forEach(effect -> { + player.removePotionEffect(effect.getType()); + }); + player.damage(player.getHealth()); + return true; + } + if (!s.hasPermission("command.kill")) { + s.sendMessage(Lang.NOPERM.s()); + return true; + } + if (args.length != 1) { + s.sendMessage(Utils.f("&c/kill <player>")); + return true; + } + Player target = Bukkit.getPlayer(args[0]); + if (target == null) { + s.sendMessage(Lang.VICE.f("&7That player is not online!")); + return true; + } + target.getActivePotionEffects().forEach(effect -> { + target.removePotionEffect(effect.getType()); + }); + target.damage(target.getHealth()); + s.sendMessage(Lang.VICE.f("&7You killed &a" + + Core.getUserManager().getLoadedUser(target.getUniqueId()).getColoredName(target) + "&7!")); + return true; + } +} + diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/LogoutCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/LogoutCommand.java new file mode 100644 index 0000000..beb8ef7 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/LogoutCommand.java @@ -0,0 +1,52 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.commands.CoreCommand; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.storage.BooleanStorageType; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +/** + * Created by Timothy Lampen on 2017-08-14. + */ +public class LogoutCommand extends CoreCommand<Player> { + public LogoutCommand() {//currently disabled, if enabled again, if a player logs out successfully, logs in, logs out without the command, the npc does not spawn see USED_LOGOUT + super("logout", "safetly logs out the user from the server without an NPC"); + } + + @Override + public void execute(Player player, String[] args) { + new LogoutTask(player).runTaskTimer(Vice.getInstance(), 0, 20); + } + + private class LogoutTask extends BukkitRunnable { + + private final Location location; + private int counter = 15; + private final Player player; + + public LogoutTask(Player player){ + this.player = player; + this.location = player.getLocation(); + } + + @Override + public void run() { + if(player.getLocation().distance(location)>1) { + cancel(); + player.sendMessage(Lang.COMBATTAG.f("&7Stopped logging your player out as you have moved.")); + return; + } + player.sendMessage(Lang.COMBATTAG.f("&7Logging your player out in &e&l" + counter + " &7second" + (counter==1 ? "s." : "."))); + if(counter==0){ + Vice.getUserManager().getLoadedUser(player.getUniqueId()).setBooleanToStorage(BooleanStorageType.USED_LOGOUT, true); + player.kickPlayer(Lang.COMBATTAG.f("&7You have successfully logged out.")); + } + else + counter--; + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/LotteryCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/LotteryCommand.java new file mode 100644 index 0000000..0809ebf --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/LotteryCommand.java @@ -0,0 +1,92 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.tasks.Lottery; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.time.LocalDateTime; +import java.time.ZoneId; + +public class LotteryCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!s.hasPermission("command.lottery")) { + s.sendMessage(Lang.NOPERM.toString()); + return true; + } + if (args.length == 0) { + s.sendMessage(Utils.f("&c/lottery sethologram")); + s.sendMessage(Utils.f("&c/lottery start <year> <month> <day> <hour> <minute>")); + s.sendMessage(Utils.f("&c/lottery end")); + s.sendMessage(Utils.f("&c/lottery time")); + s.sendMessage(Utils.f("&c/lottery tickets balance <player>")); + s.sendMessage(Utils.f("&c/lottery tickets give/take <player> <amount>")); + return true; + } + switch (args[0].toLowerCase()) { + case "sethologram": + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + Player player = (Player) s; + Vice.getLottery().setHologramLocation(player.getLocation()); + s.sendMessage(Lang.LOTTERY.f("&7The hologram has been set at your location.")); + return true; + case "start": + if (args.length != 6) { + s.sendMessage(Lang.LOTTERY.f("&7Please specify when the lottery should end in the following format: /lottery start <year> <month> <day> <hour> <minute>")); + return true; + } + int year = Integer.parseInt(args[1]); + int month = Integer.parseInt(args[2]); + int day = Integer.parseInt(args[3]); + int hour = Integer.parseInt(args[4]); + int minute = Integer.parseInt(args[5]); + LocalDateTime end = LocalDateTime.of(year, month, day, hour, minute); + Vice.getLottery().setEnd(end); + return true; + case "end": { + Vice.getLottery().end(); + return true; + } + case "test": { + Lottery.test(); + return true; + } + case "time": { + s.sendMessage(Lang.LOTTERY.f("&7Current time: " + LocalDateTime.now(ZoneId.of("UTC")))); + s.sendMessage(Lang.LOTTERY.f("&7Time of end: " + Vice.getLottery().getEnd())); + s.sendMessage(Lang.LOTTERY.f("&7Time until end: " + Vice.getLottery().timeToEnd())); + return true; + } + case "tickets": { + if (args.length == 1) { + s.sendMessage(Utils.f("&c/lottery tickets balance <player>")); + s.sendMessage(Utils.f("&c/lottery tickets give/take <player> <amount>")); + return true; + } + switch (args[1]) { + case "balance": + return true; + case "give": + return true; + case "take": + return true; + } + return true; + } + default: + s.sendMessage(Utils.f("&c/lottery")); + return true; + } + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/MoneyCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/MoneyCommand.java new file mode 100644 index 0000000..967879b --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/MoneyCommand.java @@ -0,0 +1,228 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Callback; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.users.ViceUser; +import net.grandtheftmc.vice.users.ViceUserDAO; +import net.grandtheftmc.vice.utils.MapUtil; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; + +public class MoneyCommand implements CommandExecutor { + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (args.length == 0) { + s.sendMessage(Utils.f("&c/money balance <player>")); + s.sendMessage(Utils.f("&c/money give <player> <amount>")); + s.sendMessage(Utils.f("&c/money take <player> <amount>")); + s.sendMessage(Utils.f("&c/money top [page] - Shows the baltop for money")); + return true; + } + switch (args[0].toLowerCase()) { + case "balance": { + if (!s.hasPermission("command.money")) { + s.sendMessage(Lang.NOPERM.toString()); + return true; + } + + if (args.length != 2) { + s.sendMessage(Utils.f("&c/money balance <player>")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player == null) { + UUID senderUUID = s instanceof Player ? ((Player) s).getUniqueId() : null; + s.sendMessage(Utils.f("&cThat player isn't online, so please wait while the permits are pulled from the database.")); + new BukkitRunnable() { + @Override + public void run() { + + Optional<Object[]> objs = ViceUserDAO.getMoneyAndName(args[1]); + if (!objs.isPresent()) return; + + String name = (String) objs.get()[0]; + int money = (int) objs.get()[1]; +// try(ResultSet rs = Core.getSQL().query("select name,money from " + Core.name() + " where name='" + args[1] + "';")) { +// if (rs.next()) { +// name = rs.getString("name"); +// money = rs.getInt("money"); +// rs.close(); +// } else { +// rs.close(); +// return; +// } +// } catch (SQLException e) { +// e.printStackTrace(); +// } + String finalName = name; + int finalMoney = money; + new BukkitRunnable() { + @Override + public void run() { + (senderUUID == null ? Bukkit.getConsoleSender() : Bukkit.getPlayer(senderUUID)).sendMessage(Lang.MONEY.f("&a " + finalName + " has $" + finalMoney)); + } + }.runTask(Vice.getInstance()); + } + }.runTaskAsynchronously(Vice.getInstance()); + return true; + } + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + s.sendMessage(Utils.f(Lang.MONEY + "&a" + player.getName() + "&7 has &a$&l" + user.getMoney() + "&7!")); + return true; + } + case "give": { + if (!s.hasPermission("command.money")) { + s.sendMessage(Lang.NOPERM.toString()); + return true; + } + + if (args.length != 3) { + s.sendMessage(Utils.f("&c/money give <player>")); + return true; + } + double amnt; + try { + amnt = Double.parseDouble(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f(Lang.MONEY + "&7The amount must be a number!")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player == null) { + s.sendMessage(Utils.f("&cThat player isn't online, so hold on a second while the money is forcibly updated in the database.")); +// Core.getSQL().updateAsyncLater("update " + Core.name() + " set money=money+" + amnt + " where name='" + args[1] + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.addMoney(args[1], amnt)); + return true; + } + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + user.addMoney(amnt); + ViceUtils.updateBoard(player, Core.getUserManager().getLoadedUser(player.getUniqueId()), user); + s.sendMessage(Utils.f(Lang.MONEY + "&7You gave &a$&l" + amnt + "&7 to &a" + player.getName() + "&7!")); + player.sendMessage( + Utils.f(Lang.MONEY + "&7You were given &a$&l" + amnt + "&7 by &a" + s.getName() + "&7!")); + return true; + } + case "take": { + if (!s.hasPermission("command.money")) { + s.sendMessage(Lang.NOPERM.toString()); + return true; + } + + if (args.length != 3) { + s.sendMessage(Utils.f("&c/money take <player>")); + return true; + } + double amnt; + try { + amnt = Double.parseDouble(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f(Lang.MONEY + "&7The amount must be a number!")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player == null) { + s.sendMessage(Utils.f("&cThat player isn't online, so hold on a second while the money is forcibly updated in the database.")); +// Core.getSQL().updateAsyncLater("update " + Core.name() + " set money=money-" + amnt + " where name='" + args[1] + "';"); + double finalAmnt = amnt; + ServerUtil.runTaskAsync(() -> ViceUserDAO.takeMoney(args[1], finalAmnt)); + return true; + } + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + if (!user.hasMoney(amnt)) + amnt = user.getMoney(); + user.takeMoney(amnt); + ViceUtils.updateBoard(player, Core.getUserManager().getLoadedUser(player.getUniqueId()), user); + s.sendMessage(Utils.f(Lang.MONEY + "&7You took &c$&l" + amnt + "&7 from &a" + player.getName() + "&7!")); + player.sendMessage( + Utils.f(Lang.MONEY + "&c$&l" + amnt + "&7 was taken from you by &a" + s.getName() + "&7!")); + return true; + } + + case "top": + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + + UUID uuid = ((Player) s).getUniqueId(); + new BukkitRunnable() { + @Override public void run() { + getTopBalance(10, results -> new BukkitRunnable() { + @Override + public void run() { + Player player = Bukkit.getPlayer(uuid); + if (player == null) return; + player.sendMessage( Lang.MONEY.f("&7Money Top:")); + + int i = 0; + for (String key : results.keySet()) { + i++; + player.sendMessage(Utils.f("&a#&l" + (i) + "&7: &r" + key + "&7 &a" + Utils.formatMoney(results.get(key)))); + } + } + }.runTask(Vice.getInstance())); + } + }.runTaskAsynchronously(Vice.getInstance()); + return true; + default: + if (s.hasPermission("command.money")) { + s.sendMessage(Utils.f("&c/money balance <player>")); + s.sendMessage(Utils.f("&c/money give <player> <amount>")); + s.sendMessage(Utils.f("&c/money take <player> <amount>")); + } + s.sendMessage(Utils.f("&c/money top - Shows the baltop for money")); + return true; + } + + } + + private void getTopBalance(int amount, Callback<LinkedHashMap<String, Double>> callback) { + LinkedHashMap<String, Double> results = new LinkedHashMap<>(); + + Optional<Object[][]> optional = ViceUserDAO.getBalanceTop(amount); + if(!optional.isPresent()) return; + + for(int i = 0; i < optional.get().length; i++) { + results.put((String)optional.get()[i][0], (double)optional.get()[i][1]); + } + + callback.call(results); + +// PreparedStatement statement = null; +// try { +// final String query = "SELECT `money`,`name` FROM `" + Core.name() + "` ORDER BY cast(`money` as double) DESC LIMIT " + amount + ";"; +// statement = Core.sql.prepareStatement(query); +// ResultSet set = statement.executeQuery(); +// while(set.next()) { +// results.put(set.getString("name"), set.getDouble("money")); +// } +// +// callback.call(results); +// } +// catch (SQLException e) { +// e.printStackTrace(); +// } +// finally { +// try { +// if(statement != null) +// statement.close(); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/NearCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/NearCommand.java new file mode 100644 index 0000000..3efd747 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/NearCommand.java @@ -0,0 +1,54 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.vice.ViceUtils; +import org.apache.commons.lang.StringUtils; +import org.bukkit.GameMode; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class NearCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.VICE.f("&cYou are not a player!")); + return true; + } + Player player = (Player)s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (!user.isRank(UserRank.VIP)) { + player.sendMessage(Lang.VICE.f("&7You must be &6&lVIP+ &7to use this command!")); + return true; + } + Map<String, Integer> nearbySet = new HashMap<>(); + int range = ViceUtils.getNearRange(user.getUserRank()); + for(Entity entity : player.getNearbyEntities(range, range, range)) { + if(entity.getType() != EntityType.PLAYER) continue; + Player target = (Player)entity; + if(target.getGameMode() != GameMode.ADVENTURE && target.getGameMode() != GameMode.SURVIVAL) continue; + int distance = (int)player.getLocation().distance(target.getLocation()); + nearbySet.put(target.getDisplayName(), distance); + } + List<String> nearbyFormatted = nearbySet.keySet().stream().map(set -> set + " &f(&c" + nearbySet.get(set) + "b&f)").collect(Collectors.toList()); + if(nearbyFormatted.isEmpty()) { + player.sendMessage(Lang.VICE.f("&7No nearby players found.")); + } else { + String message = StringUtils.join(nearbyFormatted, ", "); + player.sendMessage(Lang.VICE.f("&7Players nearby:" + message)); + } + return true; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/PayCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/PayCommand.java new file mode 100644 index 0000000..f46155b --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/PayCommand.java @@ -0,0 +1,68 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.users.ViceUser; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class PayCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.toString()); + return true; + } + if (args.length != 2) { + s.sendMessage(Utils.f("&c/pay <player> <amount>")); + return true; + } + Player player = (Player) s; + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + double amnt; + try { + amnt = Utils.round(Double.parseDouble(args[1])); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f(Lang.MONEY + "&7The amount must be a number!")); + return true; + } + if (amnt <= 0) { + s.sendMessage(Lang.MONEY.f("&7The amount must be greater than 0!")); + return true; + } + if (!user.hasMoney(amnt)) { + s.sendMessage(Utils.f(Lang.MONEY + "&7You don't have &c$&l" + amnt + "&7!")); + return true; + } + if (amnt % 1 != 0) { + s.sendMessage(Utils.f(Lang.MONEY + "&7Whole numbers only! No pennies.")); + return true; + } + Player target = Bukkit.getPlayer(args[0]); + if (target == null) { + s.sendMessage(Utils.f(Lang.MONEY + "&7That player is not online!")); + return true; + } + ViceUser targetUser = Vice.getUserManager().getLoadedUser(target.getUniqueId()); + User u = Core.getUserManager().getLoadedUser(player.getUniqueId()); + User tu = Core.getUserManager().getLoadedUser(target.getUniqueId()); + user.takeMoney(amnt); + targetUser.addMoney(amnt); + ViceUtils.updateBoard(player, u, user); + ViceUtils.updateBoard(target, tu, targetUser); + player.sendMessage(Utils.f(Lang.MONEY + "&7You sent &a$&l" + amnt + "&7 to " + tu.getColoredName(target) + "&7!")); + target.sendMessage(Utils.f(Lang.MONEY + "&7You received &a$&l" + amnt + "&7 from " + u.getColoredName(player) + "&7!")); + if (amnt > 100000) + ViceUtils.moneylog(player, target, amnt); + return true; + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/PrestigeCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/PrestigeCommand.java new file mode 100644 index 0000000..96838c1 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/PrestigeCommand.java @@ -0,0 +1,24 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.commands.CoreCommand; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +/** + * Created by Timothy Lampen on 2017-08-11. + */ +public class PrestigeCommand extends CoreCommand<Player> { + public PrestigeCommand() { + super("prestige", "gives rewards to players for continuing after regular ranks."); + } + + @Override + public void execute(Player player, String[] args) { + if(args.length==0){ + player.sendMessage(ChatColor.GRAY + "/prestige confirm " + ChatColor.YELLOW + " - prestige's your player account"); + player.sendMessage(ChatColor.GRAY + "/prestige list " + ChatColor.YELLOW + " - lists all prestige tiers avaliable and costs"); + player.sendMessage(""); + return; + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/RTPCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/RTPCommand.java new file mode 100644 index 0000000..ccbad14 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/RTPCommand.java @@ -0,0 +1,70 @@ +package net.grandtheftmc.vice.commands; + +import com.massivecraft.factions.Board; +import com.massivecraft.factions.FLocation; +import com.massivecraft.factions.Faction; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.TaxiTarget; +import net.grandtheftmc.vice.users.ViceUser; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Biome; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.concurrent.ThreadLocalRandom; + +public class RTPCommand implements CommandExecutor { + + + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + Player player = (Player) s; + ViceUser viceUser = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + if (!viceUser.canRTP()) { + player.sendMessage(Lang.TAXI.f("&7Please wait &a&l" + Utils.timeInMillisToText(viceUser.getTimeUntilRTP()) + "&7 before using this command!")); + return true; + } + World world = Bukkit.getWorld("world"); + boolean unfit = true; + int tries = 0; + Location loc = new Location(world, 0, 0, 0); + while (unfit) { + if (tries > 100) { + player.sendMessage(Lang.TAXI.f("&7Could not find suitable location to teleport you to. Please try again.")); + return true; + } + loc = new Location(world, + ThreadLocalRandom.current().nextInt(5000), + 0, + ThreadLocalRandom.current().nextInt(5000)); + loc.setY(world.getHighestBlockYAt(loc)); + Faction factionAt = Board.getInstance().getFactionAt(new FLocation(loc)); + Biome biome = world.getBiome(loc.getBlockX(), loc.getBlockZ()); + Material material = loc.getWorld().getHighestBlockAt(loc).getType(); + unfit = !factionAt.isWilderness() + || biome == Biome.OCEAN || biome == Biome.DEEP_OCEAN + || biome == Biome.FROZEN_OCEAN || biome == Biome.SKY + || biome == Biome.VOID || biome == Biome.RIVER || material == Material.WATER || material == Material.STATIONARY_WATER || material == Material.LAVA || material == Material.STATIONARY_LAVA || material == Material.CACTUS; + tries += 1; + } + loc.setY(loc.getY() + 0.5); + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + viceUser.setLastRTP(); + Vice.getWorldManager().getWarpManager().warp(player, user, viceUser, new TaxiTarget(loc), 0, -1, + "&eYou called a taxi to take you to &a" + loc.getBlockX() + "&e, &a" + loc.getBlockY() + "&e, &a" + loc.getBlockZ() + "&e in the wilderness.."); + return true; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/RankupCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/RankupCommand.java new file mode 100644 index 0000000..7eb9ba8 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/RankupCommand.java @@ -0,0 +1,49 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.ViceRank; +import net.grandtheftmc.vice.users.ViceUser; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class RankupCommand implements CommandExecutor { + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.toString()); + return true; + } + Player player = (Player) s; + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + User u = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (user.isArrested()) { + player.sendMessage(Lang.JAIL.f("&7You can't rank up in jail!")); + return true; + } + if (args.length == 1 && "confirm".equalsIgnoreCase(args[0])) { + user.rankup(player, u); + return true; + } + ViceRank nextRank = user.getRank().getNext(); + if (nextRank == null) { + player.sendMessage(Utils.f(Lang.RANKUP + "&7You can't rank up any more!")); + return true; + } + int price = nextRank.getPrice(); + + if (!user.hasMoney(price)) { + player.sendMessage(Utils.f(Lang.RANKUP + "&7You don't have the &c$&l" + price + "&7 required to rank up!")); + return true; + } + player.sendMessage(Utils.f(Lang.RANKUP + "&7Ranking up to " + nextRank.getColoredNameBold() + "&7 costs &a$&l" + price + "&7.")); + player.sendMessage(Utils.f(Lang.RANKUP + "&7Type &a/rankup confirm&7 to rank up!")); + return true; + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/ResetCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/ResetCommand.java new file mode 100644 index 0000000..54aac4e --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/ResetCommand.java @@ -0,0 +1,321 @@ +package net.grandtheftmc.vice.commands; + +import com.j0ach1mmall3.wastedvehicles.api.VehicleProperties; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.database.dao.VoteDAO; +import net.grandtheftmc.core.users.UserDAO; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.items.AmmoType; +import net.grandtheftmc.vice.users.ViceRank; +import net.grandtheftmc.vice.users.ViceUserDAO; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.io.File; +import java.util.UUID; + +public class ResetCommand implements CommandExecutor { + + + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (!s.isOp()) { + s.sendMessage(Lang.NOPERM.s()); + return true; + } + + if (args.length < 2) { + s.sendMessage(Utils.f("&c/reset&7 <target> <category/all>")); + s.sendMessage(Utils.f("&7Categories: tokens, bucks, votes, dailyStreak," + + " lastDonorReward, cosmetics, rank (ViceRank), money, bonds," + + " backpack, kitExpiries, jail, ammo, vehicles, inventory (includes echest)")); + return true; + } + + if (args.length > 2) return true; + + String name = args[0]; + Player target = Bukkit.getPlayer(name); + UUID uuid = null; + if (target != null) { + name = target.getName(); + uuid = target.getUniqueId(); + target.kickPlayer("You are being reset by an admin."); + } + + String finalName = name; + UUID finalUniqueId = uuid; + + if ("all".equalsIgnoreCase(args[1])) { + ServerUtil.runTaskAsync(() -> { + if (finalUniqueId == null) { + UUID value = UserDAO.getUuidByName(finalName); + if (value != null) { + File file = new File(Bukkit.getWorldContainer() + "/" + Bukkit.getWorlds().get(0).getName() + "/playerdata/" + value.toString()); + if (file.exists()) file.delete(); + } + } + else { + File file = new File(Bukkit.getWorldContainer() + "/" + Bukkit.getWorlds().get(0).getName() + "/playerdata/" + finalUniqueId.toString()); + if (file.exists()) file.delete(); + } + +// Core.sql.updateAsyncLater("update users set tokens=0, bucks=0, votes=0, voteStreak=0, lastVoteStreak=0, dailyStreak=0, lastDailyReward=0, lastDonorReward=0 where lastname='" + name + "';"); + UserDAO.reset(finalName); + +// Core.sql.updateAsyncLater("delete from cosmetics where name='" + finalName + "';"); + UserDAO.deleteFromByName(finalName, "cosmetics"); + +// Core.sql.updateAsyncLater("delete from " + Core.name() + " where name='" + finalName + "';"); + UserDAO.deleteFromByName(finalName, Core.name()); + +// Core.sql.updateAsyncLater("update " + Core.name() + " set backpackContents=NULL where name='" + finalName + "';"); + ViceUserDAO.setBackpackContents(finalName, null); + + ServerUtil.runTask(() -> s.sendMessage(Utils.f("&7You fully reset player &a" + finalName + "&7!"))); + }); + +// if (finalName == null) { +// new BukkitRunnable() { +// @Override +// public void run() { +// ResultSet rs = Core.sql.query("select uuid from users where lastname='" + finalName + "';"); +// UUID uuid = null; +// try { +// if (rs.next()) { +// uuid = UUID.fromString(rs.getString("uuid")); +// rs.close(); +// return; +// } +// rs.close(); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// UUID uuid = UserDAO.getUuidByName(finalName); +// if (uuid != null) { +// File file = new File(Bukkit.getWorldContainer() + "/" + Bukkit.getWorlds().get(0).getName() + "/playerdata/" + uuid); +// if (file.exists()) file.delete(); +// } +// } +// }.runTaskAsynchronously(Vice.getInstance()); +// } else { +// File file = new File(Bukkit.getWorldContainer() + "/" + Bukkit.getWorlds().get(0).getName() + "/playerdata/" + uuid); +// if (file.exists()) file.delete(); +// } +// Core.sql.updateAsyncLater("update users set tokens=0, bucks=0, votes=0, voteStreak=0, lastVoteStreak=0, dailyStreak=0, lastDailyReward=0, lastDonorReward=0 where lastname='" + name + "';"); +// Core.sql.updateAsyncLater("delete from cosmetics where name='" + name + "';"); +// Core.sql.updateAsyncLater("delete from " + Core.name() + " where name='" + name + "';"); +// Core.sql.updateAsyncLater("update " + Core.name() + " set backpackContents=NULL where name='" + name + "';"); +// s.sendMessage(Utils.f("&7You fully reset player &a" + name + "&7!")); + return true; + } + + switch (args[1].toLowerCase()) { + case "inventory": + ServerUtil.runTaskAsync(() -> { + if (finalUniqueId == null) { + UUID value = UserDAO.getUuidByName(finalName); + if (value != null) { + File file = new File(Bukkit.getWorldContainer() + "/" + Bukkit.getWorlds().get(0).getName() + "/playerdata/" + value.toString()); + if (file.exists()) file.delete(); + } + } + else { + File file = new File(Bukkit.getWorldContainer() + "/" + Bukkit.getWorlds().get(0).getName() + "/playerdata/" + finalUniqueId.toString()); + if (file.exists()) file.delete(); + } + + ServerUtil.runTask(() -> s.sendMessage(Utils.f("&7You reset player &a" + finalName + "&7 for category &a" + args[1] + "&7!"))); + }); + +// if (uuid == null) { +// new BukkitRunnable() { +// @Override +// public void run() { +// ResultSet rs = Core.sql.query("select uuid from users where lastname='" + finalName + "';"); +// UUID uuid = null; +// try { +// if (rs.next()) { +// uuid = UUID.fromString(rs.getString("uuid")); +// rs.close(); +// return; +// } +// rs.close(); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// File file = new File(Bukkit.getWorldContainer() + "/" + Bukkit.getWorlds().get(0).getName() + "/playerdata/" + uuid); +// if (file.exists()) file.delete(); +// } +// }.runTaskAsynchronously(Vice.getInstance()); +// } else { +// UUID finalUuid = uuid; +// new BukkitRunnable() { +// @Override +// public void run() { +// File file = new File(Bukkit.getWorldContainer() + "/" + Bukkit.getWorlds().get(0).getName() + "/playerdata/" + finalUuid); +// if (file.exists()) file.delete(); +// } +// }.runTaskAsynchronously(Vice.getInstance()); +// } +// s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + + case "tokens": +// Core.sql.updateAsyncLater("update users set tokens=0 where lastname='" + name + "';"); + ServerUtil.runTaskAsync(() -> UserDAO.updateUserTokensByName(finalName, 0)); + s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + + case "bucks": +// Core.sql.updateAsyncLater("update users set bucks=0 where lastname='" + name + "';"); + ServerUtil.runTaskAsync(() -> UserDAO.updateUserBucksByName(finalName, 0)); + s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + + case "votes": +// Core.sql.updateAsyncLater("update users set votes=0, voteStreak=0, lastVoteStreak=0 where lastname='" + name + "';"); + ServerUtil.runTaskAsync(() -> { + VoteDAO.updateVoteStreakByName(finalName, 0); + VoteDAO.updateUserVotesByName(finalName, 0); + VoteDAO.updateUserLastVoteStreakByName(finalName, 0); + + ServerUtil.runTask(() -> s.sendMessage(Utils.f("&7You reset player &a" + finalName + "&7 for category &a" + args[1] + "&7!"))); + }); + return true; + + case "dailystreak": +// Core.sql.updateAsyncLater("update users set dailyStreak=0, lastDailyReward=0 where lastname='" + name + "';"); + ServerUtil.runTaskAsync(() -> { + VoteDAO.updateUserDailyStreakByName(finalName, 0); + VoteDAO.updateUserLastDailyRewardByName(finalName, 0); + + ServerUtil.runTask(() -> s.sendMessage(Utils.f("&7You reset player &a" + finalName + "&7 for category &a" + args[1] + "&7!"))); + }); +// s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + + case "lastdonorreward": +// Core.sql.updateAsyncLater("update users set lastDonorReward=0 where lastname='" + name + "';"); + ServerUtil.runTaskAsync(() -> { + UserDAO.updateUserLastDonorRewardByName(finalName, 0); + + ServerUtil.runTask(() -> s.sendMessage(Utils.f("&7You reset player &a" + finalName + "&7 for category &a" + args[1] + "&7!"))); + }); +// s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + + case "cosmetics": +// Core.sql.updateAsyncLater("delete from cosmetics where name='" + name + "';"); + ServerUtil.runTaskAsync(() -> { + UserDAO.deleteFromByName(finalName, "cosmetic"); + + ServerUtil.runTask(() -> s.sendMessage(Utils.f("&7You reset player &a" + finalName + "&7 for category &a" + args[1] + "&7!"))); + }); +// s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + + case "rank": +// Core.sql.updateAsyncLater("update " + Core.name() + " set rank='JUNKIE' where name='" + name + "';"); + ServerUtil.runTaskAsync(() -> { + ViceUserDAO.setRank(finalName, ViceRank.JUNKIE); + + ServerUtil.runTask(() -> s.sendMessage(Utils.f("&7You reset player &a" + finalName + "&7 for category &a" + args[1] + "&7!"))); + }); +// s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + + case "money": +// Core.sql.updateAsyncLater("update " + Core.name() + " set money=0 where name='" + name + "';"); + ServerUtil.runTaskAsync(() -> { + ViceUserDAO.setMoney(finalName, 0); + + ServerUtil.runTask(() -> s.sendMessage(Utils.f("&7You reset player &a" + finalName + "&7 for category &a" + args[1] + "&7!"))); + }); +// s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + + case "bonds": +// Core.sql.updateAsyncLater("update " + Core.name() + " set bonds=0 where name='" + name + "';"); + ServerUtil.runTaskAsync(() -> { + ViceUserDAO.setBonds(finalName, 0); + + ServerUtil.runTask(() -> s.sendMessage(Utils.f("&7You reset player &a" + finalName + "&7 for category &a" + args[1] + "&7!"))); + }); +// s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + + case "backpack": +// Core.sql.updateAsyncLater("update " + Core.name() + " set backpackContents=NULL where name='" + name + "';"); + ServerUtil.runTaskAsync(() -> { + ViceUserDAO.setBackpackContents(finalName, null); + + ServerUtil.runTask(() -> s.sendMessage(Utils.f("&7You reset player &a" + finalName + "&7 for category &a" + args[1] + "&7!"))); + }); +// s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + + case "kitexpiries": +// Core.sql.updateAsyncLater("update " + Core.name() + " set kitExpiries=null where name='" + name + "';"); + ServerUtil.runTaskAsync(() -> { + ViceUserDAO.updateKitExpiries(finalName, null); + + ServerUtil.runTask(() -> s.sendMessage(Utils.f("&7You reset player &a" + finalName + "&7 for category &a" + args[1] + "&7!"))); + }); +// s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + + case "jail": +// Core.sql.updateAsyncLater("update " + Core.name() + " set jailTimer=-1, jailCop=NULL, jailCopName=NULL where name='" + name + "';"); + ServerUtil.runTaskAsync(() -> { + ViceUserDAO.resetJail(finalName); + ServerUtil.runTask(() -> s.sendMessage(Utils.f("&7You reset player &a" + finalName + "&7 for category &a" + args[1] + "&7!"))); + }); +// s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + + case "ammo": { + String[] st = {""}; + for (AmmoType type : AmmoType.values()) + st[0] += type.getGameItemName() + "=0, "; + + if (st[0].endsWith(", ")) + st[0] = st[0].substring(0, st[0].length() - 2); + +// Core.sql.updateAsyncLater("update " + Core.name() + " set " + st + " where name='" + name + "';"); + ServerUtil.runTaskAsync(() -> { + ViceUserDAO.resetAllAmmo(finalName, st[0]); + ServerUtil.runTask(() -> s.sendMessage(Utils.f("&7You reset player &a" + finalName + "&7 for category &a" + args[1] + "&7!"))); + }); +// s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + } + + case "vehicles": + String[] st = {"personalVehicle=NULL, "}; + for (VehicleProperties v : Vice.getWastedVehicles().getBabies().getVehicleProperties()) + st[0] += '`' + v.getIdentifier().toLowerCase() + "`=0, `" + v.getIdentifier().toLowerCase() + ":info`=NULL, "; + +// Core.sql.updateAsyncLater("update " + Core.name() + " set " + st + " where name='" + name + "';"); + ServerUtil.runTaskAsync(() -> { + ViceUserDAO.resetAllVehicles(finalName, st[0]); + ServerUtil.runTask(() -> s.sendMessage(Utils.f("&7You reset player &a" + finalName + "&7 for category &a" + args[1] + "&7!"))); + }); +// s.sendMessage(Utils.f("&7You reset player &a" + name + "&7 for category &a" + args[1] + "&7!")); + return true; + + default: + s.sendMessage(Utils.f("&c/reset&7 <target> <category/all>")); + s.sendMessage(Utils.f("&7Categories: tokens, bucks, votes, dailyStreak," + + " lastDonorReward, rank (ViceRank), money, bonds, backpack, kitExpiries, jail, ammo, vehicles")); + return true; + } + + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/ResetStatsCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/ResetStatsCommand.java new file mode 100644 index 0000000..80f2b1d --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/ResetStatsCommand.java @@ -0,0 +1,33 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Lang; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; + +/** + * Created by Timothy Lampen on 2017-08-10. + */ +public class ResetStatsCommand implements CommandExecutor{ + @Override + public boolean onCommand(CommandSender sender, Command cmd, String s, String[] args) { + if(!sender.hasPermission("command.resetstats")) return false; + if(args.length==1) { + Player player = Bukkit.getPlayer(args[0]); + if (player == null){ + sender.sendMessage(Lang.VICE.f("&7That player is not online!")); + return false; + } + sender.sendMessage(Lang.VICE.f("&7You have reset the stats of &b" + player.getName() + "&7!")); + player.sendMessage(Lang.VICE.f("&7Your stats have been reset by &b" + sender.getName() + "&b!")); + player.setMaxHealth(20); + for(PotionEffect e : player.getActivePotionEffects()){ + player.removePotionEffect(e.getType()); + } + } + return true; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/ResourcePackCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/ResourcePackCommand.java new file mode 100644 index 0000000..7087af2 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/ResourcePackCommand.java @@ -0,0 +1,48 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.resourcepack.ResourcePack; +import net.grandtheftmc.core.util.NMSVersion; +import net.grandtheftmc.vice.Vice; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import us.myles.ViaVersion.api.Via; + +public class ResourcePackCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.VICE.f("&cYou are not a player!")); + return true; + } + Player player = (Player) s; +// int version = Via.getAPI().getPlayerVersion(player.getUniqueId()); +// String url; +// if (version >= 315) { +// player.setResourcePack(Vice.getSettings().getOneElevenRespack()); +// url = Vice.getSettings().getOneElevenRespack(); +// } else { +// player.setResourcePack(Vice.getSettings().getOneTenRespack()); +// url = Vice.getSettings().getOneTenRespack(); +// } +// player.sendMessage(Lang.VICE.f("&cYou can download the server resource pack here: &b" + url)); + + NMSVersion version = NMSVersion.getVersion(player); + if(version== NMSVersion.MC_1_8) { + player.sendMessage(Lang.GTM.f("&4Your client version is not supported! Please use 1.9+")); + return false; + } + ResourcePack pack = Vice.getResourcePackManager().getResourcePack(version); + if(pack != null) { +// player.setResourcePack(pack.getPack(), pack.getHash().getBytes()); Correct hash? + player.setResourcePack(pack.getPack()); + } + else { + player.setResourcePack(Vice.getResourcePackManager().getResourcePack(NMSVersion.MC_1_11).getPack()); + } + return true; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/SellCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/SellCommand.java new file mode 100644 index 0000000..8aa818f --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/SellCommand.java @@ -0,0 +1,38 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.commands.CoreCommand; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.State; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.CheatCode; +import net.grandtheftmc.vice.users.ViceUser; +import org.bukkit.entity.Player; + +public class SellCommand extends CoreCommand<Player> { + + public SellCommand() { + super("sell", "Quick sell, open a virtual trashcan", "qsell", "quicksell"); + } + + @Override + public void execute(Player sender, String[] strings) { + sender.closeInventory(); + User user = Core.getUserManager().getLoadedUser(sender.getUniqueId()); + ViceUser viceUser = Vice.getUserManager().getLoadedUser(sender.getUniqueId()); + if (viceUser.getCheatCodeState(CheatCode.QUICKSELL).getState() == State.LOCKED && !user.getUserRank().hasRank(UserRank.ELITE)) { + sender.sendMessage(Utils.f("&cThis command requires the &7QuickSell Cheatcode&c or &e&lELITE&c!")); + return; + } + + if (viceUser.isInCombat()) { + sender.sendMessage(C.RED + "You cannot sell items while in combat!"); + return; + } + + sender.sendMessage(C.RED + "You can only use this cheatcode in your House or at spawn."); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/SkinCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/SkinCommand.java new file mode 100644 index 0000000..a266c80 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/SkinCommand.java @@ -0,0 +1,206 @@ +package net.grandtheftmc.vice.commands; + +import java.util.Optional; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.commands.CoreCommand; +import net.grandtheftmc.core.commands.RankedCommand; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.guns.weapon.Weapon; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.ViceUser; + +public class SkinCommand extends CoreCommand<Player> implements RankedCommand { + public SkinCommand() { + super("skin", "A command used to manage weapon skins."); + } + + @Override + public void execute(Player sender, String[] args) { + User user = Core.getUserManager().getLoadedUser(sender.getUniqueId()); + ViceUser ViceUser = Vice.getUserManager().getLoadedUser(sender.getUniqueId()); + + if (user.isAdmin()) { + if (args.length == 3) { + if (args[0].equalsIgnoreCase("unlock")) { + Optional<Weapon<?>> weaponOpt = null; + + try { + short weaponID = Short.parseShort(args[1]); + + weaponOpt = Vice.getWastedGuns().getWeaponManager().getWeapon(weaponID); + } catch (NumberFormatException e) { + String weaponName = args[1]; + + weaponOpt = Vice.getWastedGuns().getWeaponManager().getWeapon(weaponName); + } + + if (weaponOpt.isPresent()) { + Weapon<?> weapon = weaponOpt.get(); + + try { + short skinID = Short.parseShort(args[2]); + WeaponSkin skin = weapon.getWeaponSkins().length > skinID ? weapon.getWeaponSkins()[skinID] : null; + + if (skin != null) { + if (ViceUser.getRawUnlockedWeaponSkins().get(weapon.getUniqueIdentifier()) == null + || !ViceUser.getRawUnlockedWeaponSkins().get(weapon.getUniqueIdentifier()).contains((short) (skin.getIdentifier() - weapon.getWeaponIdentifier()))) { + ViceUser.unlockWeaponSkin(weapon, skin); + + sender.sendMessage(Utils.f("&7You unlocked this skin!")); + } else { + sender.sendMessage(Utils.f("&cThis skin has already been unlocked!")); + } + } else { + sender.sendMessage(Utils.f("&cA skin with this ID does not exist!")); + } + } catch (NumberFormatException e) { + sender.sendMessage(Utils.f("&cThe skin ID has to be a number!")); + } + } else { + sender.sendMessage(Utils.f("&cA weapon with this name/ID does not exist!")); + } + } else if (args[0].equalsIgnoreCase("lock")) { + Optional<Weapon<?>> weaponOpt = null; + + try { + short weaponID = Short.parseShort(args[1]); + + weaponOpt = Vice.getWastedGuns().getWeaponManager().getWeapon(weaponID); + } catch (NumberFormatException e) { + String weaponName = args[1]; + + weaponOpt = Vice.getWastedGuns().getWeaponManager().getWeapon(weaponName); + } + + if (weaponOpt.isPresent()) { + Weapon<?> weapon = weaponOpt.get(); + + try { + short skinID = Short.parseShort(args[2]); + WeaponSkin skin = weapon.getWeaponSkins().length > skinID ? weapon.getWeaponSkins()[skinID] : null; + + if (skin != null) { + if (ViceUser.getRawUnlockedWeaponSkins().get(weapon.getUniqueIdentifier()) != null + && ViceUser.getRawUnlockedWeaponSkins().get(weapon.getUniqueIdentifier()).contains((short) (skin.getIdentifier() - weapon.getWeaponIdentifier()))) { + ViceUser.lockWeaponSkin(weapon, skin); + + sender.sendMessage(Utils.f("&7You locked this skin!")); + } else { + sender.sendMessage(Utils.f("&cThis skin has already been locked!")); + } + } else { + sender.sendMessage(Utils.f("&cA skin with this ID does not exist!")); + } + } catch (NumberFormatException e) { + sender.sendMessage(Utils.f("&cThe skin ID has to be a number!")); + } + } else { + sender.sendMessage(Utils.f("&cA weapon with this name/ID does not exist!")); + } + } + } else if (args.length == 4) { + if (args[0].equalsIgnoreCase("unlock")) { + Player otherPlayer = Bukkit.getPlayer(args[1]); + + if (otherPlayer != null && otherPlayer.isOnline()) { + ViceUser otherViceUser = Vice.getUserManager().getLoadedUser(otherPlayer.getUniqueId()); + Optional<Weapon<?>> weaponOpt = null; + + try { + short weaponID = Short.parseShort(args[2]); + + weaponOpt = Vice.getWastedGuns().getWeaponManager().getWeapon(weaponID); + } catch (NumberFormatException e) { + String weaponName = args[2]; + + weaponOpt = Vice.getWastedGuns().getWeaponManager().getWeapon(weaponName); + } + + if (weaponOpt.isPresent()) { + Weapon<?> weapon = weaponOpt.get(); + + try { + short skinID = Short.parseShort(args[3]); + WeaponSkin skin = weapon.getWeaponSkins().length > skinID ? weapon.getWeaponSkins()[skinID] : null; + + if (skin != null) { + if (otherViceUser.getRawUnlockedWeaponSkins().get(weapon.getUniqueIdentifier()) == null + || !otherViceUser.getRawUnlockedWeaponSkins().get(weapon.getUniqueIdentifier()).contains((short) (skin.getIdentifier() - weapon.getWeaponIdentifier()))) { + otherViceUser.unlockWeaponSkin(weapon, skin); + + sender.sendMessage(Utils.f("&7You unlocked this skin for &a" + otherPlayer.getName() + "!")); + } else { + sender.sendMessage(Utils.f("&a" + otherPlayer.getName() + " already has this skin unlocked!")); + } + } else { + sender.sendMessage(Utils.f("&cA skin with this ID does not exist!")); + } + } catch (NumberFormatException e) { + sender.sendMessage(Utils.f("&cThe skin ID has to be a number!")); + } + } else { + sender.sendMessage(Utils.f("&cA weapon with this name/ID does not exist!")); + } + } + } else if (args[0].equalsIgnoreCase("lock")) { + Player otherPlayer = Bukkit.getPlayer(args[1]); + + if (otherPlayer != null && otherPlayer.isOnline()) { + ViceUser otherViceUser = Vice.getUserManager().getLoadedUser(otherPlayer.getUniqueId()); + Optional<Weapon<?>> weaponOpt = null; + + try { + short weaponID = Short.parseShort(args[2]); + + weaponOpt = Vice.getWastedGuns().getWeaponManager().getWeapon(weaponID); + } catch (NumberFormatException e) { + String weaponName = args[2]; + + weaponOpt = Vice.getWastedGuns().getWeaponManager().getWeapon(weaponName); + } + + if (weaponOpt.isPresent()) { + Weapon<?> weapon = weaponOpt.get(); + + try { + short skinID = Short.parseShort(args[3]); + WeaponSkin skin = weapon.getWeaponSkins().length > skinID ? weapon.getWeaponSkins()[skinID] : null; + + if (skin != null) { + if (otherViceUser.getRawUnlockedWeaponSkins().get(weapon.getUniqueIdentifier()) != null + && otherViceUser.getRawUnlockedWeaponSkins().get(weapon.getUniqueIdentifier()).contains((short) (skin.getIdentifier() - weapon.getWeaponIdentifier()))) { + otherViceUser.lockWeaponSkin(weapon, skin); + + sender.sendMessage(Utils.f("&7You locked this skin for &a" + otherPlayer.getName() + "!")); + } else { + sender.sendMessage(Utils.f("&a" + otherPlayer.getName() + " already has this skin locked!")); + } + } else { + sender.sendMessage(Utils.f("&cA skin with this ID does not exist!")); + } + } catch (NumberFormatException e) { + sender.sendMessage(Utils.f("&cThe skin ID has to be a number!")); + } + } else { + sender.sendMessage(Utils.f("&cA weapon with this name/ID does not exist!")); + } + } + } + } + } else { + sender.sendMessage(Utils.f("&cYou do not have permission to execute this command!")); + } + } + + @Override + public UserRank requiredRank() { + return UserRank.DEFAULT; + } +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/SkinsCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/SkinsCommand.java new file mode 100644 index 0000000..b0efc69 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/SkinsCommand.java @@ -0,0 +1,26 @@ +package net.grandtheftmc.vice.commands; + +import org.bukkit.entity.Player; + +import net.grandtheftmc.core.commands.CoreCommand; +import net.grandtheftmc.core.commands.RankedCommand; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.vice.weapon.skins.menu.MainMenu; + +public class SkinsCommand extends CoreCommand<Player> implements RankedCommand { + public SkinsCommand() { + super("skins", "View or equip your weapon skins."); + } + + @Override + public void execute(Player sender, String[] args) { + if (args.length == 0) { + new MainMenu(sender).open(); + } + } + + @Override + public UserRank requiredRank() { + return UserRank.DEFAULT; + } +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/SpawnCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/SpawnCommand.java new file mode 100644 index 0000000..fabd2cc --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/SpawnCommand.java @@ -0,0 +1,54 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.TaxiTarget; +import net.grandtheftmc.vice.world.warps.WarpManager; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class SpawnCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + WarpManager wm = Vice.getWorldManager().getWarpManager(); + Player player = (Player) s; + if (args.length == 0) { + wm.warp(player, Core.getUserManager().getLoadedUser(player.getUniqueId()), + Vice.getUserManager().getLoadedUser(player.getUniqueId()), new TaxiTarget(wm.getSpawn()), 0, -1); + + return true; + } + if (!s.hasPermission("warps.admin")) { + s.sendMessage(Lang.NOPERM.s()); + return true; + } + switch (args[0].toLowerCase()) { + case "setspawn": + wm.setSpawn(player.getLocation()); + s.sendMessage(Utils.f("&aYou set the spawn!")); + return true; + case "settutorialspawn": + wm.setTutorialSpawn(player.getLocation()); + s.sendMessage(Utils.f("&aYou set the tutorial spawn!")); + return true; + case "setjail": + wm.setJail(player.getLocation()); + s.sendMessage(Utils.f("&aYou set the jail spawn!")); + return true; + default: + s.sendMessage(Utils.f("&c/spawn")); + s.sendMessage(Utils.f("&c/spawn setspawn")); + s.sendMessage(Utils.f("&c/spawn settutorialspawn")); + return true; + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/SpectatorCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/SpectatorCommand.java new file mode 100644 index 0000000..a6e0b70 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/SpectatorCommand.java @@ -0,0 +1,64 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerTeleportEvent; + +import java.util.ArrayList; +import java.util.List; + +public class SpectatorCommand implements CommandExecutor { + private static final List<String> ACTIVE_STAFF = new ArrayList<>(); + + public static List<String> getActiveStaff() { + return ACTIVE_STAFF; + } + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + Player sender = (Player) s; + User coreSender = Core.getUserManager().getLoadedUser(sender.getUniqueId()); + if (!coreSender.isRank(UserRank.ADMIN)) { + sender.sendMessage(Lang.VICE.f("&7Permission denied!")); + return true; + } + if (ACTIVE_STAFF.contains(sender.getName())) { + ACTIVE_STAFF.remove(sender.getName()); + sender.sendMessage(Lang.VICE.f("&bSpectator Mode disabled!")); + sender.setGameMode(GameMode.SURVIVAL); + sender.teleport(Bukkit.getWorld("spawn").getSpawnLocation(), PlayerTeleportEvent.TeleportCause.COMMAND); + sender.setFlySpeed(0.1F); + } else { + ACTIVE_STAFF.add(sender.getName()); + sender.sendMessage(Lang.VICE.f("&bSpectator Mode enabled!")); + sender.teleport(this.getMapLocation(), PlayerTeleportEvent.TeleportCause.COMMAND); + sender.setGameMode(GameMode.SPECTATOR); + } + return true; + } + + private Location getMapLocation() { + Location loc = Bukkit.getWorlds().get(0).getSpawnLocation(); + if (Bukkit.getWorld("minesantos") == null) { + return loc; + } + loc.setWorld(Bukkit.getWorld("minesantos")); + loc.setX(-133.59); + loc.setY(96.000000); + loc.setZ(244.431); + return loc; + } +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/SpeedCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/SpeedCommand.java new file mode 100644 index 0000000..3fd69e5 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/SpeedCommand.java @@ -0,0 +1,60 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class SpeedCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.VICE.f("&cYou are not a player!")); + return true; + } + Player player = (Player)s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if(SpectatorCommand.getActiveStaff().contains(player.getName()) || user.isRank(UserRank.ADMIN)) { + if(args.length != 1) { + player.sendMessage(Lang.VICE.f("&7Usage: /speed <1-10>")); + } else { + float speed = Float.valueOf(args[0]); + if(user.isRank(UserRank.ADMIN) && !player.isFlying()) { + speed = getRealMoveSpeed(speed, false); + player.setWalkSpeed(speed); + } else { + speed = getRealMoveSpeed(speed, true); + player.setFlySpeed(speed); + } + player.sendMessage(Lang.VICE.f("&7Your " + (player.isFlying() ? "fly" : "walk") + + " speed has been set to &a" + Integer.min(Integer.valueOf(args[0]), 10))); + } + } else if(user.isRank(UserRank.HELPOP)) { + player.sendMessage(Lang.VICE.f("&7You must be in spectator mode to use this command.")); + } + return true; + } + + private float getRealMoveSpeed(float userSpeed, final boolean isFly) { + final float defaultSpeed = isFly ? 0.1f : 0.2f; + float maxSpeed = 1f; + + if (userSpeed > 10f) { + userSpeed = 10f; + } else if (userSpeed < 0.0001f) { + userSpeed = 0.0001f; + } + + if (userSpeed < 1f) { + return defaultSpeed * userSpeed; + } else { + float ratio = ((userSpeed - 1) / 9) * (maxSpeed - defaultSpeed); + return ratio + defaultSpeed; + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/StackCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/StackCommand.java new file mode 100644 index 0000000..1182a02 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/StackCommand.java @@ -0,0 +1,100 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.State; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.items.ArmorUpgrade; +import net.grandtheftmc.vice.items.GameItem; +import net.grandtheftmc.vice.users.CheatCode; +import net.grandtheftmc.vice.users.ViceUser; +import net.grandtheftmc.vice.utils.DurabilityUtil; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class StackCommand implements CommandExecutor { + private static final List<Material> UNUSUAL_UNSTACKABLE_MATERIALS = new ArrayList<>(Arrays.asList(Material.CHEST, Material.WATCH, Material.SKULL, Material.SKULL_ITEM)); + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.toString()); + return true; + } + Player player = (Player) s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + ViceUser ViceUser = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + + if (ViceUser.getCheatCodeState(CheatCode.STACK).getState()== State.LOCKED) { + player.sendMessage(Lang.CHEAT_CODES.f(CheatCode.STACK.getLockedLore())); + return false; + } + if(user.isOnCooldown("stack_command")) { + player.sendMessage(Lang.CHEAT_CODES.f("&7You must wait &a" + Utils.timeInSecondsToText(user.getCooldownTimeLeft("stack_command"), C.RED, C.RED, C.GRAY) + " &7before using this cheatcode again!")); + return false; + } + int affected = 0; + for(int i = 0; i<player.getInventory().getSize(); i++) { + ItemStack is = player.getInventory().getItem(i); + if(is==null || is.getType()==Material.AIR) + continue; + if(UNUSUAL_UNSTACKABLE_MATERIALS.contains(is.getType()) && is.getAmount()>=1) + continue; + GameItem gameItem = Vice.getItemManager().getItem(is); + if(ViceUtils.isArmorPiece(is.getType()) && (DurabilityUtil.getDurability(is)-1!=is.getType().getMaxDurability())) + continue; + int maxStackSize = (ViceUtils.isTool(is.getType()) && is.getEnchantments().size()==0) || ViceUtils.isArmorPiece(is.getType()) || (gameItem!=null && (gameItem.getType()== GameItem.ItemType.DRUG || gameItem.getType()== GameItem.ItemType.WEAPON)) ? 64 : is.getMaxStackSize(); + if(is.getAmount()>=maxStackSize) + continue; + int amountNeeded = maxStackSize-is.getAmount(); + for(int j = i+1; j<player.getInventory().getSize(); j++) { + ItemStack compare = player.getInventory().getItem(j); + if(compare==null || compare.getDurability()!=is.getDurability() || compare.getType()!=is.getType() || (ViceUtils.isArmorPiece(compare.getType()) && ( DurabilityUtil.getDurability(compare)-1!=compare.getType().getMaxDurability()) || (is.getEnchantments().size()!=compare.getEnchantments().size() || !is.getEnchantments().keySet().containsAll(compare.getEnchantments().keySet())) || (ArmorUpgrade.getArmorUpgrades(is).size()!=ArmorUpgrade.getArmorUpgrades(compare).size() || !ArmorUpgrade.getArmorUpgrades(is).containsAll(ArmorUpgrade.getArmorUpgrades(compare))))) + continue; + if(is.getAmount()>=maxStackSize) + break; + if(compare.getAmount()>amountNeeded) { + is.setAmount(maxStackSize); + compare.setAmount(compare.getAmount()-amountNeeded); + affected++; + break; + } + else { + is.setAmount(is.getAmount()+compare.getAmount()); + amountNeeded -= compare.getAmount(); + player.getInventory().setItem(j, null); + affected++; + } + } + player.getInventory().setItem(i, is); + } + + if (affected > 0) { + // user.addCooldown("stack_command", ViceUtils.getStackDelay(user.getUserRank()), false, true); + new BukkitRunnable() { + @Override + public void run() { + player.updateInventory(); + } + }.runTaskLater(Core.getInstance(), 5); + player.sendMessage(Lang.VICE.f("&7Items compacted into stacks!")); + } else { + player.sendMessage(Lang.VICE.f("&7No stackable items found!")); + } + return true; + } + + +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/StatsCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/StatsCommand.java new file mode 100644 index 0000000..39e953d --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/StatsCommand.java @@ -0,0 +1,39 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.vice.utils.Stats; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class StatsCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.VICE.f("&cYou are not a player!")); + return true; + } + Player player = (Player)s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if(args.length == 0) { + player.sendMessage(Core.getAnnouncer().getHeader()); + Stats.getInstance().getStats(player).forEach(message -> player.sendMessage(message)); + player.sendMessage(Core.getAnnouncer().getFooter()); + } else { + if(Bukkit.getPlayer(args[0]) != null) { + Player target = Bukkit.getPlayer(args[0]); + player.sendMessage(Core.getAnnouncer().getHeader()); + Stats.getInstance().getStats(target).forEach(message -> player.sendMessage(message)); + player.sendMessage(Core.getAnnouncer().getFooter()); + } else { + player.sendMessage(Lang.VICE.f("&7Player not found!")); + } + } + return true; + } +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/TeleportCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/TeleportCommand.java new file mode 100644 index 0000000..f61217b --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/TeleportCommand.java @@ -0,0 +1,83 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class TeleportCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + Player sender = (Player) s; + User coreSender = Core.getUserManager().getLoadedUser(sender.getUniqueId()); + if (!coreSender.isRank(UserRank.HELPOP) || !coreSender.isRank(UserRank.ADMIN) && !SpectatorCommand.getActiveStaff().contains(sender.getName())) { + sender.sendMessage(Lang.VICE.f("&7Permission denied!")); + return true; + } + if (args.length == 1) { + Player target = Bukkit.getPlayer(args[0]); + if (target == null) { + sender.sendMessage(Lang.VICE.f("&7That player is not online!")); + return true; + } + if (Core.getUserManager().getLoadedUser(target.getUniqueId()).isRank(UserRank.ADMIN) && !coreSender.isRank(UserRank.ADMIN)) { + sender.sendMessage(Lang.VICE.f("&7You may not teleport to that player.")); + return true; + } + sender.teleport(target.getLocation()); + sender.sendMessage(Lang.VICE.f("&7You have been teleported to" + target.getDisplayName() + "&7!")); + } else if (args.length == 2) { + if (!coreSender.isRank(UserRank.ADMIN)) { + sender.sendMessage(Lang.VICE.f("&7Permission denied!")); + return true; + } + Player targetFrom = Bukkit.getPlayer(args[0]); + Player targetTo = Bukkit.getPlayer(args[1]); + if (targetFrom == null || targetTo == null) { + sender.sendMessage(Lang.VICE.f("&7Player(s) not found!")); + return true; + } + if (Core.getUserManager().getLoadedUser(targetFrom.getUniqueId()).isRank(UserRank.ADMIN) || + Core.getUserManager().getLoadedUser(targetTo.getUniqueId()).isRank(UserRank.ADMIN)) { + sender.sendMessage(Lang.VICE.f("&7You may not teleport that player.")); + return true; + } + targetFrom.teleport(targetTo.getLocation()); + sender.sendMessage(Lang.VICE.f("&7You teleported " + targetFrom.getDisplayName() + + " to " + targetTo.getDisplayName() + '!')); + } + else if(args.length==3){ + int[] coords = new int[3]; + for (int i = 0; i < 3; i++) { + try{ + coords[i] = Integer.parseInt(args[i]); + }catch (NumberFormatException nfe){ + sender.sendMessage(Lang.VICE.f("&7You did not input a number!")); + return false; + } + } + + sender.teleport(new Location(sender.getWorld(), coords[0], coords[1], coords[2])); + sender.sendMessage(Lang.VICE.f("&7You have been teleported to the selected coordinates.")); + } + else { + sender.sendMessage(Lang.VICE.f("&7Usage:")); + sender.sendMessage(Utils.f("&a/teleport <player>")); + sender.sendMessage(Utils.f("&a/teleport <playerfrom> <playerto>")); + sender.sendMessage(Utils.f("&a/teleport <x> <y> <z>")); + } + return true; + } +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/TokenShopCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/TokenShopCommand.java new file mode 100644 index 0000000..5b36ea6 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/TokenShopCommand.java @@ -0,0 +1,24 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.menus.MenuManager; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +/** + * Created by colt on 11/6/16. + */ +public class TokenShopCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + MenuManager.openMenu((Player)s, "tokenshop"); + return true; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/TopKillersCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/TopKillersCommand.java new file mode 100644 index 0000000..8905be1 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/TopKillersCommand.java @@ -0,0 +1,36 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.vice.ViceUtils; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.Iterator; +import java.util.Map; + +public class TopKillersCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.VICE.f("&cYou are not a player!")); + return true; + } + Player player = (Player)s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + Map<String, Integer> topKillers = ViceUtils.sortByValue(ViceUtils.getTopKillers(5)); + Iterator iterator = topKillers.entrySet().iterator(); + int i = 1; + while (iterator.hasNext()) { + Map.Entry pair = (Map.Entry)iterator.next(); + player.sendMessage(Utils.f("&7#" + i++ + " &a" + pair.getKey() + " &7- " + pair.getValue() + " &7kills")); + iterator.remove(); + } + return true; + } +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/TpaCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/TpaCommand.java new file mode 100644 index 0000000..d5eb528 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/TpaCommand.java @@ -0,0 +1,60 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.ViceUser; +import net.grandtheftmc.vice.world.warps.WarpManager; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.UUID; + +public class TpaCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Utils.f(Lang.TAXI + "&eYou are not a player!")); + return true; + } + WarpManager wm = Vice.getWorldManager().getWarpManager(); + Player player = (Player) s; + UUID uuid = player.getUniqueId(); + User user = Core.getUserManager().getLoadedUser(uuid); + ViceUser viceUser = Vice.getUserManager().getLoadedUser(uuid); + switch (lbl) { + case "tpa": + if (args.length != 1) { + s.sendMessage(Utils.f("&c/tpa <player>")); + return true; + } + wm.tpa(player, user, viceUser, Bukkit.getPlayer(args[0])); + return true; + case "tpahere": + if (args.length != 1) { + s.sendMessage(Utils.f("&c/tpahere <player>")); + return true; + } + wm.tpaHere(player, user, viceUser, Bukkit.getPlayer(args[0])); + return true; + case "tpdeny": + case "tpno": + wm.tpDeny(player, user, viceUser); + return true; + default: + if (args.length != 0) { + s.sendMessage(Utils.f("&c/" + lbl)); + return true; + } + wm.tpAccept(player, user, viceUser); + return true; + } + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/VehicleCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/VehicleCommand.java new file mode 100644 index 0000000..d25ac75 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/VehicleCommand.java @@ -0,0 +1,132 @@ +package net.grandtheftmc.vice.commands; + +import com.j0ach1mmall3.wastedvehicles.api.VehicleProperties; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.ViceUser; +import net.grandtheftmc.vice.users.ViceUserDAO; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.List; +import java.util.Optional; + +/** + * Created by Liam on 24/09/2016. + */ +public class VehicleCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command cmd, String lbl, String[] args) { + if (!s.hasPermission("command.vehicle")) { + s.sendMessage(Lang.NOPERM.s()); + return true; + } + if (args.length == 0) { + s.sendMessage(Lang.VEHICLES.f("&7/vehicle list [player]")); + s.sendMessage(Lang.VEHICLES.f("&7/vehicle give <player> <name>")); + s.sendMessage(Lang.VEHICLES.f("&7/vehicle remove <player> <name>")); + return true; + } + switch (args[0].toLowerCase()) { + case "list": + if (args.length > 2) { + s.sendMessage(Utils.f("&c/vehicle list <type>")); + return true; + } + List<VehicleProperties> vehicles = Vice.getWastedVehicles().getBabies().getVehicleProperties(); + if (args.length == 2) { + Player player = Bukkit.getPlayer(args[1]); + if (player == null) { + s.sendMessage(Lang.VEHICLES.f("&7That player is not online!")); + return true; + } + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + vehicles = user.getVehicleProperties(); + if (vehicles.isEmpty()) { + s.sendMessage(Lang.VEHICLES.f("&7That player has no vehicles!")); + return true; + } + String msg = ""; + for (VehicleProperties v : vehicles) + if (player == null || user.hasVehicle(v.getIdentifier())) + msg += "&c" + v.getIdentifier() + "&7, "; + if (msg.endsWith("&7, ")) + msg.substring(0, msg.length() - 4); + s.sendMessage(Lang.VEHICLES.f("&7List of vehicles of player " + player.getName() + "&7:")); + s.sendMessage(Utils.f(msg)); + return true; + } else if (vehicles.isEmpty()) { + s.sendMessage(Lang.VEHICLES.f("&7There are no vehicles!")); + return true; + } + String msg = ""; + for (VehicleProperties v : vehicles) + msg += "&c" + v.getIdentifier() + "&7, "; + if (msg.endsWith("&7, ")) + msg.substring(0, msg.length() - 4); + s.sendMessage(Lang.VEHICLES.f("&7List of vehicles:")); + s.sendMessage(Utils.f(msg)); + return true; + case "give": { + if (args.length != 3) { + s.sendMessage(Utils.f("&c/vehicle give <player> <name>")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + Optional<VehicleProperties> opt = Vice.getWastedVehicles().getVehicle(args[2]); + if (opt == null || !opt.isPresent() || opt.get() == null) { + s.sendMessage(Lang.VEHICLES.f("&7That vehicle does not exist!")); + return true; + } + VehicleProperties vehicle = opt.get(); + if (player == null) { +// Core.sql.updateAsyncLater("update " + Core.name() + " set `" + vehicle.getIdentifier().toLowerCase() + "`=true where name='" + args[1] + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.setVehiclePerm(args[1], vehicle, true)); + + s.sendMessage(Lang.VEHICLES.f("&7That player is not online, so his vehicles have been updated directly in the database!")); + return true; + } + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + user.giveVehiclePerm(player, vehicle); + s.sendMessage(Lang.VEHICLES.f("&7You gave vehicle &a" + vehicle.getIdentifier() + "&7 to player " + player.getName() + "&7!")); + return true; + } + case "remove": + if (args.length != 3) { + s.sendMessage(Utils.f("&c/vehicle remove <player> <name>")); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + Optional<VehicleProperties> opt = Vice.getWastedVehicles().getVehicle(args[2]); + if (opt == null || !opt.isPresent() || opt.get() == null) { + s.sendMessage(Lang.VEHICLES.f("&7That vehicle does not exist!")); + return true; + } + VehicleProperties vehicle = opt.get(); + if (player == null) { +// Core.sql.updateAsyncLater("update " + Core.name() + " set `" + vehicle.getIdentifier().toLowerCase() + "`=false where name='" + args[1] + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.setVehiclePerm(args[1], vehicle, false)); + + s.sendMessage(Lang.VEHICLES.f("&7That player is not online, so his vehicles have been updated directly in the database!")); + return true; + } + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + user.removeVehiclePerm(player, vehicle); + s.sendMessage(Lang.VEHICLES.f("&7You removed vehicle &a" + vehicle.getIdentifier() + "&7 from player " + player.getName() + "&7!")); + return true; + default: + s.sendMessage(Lang.VEHICLES.f("&7/vehicle list [player]")); + s.sendMessage(Lang.VEHICLES.f("&7/vehicle give <player> <name>")); + s.sendMessage(Lang.VEHICLES.f("&7/vehicle remove <player> <name>")); + return true; + } + + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/ViceAdminCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/ViceAdminCommand.java new file mode 100644 index 0000000..8d1a0d7 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/ViceAdminCommand.java @@ -0,0 +1,95 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.ViceUser; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import java.util.Map; + +public class ViceAdminCommand implements CommandExecutor { + + + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + if (!s.hasPermission("command.admin")) { + s.sendMessage(Lang.NOPERM.s()); + return true; + } + Player player = (Player) s; + if (args.length == 0) { + s.sendMessage(Utils.f("&c/viceadmin release <player>")); + s.sendMessage(Utils.f("&c/viceadmin target <player>")); + s.sendMessage(Utils.f("&c/viceadmin kitexpiries <player>")); + s.sendMessage(Utils.f("&c/viceadmin trashcan")); + s.sendMessage(Utils.f("&c/viceadmin gravity <modifier>")); + return true; + } + switch (args[0].toLowerCase()) { + case "trashcan": { + ItemStack item = Utils.createItem(Material.DROPPER, "&7&lTrash Can"); + //Utils.b(ArmorUpgrade.TANK.getEnchantment().getName()); + // items.addUnsafeEnchantment(ArmorUpgrade.TANK.getEnchantment(), 1); + for (Enchantment e : item.getEnchantments().keySet()) + Utils.b(e.getName()); + player.getInventory().addItem(item); + s.sendMessage(Utils.f("&7A Trash Can was added to your inventory. Place it so players can sell items in it.")); + return true; + } + case "kitexpiries": { + if (args.length != 2) { + s.sendMessage(Utils.f("&c/viceadmin kitexpiries <player>")); + return true; + } + Player p = Bukkit.getPlayer(args[1]); + if (p == null) { + s.sendMessage(Utils.f("&cThat player is not online!")); + return true; + } + ViceUser user = Vice.getUserManager().getLoadedUser(p.getUniqueId()); + s.sendMessage(Utils.f("&7Player &a" + p.getName() + "&7 has the following kit expiries:")); + for (Map.Entry<String, Long> entry : user.getKitExpiries().entrySet()) + s.sendMessage(entry.getKey() + ": expiry " + entry.getValue() + " time left " + (entry.getValue() - System.currentTimeMillis())); + s.sendMessage("KitExpiriesString: " + user.getKitExpiriesString()); + return true; + } + + case "release": { + if (args.length != 2) { + s.sendMessage(Utils.f("&c/viceadmin release <player>")); + return true; + } + Player p = Bukkit.getPlayer(args[1]); + if (p == null) { + s.sendMessage(Utils.f("&cThat player is not online!")); + return true; + } + ViceUser user = Vice.getUserManager().getLoadedUser(p.getUniqueId()); + user.setJailTimer(-1); + p.teleport(Vice.getWorldManager().getWarpManager().getSpawn().getLocation()); + s.sendMessage(Utils.f("&aYou released " + p.getName() + " from jail!")); + return true; + } + default: + s.sendMessage(Utils.f("&c/viceadmin release <player>")); + s.sendMessage(Utils.f("&c/viceadmin target <player>")); + s.sendMessage(Utils.f("&c/viceadmin kitexpiries <player>")); + s.sendMessage(Utils.f("&c/viceadmin trashcan")); + s.sendMessage(Utils.f("&c/viceadmin gravity <modifier>")); + return true; + } + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/ViceRankCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/ViceRankCommand.java new file mode 100644 index 0000000..eb3a843 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/ViceRankCommand.java @@ -0,0 +1,66 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.ViceRank; +import net.grandtheftmc.vice.users.ViceUser; + +import net.grandtheftmc.vice.users.ViceUserDAO; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class ViceRankCommand implements CommandExecutor { + + // TODO add command/support for CopRanks + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!s.hasPermission("command.ViceRank")) { + s.sendMessage(Utils.f("&cYou do not have permission to execute this command!")); + return true; + } + if (args.length == 0) { + s.sendMessage(Utils.f("&c/ViceRank set <player> <rank>")); + return true; + } + switch (args[0].toLowerCase()) { + case "set": + if (args.length != 3) { + s.sendMessage(Utils.f("&c/ViceRank set <player> <rank>")); + return true; + } + ViceRank rank = ViceRank.getRankOrNull(args[2]); + if (rank == null) { + String msg = Lang.RANKS + "&7There is no ViceRank with the name &a" + args[2] + "&7! Valid ranks: "; + for (ViceRank r : ViceRank.values()) + msg = msg + "&a" + r.getColoredNameBold() + "&7, "; + if (msg.endsWith("&7, ")) + msg = msg.substring(0, msg.length() - 4); + msg += "&c."; + s.sendMessage(Utils.f(msg)); + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player == null) { +// Core.sql.updateAsyncLater("update vice set rank='" + rank.getName() + "' where name='" + args[1] + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.updateRankByName(args[1], rank)); + s.sendMessage(Utils.f(Lang.RANKS + "&7That player is not online, so his rank has been forcibly updated in the database.")); + return true; + } + ViceUser u = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + u.setRank(rank, player, Core.getUserManager().getLoadedUser(player.getUniqueId())); + s.sendMessage(Utils.f(Lang.RANKS + "&a" + player.getName() + " &7is now a &a" + u.getRank().getColoredNameBold() + "&7!")); + return true; + + default: + s.sendMessage(Utils.f("&c/ViceRank set <player> <rank>")); + return true; + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/ViceRanksCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/ViceRanksCommand.java new file mode 100644 index 0000000..06cacc6 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/ViceRanksCommand.java @@ -0,0 +1,26 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.users.ViceRank; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class ViceRanksCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + Player player = (Player) s; + player.sendMessage(Lang.RANKS.s()); + for (ViceRank rank : ViceRank.values()) { + player.sendMessage(Utils.f(rank.getColoredNameBold() + " &7costs &a&l$" + rank.getPrice())); + } + return true; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/WarpCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/WarpCommand.java new file mode 100644 index 0000000..c36dd14 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/WarpCommand.java @@ -0,0 +1,140 @@ +package net.grandtheftmc.vice.commands; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.TaxiTarget; +import net.grandtheftmc.vice.world.warps.Warp; +import net.grandtheftmc.vice.world.warps.WarpManager; +import org.bukkit.Location; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.List; + +public class WarpCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command cmd, String label, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + WarpManager wm = Vice.getWorldManager().getWarpManager(); + Player player = (Player) s; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (args.length == 0) { + if (!s.hasPermission("warps.admin")) { + Vice.getWorldManager().getWarpManager().warp(player, user, Vice.getUserManager().getLoadedUser(player.getUniqueId()), + new TaxiTarget(Vice.getWorldManager().getWarpManager().getRandomWarp()), 0, -1); + return true; + } + s.sendMessage(Utils.f("&c/warp list")); + s.sendMessage(Utils.f("&c/warp set <name>")); + s.sendMessage(Utils.f("&c/warp delete <name>")); + s.sendMessage(Utils.f("&c/warp <warp>")); + s.sendMessage(Utils.f("&c/warp load")); + s.sendMessage(Utils.f("&c/warp save")); + return true; + } + if (!s.hasPermission("warps.admin")) return true; + switch (args[0].toLowerCase()) { + case "list": + List<Warp> list = wm.getWarps(); + s.sendMessage(Utils.f("&aWarps&7: (&a" + list.size() + "&7)")); + if (list.isEmpty()) { + s.sendMessage(Utils.f("&cNone!")); + return true; + } + String msg = "&a" + list.get(0).getName(); + for (int i = 1; i < wm.getWarps().size(); i++) + msg = msg + "&7, &a" + list.get(i).getName(); + s.sendMessage(Utils.f(msg)); + return true; + case "set": { + if (args.length != 2) { + s.sendMessage(Utils.f("&c/warp set <name>")); + return true; + } + + String warpName = args[1]; + switch (warpName.toLowerCase()) { + case "spawn": + wm.setSpawn(player.getLocation()); + s.sendMessage(Utils.f("&aYou set the spawn!")); + return true; + case "tutorialspawn": + wm.setTutorialSpawn(player.getLocation()); + s.sendMessage(Utils.f("&aYou set the tutorial spawn!")); + return true; + case "jail": + wm.setJail(player.getLocation()); + s.sendMessage(Utils.f("&aYou set the jail spawn!")); + return true; + default: + break; + } + Warp warp = wm.getWarp(warpName); + if (warp != null) { + warp.setLocation(player.getLocation()); + warp.setName(warpName); + s.sendMessage(Utils.f("&7Warp &a" + warpName + "&7 was set to your current location!")); + return true; + } + warp = new Warp(warpName, player.getLocation()); + wm.addWarp(warp); + s.sendMessage(Utils.f("&7A new warp with the name &a" + warpName + "&7 was set to your current location!")); + return true; + } + case "delete": { + if (args.length != 2) { + s.sendMessage(Utils.f("&c/warp delete <name>")); + return true; + } + String warpName = args[1]; + Warp warp = wm.getWarp(warpName); + if (warp == null) { + s.sendMessage(Utils.f("&cThat warp does not exist!")); + return true; + } + Location loc = warp.getLocation(); + wm.removeWarp(warp); + s.sendMessage(Utils.f("&cWarp &a" + warpName + "&c at &a" + loc.getX() + "&c," + loc.getY() + "&c," + + loc.getZ() + "&c was removed.")); + return true; + } + case "load": + Vice.getSettings().setWarpsConfig(Utils.loadConfig("warps")); + Vice.getWorldManager().getWarpManager().loadWarps(); + s.sendMessage(Lang.WARP.f("&7Loaded Warps!")); + return true; + case "save": + Vice.getWorldManager().getWarpManager().saveWarps(); + s.sendMessage(Lang.WARP.f("&7Saved Warps!")); + return true; + default: + if (args.length != 1) { + s.sendMessage(Utils.f("&c/warp list")); + s.sendMessage(Utils.f("&c/warp set <name>")); + s.sendMessage(Utils.f("&c/warp delete <name>")); + s.sendMessage(Utils.f("&c/warp <warp>")); + s.sendMessage(Utils.f("&c/warp load")); + s.sendMessage(Utils.f("&c/warp save")); + return true; + } + String warpName = args[0]; + Warp warp = wm.getWarp(warpName); + if (warp == null) { + s.sendMessage(Utils.f("&cThat warp does not exist!")); + return true; + } + Vice.getWorldManager().getWarpManager().warp(player, user, Vice.getUserManager().getLoadedUser(player.getUniqueId()), + new TaxiTarget(warp), 200, -1); + return true; + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/ZoneCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/ZoneCommand.java new file mode 100644 index 0000000..3d2360d --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/commands/ZoneCommand.java @@ -0,0 +1,179 @@ +package net.grandtheftmc.vice.commands; + +import com.sk89q.worldedit.bukkit.WorldEditPlugin; +import com.sk89q.worldedit.bukkit.selections.Selection; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.commands.CoreCommand; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.world.ViceSelection; +import net.grandtheftmc.vice.world.ZoneFlag; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +/** + * Created by Timothy Lampen on 8/25/2017. + */ +public class ZoneCommand extends CoreCommand<Player>{ + public ZoneCommand() { + super(" zone", "selects cubiod regions for various purposes"); + } + + @Override + public void execute(Player player, String[] args) { + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if(!user.getUserRank().isHigherThan(UserRank.ADMIN) && !player.isOp()) { + player.sendMessage(Lang.NOPERM.f("")); + return; + } + if(args.length==0) { + + player.sendMessage(Utils.f("&e/zone add <name> <flag,flag,...> [ignoreheight] &7- makes your current selection into a police-free zone. [ignore height refers to if the zone should take into account the y coord.]")); + player.sendMessage(Utils.f("&e/zone remove <name> &7- removes the zone that you are currently in.")); + player.sendMessage(Utils.f("&e/zone addflag <name> <flag> &7- Adds a certain flag to the zone with the selected name.")); + player.sendMessage(Utils.f("&e/zone removeflag <name> <flag> &7- Removes a certain flag from the zone with the selected name.")); + player.sendMessage(Utils.f("&e/zone list [all]&7- Lists all the zones that you are currently standing in [or on the server].")); + player.sendMessage(Utils.f("&7Possible flags: &eCOP_TELEPORT_STATION&7, &eCOP_CANT_ARREST")); + return; + } + switch (args[0].toLowerCase()) { + case "addflag": { + if(args.length!=3) { + player.sendMessage(Lang.VICE.f("&7/zone addflag <name> <flag>")); + return; + } + Optional<ViceSelection> zone = Vice.getWorldManager().getZone(args[1]); + if(!zone.isPresent()) { + player.sendMessage(Lang.VICE.f("&7Unable to find zone with the name: &e" + args[1])); + return; + } + ZoneFlag flag; + try { + flag = ZoneFlag.valueOf(args[2].toUpperCase()); + }catch (Exception e){ + player.sendMessage(Lang.VICE.f("&7Unable to find flag with name: &e" + args[2].toUpperCase())); + return; + } + + if(zone.get().getFlags().contains(flag)) { + player.sendMessage(Lang.VICE.f("&7This zone already has this flag!")); + return; + } + + zone.get().addFlag(flag); + player.sendMessage(Lang.VICE.f("&7You have added the flag: &e" + flag.toString() + " &7to the zone with name: &e" + args[1] + "&7.")); + return; + } + case "removeflag": { + if(args.length!=3) { + player.sendMessage(Lang.VICE.f("&7/zone removeflag <name> <flag>")); + return; + } + Optional<ViceSelection> zone = Vice.getWorldManager().getZone(args[1]); + if(!zone.isPresent()) { + player.sendMessage(Lang.VICE.f("&7Unable to find zone with the name: &e" + args[1])); + return; + } + ZoneFlag flag; + try { + flag = ZoneFlag.valueOf(args[2].toUpperCase()); + }catch (Exception e){ + player.sendMessage(Lang.VICE.f("&7Unable to find flag with name: " + args[2].toUpperCase())); + return; + } + + if(!zone.get().removeFlag(flag)) { + player.sendMessage(Lang.VICE.f("&7This zone doesnt have this flag!")); + + } + + player.sendMessage(Lang.VICE.f("&7You have removed the flag: &e" + flag.toString() + " &7from the zone with name: &e" + args[1] + "&7.")); + return; + } + case "list": { + boolean all = args.length==2; + List<ViceSelection> zones; + if(all) + zones = Vice.getWorldManager().getZones(); + else + zones = Vice.getWorldManager().getZones(player.getLocation()); + if(zones.size()==0) { + player.sendMessage(Lang.VICE.f("&7Could not find any zones!")); + return; + } + player.sendMessage(Utils.f("&7Zones:")); + for(ViceSelection zone : zones) { + StringBuilder sb = new StringBuilder(); + zone.getFlags().forEach(flag -> sb.append("&e " + flag.toString() + "&e,")); + sb.deleteCharAt(sb.length()-1); + player.sendMessage(Utils.f("&7Name: &e" + zone.getName() + " &7| Flags: &e" + sb.toString())); + } + return; + } + case "remove": { + if(args.length < 2) { + player.sendMessage(Lang.VICE.f("&7/zone remove <name>")); + return; + } + String name = args[1]; + if(!Vice.getWorldManager().removeZone(name)) { + player.sendMessage(Lang.VICE.f("&7There is no existing zone with the name &e" + name + "&7!")); + return; + } + player.sendMessage(Lang.VICE.f("&7You have removed the zone with name: &e" + name + "&7.")); + return; + } + case "add": { + if(args.length < 2) { + player.sendMessage(Lang.VICE.f("&7/zone add <name> <flag,flag,...> [ignoreheight]")); + return; + } + WorldEditPlugin worldEdit = (WorldEditPlugin) Bukkit.getPluginManager().getPlugin("WorldEdit"); + Selection selction = worldEdit.getSelection(player); + if(selction==null) { + player.sendMessage(Lang.VICE.f("&7Please select a region using the world edit tool (found using //wand)")); + return; + } + + List<ZoneFlag> flags = new ArrayList<>(); + if(!args[2].contains(",")) { + ZoneFlag flag; + try { + flag = ZoneFlag.valueOf(args[2].toUpperCase()); + }catch (Exception e){ + player.sendMessage(Lang.VICE.f("&7Unable to find flag with name: " + args[2].toUpperCase())); + return; + } + flags.add(flag); + } + else{ + for(String s : args[2].toUpperCase().split(",")) { + ZoneFlag flag; + try { + flag = ZoneFlag.valueOf(s); + }catch (Exception e){ + player.sendMessage(Lang.VICE.f("&7Unable to find flag with name: " + s.toUpperCase())); + return; + } + flags.add(flag); + } + } + + boolean ignoreheight = args.length != 4 || !args[3].equalsIgnoreCase("false"); + + ViceSelection vSelection = new ViceSelection(args[1], flags, selction.getMaximumPoint(), selction.getMinimumPoint(), ignoreheight); + Vice.getWorldManager().addZone(vSelection); + player.sendMessage(Lang.VICE.f("&7You have created a zone with your current selection with flags: &e" + args[2].toUpperCase()) + "&7 and ignoreheight: &e" + ignoreheight); + return; + } + } + + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dao/CheatCodeDAO.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dao/CheatCodeDAO.java new file mode 100644 index 0000000..445c4ae --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dao/CheatCodeDAO.java @@ -0,0 +1,42 @@ +package net.grandtheftmc.vice.dao; + +import com.google.common.collect.Maps; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.util.State; +import net.grandtheftmc.vice.users.CheatCode; +import net.grandtheftmc.vice.users.CheatCodeState; + +import java.sql.*; +import java.util.HashMap; +import java.util.Optional; + +public class CheatCodeDAO { + + public static Optional<HashMap<CheatCode, CheatCodeState>> getCheatCodes(String name) { + //"Select * from " + Core.name() + " where name='" + args[1] + "'" + HashMap<CheatCode, CheatCodeState> map = Maps.newHashMap(); + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT `cheatcodes` FROM " + Core.name() + " WHERE `name`=?;")) { + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + Blob b = result.getBlob("cheatcodes"); + if(b!=null) { + String cheatCodesBlob = new String(b.getBytes(1, (int) b.length())); + for (String serializedCheatCode : cheatCodesBlob.split("-")) { + String[] split = serializedCheatCode.split("#"); + map.put(CheatCode.valueOf(split[0]), new CheatCodeState(State.valueOf(split[1]), Boolean.valueOf(split[2]))); + } + } + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + return Optional.empty(); + } + + return Optional.of(map); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dao/MachineDAO.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dao/MachineDAO.java new file mode 100644 index 0000000..b8c9d7b --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dao/MachineDAO.java @@ -0,0 +1,157 @@ +package net.grandtheftmc.vice.dao; + +import com.google.common.collect.Lists; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.machine.BaseMachine; +import net.grandtheftmc.vice.machine.data.MachineDataType; +import net.grandtheftmc.vice.machine.type.*; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.inventory.ItemStack; + +import java.sql.*; +import java.util.List; +import java.util.Optional; + +public class MachineDAO { + +//CREATE TABLE IF NOT EXISTS vice_machine ( +//id INT NOT NULL AUTO_INCREMENT, +//server_key VARCHAR(10) NOT NULL, +//type INT NOT NULL, +//world VARCHAR(8) NOT NULL, +//x INT NOT NULL, +//y INT NOT NULL, +//z INT NOT NULL, +//PRIMARY KEY (id) +//); + +//CREATE TABLE IF NOT EXISTS vice_machine_data ( +//machine_id INT NOT NULL, +//fuel DOUBLE NOT NULL, +//durability DOUBLE NOT NULL, +//progress DOUBLE NOT NULL, +//content BLOB, +//PRIMARY KEY (machine_id), +//FOREIGN KEY (machine_id) REFERENCES vice_machine(id) ON DELETE CASCADE +//); + +//INSERT INTO vice_machine (server_key, type, world, x, y, z) VALUES (?, ?, ?, ?, ?, ?, ?); +//INSERT INTO vice_machine_data (machine_id, fuel, durability, progress, content) VALUES (?, ?, ?, ?, ?); + +//SELECT M.id, M.type, M.world, M.x, M.y, M.z, MD.fuel, MD.durability, MD.progress, MD.content +//FROM vice_machine M, vice_machine_data MD +//WHERE M.id=MD.id AND M.server_key=?; + +//DELETE FROM vice_machine WHERE id=?; + + public static List<BaseMachine> getMachines(Connection connection) { + final String query = "SELECT M.id, M.type, M.world, M.x, M.y, M.z, MD.fuel, MD.durability, MD.progress, MD.content" + + " FROM vice_machine M, vice_machine_data MD WHERE M.id=MD.machine_id AND M.server_key=?;"; + + List<BaseMachine> list = Lists.newArrayList(); + + try (PreparedStatement statement = connection.prepareStatement(query)) { + statement.setString(1, Core.name()); + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + int uniqueId = result.getInt("id"); + int machineType = result.getInt("type"); + String world = result.getString("world"); + int x = result.getInt("x"); + int y = result.getInt("y"); + int z = result.getInt("z"); + double fuel = result.getDouble("fuel"); + double durability = result.getDouble("durability"); + double progress = result.getDouble("progress"); + ItemStack[] content = ViceUtils.fromBase64(result.getString("content")); + + BaseMachine machine = null; + switch (machineType) { + case 1: machine = new MachineSmallDryingChamber(); break; + case 2: machine = new MachineMediumDryingChamber(); break; + case 3: machine = new MachineLargeDryingMachine(); break; + case 4: machine = new MachineBeerDistillery(); break; + case 5: machine = new MachineVodkaDistillery(); break; + case 6: machine = new MachineCocaProcessor(); break; + case 7: machine = new MachinePulpCondenser(); break; + case 8: machine = new MachineBasicMethProducer(); break; + case 9: machine = new MachineAdvancedMethProducer(); break; + case 10: machine = new MachineSugarBox(); break; + } + + if (machine == null) continue; + + machine.setUniqueIdentifier(uniqueId); + machine.setLocation(new Location(Bukkit.getWorld(world), x, y, z)); + machine.setContents(content); + + machine.getData(MachineDataType.FUEL).setCurrent(fuel); + machine.getData(MachineDataType.DURABILITY).setCurrent(durability); + machine.getData(MachineDataType.PROGRESS).setCurrent(progress); + + list.add(machine); + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + + return list; + } + + public static <T extends BaseMachine> T addMachine(Connection connection, T machine) { + final String query = "INSERT INTO vice_machine (server_key, type, world, x, y, z) VALUES (?, ?, ?, ?, ?, ?);"; + try (PreparedStatement statement = connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS)) { + statement.setString(1, Core.name()); + statement.setInt(2, machine.getMachineIdentifier()); + statement.setString(3, machine.getLocation().getWorld().getName()); + statement.setInt(4, machine.getLocation().getBlockX()); + statement.setInt(5, machine.getLocation().getBlockY()); + statement.setInt(6, machine.getLocation().getBlockZ()); + + statement.executeUpdate(); + try (ResultSet result = statement.getGeneratedKeys()) { + if (result.next()) { + machine.setUniqueIdentifier(result.getInt(1)); + return machine; + } + + return null; + } + } catch (SQLException e) { + e.printStackTrace(); + } + return null; + } + + public static void updateMachineData(Connection connection, BaseMachine machine) { + final String query = "INSERT INTO vice_machine_data (machine_id, fuel, durability, progress, content) VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE fuel=?, durability=?, progress=?, content=?;"; + try (PreparedStatement statement = connection.prepareStatement(query)) { + statement.setInt(1, machine.getUniqueIdentifier()); + statement.setDouble(2, machine.getData(MachineDataType.FUEL).getCurrent()); + statement.setDouble(3, machine.getData(MachineDataType.DURABILITY).getCurrent()); + statement.setDouble(4, machine.getData(MachineDataType.PROGRESS).getCurrent()); + statement.setString(5, ViceUtils.toBase64(machine.getContents())); + statement.setDouble(6, machine.getData(MachineDataType.FUEL).getCurrent()); + statement.setDouble(7, machine.getData(MachineDataType.DURABILITY).getCurrent()); + statement.setDouble(8, machine.getData(MachineDataType.PROGRESS).getCurrent()); + statement.setString(9, ViceUtils.toBase64(machine.getContents())); + + statement.execute(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + public static void removeMachine(Connection connection, int uniqueIdentifier) { + final String query = "DELETE FROM vice_machine WHERE id=?;"; + try (PreparedStatement statement = connection.prepareStatement(query)) { + statement.setInt(1, uniqueIdentifier); + statement.execute(); + } catch (SQLException e) { + e.printStackTrace(); + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/display/DisplayManager.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/display/DisplayManager.java new file mode 100644 index 0000000..74df06d --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/display/DisplayManager.java @@ -0,0 +1,34 @@ +package net.grandtheftmc.vice.display; + +import net.grandtheftmc.core.util.Component; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.display.cont.CartelListener; +import net.grandtheftmc.vice.display.cont.PlayerStatsListener; +import net.grandtheftmc.vice.hologram.HologramManager; + +public class DisplayManager implements Component <DisplayManager, Vice> { + + // TODO: Find a better place for this to go + + private final PlayerStatsListener playerStatsListener; + private final CartelListener cartelListener; + + public DisplayManager(Vice plugin, HologramManager hologramManager) { + this.playerStatsListener = new PlayerStatsListener(plugin, hologramManager); + this.cartelListener = new CartelListener(plugin, hologramManager); + } + + @Override + public DisplayManager onDisable(Vice plugin) { + this.playerStatsListener.task.cancel(); + this.cartelListener.task[0].cancel(); + this.cartelListener.task[1].cancel(); + + this.playerStatsListener.hologram.destroy(); + this.cartelListener.hologram[0].destroy(); + this.cartelListener.hologram[1].destroy(); + + return this; + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/display/cont/CartelListener.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/display/cont/CartelListener.java new file mode 100644 index 0000000..df3bc9d --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/display/cont/CartelListener.java @@ -0,0 +1,196 @@ +package net.grandtheftmc.vice.display.cont; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.massivecraft.factions.FPlayers; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.Factions; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.vice.hologram.CoreHologram; +import net.grandtheftmc.vice.hologram.Hologram; +import net.grandtheftmc.vice.hologram.HologramManager; +import net.grandtheftmc.vice.hologram.event.HologramReceiveEvent; +import net.grandtheftmc.vice.hologram.exception.HologramDuplicateException; +import net.grandtheftmc.vice.hologram.exception.HologramDuplicateNodeException; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitTask; + +import java.text.NumberFormat; +import java.util.*; + +public final class CartelListener implements Listener { + + private ArrayList<Faction> factionList = Lists.newArrayList(); + + public final Hologram[] hologram; + public final BukkitTask[] task; + + public CartelListener(JavaPlugin plugin, HologramManager hologramManager) { + this.hologram = new Hologram[2]; + this.task = new BukkitTask[2]; + + ServerUtil.runTaskLater(() -> { + Location origin = new Location(Bukkit.getWorld("spawn"), 145.5, 82, 220.5); // TODO: Figure out where this needs to go + + try { + + this.hologram[0] = hologramManager.create(4, origin); + this.hologram[0].addNode(1); + this.hologram[0].addNode(2); + this.hologram[0].addNode(3); + this.hologram[0].addNode(4); + + this.hologram[1] = hologramManager.create(5, new Location(Bukkit.getWorld("spawn"), 121.5, 80, 235.5)); + for (int i = 1; i < 15; i++) hologram[1].addNode(i); + + task[1] = Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, () -> { + ServerUtil.runTask(() -> { + factionList.clear(); + + factionList = Factions.getInstance().getAllFactions(); + factionList.remove(Factions.getInstance().getWilderness()); + factionList.remove(Factions.getInstance().getSafeZone()); + factionList.remove(Factions.getInstance().getWarZone()); + factionList.sort((o1, o2) -> { +// double f1Worth = Math.pow(o1.getLandRounded() * 64, 2) + o1.getStash(); +// double f2Worth = Math.pow(o2.getLandRounded() * 64, 2) + o2.getStash(); + + double f1Worth = o1.getStash(); + if (o1.getAllClaims().size() > 0) f1Worth += 50000 * 1.05 * o1.getAllClaims().size(); + + double f2Worth = o2.getStash(); + if (o2.getAllClaims().size() > 0) f2Worth += 50000 * 1.05 * o2.getAllClaims().size(); + + if (f1Worth < f2Worth) + return 1; + else if (f1Worth > f2Worth) + return -1; + return 0; + }); + }); + }, 10L, 5 * 60 * 20); + + // Update Cartel stats every 15 seconds + task[0] = Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, () -> { + this.hologram[0].refresh(); + this.hologram[1].refresh(); + }, 20L, 15 * 20L); + + } catch (HologramDuplicateException | HologramDuplicateNodeException e) { + e.printStackTrace(); + } + }, 5 * 20L); + + Bukkit.getPluginManager().registerEvents(this, plugin); + } + + @EventHandler(ignoreCancelled = true) + protected final void onPlayerJoin(PlayerJoinEvent event) { + if (this.hologram[0] != null) { + ServerUtil.runTaskLaterAsync(() -> this.hologram[0].spawn(event.getPlayer()), 20L); + } + + if (this.hologram[1] != null) { + ServerUtil.runTaskLaterAsync(() -> this.hologram[1].spawn(event.getPlayer()), 20L); + } + } + + @EventHandler(ignoreCancelled = true) + protected final void onHologramReceive(HologramReceiveEvent event) { + int id = event.getHologram().getId(); + int nodeId = event.getNode().getId(); + + if (id == 4) { + Player player = event.getPlayer(); + Faction cartel = FPlayers.getInstance().getByPlayer(player).getFaction(); + + // The player is not in a Cartel so lets display a little info message instead + if (cartel == null || cartel.isWilderness() || cartel.isWarZone()) { + if (nodeId == 1) { + event.setText("&6&lCartels"); + } else if (nodeId == 2) { + event.setText("&eCreate or join a Cartel and conquer Vice!"); + } else if (nodeId == 3) { + event.setText(" "); + event.setDisplay(false); + } else if (nodeId == 4) { + event.setText(" "); + event.setDisplay(false); + } + + return; + } + + int online = cartel.getOnlinePlayers().size(); + int size = cartel.getSize(); + int kills = cartel.getKills(); + int deaths = cartel.getDeaths(); + double stash = cartel.getStash(); + String formattedStash = NumberFormat.getCurrencyInstance(Locale.US).format(stash); + + // Cartel name + if (nodeId == 1) { + event.setText("&6&l" + ChatColor.stripColor(cartel.getTag())); + } + + // Cartel member count + else if (nodeId == 2) { + event.setText("&e" + online + "/" + size + " members online"); + } + + // Cartel balance or 'stash' + else if (nodeId == 3) { + event.setText("&eStash&f: " + formattedStash); // NumberFormat adds the '$' + } + + // Cartel Kills and Deaths + else if (nodeId == 4) { + event.setText("&aKills&f: " + kills + " &e| " + "&cDeaths&f: " + deaths); + } + } + + else if (id == 5) { + if (nodeId == 1) { + event.setText(C.GOLD + C.BOLD + "TOP CARTELS"); + return; + } + + if (nodeId == 12) { + event.setDisplay(false); + return; + } + + if (nodeId == 13) { + event.setText(C.YELLOW + C.ITALIC + "The Cartel leaderboard is"); + return; + } + + if (nodeId == 14) { + event.setText(C.YELLOW + C.ITALIC + "calculated via 'stash * land worth'"); + return; + } + + int correctNode = nodeId - 2; + if (this.factionList.size() > correctNode) { + Faction faction = this.factionList.get(correctNode); + + NumberFormat format = NumberFormat.getCurrencyInstance(Locale.US); + double worth = faction.getStash(); + if (faction.getAllClaims().size() > 0) worth += 50000 * 1.05 * faction.getAllClaims().size(); + event.setText(C.YELLOW + "#" + (correctNode + 1) + C.WHITE + " " + faction.getTag() + C.GRAY + " - " + C.GREEN + format.format(worth)); + return; + } + + event.setText(C.YELLOW + "#" + (correctNode + 1) + C.WHITE + " Unknown" + C.GRAY + " - " + C.GREEN + "$0.00"); + } + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/display/cont/PlayerStatsListener.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/display/cont/PlayerStatsListener.java new file mode 100644 index 0000000..c5e33df --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/display/cont/PlayerStatsListener.java @@ -0,0 +1,127 @@ +package net.grandtheftmc.vice.display.cont; + +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.hologram.Hologram; +import net.grandtheftmc.vice.hologram.HologramManager; +import net.grandtheftmc.vice.hologram.event.HologramReceiveEvent; +import net.grandtheftmc.vice.hologram.exception.HologramDuplicateException; +import net.grandtheftmc.vice.hologram.exception.HologramDuplicateNodeException; +import net.grandtheftmc.vice.users.ViceRank; +import net.grandtheftmc.vice.users.ViceUser; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitTask; + +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.util.Locale; + +public class PlayerStatsListener implements Listener { + + public Hologram hologram; + public BukkitTask task; + + /** + * Registers listeners and creates the hologram object + * @param plugin + * @param hologramManager + */ + public PlayerStatsListener(JavaPlugin plugin, HologramManager hologramManager) { + ServerUtil.runTaskLater(() -> { + Location origin = new Location(Bukkit.getWorld("spawn"), 127.5, 82, 220.5); // TODO: Figure out where this needs to go + + try { + + this.hologram = hologramManager.create(3, origin); + this.hologram.addNode(1); + this.hologram.addNode(2); + this.hologram.addNode(3); + this.hologram.addNode(4); + this.hologram.addNode(5); + + // Updates the stats every 5 seconds + task = Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, () -> { + this.hologram.refresh(2); + this.hologram.refresh(3); + this.hologram.refresh(4); + this.hologram.refresh(5); + }, 20L, 5 * 20L); + + } catch (HologramDuplicateException | HologramDuplicateNodeException e) { + e.printStackTrace(); + } + }, 5 * 20L); + + Bukkit.getPluginManager().registerEvents(this, plugin); + } + + /** + * Sends the hologram to the player 1 second after they join + * @param event + */ + @EventHandler + protected final void onPlayerJoin(PlayerJoinEvent event) { + if (this.hologram == null) return; + ServerUtil.runTaskLaterAsync(() -> this.hologram.spawn(event.getPlayer()), 20L); + } + + /** + * Fires when the player has received their hologram, information is set/removed/updated here + * @param event + */ + @EventHandler + protected final void onHologramReceive(HologramReceiveEvent event) { + int id = event.getHologram().getId(); + int nodeId = event.getNode().getId(); + + if(id != 3) return; + + Player player = event.getPlayer(); + ViceUser viceUser = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + + ViceRank rank = viceUser.getRank(); + int kills = viceUser.getKills(), deaths = viceUser.getDeaths(), killstreak = viceUser.getKillStreak(); + double kd = 0.00; + double money = viceUser.getMoney(); + String formattedMoney = NumberFormat.getCurrencyInstance(Locale.US).format(money); + + if(deaths == 0) // Need to check if deaths is 0, throws an ArithmeticException otherwise + kd = kills; + else if(kills > 0) + kd = kills / deaths; + + DecimalFormat decimalFormat = new DecimalFormat("0.00"); + + // Stats title + if(nodeId == 1) { + event.setText("&6&l" + player.getName() + "'s Stats"); + } + + // ViceRank + else if(nodeId == 2) { + event.setText("&eRank&f: " + rank.getColoredName()); + } + + // Kills, Deaths + else if(nodeId == 3) { + event.setText("&aKills&f: " + kills + " &e| " + "&cDeaths&f: " + deaths); + } + + // K/D and Killstreaks + else if(nodeId == 4) { + event.setText("&aK/D Ratio&f: " + decimalFormat.format(kd) + " &e| " + "&cKillstreak&f: " + killstreak); + } + + // Money + else if(nodeId == 5) { + event.setText("&2Money&f: " + formattedMoney); + } + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dropship/DropShip.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dropship/DropShip.java new file mode 100644 index 0000000..392ef37 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dropship/DropShip.java @@ -0,0 +1,88 @@ +package net.grandtheftmc.vice.dropship; + +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.areas.obj.Area; +import net.grandtheftmc.vice.lootcrates.LootCrate; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.block.Chest; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.java.JavaPlugin; + +import java.util.Optional; + +public final class DropShip { + + private final JavaPlugin plugin; + private final DropShipManager dropShipManager; + + private final DropShipTask dropShipTask; + private final Player caller; + private final Area settlement; + private final Area.DropType dropType; + + private DropShipState dropState = DropShipState.IDLE; + + public DropShip(JavaPlugin plugin, DropShipManager dropShipManager, Player caller, Area settlement, boolean major) { + this.plugin = plugin; + this.dropShipManager = dropShipManager; + this.dropShipTask = new DropShipTask(major, dropShipManager, this); + this.caller = caller; + this.settlement = settlement; + this.dropType = major ? Area.DropType.MAJOR : Area.DropType.MINOR; + } + + public void start() { + this.dropShipTask.runTaskTimer(this.plugin, 0, 20L); + this.setDropState(DropShipState.IN_PROGRESS); + } + + public void stop() { + this.setDropState(DropShipState.ENDING); + this.dropShipTask.stop(); + this.dropShipManager.reset(); + } + + protected void restock() { + System.out.println("Settlement '" + this.settlement.getName() + "' has " + this.settlement.getChests().size() + " Chests."); + for (Chest chest : this.settlement.getChests()) { + if (!chest.getChunk().isLoaded()) + chest.getChunk().load(); + + refill(chest).ifPresent(lootCrate -> lootCrate.restock(this.dropType)); + } + } + + private Optional<LootCrate> refill(Chest chest) { + for (LootCrate crate : Vice.getCrateManager().getCrates()) { + if (crate.getLocation().getBlock().getLocation().toString().equals(chest.getLocation().toString())) { + return Optional.of(crate); + } + } + + Vice.getCrateManager().addCrate(chest.getLocation()); + return Optional.of(Vice.getCrateManager().getCrate(chest.getLocation())); + } + + public DropShipTask getDropShipTask() { + return dropShipTask; + } + + public DropShipState getDropState() { + return dropState; + } + + public void setDropState(DropShipState dropState) { + this.dropState = dropState; + } + + public Player getCaller() { + return caller; + } + + public Area getSettlement() { + return settlement; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dropship/DropShipConfirmationMenu.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dropship/DropShipConfirmationMenu.java new file mode 100644 index 0000000..6fd9225 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dropship/DropShipConfirmationMenu.java @@ -0,0 +1,4 @@ +package net.grandtheftmc.vice.dropship; + +public final class DropShipConfirmationMenu { +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dropship/DropShipHandler.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dropship/DropShipHandler.java new file mode 100644 index 0000000..7df57a7 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dropship/DropShipHandler.java @@ -0,0 +1,118 @@ +package net.grandtheftmc.vice.dropship; + +import net.grandtheftmc.core.gui.ConfirmationMenu; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.Component; +import net.grandtheftmc.vice.dropship.event.DropShipStartEvent; +import net.grandtheftmc.vice.items.ItemManager; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.Action; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.java.JavaPlugin; + +public final class DropShipHandler<T extends JavaPlugin> implements Component<DropShipManager, T> { + + private final DropShipManager dropShipManager; + private final ItemStack dropitem; + private final ItemStack majorDropitem; + private final T plugin; + + public DropShipHandler(DropShipManager dropShipManager, ItemManager itemManager, T plugin) { + this.dropShipManager = dropShipManager; + this.plugin = plugin; + this.dropitem = itemManager.getItem("dropship").getItem(); + this.majorDropitem = itemManager.getItem("majordropship").getItem(); + + Bukkit.getPluginManager().registerEvents(this, plugin); + } + + @Override + public DropShipManager onEnable(T plugin) { + return this.dropShipManager; + } + + @Override + public DropShipManager onDisable(T plugin) { + return this.dropShipManager; + } + + @EventHandler + protected final void onItemInteract(PlayerInteractEvent event) { + if (event.getHand() != EquipmentSlot.HAND) return; + if (event.getAction() != Action.RIGHT_CLICK_BLOCK && event.getAction() != Action.RIGHT_CLICK_AIR) return; + + ItemStack item = event.getItem(); + boolean small = false, major = false; + + if (item == null) + return; + + if (item.isSimilar(this.dropitem)) + small = true; + + if (item.isSimilar(this.majorDropitem)) + major = true; + + if (!small && !major) return; + + //Check if a player can start a drop ship. + if (!this.dropShipManager.canStartDrop()) { + event.setCancelled(true); + event.getPlayer().sendMessage(C.RED + "You cannot activate a dropship until the current event has finished.");//TODO, FORMAT. + return; + } + + boolean finalMajor = major; + ConfirmationMenu menu = new ConfirmationMenu(this.plugin, item.clone()) { + @Override + protected void onConfirm(InventoryClickEvent e, Player p) { + dropShipManager.getClosestArea(finalMajor, event.getPlayer(), area -> { + if (area == null) { + event.setCancelled(true); + event.getPlayer().sendMessage(C.RED + "Couldn't find a nearby settlement."); + return; + } + + if (item.getAmount() > 1) { + item.setAmount(item.getAmount() - 1); + } else { + event.getPlayer().getInventory().setItemInMainHand(new ItemStack(Material.AIR)); + } + + event.getPlayer().updateInventory(); + + dropShipManager.startDropShop(finalMajor, event.getPlayer(), area); + }); + } + + @Override + protected void onDeny(InventoryClickEvent e, Player p) { + event.setCancelled(true); + } + }; + + menu.open(event.getPlayer()); + } + + @EventHandler + protected final void onDropshipStart(DropShipStartEvent event) { + event.getDropShip().restock(); + } + + @EventHandler + protected final void onFallDamage(EntityDamageEvent event) { + if (!(event.getEntity() instanceof Player)) return; + Player player = (Player) event.getEntity(); + if (!this.dropShipManager.userDamageMap.containsKey(player.getUniqueId())) return; + + event.setCancelled(true); + this.dropShipManager.userDamageMap.remove(player.getUniqueId()); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dropship/DropShipManager.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dropship/DropShipManager.java new file mode 100644 index 0000000..1335967 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dropship/DropShipManager.java @@ -0,0 +1,199 @@ +package net.grandtheftmc.vice.dropship; + +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.Callback; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.areas.AreaManager; +import net.grandtheftmc.vice.areas.obj.Area; +import net.grandtheftmc.vice.items.ItemManager; +import net.grandtheftmc.vice.lootcrates.LootCrate; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.block.Chest; +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +public final class DropShipManager { + + /** + * Drop item redeem - trigger for nearest city. + * Alert players in chat 60 seconds before, clickable : teleport + * Alert players in chat onStart, clickable : teleport + * Restock chests in city + * + * If a player started the dropship, they should be celebrated in chat. + * + * Chest drops are the same as they are on GTM - will most likely be slightly balanced / changed going forwards. + * + * + */ + + protected final ConcurrentHashMap<UUID, Long> userDamageMap = new ConcurrentHashMap<>(); + + private final JavaPlugin plugin; + private final AreaManager areaManager; + + private DropShip serverDropShip = null; + private DropShip dropShip = null; + + public DropShipManager(JavaPlugin plugin, AreaManager areaManager, ItemManager itemManager) { + this.plugin = plugin; + this.areaManager = areaManager; + + new DropShipHandler<JavaPlugin>(this, itemManager, plugin); + new DropShipTeleportCommand(this); + + new BukkitRunnable() { + /** + * When an object implementing interface <code>Runnable</code> is used + * to create a thread, starting the thread causes the object's + * <code>run</code> method to be called in that separately executing + * thread. + * <p> + * The general contract of the method <code>run</code> is that it may + * take any action whatsoever. + * + * @see Thread#run() + */ + @Override + public void run() { + for (Area area : areaManager.getAreas()) { + if (area.getAreaType() == Area.AreaType.TOWN) continue; + + for (Chest chest : area.getChests()) { + ServerUtil.runTask(() -> { + LootCrate lootCrate = Vice.getCrateManager().getCrate(chest.getLocation()); + if (lootCrate == null) return; + lootCrate.restock(Area.DropType.DEFAULT); + }); + } + } + + Bukkit.broadcastMessage(C.YELLOW + C.BOLD + "DROP SHIP"); + Bukkit.broadcastMessage(C.GOLD + "All settlement chests have been restocked."); + } + }.runTaskTimerAsynchronously(plugin, 20 * 60, 20 * 60 * 60 * 8); + + new BukkitRunnable() { + /** + * When an object implementing interface <code>Runnable</code> is used + * to create a thread, starting the thread causes the object's + * <code>run</code> method to be called in that separately executing + * thread. + * <p> + * The general contract of the method <code>run</code> is that it may + * take any action whatsoever. + * + * @see Thread#run() + */ + @Override + public void run() { + for (UUID uuid : userDamageMap.keySet()) { + long time = userDamageMap.get(uuid); + if (time <= System.currentTimeMillis()) { + userDamageMap.remove(uuid); + } + } + } + }.runTaskTimerAsynchronously(plugin, 20 * 10, 20 * 10); + } + + /** + * Start a drop ship event. + * @param player - Caller of the drop ship + * @param area - Settlement to start the event at + */ + public void startDropShop(boolean major, Player player, Area area) { + if (this.dropShip != null) return; + this.dropShip = new DropShip(plugin, this, player, area, major); + this.dropShip.setDropState(DropShipState.STARTING); + this.dropShip.start(); + } + + /** + * Force stop an event. + */ + public void forceStop() { + if (this.dropShip == null) return; + this.dropShip.stop(); + } + + public void reset() { + this.dropShip = null; + } + + /** + * Get the currently active drop ship event. + * + * @return currently active drop ship + */ + public DropShip getDropShip() { + return dropShip; + } + + /** + * Check if a drop ship can be started. + * + * @return active state + */ + public boolean canStartDrop() { + return this.dropShip == null; + } + + /** + * Check if a drop ship event is currently active. + * + * @return active state + */ + public boolean isActive() { + return !this.canStartDrop(); + } + + /** + * Get the closest Area to a players current location. + * + * @param player - The Player + * @param callback - The return function of the closest Area + */ + public void getClosestArea(boolean major, Player player, Callback<Area> callback) { + ServerUtil.runTaskAsync(() -> { + Area closest = null; + double distance = -1; + for (Area area : this.areaManager.getAreas()) { + if (area.getAreaType() != Area.AreaType.TOWN) continue; + + double a = getDistanceSquared(player, area.getMaxX(), area.getMaxZ()); + double b = getDistanceSquared(player, area.getMinX(), area.getMinZ()); + + if (closest == null) { + closest = area; + distance = a < b ? a : b; + continue; + } + + if (a < distance) { + closest = area; + distance = a; + } + + if (b < distance) { + closest = area; + distance = b; + } + } + + callback.call(closest); + }); + } + + private double getDistanceSquared(Player player, int x, int z) { + Location origin = player.getLocation().clone(); + origin.setY(0); + return origin.distanceSquared(new Location(origin.getWorld(), x, origin.getY(), z)); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dropship/DropShipState.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dropship/DropShipState.java new file mode 100644 index 0000000..b87b98d --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dropship/DropShipState.java @@ -0,0 +1,17 @@ +package net.grandtheftmc.vice.dropship; + +public enum DropShipState { + + /** This is active while initialising */ + IDLE, + + /** This is active when the init process is complete */ + STARTING, + + /** This is active when the drop ship is in progress */ + IN_PROGRESS, + + /** This is active when the drop ship is finishing */ + ENDING, + ; +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dropship/DropShipTask.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dropship/DropShipTask.java new file mode 100644 index 0000000..f8dde81 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dropship/DropShipTask.java @@ -0,0 +1,133 @@ +package net.grandtheftmc.vice.dropship; + +import com.google.common.collect.Sets; +import net.grandtheftmc.vice.dropship.event.DropShipCountdownEvent; +import net.grandtheftmc.vice.dropship.event.DropShipStartEvent; +import net.grandtheftmc.vice.utils.TextHelper; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.HoverEvent; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.Set; + +public final class DropShipTask extends BukkitRunnable { + + private final DropShipManager dropShipManager; + private final DropShip dropShip; + private final int[] announceTimes = new int[] { 60, 30, 10 }; + private int timer; + + private final Set<Player> players; + private boolean major; + + public DropShipTask(boolean major, DropShipManager dropShipManager, DropShip dropShip) { + this.dropShipManager = dropShipManager; + this.dropShip = dropShip; + this.timer = 60; + this.major = major; + + this.players = Sets.newHashSet(); + } + + /** + * When an object implementing interface <code>Runnable</code> is used + * to create a thread, starting the thread causes the object's + * <code>run</code> method to be called in that separately executing + * thread. + * <p> + * The general contract of the method <code>run</code> is that it may + * take any action whatsoever. + * + * @see Thread#run() + */ + @Override + public final void run() { + + for (Player player : this.players) { + if (player.hasPotionEffect(PotionEffectType.LEVITATION) && player.isOnGround()) { + player.removePotionEffect(PotionEffectType.LEVITATION); + } + } + + DropShipCountdownEvent countdownEvent = new DropShipCountdownEvent(this.dropShip, this.timer); + Bukkit.getPluginManager().callEvent(countdownEvent); + + if (!this.canBroadcast()) { + + if (this.isDone()) { + + TextHelper hover = new TextHelper().setText("Click here to teleport to\nthe drop ship event!").setColor(ChatColor.YELLOW).setItalic(true); + ClickEvent clickEvent = new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/dropshiptp"); + HoverEvent hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, hover.toBaseComponent()); + + TextHelper text = new TextHelper("DROP SHIP\n").setBold(true).setColor(ChatColor.YELLOW) + .setHover(hoverEvent).setClick(clickEvent) + .addExtra(new TextHelper(" A" + (this.major ? " major" : "n") + " event has started at ").setBold(false).setColor(ChatColor.WHITE).setItalic(true)) + .addExtra(new TextHelper(this.dropShip.getSettlement().getName().replace("_", " ")).setBold(false).setColor(ChatColor.GOLD).setItalic(true)) + .addExtra(new TextHelper(".").setBold(false).setColor(ChatColor.WHITE).setItalic(true)) + .addExtra(new TextHelper("\n Click this message to teleport to the " + (this.major ? "Town" : "Village") + " and collect the loot!").setBold(false).setColor(ChatColor.WHITE).setItalic(true)) + .addExtra(new TextHelper("\n")); + + for (Player player : Bukkit.getOnlinePlayers()) { + player.spigot().sendMessage(text.build()); + } + + DropShipStartEvent startEvent = new DropShipStartEvent(this.dropShip); + Bukkit.getPluginManager().callEvent(startEvent); + + this.dropShip.stop(); + return; + } + + timer -= 1; + return; + } + + TextHelper hover = new TextHelper().setText("Click here to teleport to\nthe drop ship event!").setColor(ChatColor.YELLOW).setItalic(true); + ClickEvent clickEvent = new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/dropshiptp"); + HoverEvent hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, hover.toBaseComponent()); + + TextHelper text = new TextHelper("DROP SHIP\n").setBold(true).setColor(ChatColor.YELLOW) + .setHover(hoverEvent).setClick(clickEvent) + .addExtra(new TextHelper(" A" + (this.major ? " major" : "n") + " event is starting at ").setBold(false).setColor(ChatColor.WHITE).setItalic(true)) + .addExtra(new TextHelper(this.dropShip.getSettlement().getName().replace("_", " ")).setBold(false).setColor(ChatColor.GOLD).setItalic(true)) + .addExtra(new TextHelper(" in " + this.timer + " seconds.").setBold(false).setColor(ChatColor.WHITE).setItalic(true)) + .addExtra(new TextHelper("\n Click this message to teleport to the " + (this.major ? "Town" : "Village") + " and collect the loot!").setBold(false).setColor(ChatColor.WHITE).setItalic(true)) + .addExtra(new TextHelper("\n")); + + for (Player player : Bukkit.getOnlinePlayers()) { + player.sendMessage(""); + player.spigot().sendMessage(text.build()); + } + + timer -= 1; + } + + public void stop() { + this.cancel(); + this.players.clear(); + } + + private final boolean canBroadcast() { + for (int i : this.announceTimes) { + if (i == this.timer) return true; + } + return false; + } + + private final boolean isDone() { + return this.timer <= 0; + } + + public void addPlayer(Player player) { + this.players.add(player); + } + + public boolean contains(Player player) { + return this.players.contains(player); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dropship/DropShipTeleportCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dropship/DropShipTeleportCommand.java new file mode 100644 index 0000000..4e7bc5f --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dropship/DropShipTeleportCommand.java @@ -0,0 +1,59 @@ +package net.grandtheftmc.vice.dropship; + +import net.grandtheftmc.core.commands.CoreCommand; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.vice.areas.obj.Area; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; + +public class DropShipTeleportCommand extends CoreCommand<Player> { + + private final DropShipManager dropShipManager; + private final ThreadLocalRandom random; + + public DropShipTeleportCommand(DropShipManager dropShipManager) { + super("dropshiptp", "Teleport to a drop ship event."); + this.dropShipManager = dropShipManager; + this.random = ThreadLocalRandom.current(); + } + + @Override + public void execute(Player sender, String[] strings) { + if (!this.dropShipManager.isActive()) { + sender.sendMessage(C.RED + "There isn't an acitve drop ship event."); + return; + } + + if (this.dropShipManager.getDropShip().getDropShipTask().contains(sender)) { + sender.sendMessage(C.RED + "You can only teleport once.."); + return; + } + + this.dropShipManager.getDropShip().getDropShipTask().addPlayer(sender); + + Location location = this.getRandomLocation(); + if (location == null) { + sender.sendMessage(C.RED + "There was an error teleporting you, try again."); + return; + } + + sender.teleport(location); + + sender.removePotionEffect(PotionEffectType.LEVITATION); + sender.addPotionEffect(new PotionEffect(PotionEffectType.LEVITATION, 120 * 20, -4, true, false)); + this.dropShipManager.userDamageMap.put(sender.getUniqueId(), System.currentTimeMillis() + (1000 * 120)); + } + + private Location getRandomLocation() { + Area area = this.dropShipManager.getDropShip().getSettlement(); + int x = this.random.nextInt(area.getMinX(), area.getMaxX()); + int z = this.random.nextInt(area.getMinZ(), area.getMaxZ()); + int y = area.getWorld().getHighestBlockYAt(x, z) + this.random.nextInt(80, 100); + return new Location(area.getWorld(), x, y, z); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dropship/event/DropShipCountdownEvent.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dropship/event/DropShipCountdownEvent.java new file mode 100644 index 0000000..23716ef --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dropship/event/DropShipCountdownEvent.java @@ -0,0 +1,24 @@ +package net.grandtheftmc.vice.dropship.event; + +import net.grandtheftmc.core.events.CoreEvent; +import net.grandtheftmc.vice.dropship.DropShip; + +public final class DropShipCountdownEvent extends CoreEvent { + + private final DropShip dropShip; + private final int timer; + + public DropShipCountdownEvent(DropShip dropShip, int timer) { + super(false); + this.dropShip = dropShip; + this.timer = timer; + } + + public DropShip getDropShip() { + return dropShip; + } + + public int getTimer() { + return timer; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dropship/event/DropShipStartEvent.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dropship/event/DropShipStartEvent.java new file mode 100644 index 0000000..bd1ec13 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/dropship/event/DropShipStartEvent.java @@ -0,0 +1,18 @@ +package net.grandtheftmc.vice.dropship.event; + +import net.grandtheftmc.core.events.CoreEvent; +import net.grandtheftmc.vice.dropship.DropShip; + +public final class DropShipStartEvent extends CoreEvent { + + private final DropShip dropShip; + + public DropShipStartEvent(DropShip dropShip) { + super(false); + this.dropShip = dropShip; + } + + public DropShip getDropShip() { + return dropShip; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/BaseDrug.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/BaseDrug.java new file mode 100644 index 0000000..560eb2d --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/BaseDrug.java @@ -0,0 +1,18 @@ +package net.grandtheftmc.vice.drug; + +public abstract class BaseDrug implements Drug { + + private final String name; + + /** + * Construct a drug + */ + public BaseDrug(String name) { + this.name = name; + } + + @Override + public String getName() { + return name; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/Drug.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/Drug.java new file mode 100644 index 0000000..e1ccab7 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/Drug.java @@ -0,0 +1,5 @@ +package net.grandtheftmc.vice.drug; + +public interface Drug { + String getName(); +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/DrugManager.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/DrugManager.java new file mode 100644 index 0000000..7374f7d --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/DrugManager.java @@ -0,0 +1,53 @@ +package net.grandtheftmc.vice.drug; + +import com.google.common.collect.Lists; +import net.grandtheftmc.vice.drug.attribute.DrugAttribute; +import net.grandtheftmc.vice.drug.item.*; +import net.grandtheftmc.vice.drug.item.beer.BeerBottle; +import net.grandtheftmc.vice.drug.item.beer.CraftBeer; +import net.grandtheftmc.vice.drug.item.beer.HumulusLupulusFruit; +import net.grandtheftmc.vice.drug.item.beer.HumulusLupulusSeed; +import net.grandtheftmc.vice.drug.item.meth.puremeth.Methylamine; +import net.grandtheftmc.vice.drug.item.meth.puremeth.PureMeth; +import net.grandtheftmc.vice.drug.item.meth.whitemeth.EphredraSinica; +import net.grandtheftmc.vice.drug.item.meth.whitemeth.EphredraSinicaSeeds; +import net.grandtheftmc.vice.drug.item.meth.whitemeth.WhiteMeth; +import org.bukkit.event.Event; + +import java.util.Arrays; +import java.util.List; + +public final class DrugManager { + + private final List<BaseDrugItem<? extends DrugAttribute>> drugList; + + public DrugManager() { + this.drugList = Lists.newArrayList(); +// this.drugList.addAll(Arrays.asList( +// new BeerBottle(), +// new CraftBeer(), +// new HumulusLupulusFruit(), +// new HumulusLupulusSeed(), +// new Methylamine(), +// new PureMeth(), +// new EphredraSinica(), +// new EphredraSinicaSeeds(), +// new WhiteMeth(), +// new Acid(), +// new Cocaine(), +// new ConcentratedMagicMushroom(), +// new Crack(), +// new DistilledVodka(), +// new DriedMagicMushroom(), +// new Hop(), +// new Joint(), +// new LSD(), +// new MagicMushroom(), +// new MarijuanaLeaf(), +// new MarijuanaSeed(), +// new PotBrownie(), +// new Vodka(), +// new WeedBuds() +// )); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/DrugType.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/DrugType.java new file mode 100644 index 0000000..00527d2 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/DrugType.java @@ -0,0 +1,17 @@ +package net.grandtheftmc.vice.drug; + +public enum DrugType { + BEER(), + VODKA(), + CRAFT_BEER(), + MARIJUANA(), + JOINT(), + POT_BROWNIE(), + MAGIC_MUSHROOM(), + CRACK(), + METH(), + LSD(), + COCAINE(), + ; + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/attribute/DrugAttribute.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/attribute/DrugAttribute.java new file mode 100644 index 0000000..111875f --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/attribute/DrugAttribute.java @@ -0,0 +1,7 @@ +package net.grandtheftmc.vice.drug.attribute; + +import org.bukkit.event.Event; + +public interface DrugAttribute<T extends Event> { + void onEvent(T event); +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/attribute/DrugBrewable.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/attribute/DrugBrewable.java new file mode 100644 index 0000000..5d93253 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/attribute/DrugBrewable.java @@ -0,0 +1,28 @@ +package net.grandtheftmc.vice.drug.attribute; + +import org.bukkit.inventory.ItemStack; + +public interface DrugBrewable extends DrugAttribute { + + /** + * Brewing time in milliseconds. + * + * @return time + */ + int getBrewTime(); + + /** + * Cab the given item be brewed. + * + * @param item brewable item + * @return + */ + boolean isBrewable(ItemStack item); + + /** + * Get the Item that is returned from a finished brew. + * + * @return item + */ + ItemStack getBrewResult(); +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/attribute/DrugCraftable.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/attribute/DrugCraftable.java new file mode 100644 index 0000000..53d3192 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/attribute/DrugCraftable.java @@ -0,0 +1,13 @@ +package net.grandtheftmc.vice.drug.attribute; + +import net.grandtheftmc.vice.utils.recipe.ShapedRegister; +import net.grandtheftmc.vice.utils.recipe.ShapelessRegister; +import org.bukkit.event.inventory.PrepareItemCraftEvent; + +public interface DrugCraftable extends DrugAttribute< PrepareItemCraftEvent > { + + default ShapelessRegister getShapelessRecipe() { return null; } + default ShapedRegister getShapedRecipe() { return null; } + + boolean isShapeless(); +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/attribute/DrugDrinkable.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/attribute/DrugDrinkable.java new file mode 100644 index 0000000..c90c706 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/attribute/DrugDrinkable.java @@ -0,0 +1,4 @@ +package net.grandtheftmc.vice.drug.attribute; + +public interface DrugDrinkable extends DrugAttribute { +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/attribute/DrugGrowable.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/attribute/DrugGrowable.java new file mode 100644 index 0000000..c3ec587 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/attribute/DrugGrowable.java @@ -0,0 +1,20 @@ +package net.grandtheftmc.vice.drug.attribute; + +import org.bukkit.inventory.ItemStack; + +public interface DrugGrowable extends DrugAttribute { + + /** + * Growth time in milliseconds. + * + * @return time + */ + int getGrowthTime(); + + /** + * Get the Item that is returned from a fully grown plant. + * + * @return item + */ + ItemStack getPlantGrowthResult(); +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/attribute/DrugMachine.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/attribute/DrugMachine.java new file mode 100644 index 0000000..beaa6f7 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/attribute/DrugMachine.java @@ -0,0 +1,7 @@ +package net.grandtheftmc.vice.drug.attribute; + +import net.grandtheftmc.vice.drug.attribute.DrugAttribute; +import org.bukkit.event.Event; + +public interface DrugMachine<T extends Event> extends DrugAttribute<T> { +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/attribute/DrugPlaceable.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/attribute/DrugPlaceable.java new file mode 100644 index 0000000..1062719 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/attribute/DrugPlaceable.java @@ -0,0 +1,31 @@ +package net.grandtheftmc.vice.drug.attribute; + +import org.bukkit.Material; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.inventory.ItemStack; + +public interface DrugPlaceable extends DrugAttribute< BlockPlaceEvent > { + + /** + * Check if the plant is of type. + * + * @param item Material type + * @return + */ + boolean isPlant(ItemStack item); + + /** + * Get the blocks that the plant can grow on. + * + * @return Material array + */ + Material[] getPlantableBlocks(); + + /** + * Check if a Material accepts plant growth. + * + * @param material Given Block type + * @return true = can be planted + */ + boolean canPlantOn(Material material); +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/attribute/DrugPlantable.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/attribute/DrugPlantable.java new file mode 100644 index 0000000..58ad7eb --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/attribute/DrugPlantable.java @@ -0,0 +1,32 @@ +package net.grandtheftmc.vice.drug.attribute; + +import org.bukkit.Material; +import org.bukkit.event.Event; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; + +public interface DrugPlantable extends DrugAttribute< PlayerInteractEvent > { + + /** + * Check if the plant is of type. + * + * @param item Material type + * @return + */ + boolean isPlant(ItemStack item); + + /** + * Get the blocks that the plant can grow on. + * + * @return Material array + */ + Material[] getPlantableBlocks(); + + /** + * Check if a Material accepts plant growth. + * + * @param material Given Block type + * @return true = can be planted + */ + boolean canPlantOn(Material material); +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/Acid.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/Acid.java new file mode 100644 index 0000000..ed5d12f --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/Acid.java @@ -0,0 +1,17 @@ +package net.grandtheftmc.vice.drug.item; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drug.DrugType; +import net.grandtheftmc.vice.drug.attribute.DrugGrowable; + +public final class Acid extends BaseDrugItem<DrugGrowable> { + + /** + * Construct a new Drug Item + */ + public Acid() { + super("Acid", DrugType.MARIJUANA); + + setGameItem(Vice.getItemManager().getItem(super.getShortName())); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/BaseDrugItem.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/BaseDrugItem.java new file mode 100644 index 0000000..6c9aa65 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/BaseDrugItem.java @@ -0,0 +1,88 @@ +package net.grandtheftmc.vice.drug.item; + +import net.grandtheftmc.vice.drug.DrugType; +import net.grandtheftmc.vice.drug.attribute.DrugAttribute; +import net.grandtheftmc.vice.items.GameItem; + +public abstract class BaseDrugItem<T extends DrugAttribute> implements DrugItem<T> { + + private final String name, shortName; + private GameItem gameItem; + private final DrugType drugType; + + private T attribute = null; + + /** + * Construct a new Drug Item + */ + public BaseDrugItem(String name, DrugType drugType) { + this.name = name; + this.shortName = name.toLowerCase().replace(" ", ""); + this.drugType = drugType; + } + + /** + * Get the name of the DrugItem + * + * @return name + */ + @Override + public String getName() { + return name; + } + + /** + * Get the short name of the DrugItem + * + * @return name + */ + @Override + public String getShortName() { + return shortName; + } + + /** + * Get the GameItem version of this DrugItem. + * + * @return Game Item + */ + @Override + public GameItem getGameItem() { + return gameItem; + } + + /** + * Set the Game Item. + * + * @param gameItem Item + */ + @Override + public void setGameItem(GameItem gameItem) { + this.gameItem = gameItem; + } + + /** + * Get the Type of Drug this Item is affiliated with. + * + * @return Drug Type + */ + @Override + public DrugType getDrugType() { + return drugType; + } + + @Override + public T getAttribute() { + return attribute; + } + + @Override + public void setAttribute(T attribute) { + this.attribute = attribute; + } + + @Override + public String toString() { + return "" + this.name + ":{" + "DrugType:" + drugType.name() + ", Attribute:" + attribute.getClass().getSimpleName() + "}"; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/Cocaine.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/Cocaine.java new file mode 100644 index 0000000..cc2714c --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/Cocaine.java @@ -0,0 +1,17 @@ +package net.grandtheftmc.vice.drug.item; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drug.DrugType; +import net.grandtheftmc.vice.drug.attribute.DrugGrowable; + +public final class Cocaine extends BaseDrugItem<DrugGrowable> { + + /** + * Construct a new Drug Item + */ + public Cocaine() { + super("Cocaine", DrugType.COCAINE); + + setGameItem(Vice.getItemManager().getItem(super.getShortName())); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/ConcentratedMagicMushroom.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/ConcentratedMagicMushroom.java new file mode 100644 index 0000000..8a43bef --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/ConcentratedMagicMushroom.java @@ -0,0 +1,17 @@ +package net.grandtheftmc.vice.drug.item; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drug.DrugType; +import net.grandtheftmc.vice.drug.attribute.DrugGrowable; + +public final class ConcentratedMagicMushroom extends BaseDrugItem<DrugGrowable> { + + /** + * Construct a new Drug Item + */ + public ConcentratedMagicMushroom() { + super("Concentrated Magic Mushroom", DrugType.MAGIC_MUSHROOM); + + super.setGameItem(Vice.getItemManager().getItem(super.getShortName())); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/Crack.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/Crack.java new file mode 100644 index 0000000..9a91d2a --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/Crack.java @@ -0,0 +1,17 @@ +package net.grandtheftmc.vice.drug.item; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drug.DrugType; +import net.grandtheftmc.vice.drug.attribute.DrugGrowable; + +public final class Crack extends BaseDrugItem<DrugGrowable> { + + /** + * Construct a new Drug Item + */ + public Crack() { + super("Crack", DrugType.CRACK); + + super.setGameItem(Vice.getItemManager().getItem(super.getShortName())); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/DistilledVodka.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/DistilledVodka.java new file mode 100644 index 0000000..40b0659 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/DistilledVodka.java @@ -0,0 +1,45 @@ +package net.grandtheftmc.vice.drug.item; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drug.DrugType; +import net.grandtheftmc.vice.drug.attribute.DrugCraftable; +import net.grandtheftmc.vice.items.ItemManager; +import net.grandtheftmc.vice.utils.recipe.ShapelessRegister; +import org.bukkit.Material; +import org.bukkit.event.inventory.PrepareItemCraftEvent; +import org.bukkit.inventory.ItemStack; + +public final class DistilledVodka extends BaseDrugItem< DrugCraftable > { + + /** + * Construct a new Drug Item + */ + public DistilledVodka() { + super("Distilled Vodka", DrugType.VODKA); + + setGameItem(Vice.getItemManager().getItem(super.getShortName())); + + ShapelessRegister recipe = new ShapelessRegister(ItemManager.NAMESPACED_KEY, super.getGameItem().getItem().clone()); + + ItemStack vodka = Vodka.OUTPUT.clone(); + recipe.addIngredient(2, vodka); + + ItemStack arrow = new ItemStack(Material.ARROW); + recipe.addIngredient(1, arrow); + + recipe.register(); + + setAttribute(new DrugCraftable() { + @Override + public boolean isShapeless() { + return false; + } + + @Override + public void onEvent(PrepareItemCraftEvent event) { + + } + }); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/DriedMagicMushroom.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/DriedMagicMushroom.java new file mode 100644 index 0000000..6a16cc6 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/DriedMagicMushroom.java @@ -0,0 +1,25 @@ +package net.grandtheftmc.vice.drug.item; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drug.DrugType; +import net.grandtheftmc.vice.drug.attribute.DrugMachine; +import org.bukkit.event.Event; + +public final class DriedMagicMushroom extends BaseDrugItem<DrugMachine> { + + /** + * Construct a new Drug Item + */ + public DriedMagicMushroom() { + super("Dried Magic Mushroom", DrugType.MAGIC_MUSHROOM); + + setGameItem(Vice.getItemManager().getItem(super.getShortName())); + + setAttribute(new DrugMachine() { + @Override + public void onEvent(Event event) { + + } + }); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/DrugItem.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/DrugItem.java new file mode 100644 index 0000000..c007da6 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/DrugItem.java @@ -0,0 +1,46 @@ +package net.grandtheftmc.vice.drug.item; + +import net.grandtheftmc.vice.drug.DrugType; +import net.grandtheftmc.vice.drug.attribute.DrugAttribute; +import net.grandtheftmc.vice.items.GameItem; + +public interface DrugItem<T extends DrugAttribute> { + + /** + * Get the name of the DrugItem + * + * @return name + */ + String getName(); + + /** + * Get the short name of the DrugItem + * + * @return name + */ + String getShortName(); + + /** + * Get the GameItem version of this DrugItem. + * + * @return Game Item + */ + GameItem getGameItem(); + + /** + * Set the Game Item. + * + * @param gameItem Item + */ + void setGameItem(GameItem gameItem); + + /** + * Get the Type of Drug this Item is affiliated with. + * + * @return Drug Type + */ + DrugType getDrugType(); + + T getAttribute(); + void setAttribute(T attribute); +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/Hop.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/Hop.java new file mode 100644 index 0000000..e4f9aa8 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/Hop.java @@ -0,0 +1,19 @@ +package net.grandtheftmc.vice.drug.item; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drug.DrugType; +import net.grandtheftmc.vice.drug.attribute.DrugGrowable; + +public final class Hop extends BaseDrugItem<DrugGrowable> { + + /** + * Construct a new Drug Item + */ + public Hop() { + super("Hop", DrugType.BEER); + + setGameItem(Vice.getItemManager().getItem(super.getShortName())); + + setAttribute(null); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/Joint.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/Joint.java new file mode 100644 index 0000000..29e0ed3 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/Joint.java @@ -0,0 +1,78 @@ +package net.grandtheftmc.vice.drug.item; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drug.DrugType; +import net.grandtheftmc.vice.drug.attribute.DrugCraftable; +import net.grandtheftmc.vice.items.ItemManager; +import net.grandtheftmc.vice.utils.recipe.ShapedRegister; +import org.bukkit.Material; +import org.bukkit.event.inventory.PrepareItemCraftEvent; +import org.bukkit.inventory.ItemStack; +import us.myles.ViaVersion.util.ConcurrentList; + +import java.util.Arrays; +import java.util.stream.Collectors; + +public final class Joint extends BaseDrugItem< DrugCraftable > { + + /** + * Construct a new Drug Item + */ + public Joint() { + super("Joint", DrugType.JOINT); + + setGameItem(Vice.getItemManager().getItem(super.getShortName())); + + ShapedRegister recipe = new ShapedRegister(ItemManager.NAMESPACED_KEY, super.getGameItem().getItem().clone()); + recipe.shape("000","010","222"); + ItemStack bud = MarijuanaLeaf.getOutput(); + recipe.setIngredient('1', bud); + ItemStack paper = new ItemStack(Material.PAPER); + recipe.setIngredient('2', paper); + recipe.register(); + + setAttribute(new DrugCraftable() { + @Override + public boolean isShapeless() { + return false; + } + + @Override + public void onEvent(PrepareItemCraftEvent event) { + if (event.getInventory() == null) return; + if (event.getRecipe().getResult() != recipe.getOutput()) return; + + ConcurrentList<ItemStack> matrix = new ConcurrentList<>(); + matrix.addAll(Arrays.stream(event.getInventory().getMatrix()).filter(i -> i != null && i.getType() != Material.AIR).collect(Collectors.toList())); + + int budCount = (int) matrix.stream().filter(item -> { + if (item != null && item.equals(bud)) { + matrix.remove(item); + return true; + } + return false; + }).count(); + int paperCount = (int) matrix.stream().filter(item -> { + if (item != null && item.getType() == paper.getType()) { + matrix.remove(item); + return true; + } + return false; + }).count(); + + if (!matrix.isEmpty()) { + event.getInventory().setResult(new ItemStack(Material.AIR)); + return; + } + + if (budCount == 1 && paperCount == 3) { + event.getInventory().setResult(recipe.getOutput()); + System.out.println("" + event.getInventory().getResult().getType().name()); + return; + } + + event.getInventory().setResult(new ItemStack(Material.AIR)); + } + }); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/LSD.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/LSD.java new file mode 100644 index 0000000..d48aa8e --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/LSD.java @@ -0,0 +1,17 @@ +package net.grandtheftmc.vice.drug.item; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drug.DrugType; +import net.grandtheftmc.vice.drug.attribute.DrugGrowable; + +public final class LSD extends BaseDrugItem<DrugGrowable> { + + /** + * Construct a new Drug Item + */ + public LSD() { + super("LSD", DrugType.LSD); + + setGameItem(Vice.getItemManager().getItem(super.getShortName())); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/MagicMushroom.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/MagicMushroom.java new file mode 100644 index 0000000..08dcd75 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/MagicMushroom.java @@ -0,0 +1,17 @@ +package net.grandtheftmc.vice.drug.item; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drug.DrugType; +import net.grandtheftmc.vice.drug.attribute.DrugGrowable; + +public class MagicMushroom extends BaseDrugItem<DrugGrowable> { + + /** + * Construct a new Drug Item + */ + public MagicMushroom() { + super("Magic Mushroom", DrugType.MAGIC_MUSHROOM); + + setGameItem(Vice.getItemManager().getItem(super.getShortName())); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/MarijuanaLeaf.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/MarijuanaLeaf.java new file mode 100644 index 0000000..01739fa --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/MarijuanaLeaf.java @@ -0,0 +1,35 @@ +package net.grandtheftmc.vice.drug.item; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drug.DrugType; +import net.grandtheftmc.vice.drug.attribute.DrugMachine; +import org.bukkit.event.Event; +import org.bukkit.inventory.ItemStack; + +public final class MarijuanaLeaf extends BaseDrugItem<DrugMachine> { + + private static final ItemStack OUTPUT = Vice.getItemManager().getItem("").getItem(); + + /** + * Construct a new Drug Item + */ + public MarijuanaLeaf() { + super("Marijuana Leaf", DrugType.MARIJUANA); + + setGameItem(Vice.getItemManager().getItem(super.getShortName())); + + setAttribute(new DrugMachine() { + + //OUTPUT + + @Override + public void onEvent(Event event) { + + } + }); + } + + protected static ItemStack getOutput() { + return OUTPUT.clone(); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/MarijuanaSeed.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/MarijuanaSeed.java new file mode 100644 index 0000000..53ef942 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/MarijuanaSeed.java @@ -0,0 +1,54 @@ +package net.grandtheftmc.vice.drug.item; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drug.DrugType; +import net.grandtheftmc.vice.drug.attribute.DrugPlaceable; +import org.bukkit.Material; +import org.bukkit.block.BlockFace; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.inventory.ItemStack; + +public final class MarijuanaSeed extends BaseDrugItem< DrugPlaceable > { + + private static final Material[] ACCEPTED_BLOCKS = new Material[]{ Material.SAND, Material.DIRT, Material.GRASS, Material.SOIL }; + + /** + * Construct a new Drug Item + */ + public MarijuanaSeed() { + super("Marijuana Seed", DrugType.MARIJUANA); + + setGameItem(Vice.getItemManager().getItem(super.getShortName())); + + setAttribute(new DrugPlaceable() { + @Override + public boolean isPlant(ItemStack item) { + return item.isSimilar(MarijuanaSeed.super.getGameItem().getItem()); + } + + @Override + public Material[] getPlantableBlocks() { + return ACCEPTED_BLOCKS; + } + + @Override + public boolean canPlantOn(Material material) { + for (Material m : ACCEPTED_BLOCKS) { + if (material == m) return true; + } + return false; + } + + @Override + public void onEvent(BlockPlaceEvent event) { + if (!this.isPlant(event.getItemInHand())) return; + if (!this.canPlantOn(event.getBlockAgainst().getType())) { + event.setCancelled(true); + return; + } + + System.out.println("Placed plant: " + MarijuanaSeed.super.getName()); + } + }); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/PotBrownie.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/PotBrownie.java new file mode 100644 index 0000000..af229db --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/PotBrownie.java @@ -0,0 +1,78 @@ +package net.grandtheftmc.vice.drug.item; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drug.DrugType; +import net.grandtheftmc.vice.drug.attribute.DrugCraftable; +import net.grandtheftmc.vice.items.ItemManager; +import net.grandtheftmc.vice.utils.recipe.ShapedRegister; +import org.bukkit.Material; +import org.bukkit.event.inventory.PrepareItemCraftEvent; +import org.bukkit.inventory.ItemStack; +import us.myles.ViaVersion.util.ConcurrentList; + +import java.util.Arrays; +import java.util.stream.Collectors; + +public final class PotBrownie extends BaseDrugItem< DrugCraftable > { + + /** + * Construct a new Drug Item + */ + public PotBrownie() { + super("Pot Brownie", DrugType.POT_BROWNIE); + + setGameItem(Vice.getItemManager().getItem(super.getShortName())); + + ShapedRegister recipe = new ShapedRegister(ItemManager.NAMESPACED_KEY, super.getGameItem().getItem().clone()); + recipe.shape("111","121","111"); + ItemStack cookie = new ItemStack(Material.PAPER); + recipe.setIngredient('1', cookie); + ItemStack bud = MarijuanaLeaf.getOutput(); + recipe.setIngredient('2', bud); + recipe.register(); + + setAttribute(new DrugCraftable() { + @Override + public boolean isShapeless() { + return false; + } + + @Override + public void onEvent(PrepareItemCraftEvent event) { + if (event.getInventory() == null) return; + if (event.getRecipe().getResult() != recipe.getOutput()) return; + + ConcurrentList<ItemStack> matrix = new ConcurrentList<>(); + matrix.addAll(Arrays.stream(event.getInventory().getMatrix()).filter(i -> i != null && i.getType() != Material.AIR).collect(Collectors.toList())); + + int budCount = (int) matrix.stream().filter(item -> { + if (item != null && item.equals(bud)) { + matrix.remove(item); + return true; + } + return false; + }).count(); + int cookieCount = (int) matrix.stream().filter(item -> { + if (item != null && item.getType() == cookie.getType()) { + matrix.remove(item); + return true; + } + return false; + }).count(); + + if (!matrix.isEmpty()) { + event.getInventory().setResult(new ItemStack(Material.AIR)); + return; + } + + if (budCount == 1 && cookieCount == 8) { + event.getInventory().setResult(recipe.getOutput()); + System.out.println("" + event.getInventory().getResult().getType().name()); + return; + } + + event.getInventory().setResult(new ItemStack(Material.AIR)); + } + }); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/Vodka.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/Vodka.java new file mode 100644 index 0000000..896f849 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/Vodka.java @@ -0,0 +1,22 @@ +package net.grandtheftmc.vice.drug.item; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drug.DrugType; +import net.grandtheftmc.vice.drug.attribute.DrugBrewable; +import org.bukkit.inventory.ItemStack; + +public final class Vodka extends BaseDrugItem<DrugBrewable> { + + protected static final ItemStack OUTPUT = Vice.getItemManager().getItem("vodka").getItem(); + + /** + * Construct a new Drug Item + */ + public Vodka() { + super("Vodka", DrugType.VODKA); + + setGameItem(Vice.getItemManager().getItem(super.getShortName())); + + setAttribute(null); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/WeedBuds.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/WeedBuds.java new file mode 100644 index 0000000..d958d3b --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/WeedBuds.java @@ -0,0 +1,16 @@ +package net.grandtheftmc.vice.drug.item; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drug.DrugType; + +public final class WeedBuds extends BaseDrugItem { + + /** + * Construct a new Drug Item + */ + public WeedBuds() { + super("Weed Buds", DrugType.MARIJUANA); + + setGameItem(Vice.getItemManager().getItem(super.getShortName())); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/beer/BeerBottle.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/beer/BeerBottle.java new file mode 100644 index 0000000..436a22c --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/beer/BeerBottle.java @@ -0,0 +1,23 @@ +package net.grandtheftmc.vice.drug.item.beer; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drug.DrugType; +import net.grandtheftmc.vice.drug.attribute.DrugMachine; +import net.grandtheftmc.vice.drug.item.BaseDrugItem; +//import net.grandtheftmc.vice.machine.event.MachineRecipeCompleteEvent; + +public final class BeerBottle extends BaseDrugItem<DrugMachine> { + + /** + * Construct a new Drug Item + */ + public BeerBottle() { + super("Beer Bottle", DrugType.BEER); + + super.setGameItem(Vice.getItemManager().getItem(super.getShortName())); + + super.setAttribute(event -> { + + }); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/beer/CraftBeer.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/beer/CraftBeer.java new file mode 100644 index 0000000..66addef --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/beer/CraftBeer.java @@ -0,0 +1,21 @@ +package net.grandtheftmc.vice.drug.item.beer; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drug.DrugType; +import net.grandtheftmc.vice.drug.attribute.DrugMachine; +import net.grandtheftmc.vice.drug.item.BaseDrugItem; +//import net.grandtheftmc.vice.machine.event.MachineRecipeCompleteEvent; + +public final class CraftBeer extends BaseDrugItem<DrugMachine> { + + /** + * Construct a new Drug Item + */ + public CraftBeer() { + super("Craft Beer", DrugType.CRAFT_BEER); + + setGameItem(Vice.getItemManager().getItem(super.getShortName())); + + setAttribute(null); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/beer/HumulusLupulusFruit.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/beer/HumulusLupulusFruit.java new file mode 100644 index 0000000..71248a1 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/beer/HumulusLupulusFruit.java @@ -0,0 +1,26 @@ +package net.grandtheftmc.vice.drug.item.beer; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drug.DrugType; +import net.grandtheftmc.vice.drug.attribute.DrugMachine; +import net.grandtheftmc.vice.drug.item.BaseDrugItem; +import org.bukkit.event.Event; + +public final class HumulusLupulusFruit extends BaseDrugItem<DrugMachine> { + + /** + * Construct a new Drug Item + */ + public HumulusLupulusFruit() { + super("Humulus Lupulus Fruit", DrugType.BEER); + + setGameItem(Vice.getItemManager().getItem(super.getShortName())); + + setAttribute(new DrugMachine() { + @Override + public void onEvent(Event event) { + + } + }); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/beer/HumulusLupulusSeed.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/beer/HumulusLupulusSeed.java new file mode 100644 index 0000000..2b36b4e --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/beer/HumulusLupulusSeed.java @@ -0,0 +1,47 @@ +package net.grandtheftmc.vice.drug.item.beer; + +import net.grandtheftmc.vice.drug.DrugType; +import net.grandtheftmc.vice.drug.attribute.DrugPlantable; +import net.grandtheftmc.vice.drug.item.BaseDrugItem; +import org.bukkit.Material; +import org.bukkit.block.BlockFace; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; + +public final class HumulusLupulusSeed extends BaseDrugItem< DrugPlantable > { + + private static final Material[] ACCEPTED_BLOCKS = new Material[]{ Material.SAND }; + + /** + * Construct a new Drug Item + */ + public HumulusLupulusSeed() { + super("Humulus Lupulus Seed", DrugType.BEER); + + super.setAttribute(new DrugPlantable() { + @Override + public void onEvent(PlayerInteractEvent event) { + if (!this.isPlant(event.getItem())) return; + if (event.getBlockFace() != BlockFace.UP) return; + if (!this.canPlantOn(event.getClickedBlock().getType())) return; + + //TODO Plant seed. + } + + @Override + public boolean isPlant(ItemStack item) { + return item.isSimilar(HumulusLupulusSeed.super.getGameItem().getItem()); + } + + @Override + public Material[] getPlantableBlocks() { + return ACCEPTED_BLOCKS; + } + + @Override + public boolean canPlantOn(Material material) { + return material == ACCEPTED_BLOCKS[0]; + } + }); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/meth/puremeth/Methylamine.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/meth/puremeth/Methylamine.java new file mode 100644 index 0000000..9538092 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/meth/puremeth/Methylamine.java @@ -0,0 +1,18 @@ +package net.grandtheftmc.vice.drug.item.meth.puremeth; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drug.DrugType; +import net.grandtheftmc.vice.drug.attribute.DrugGrowable; +import net.grandtheftmc.vice.drug.item.BaseDrugItem; + +public final class Methylamine extends BaseDrugItem<DrugGrowable> { + + /** + * Construct a new Drug Item + */ + public Methylamine() { + super("Methylamine", DrugType.METH); + + setGameItem(Vice.getItemManager().getItem(super.getShortName())); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/meth/puremeth/PureMeth.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/meth/puremeth/PureMeth.java new file mode 100644 index 0000000..4f9b72a --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/meth/puremeth/PureMeth.java @@ -0,0 +1,18 @@ +package net.grandtheftmc.vice.drug.item.meth.puremeth; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drug.DrugType; +import net.grandtheftmc.vice.drug.attribute.DrugGrowable; +import net.grandtheftmc.vice.drug.item.BaseDrugItem; + +public final class PureMeth extends BaseDrugItem<DrugGrowable> { + + /** + * Construct a new Drug Item + */ + public PureMeth() { + super("Pure Meth", DrugType.METH); + + setGameItem(Vice.getItemManager().getItem(super.getShortName())); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/meth/whitemeth/EphredraSinica.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/meth/whitemeth/EphredraSinica.java new file mode 100644 index 0000000..bbd01a0 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/meth/whitemeth/EphredraSinica.java @@ -0,0 +1,18 @@ +package net.grandtheftmc.vice.drug.item.meth.whitemeth; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drug.DrugType; +import net.grandtheftmc.vice.drug.attribute.DrugGrowable; +import net.grandtheftmc.vice.drug.item.BaseDrugItem; + +public final class EphredraSinica extends BaseDrugItem<DrugGrowable> { + + /** + * Construct a new Drug Item + */ + public EphredraSinica() { + super("Ephredra Sinica", DrugType.METH); + + super.setGameItem(Vice.getItemManager().getItem(super.getShortName())); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/meth/whitemeth/EphredraSinicaSeeds.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/meth/whitemeth/EphredraSinicaSeeds.java new file mode 100644 index 0000000..13376bd --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/meth/whitemeth/EphredraSinicaSeeds.java @@ -0,0 +1,50 @@ +package net.grandtheftmc.vice.drug.item.meth.whitemeth; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drug.DrugType; +import net.grandtheftmc.vice.drug.attribute.DrugPlantable; +import net.grandtheftmc.vice.drug.item.BaseDrugItem; +import org.bukkit.Material; +import org.bukkit.block.BlockFace; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; + +public final class EphredraSinicaSeeds extends BaseDrugItem<DrugPlantable> { + + private static final Material[] ACCEPTED_BLOCKS = new Material[]{ Material.SAND }; + + /** + * Construct a new Drug Item + */ + public EphredraSinicaSeeds() { + super("Ephredra Sinica Seed", DrugType.METH); + + super.setGameItem(Vice.getItemManager().getItem(super.getShortName())); + + super.setAttribute(new DrugPlantable() { + @Override + public void onEvent(PlayerInteractEvent event) { + if (!this.isPlant(event.getItem())) return; + if (event.getBlockFace() != BlockFace.UP) return; + if (!this.canPlantOn(event.getClickedBlock().getType())) return; + + //TODO Plant seed. + } + + @Override + public boolean isPlant(ItemStack item) { + return item.isSimilar(EphredraSinicaSeeds.super.getGameItem().getItem()); + } + + @Override + public Material[] getPlantableBlocks() { + return ACCEPTED_BLOCKS; + } + + @Override + public boolean canPlantOn(Material material) { + return material == ACCEPTED_BLOCKS[0]; + } + }); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/meth/whitemeth/WhiteMeth.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/meth/whitemeth/WhiteMeth.java new file mode 100644 index 0000000..74ef2e5 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drug/item/meth/whitemeth/WhiteMeth.java @@ -0,0 +1,18 @@ +package net.grandtheftmc.vice.drug.item.meth.whitemeth; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drug.DrugType; +import net.grandtheftmc.vice.drug.attribute.DrugGrowable; +import net.grandtheftmc.vice.drug.item.BaseDrugItem; + +public final class WhiteMeth extends BaseDrugItem<DrugGrowable> { + + /** + * Construct a new Drug Item + */ + public WhiteMeth() { + super("White Meth", DrugType.METH); + + setGameItem(Vice.getItemManager().getItem(super.getShortName())); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/Drug.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/Drug.java new file mode 100644 index 0000000..dd8032e --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/Drug.java @@ -0,0 +1,55 @@ +package net.grandtheftmc.vice.drugs; + +import net.grandtheftmc.vice.drugs.categories.DrugCategory; +import org.bukkit.entity.Player; + +import java.util.Optional; + +/** + * Created by Remco on 25-3-2017. + */ +public abstract class Drug { + + private final String name; + private int duration; + + protected Drug(String name, int duration) { + this.name = name; + this.duration = duration; + } + + /** + * General startpoint for applying drugs. + * + * @param player + * @return + */ + public abstract boolean apply(Player player); + + /** + * Name of the drug + * + * @return + */ + public String getName() { + return name; + } + + + /** + * Duration of the particle effects + * + * @return + */ + public int getDuration() { + return duration; + } + + public Optional<DrugCategory> getCategory() { + return DrugCategory.byDrug(this); + } + + protected Drug getInstance(){ + return this; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/DrugCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/DrugCommand.java new file mode 100644 index 0000000..64aacdd --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/DrugCommand.java @@ -0,0 +1,52 @@ +package net.grandtheftmc.vice.drugs; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.Collection; + +public class DrugCommand implements CommandExecutor { + public static Collection<String> addingBlocks = new ArrayList<>(); + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!s.hasPermission("vice.drugs.admin")) { + s.sendMessage(Utils.f("&cYou do not have permission to execute this command!")); + return true; + } + if (!(s instanceof Player)) { + s.sendMessage(Lang.VICE.f("&cYou are not a player!")); + return true; + } + Player player = (Player) s; + if (args.length != 1) { + sendHelp(player); + return true; + } + switch (args[0]) { + case "lb": + case "lockedblock": + if (addingBlocks.contains(player.getName())) { + player.sendMessage(Lang.DRUGS.f("&cYou are no longer adding/removing locked blocks")); + addingBlocks.remove(player.getName()); + } else { + player.sendMessage(Lang.DRUGS.f("&aYou are now adding/removing locked blocks")); + addingBlocks.add(player.getName()); + } + return true; + default: + sendHelp(player); + } + return true; + } + + public void sendHelp(Player player) { + player.sendMessage(Lang.DRUGS.f("&7Usage:")); + player.sendMessage(Utils.f("&a/drugs [lb/lockedblock] &7- Enable/Disable the Adding or Removal of locked blocks")); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/DrugComponent.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/DrugComponent.java new file mode 100644 index 0000000..f8a9527 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/DrugComponent.java @@ -0,0 +1,131 @@ +package net.grandtheftmc.vice.drugs; + +import net.grandtheftmc.core.util.Component; +import net.grandtheftmc.vice.Vice; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; + +import java.util.Random; + +public final class DrugComponent implements Component<DrugComponent, Vice> { + + private final Random random; + private BukkitTask task; + + public DrugComponent(Vice vice) { + this.random = new Random(); + + SeedType.init(); + + this.task = new BukkitRunnable() { + @Override + public void run() { + for (SeedType type : SeedType.values()) { + for (SeedDrop drop : type.getDrops()) { + if (System.currentTimeMillis() < drop.getLast()) continue; + drop.next(); + + Bukkit.getOnlinePlayers().forEach(player -> { + if (!player.getLocation().getWorld().getName().equals("spawn") && player.getLocation().getBlock().getBiome() == drop.getBiome()) { + dropItem(type.getItemStack(), player.getLocation(), drop.getRange()); + } + }); + } + } + } + }.runTaskTimer(vice, 1000, 20 * 10); + } + + @Override + public DrugComponent onDisable(Vice plugin) { + this.task.cancel(); + return this; + } + + private void dropItem(ItemStack itemStack, Location location, int radius) { + int x = this.random.nextInt(radius); + int z = this.random.nextInt(radius); + if (this.random.nextBoolean()) x = -x; + if (this.random.nextBoolean()) z = -z; + + Location loc = location.clone().add(x, 0, z); + loc.setY(loc.getWorld().getHighestBlockYAt(loc) + 1); + + loc.getWorld().dropItem(loc, itemStack.clone()); + } + + @EventHandler + protected final void onBlockBreak(BlockBreakEvent event) { + if (event.getBlock() == null) return; + + switch (event.getBlock().getType()) { + case CACTUS: + case SUGAR_CANE_BLOCK: { + int i = this.random.nextInt(100); + if (i <= 2) this.destroyPlant(event.getBlock(), event.getBlock().getType()); + break; + } + + case POTATO: { + int i = this.random.nextInt(100); + event.setDropItems(false); + if (i <= 90) event.getBlock().getWorld().dropItemNaturally(event.getBlock().getLocation(), new ItemStack(Material.POTATO_ITEM)); + event.getBlock().getWorld().dropItemNaturally(event.getBlock().getLocation(), new ItemStack(Material.POTATO_ITEM)); + break; + } + + case MELON_BLOCK: { + event.setDropItems(false); + event.getBlock().getWorld().dropItemNaturally(event.getBlock().getLocation(), Vice.getItemManager().getItem("cocaleaf").getItem()); + event.getBlock().getWorld().dropItemNaturally(event.getBlock().getLocation(), Vice.getItemManager().getItem("cocaleaf").getItem()); + + int i = this.random.nextInt(100); + if (i <= 3) { + for (BlockFace face : new BlockFace[] {BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST}) { + if (event.getBlock().getRelative(face).getType() == Material.MELON_STEM) { + event.getBlock().getRelative(face).setType(Material.AIR); + break; + } + } + } + } + + case NETHER_STALK: + event.setDropItems(false); + event.getBlock().getWorld().dropItemNaturally(event.getBlock().getLocation(), Vice.getItemManager().getItem("ergotfungi").getItem()); + + int i = this.random.nextInt(100); + if (i <= 2) { + for (BlockFace face : new BlockFace[] {BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST}) { + if (event.getBlock().getRelative(face).getType() == Material.NETHER_STALK) { + event.getBlock().getRelative(face).setType(Material.AIR); + break; + } + } + } + break; + + case LONG_GRASS: + event.setDropItems(false); + break; + } + } + + private void destroyPlant(Block block, Material material) { + Location origin = block.getLocation().clone(); + for (int i = block.getY() - 5; i < block.getY() + 5; i++) { + Block found = origin.getWorld().getBlockAt(origin.getBlockX(), i, origin.getBlockZ()); + if (found.getType() == material) { + found.setType(Material.AIR); + } + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/DrugEffect.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/DrugEffect.java new file mode 100644 index 0000000..9163db8 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/DrugEffect.java @@ -0,0 +1,13 @@ +package net.grandtheftmc.vice.drugs; + +import org.bukkit.entity.Player; + +/** + * Created by Remco on 25-3-2017. + */ +@FunctionalInterface +public interface DrugEffect { + + void apply(Drug drug, int duration, Player player); + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/DrugHelper.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/DrugHelper.java new file mode 100644 index 0000000..e0c86b6 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/DrugHelper.java @@ -0,0 +1,26 @@ +package net.grandtheftmc.vice.drugs; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drugs.internal.service.Helper; +import net.grandtheftmc.vice.drugs.internal.service.Service; + +/** + * Created by Remco on 25-3-2017. + */ +public class DrugHelper implements Helper { + + @Override + public String getHelperName() { + return "Drug Helper"; + } + + @Override + public Class<? extends Service> getServiceClass() { + return DrugService.class; + } + + private DrugService getService() { + return (DrugService) Vice.getInstance().getDrugManager().getService(); + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/DrugManager.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/DrugManager.java new file mode 100644 index 0000000..de6e758 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/DrugManager.java @@ -0,0 +1,149 @@ +package net.grandtheftmc.vice.drugs; + +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drugs.example.*; +import net.grandtheftmc.vice.drugs.internal.manager.Manager; +import net.grandtheftmc.vice.drugs.items.DrugItem; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; + +public class DrugManager extends Manager { + private EffectManager effectManager; + private LockedBlocks lockedBlocks; + private final Set<UUID> ods = new HashSet<>(); + private final Set<UUID> unmoveable = new HashSet<>(); + + public DrugManager() { + super("Drug Manager", new AtomicInteger(1), new DrugService()); + } + + @Override + public void start() { + DrugService service = (DrugService) this.getService(); + ItemStack mdma = DrugUtil.setDisplayName(new ItemStack(Material.DIAMOND_SWORD, 1, (short) 755), Utils.f("&e&lMDMA")); + mdma = DrugUtil.hideDurability(mdma); + mdma = DrugUtil.addLore(mdma, "&7Take me to a higher place!"); + service.addDrug(new MDMA(), new DrugItem(mdma, new MDMA())); + + ItemStack lsd = DrugUtil.setDisplayName(new ItemStack(Material.DIAMOND_SPADE, 1, (short) 16), Utils.f("&d&lLSD")); + lsd = DrugUtil.hideDurability(lsd); + DrugItem drugItem = new DrugItem(lsd, new LSD()); + service.addDrug(new LSD(), drugItem); + + + ItemStack weed = DrugUtil.setDisplayName(new ItemStack(Material.DIAMOND_SPADE, 1, (short) 7), Utils.f("&2&lWeed Buds")); + weed = DrugUtil.hideDurability(weed); + service.addDrug(new Weed(), new DrugItem(weed, new Weed())); + + ItemStack joint = DrugUtil.setDisplayName(new ItemStack(Material.DIAMOND_SWORD, 1, (short) 752), Utils.f("&2&lJoint")); + joint = DrugUtil.hideDurability(joint); + service.addDrug(new Joint(), new DrugItem(joint, new Joint())); + + ItemStack steroids = DrugUtil.setDisplayName(new ItemStack(Material.DIAMOND_SWORD, 1, (short) 758), Utils.f("&c&lBull Shark Testosterone")); + steroids = DrugUtil.hideDurability(steroids); + steroids = DrugUtil.addLore(steroids, "&7Don’t mess with me!"); + service.addDrug(new Steroids(), new DrugItem(steroids, new Steroids())); + + ItemStack alcohol = DrugUtil.setDisplayName(new ItemStack(Material.DIAMOND_SPADE, 1, (short) 2), Utils.f("&e&lBeer")); + alcohol = DrugUtil.hideDurability(alcohol); + service.addDrug(new Alcohol(), new DrugItem(alcohol, new Alcohol())); + + ItemStack meth = DrugUtil.setDisplayName(new ItemStack(Material.DIAMOND_SWORD, 1, (short) 759), Utils.f("&c&lMeth Pipe")); + meth = DrugUtil.hideDurability(meth); + service.addDrug(new Meth(), new DrugItem(meth, new Meth())); + + ItemStack cocaine = DrugUtil.setDisplayName(new ItemStack(Material.DIAMOND_SPADE, 1, (short) 14), Utils.f("&f&lCocaine")); + cocaine = DrugUtil.hideDurability(cocaine); + service.addDrug(new Cocaine(), new DrugItem(cocaine, new Cocaine())); + + ItemStack heroin = DrugUtil.setDisplayName(new ItemStack(Material.DIAMOND_SWORD, 1, (short) 760), Utils.f("&b&lHeroin Syringe")); + heroin = DrugUtil.hideDurability(heroin); + heroin = DrugUtil.addLore(heroin, "&7Stick this thing in my arm!"); + service.addDrug(new Heroin(), new DrugItem(heroin, new Heroin())); + + this.effectManager = new EffectManager(); + this.lockedBlocks = new LockedBlocks(); + } + + @Override + public void stop() { + this.lockedBlocks.save(); + } + + @Override + public boolean destroy() { + return false; + } + + /** + * @apiNote see note in ItemManager#loadRecipes() + */ + public void loadDrugRecipes() { +// Vice.getItemManager().registerCustomRecipe(new HeroinCraftingRecipe()); +// Vice.getItemManager().registerCustomRecipe(new OpiumCraftingRecipe()); +// Vice.getItemManager().registerCustomRecipe(new JointCraftingRecipe()); +// Vice.getItemManager().registerCustomRecipe(new PotBrownieCraftingRecipe()); +// Vice.getItemManager().registerCustomRecipe(new WeedBudCraftingRecipe()); +// Vice.getItemManager().registerCustomRecipe(new CocaineCraftingRecipe()); +// Vice.getItemManager().registerCustomRecipe(new LSDCraftingRecipe()); +// Vice.getItemManager().registerCustomRecipe(new MethPipeCraftingRecipe()); +// Vice.getItemManager().registerCustomRecipe(new MethBaggyBrewingRecipe()); +// Vice.getItemManager().registerCustomRecipe(new BeerBrewingRecipe()); +// Vice.getItemManager().registerCustomRecipe(new MDMABrewingRecipe()); +// Vice.getItemManager().registerCustomRecipe(new HopsCraftingRecipe()); +// Vice.getItemManager().registerCustomRecipe(new VodkaBrewingRecipe()); +// Vice.getItemManager().registerCustomRecipe(new HeroinSyringeCraftingRecipe()); +// Vice.getItemManager().registerCustomRecipe(new SyringeCraftingRecipe()); + } + + + public EffectManager getEffectManager() { + return this.effectManager; + } + + public LockedBlocks getLockedBlocks() { + return this.lockedBlocks; + } + + /** + * @param uuid the uuid of the player + * @return if the player CAN OD again + */ + public boolean inOD(UUID uuid) { + return this.ods.contains(uuid); + } + + + /*** + * @param uuid uuid of the player + * + * Use when a player has OD'd (at the start of the OD sequence) + */ + public void addOD(UUID uuid) { + if (!this.ods.contains(uuid)) { + this.ods.add(uuid); + } + } + + /** + * @param uuid the player + * <p> + * Use after the OD has completed (at the end of the same OD sequence) + */ + public void removeOD(UUID uuid) { + if (this.ods.contains(uuid)) { + this.ods.remove(uuid); + } + } + + public static boolean isDrug(ItemStack itemStack) { + return ((DrugService) Vice.getDrugManager().getService()).getAllDrugItems().stream().anyMatch(drugItem -> drugItem.getItemStack().isSimilar(itemStack)); + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/DrugParam.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/DrugParam.java new file mode 100644 index 0000000..6256c94 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/DrugParam.java @@ -0,0 +1,17 @@ +package net.grandtheftmc.vice.drugs; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Created by Remco on 25-3-2017. + */ + +@Documented +@Retention(RetentionPolicy.RUNTIME) +public @interface DrugParam { + + FunctionalInterface value(); + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/DrugService.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/DrugService.java new file mode 100644 index 0000000..3a840e1 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/DrugService.java @@ -0,0 +1,70 @@ +package net.grandtheftmc.vice.drugs; + +import com.google.common.collect.HashBasedTable; +import com.google.common.collect.Table; +import net.grandtheftmc.vice.drugs.internal.service.Service; +import net.grandtheftmc.vice.drugs.items.DrugItem; +import org.bukkit.inventory.ItemStack; + +import java.util.Collection; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +/** + * Created by Remco on 25-3-2017. + */ +public class DrugService extends Service { + + //All items, sorted on: + private final Table<DrugParam[], DrugItem, Drug> items = HashBasedTable.create(); + + public DrugService() { + super("Drug Item Service", new DrugHelper()); + } + + public Drug addDrug(Drug drug, DrugItem item, DrugParam... params) { + if (this.items.columnKeySet().stream().noneMatch((match) -> false)) { + items.put(params, item, drug); + return drug; + } + return null; + } + + public final Collection<Drug> getDrugs() { + return items.values(); + } + + public final Set<DrugItem> getItems() { + return items.columnKeySet(); + } + + public Drug getDrug(ItemStack item) { + return getDrug(DrugItem.getByItemStack(item)); + } + + public Drug getDrug(DrugItem drugItem) { + return items.columnMap().values().stream().map(Map::values).filter(drugs -> drugs.stream().findFirst().isPresent() && drugs.stream().anyMatch(drugItem::isValid)).map((drug) -> drug.stream().findFirst().get()).findFirst().orElse(null); + } + + public Optional<Drug> getDrug(String name) { + Optional<Drug> drug = items.values().stream().filter(targetDrug -> targetDrug.getName().equalsIgnoreCase(name)).findFirst(); + if (!drug.isPresent()) return Optional.empty(); + return drug; + } + + public Optional<DrugItem> getDrugItem(String name) { + Optional<DrugItem> drug = items.columnKeySet().stream().filter(drugItem -> drugItem.getItemStack().getItemMeta().getDisplayName().equals(name)).findFirst(); + if (!drug.isPresent()) return Optional.empty(); + return drug; + } + + public Set<DrugItem> getAllDrugItems() { + return items.columnKeySet(); + } + + public Table<DrugParam[], DrugItem, Drug> getRawItems() { + return items; + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/DrugUtil.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/DrugUtil.java new file mode 100644 index 0000000..314ecba --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/DrugUtil.java @@ -0,0 +1,195 @@ +package net.grandtheftmc.vice.drugs; + +import net.grandtheftmc.core.util.Utils; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.*; +import java.util.concurrent.ThreadLocalRandom; + +public class DrugUtil { + private static Collection<Material> ignoreBlocks = Arrays.asList(Material.AIR, Material.SIGN, Material.SIGN_POST, + Material.WALL_SIGN, Material.IRON_DOOR, Material.IRON_DOOR_BLOCK, Material.CHEST, + Material.WOODEN_DOOR, Material.WOOD_DOOR); + + public static Sound getRandomParanoiaSound() { + int roll = ThreadLocalRandom.current().nextInt(0, 5); + switch (roll) { + default: + case 0: + return Sound.ENTITY_GHAST_SCREAM; + case 1: + return Sound.ENTITY_ZOMBIE_AMBIENT; + case 2: + return Sound.ENTITY_GHAST_AMBIENT; + case 3: + return Sound.ENTITY_SPIDER_AMBIENT; + case 4: + return Sound.ENTITY_CREEPER_PRIMED; + } + } + + public static Sound getRandomAmbientSound() { + int roll = ThreadLocalRandom.current().nextInt(0, 9); + switch (roll) { + default: + case 0: + return Sound.AMBIENT_CAVE; + case 1: + return Sound.ENTITY_RABBIT_AMBIENT; + case 2: + return Sound.ENTITY_BAT_AMBIENT; + case 3: + return Sound.ENTITY_CREEPER_PRIMED; + case 4: + return Sound.ENTITY_CAT_AMBIENT; + case 5: + return Sound.ENTITY_ENDERDRAGON_FIREBALL_EXPLODE; + case 6: + return Sound.BLOCK_CLOTH_BREAK; + case 7: + return Sound.ENTITY_ZOMBIE_INFECT; + case 8: + return Sound.ENTITY_ZOMBIE_PIG_ANGRY; + } + } + + public static String getParanoiaMessage(){ + switch(ThreadLocalRandom.current().nextInt( 10)){ + case 0: + return "They are always watching you"; + case 1: + return "I can see you"; + case 2: + return "I know where you live"; + case 3: + return "There is a camera in front of you, say hi :)"; + case 4: + return "Don't go home, it's not safe"; + case 5: + return "Even when you don't see me I am there"; + case 6: + return "The computer never turns off"; + case 7: + return "The police know what you have done"; + case 8: + return "I can see what you do behind closed doors"; + case 9: + return "I am the monster under your bed"; + default: + return ""; + } + } + + + /*ublic static void sendWorldEnvironment(Player player, World.Environment environment) { + CraftPlayer craftPlayer = (CraftPlayer) player; + CraftWorld world = (CraftWorld) player.getWorld(); + Location location = player.getLocation(); + + PacketPlayOutRespawn packet = new PacketPlayOutRespawn(environment.getId(), EnumDifficulty.getById(world.getDifficulty().getValue()), WorldType.NORMAL, EnumGamemode.getById(player.getGameMode().getValue())); + + craftPlayer.getHandle().playerConnection.sendPacket(packet); + + int viewDistance = Vice.getInstance().getServer().getViewDistance(); + + int xMin = location.getChunk().getX() - viewDistance; + int xMax = location.getChunk().getX() + viewDistance; + int zMin = location.getChunk().getZ() - viewDistance; + int zMax = location.getChunk().getZ() + viewDistance; + + for (int x = xMin; x < xMax; ++x){ + for (int z = zMin; z < zMax; ++z){ + world.refreshChunk(x, z); + } + } + + player.updateInventory(); + + player.teleport(player.getLocation()); + }*/ + + + public static Collection<Block> getNearbyBlocks(Location location, int radius) { + Collection<Block> blocks = new ArrayList<>(); + + for (int x = location.getBlockX() - radius ; x <= location.getBlockX() + radius ; x++) { + for (int z = location.getBlockZ() - radius ; z <= location.getBlockZ() + radius ; z++) { + for(int y = location.getBlockY() - radius ; y <= location.getBlockY() + radius; y++) { + Block block = location.getWorld().getBlockAt(x, y, z); + if (!block.isEmpty() && !ignoreBlocks.contains(block.getType())) { + blocks.add(block); + } + } + } + } + return blocks; + } + + public static ItemStack setDisplayName(ItemStack itemStack, String displayName) { + ItemMeta itemMeta = itemStack.getItemMeta(); + itemMeta.setDisplayName(displayName); + itemStack.setItemMeta(itemMeta); + return itemStack; + } + + public static ItemStack addLore(ItemStack itemStack, String... lore) { + ItemMeta itemMeta = itemStack.getItemMeta(); + List<String> lores = itemMeta.hasLore() ? itemMeta.getLore() : new ArrayList<>(); + for (String a : lore) lores.add(Utils.f(a)); + itemMeta.setLore(lores); + itemStack.setItemMeta(itemMeta); + return itemStack; + } + + public static ItemStack clearLore(ItemStack itemStack) { + ItemMeta itemMeta = itemStack.getItemMeta(); + itemMeta.setLore(new ArrayList<>()); + itemStack.setItemMeta(itemMeta); + return itemStack; + } + + public static ItemStack hideDurability(ItemStack itemStack) { + ItemStack is = itemStack.clone(); + ItemMeta itemMeta = is.getItemMeta(); + itemMeta.setUnbreakable(true); + itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, + ItemFlag.HIDE_UNBREAKABLE, + ItemFlag.HIDE_PLACED_ON, + ItemFlag.HIDE_ENCHANTS, + ItemFlag.HIDE_POTION_EFFECTS, + ItemFlag.HIDE_DESTROYS); + is.setItemMeta(itemMeta); + return is; + } + + public static Optional<Map<Integer, ItemStack>> findItem(Inventory inventory, ItemStack itemStack) { + Map<Integer, ItemStack> map = new HashMap<>(); + for (int i = 0; i < inventory.getSize(); i++) { + if (inventory.getItem(i) == null) continue; + ItemStack search = inventory.getItem(i); + System.out.print(search.getType().toString() + " :: " + + itemStack.getType().toString()); + System.out.print(search.getData().getData() + " :: " + + itemStack.getData().getData()); + System.out.print(search.getItemMeta().getDisplayName() + " :: " + + itemStack.getItemMeta().getDisplayName()); + if (search.getType() == itemStack.getType() + && search.getData().getData() == itemStack.getData().getData() + && search.getItemMeta().getDisplayName().equals(itemStack.getItemMeta().getDisplayName())) { + map.put(i, search); + System.out.print("found"); + break; + } + } + return map.isEmpty() ? Optional.empty() : Optional.of(map); + } + + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/EffectManager.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/EffectManager.java new file mode 100644 index 0000000..c5987db --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/EffectManager.java @@ -0,0 +1,48 @@ +package net.grandtheftmc.vice.drugs; + +import net.grandtheftmc.vice.Vice; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; + +import java.util.HashMap; +import java.util.UUID; + +public class EffectManager { + + private final HashMap<UUID, Long> cancelEffects = new HashMap<>(); + + /** + * @param player the player who will be getting the effect + * @param effect the effect that may be addded / extended + */ + public void addEffect(Player player, PotionEffect effect) { + Bukkit.getScheduler().runTask(Vice.getInstance(), () -> { + player.addPotionEffect(effect); + }); + } + + /** + * @param player the player who is being checked + * @param origTime the time that the player originally used the drug* + * @return true if the player is still able to have the drug effects + */ + public boolean canRecieveOngoingEffect(Player player, long origTime) { + return player.isOnline() && player.isValid() && cancelEffects.getOrDefault(player.getUniqueId(), (long) 0) <= origTime; + } + + + /** + * @param player the player whose effects will be cancelled + */ + public void cancelEffects(Player player) { + Bukkit.getScheduler().runTask(Vice.getInstance(), () -> { + if (!cancelEffects.containsKey(player.getUniqueId())) { + cancelEffects.put(player.getUniqueId(), System.currentTimeMillis()); + } + for (PotionEffect p : player.getActivePotionEffects()) { + player.removePotionEffect(p.getType()); + } + }); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/LockedBlocks.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/LockedBlocks.java new file mode 100644 index 0000000..e1f4b84 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/LockedBlocks.java @@ -0,0 +1,45 @@ +package net.grandtheftmc.vice.drugs; + +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import org.bukkit.Location; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class LockedBlocks { + private Collection<Location> lockedBlocks; + private YamlConfiguration config; + + public LockedBlocks() { + this.lockedBlocks = new ArrayList<>(); + this.config = Vice.getSettings().getDrugBlocksConfig(); + load(); + } + + public void load() { + if (!config.getStringList("blocks").isEmpty()) { + for (String stringLoc : config.getStringList("blocks")) { + Location location = Utils.blockLocationFromString(stringLoc); + if (location != null) this.lockedBlocks.add(location); + } + } + } + + public void save() { + List<String> serializedLocs = new ArrayList<>(); + this.lockedBlocks.forEach(location -> { + if (location != null) + serializedLocs.add(Utils.blockLocationToString(location)); + }); + config.set("blocks", serializedLocs); + Utils.saveConfig(config, "drugblocks"); + } + + public Collection<Location> getLocations() { + return this.lockedBlocks; + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/SeedDrop.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/SeedDrop.java new file mode 100644 index 0000000..ae9ab55 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/SeedDrop.java @@ -0,0 +1,44 @@ +package net.grandtheftmc.vice.drugs; + +import org.bukkit.block.Biome; + +public final class SeedDrop { + private final int uniqueId; + + private final int range; + private final int interval; + private final Biome biome; + + private long last; + + SeedDrop(int uniqueId, int range, int interval, Biome biome) { + this.uniqueId = uniqueId; + this.range = range; + this.interval = interval; + this.biome = biome; + } + + public int getUniqueId() { + return uniqueId; + } + + public int getRange() { + return range; + } + + public int getInterval() { + return interval; + } + + public Biome getBiome() { + return biome; + } + + public long getLast() { + return last; + } + + public void next() { + this.last = System.currentTimeMillis() + (this.interval * 1000); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/SeedType.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/SeedType.java new file mode 100644 index 0000000..f5633bc --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/SeedType.java @@ -0,0 +1,80 @@ +package net.grandtheftmc.vice.drugs; + +import net.grandtheftmc.vice.Vice; +import org.bukkit.Material; +import org.bukkit.block.Biome; +import org.bukkit.inventory.ItemStack; + +public final class SeedType { + protected static SeedType POTATO_SEED, ERGOT_FUNGI, COCA_SEED, MARIJUANA, HUMULUS_SEED; + + static { + POTATO_SEED = new SeedType( + new ItemStack(Material.POTATO), + new SeedDrop(1, 20, 30, Biome.BIRCH_FOREST), + new SeedDrop(2, 20, 40, Biome.FOREST)//Deciduous Forest + ); + + ERGOT_FUNGI = new SeedType( + Vice.getItemManager().getItem("ergotfungi").getItem(), + new SeedDrop(3, 20, 30, Biome.JUNGLE), + new SeedDrop(4, 20, 40, Biome.ROOFED_FOREST),//Fantasy Forest + new SeedDrop(5, 20, 40, Biome.MUSHROOM_ISLAND),//Farmland + new SeedDrop(6, 20, 40, Biome.MUTATED_ROOFED_FOREST)//Forgotten Forest + ); + + COCA_SEED = new SeedType( + Vice.getItemManager().getItem("cocaseed").getItem(), + new SeedDrop(7, 20, 40, Biome.DEEP_OCEAN), + new SeedDrop(8, 20, 40, Biome.DESERT), + new SeedDrop(9, 20, 30, Biome.TAIGA),//Mega Spruce Taiga + new SeedDrop(10, 20, 30, Biome.MUTATED_TAIGA),//Mega Taiga + new SeedDrop(11, 20, 30, Biome.MUTATED_REDWOOD_TAIGA),//Mega Taiga + new SeedDrop(12, 20, 30, Biome.MESA) + ); + + MARIJUANA = new SeedType( + Vice.getItemManager().getItem("marijuanaseed").getItem(), + new SeedDrop(13, 20, 30, Biome.JUNGLE), + new SeedDrop(14, 20, 40, Biome.BIRCH_FOREST),//Snowy Pine + new SeedDrop(15, 20, 40, Biome.MUTATED_BIRCH_FOREST),//Snowy Pine + new SeedDrop(16, 20, 40, Biome.MUTATED_SWAMPLAND),//Swamp Edge + new SeedDrop(17, 20, 40, Biome.SWAMPLAND) + ); + + HUMULUS_SEED = new SeedType( + Vice.getItemManager().getItem("humulusseed").getItem(), + new SeedDrop(18, 20, 30, Biome.OCEAN), + new SeedDrop(19, 20, 30, Biome.BIRCH_FOREST),//Pine Forest + new SeedDrop(20, 20, 30, Biome.PLAINS), + new SeedDrop(21, 20, 40, Biome.RIVER), + new SeedDrop(22, 20, 40, Biome.SAVANNA) + ); + } + + private static SeedType[] values; + + private final ItemStack itemStack; + private final SeedDrop[] drops; + + public SeedType(ItemStack itemStack, SeedDrop... drops) { + this.itemStack = itemStack; + this.drops = drops; + } + + public ItemStack getItemStack() { + return itemStack; + } + + public SeedDrop[] getDrops() { + return drops; + } + + public static void init() { + values = new SeedType[] {POTATO_SEED, ERGOT_FUNGI, COCA_SEED, MARIJUANA, HUMULUS_SEED}; + } + + public static SeedType[] values() { + return values; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/DrugCategory.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/DrugCategory.java new file mode 100644 index 0000000..9f3ef46 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/DrugCategory.java @@ -0,0 +1,37 @@ +package net.grandtheftmc.vice.drugs.categories; + +import net.grandtheftmc.vice.drugs.Drug; +import net.grandtheftmc.vice.drugs.categories.examples.*; + +import java.util.Arrays; +import java.util.Optional; + +/** + * Created by Remco on 25-3-2017. + */ +public enum DrugCategory { + + STIMULANTS(Stimulants.class), + INHALANTS(Inhalants.class), + CANNABINOIDS(Cannabinoids.class), + DEPRESSANTS(Depressants.class), + OPIOIDS(Opioids.class), + ANABOLIC_STEROIDS(AnabolicSteroids.class), + HALLUCINOGENS(Hallucinogens.class), + ALCOHOL(AAlcohol.class), + PRESCRIPTION_DRUGS(PrescriptionDrugs.class); + + private final Class<?>[] categories; + + DrugCategory(Class<?>... categories) { + this.categories = categories; + } + + public Class<?>[] getCategories() { + return categories; + } + + public static Optional<DrugCategory> byDrug(Drug drug){ + return Arrays.stream(values()).filter((categorie) -> Arrays.stream(categorie.categories).anyMatch((categoryClass) -> categoryClass.equals(drug.getClass().getSuperclass()))).findFirst(); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/IDrugCategory.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/IDrugCategory.java new file mode 100644 index 0000000..3f586dd --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/IDrugCategory.java @@ -0,0 +1,20 @@ +package net.grandtheftmc.vice.drugs.categories; + +/** + * Created by Remco on 25-3-2017. + */ +public interface IDrugCategory { + + /** + * The name of the current Category, so we can define it somewhere. + * @return name + */ + String name(); + + /** + * The general description of the category of Drug. + * @return description + */ + String description(); + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/examples/AAlcohol.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/examples/AAlcohol.java new file mode 100644 index 0000000..07727e1 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/examples/AAlcohol.java @@ -0,0 +1,24 @@ +package net.grandtheftmc.vice.drugs.categories.examples; + +import net.grandtheftmc.vice.drugs.Drug; +import net.grandtheftmc.vice.drugs.categories.IDrugCategory; + +/** + * Created by Remco on 25-3-2017. + */ +public abstract class AAlcohol extends Drug implements IDrugCategory { + + protected AAlcohol(String name, int duration) { + super(name, duration); + } + + @Override + public String name() { + return "Alcohol"; + } + + @Override + public String description() { + return "Can make you feel very special. You won't be walking straight if you drink too much though."; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/examples/AnabolicSteroids.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/examples/AnabolicSteroids.java new file mode 100644 index 0000000..f0baccc --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/examples/AnabolicSteroids.java @@ -0,0 +1,24 @@ +package net.grandtheftmc.vice.drugs.categories.examples; + +import net.grandtheftmc.vice.drugs.Drug; +import net.grandtheftmc.vice.drugs.categories.IDrugCategory; + +/** + * Created by Remco on 25-3-2017. + */ +public abstract class AnabolicSteroids extends Drug implements IDrugCategory { + + protected AnabolicSteroids(String name, int duration) { + super(name, duration); + } + + @Override + public String name() { + return "Anabolic Steroids"; + } + + @Override + public String description() { + return "Improves physical performance, enlarges muscles and increases strength."; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/examples/Cannabinoids.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/examples/Cannabinoids.java new file mode 100644 index 0000000..d1afe10 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/examples/Cannabinoids.java @@ -0,0 +1,24 @@ +package net.grandtheftmc.vice.drugs.categories.examples; + +import net.grandtheftmc.vice.drugs.Drug; +import net.grandtheftmc.vice.drugs.categories.IDrugCategory; + +/** + * Created by Remco on 25-3-2017. + */ +public abstract class Cannabinoids extends Drug implements IDrugCategory { + + protected Cannabinoids(String name, int duration) { + super(name, duration); + } + + @Override + public String name() { + return "Cannabinoids"; + } + + @Override + public String description() { + return "Give you a feeling of euphoria. May cause confusion, memory problems, anxiety and a higher heart rate."; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/examples/Depressants.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/examples/Depressants.java new file mode 100644 index 0000000..1cad7c7 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/examples/Depressants.java @@ -0,0 +1,24 @@ +package net.grandtheftmc.vice.drugs.categories.examples; + +import net.grandtheftmc.vice.drugs.Drug; +import net.grandtheftmc.vice.drugs.categories.IDrugCategory; + +/** + * Created by Remco on 25-3-2017. + */ +public abstract class Depressants extends Drug implements IDrugCategory { + + protected Depressants(String name, int duration) { + super(name, duration); + } + + @Override + public String name() { + return "Depressants"; + } + + @Override + public String description() { + return "Slows down activity in the central nervous system. They slow down the body and give you the feeling of relaxation."; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/examples/Hallucinogens.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/examples/Hallucinogens.java new file mode 100644 index 0000000..b861b4c --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/examples/Hallucinogens.java @@ -0,0 +1,24 @@ +package net.grandtheftmc.vice.drugs.categories.examples; + +import net.grandtheftmc.vice.drugs.Drug; +import net.grandtheftmc.vice.drugs.categories.IDrugCategory; + +/** + * Created by Remco on 25-3-2017. + */ +public abstract class Hallucinogens extends Drug implements IDrugCategory { + + protected Hallucinogens(String name, int duration) { + super(name, duration); + } + + @Override + public String name() { + return "Hallucinogens"; + } + + @Override + public String description() { + return "Change the mind and cause the appearance of things that are not really there."; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/examples/Inhalants.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/examples/Inhalants.java new file mode 100644 index 0000000..b905d07 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/examples/Inhalants.java @@ -0,0 +1,23 @@ +package net.grandtheftmc.vice.drugs.categories.examples; + +import net.grandtheftmc.vice.drugs.Drug; +import net.grandtheftmc.vice.drugs.categories.IDrugCategory; + +/** + * Created by Remco on 25-3-2017. + */ +public abstract class Inhalants extends Drug implements IDrugCategory{ + + protected Inhalants(String name, int duration) { + super(name, duration); + } + @Override + public String name() { + return "Inhalants"; + } + + @Override + public String description() { + return "Give you immediate results. These can have sudden mental damage."; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/examples/Opioids.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/examples/Opioids.java new file mode 100644 index 0000000..773762c --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/examples/Opioids.java @@ -0,0 +1,24 @@ +package net.grandtheftmc.vice.drugs.categories.examples; + +import net.grandtheftmc.vice.drugs.Drug; +import net.grandtheftmc.vice.drugs.categories.IDrugCategory; + +/** + * Created by Remco on 25-3-2017. + */ +public abstract class Opioids extends Drug implements IDrugCategory { + + protected Opioids(String name, int duration) { + super(name, duration); + } + + @Override + public String name() { + return "Opioids"; + } + + @Override + public String description() { + return "Can cause drowsiness, confusion, nausea, feeligns of euphoria, respiratory complications and relieve pain."; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/examples/PrescriptionDrugs.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/examples/PrescriptionDrugs.java new file mode 100644 index 0000000..cdb4ea7 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/examples/PrescriptionDrugs.java @@ -0,0 +1,24 @@ +package net.grandtheftmc.vice.drugs.categories.examples; + +import net.grandtheftmc.vice.drugs.Drug; +import net.grandtheftmc.vice.drugs.categories.IDrugCategory; + +/** + * Created by Remco on 25-3-2017. + */ +public abstract class PrescriptionDrugs extends Drug implements IDrugCategory { + + protected PrescriptionDrugs(String name, int duration) { + super(name, duration); + } + + @Override + public String name() { + return "Prescription Drugs"; + } + + @Override + public String description() { + return "Can be very helpful (if used wisely). Can be very dangerous."; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/examples/Stimulants.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/examples/Stimulants.java new file mode 100644 index 0000000..2c5e4cf --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/categories/examples/Stimulants.java @@ -0,0 +1,25 @@ +package net.grandtheftmc.vice.drugs.categories.examples; + +import net.grandtheftmc.vice.drugs.Drug; +import net.grandtheftmc.vice.drugs.categories.IDrugCategory; + +/** + * Created by Remco on 25-3-2017. + */ +public abstract class Stimulants extends Drug implements IDrugCategory { + + protected Stimulants(String name, int duration) { + super(name, duration); + } + + @Override + public String name() { + return "Stimulants"; + } + + @Override + public String description() { + return "Speeds up your nevous system and make you feel very alive. Also known as \"uppers\" because of their ability to make you feel very awake."; + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/events/DrugUseEvent.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/events/DrugUseEvent.java new file mode 100644 index 0000000..533b6aa --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/events/DrugUseEvent.java @@ -0,0 +1,52 @@ +package net.grandtheftmc.vice.drugs.events; + +import net.grandtheftmc.vice.drugs.Drug; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * Created by Remco on 25-3-2017. + */ +public class DrugUseEvent extends Event implements Cancellable { + + private final static HandlerList handlers = new HandlerList(); + + private boolean cancelled; + private final Player user; + private final Drug drug; + + public DrugUseEvent(Player user, Drug drug) { + this.user = user; + this.drug = drug; + this.cancelled = false; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean b) { + this.cancelled = b; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList(){ + return handlers; + } + + public Player getUser() { + return user; + } + + public Drug getDrug() { + return drug; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/events/listener/DrugListener.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/events/listener/DrugListener.java new file mode 100644 index 0000000..34e66fd --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/events/listener/DrugListener.java @@ -0,0 +1,99 @@ +package net.grandtheftmc.vice.drugs.events.listener; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drugs.Drug; +import net.grandtheftmc.vice.drugs.DrugService; +import net.grandtheftmc.vice.drugs.events.DrugUseEvent; +import net.grandtheftmc.vice.drugs.example.Alcohol; +import net.grandtheftmc.vice.drugs.example.Heroin; +import net.grandtheftmc.vice.drugs.example.Weed; +import net.grandtheftmc.vice.drugs.items.DrugItem; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; + +import java.util.Optional; + +public class DrugListener implements Listener { + + @EventHandler + public void onEat(PlayerInteractEvent event) { + Player player = event.getPlayer(); + ItemStack is = event.getItem(); + if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) { + if (is != null && is.getItemMeta() != null) { + DrugItem item = DrugItem.getByItemStack(is); + DrugService drugService = (DrugService) Vice.getInstance().getDrugManager().getService(); + if (item != null) { + if (drugService.getDrugs().stream().anyMatch(item::isValid)) { + Drug drug = drugService.getDrug(item); + if (drug != null && !(drug instanceof Weed)) { + if (drug.apply(player)) { + if (event.getItem().getAmount() > 1) { + player.getInventory().getItemInMainHand().setAmount(event.getItem().getAmount() - 1); + } else { + player.getInventory().setItemInMainHand(null); + } + event.setCancelled(true); + } + } + } + } else { + if(Vice.getItemManager().getItem("vodka") != null) { + if (is.isSimilar(Vice.getItemManager().getItem("vodka").getItem())) { + Optional<Drug> alcohol = ((DrugService) Vice.getInstance().getDrugManager().getService()).getDrug("alcohol"); + if (alcohol.isPresent()) { + ((Alcohol) alcohol.get()).potentApply(player, true); + if (event.getItem().getAmount() > 1) { + player.getInventory().getItemInMainHand().setAmount(event.getItem().getAmount() - 1); + } else { + player.getInventory().setItemInMainHand(null); + } + event.setCancelled(true); + } + } + } + } + } + } + } + + @EventHandler + public void onHit(EntityDamageByEntityEvent event) { + if (event.getDamager() instanceof Player && event.getEntity() instanceof Player) { + Player damager = (Player) event.getDamager(); + Player hurt = (Player) event.getEntity(); + ItemStack itemStack = damager.getInventory().getItemInMainHand(); + if (itemStack != null && itemStack.getItemMeta() != null) { + DrugItem item = DrugItem.getByItemStack(itemStack); + DrugService drugService = (DrugService) Vice.getInstance().getDrugManager().getService(); + if (item != null) { + if (drugService.getDrugs().stream().anyMatch(item::isValid)) { + Drug drug = drugService.getDrug(item); + if (drug instanceof Heroin) { + hurt.damage(6); + drug.apply(hurt); + hurt.sendMessage(Lang.DRUGS.f("&7You have been drugged.")); + } + } + } + } + } + } + + @EventHandler + protected final void onDrugUse(DrugUseEvent event) { + if(event.getUser() == null || event.getDrug() == null) return; + if(event.getUser().getLocation().getWorld().getName().equalsIgnoreCase("spawn")) { + if(event.getDrug() instanceof Alcohol) { + event.setCancelled(true); + event.getUser().updateInventory(); + } + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/events/listener/DrugPlacementListener.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/events/listener/DrugPlacementListener.java new file mode 100644 index 0000000..a4fc8d0 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/events/listener/DrugPlacementListener.java @@ -0,0 +1,129 @@ +package net.grandtheftmc.vice.drugs.events.listener; + +import org.bukkit.event.Listener; + +public class DrugPlacementListener implements Listener { + + /*@EventHandler + public void onInteract(PlayerInteractEvent event) { + if (event.getClickedBlock() == null) return; + Player player = event.getPlayer(); + if (Objects.equals(player.getWorld().getName(), "spawn")) return; + Block block = event.getClickedBlock(); + Location blockLocation = block.getLocation(); + ItemStack hand = player.getInventory().getItemInMainHand(); + if (event.getAction() == Action.RIGHT_CLICK_BLOCK) { + if (block.getType() == Material.BREWING_STAND) { + event.setCancelled(true); + LockedBlocks lockedBlocks = Vice.getDrugManager().getLockedBlocks(); + if (DrugCommand.addingBlocks.contains(player.getName())) { + if (lockedBlocks.getLocations().contains(block.getLocation())) { + player.sendMessage(Lang.DRUGS.f("&cBlock is no longer locked.")); + lockedBlocks.getLocations().remove(block.getLocation()); + } else { + player.sendMessage(Lang.DRUGS.f("&aBlock is now locked!")); + lockedBlocks.getLocations().add(block.getLocation()); + } + return; + } + if (player.isSneaking()) { + if (lockedBlocks.getLocations().contains(block.getLocation())) { + player.sendMessage(Lang.DRUGS.f("&7This Bong cannot be removed.")); + return; + } + + block.getWorld().dropItemNaturally(blockLocation, getBongItem()); + block.setType(Material.AIR); + player.playSound(blockLocation, Sound.BLOCK_GLASS_BREAK, 3.0F, 3.0F); + } else { + if (hand.getType() == getWeedItem().getType()) { + Optional<Drug> weed = ((DrugService) Vice.getDrugManager().getService()).getDrug("weed"); + if (weed.isPresent()) { + weed.get().apply(player); + if (hand.getAmount() > 1) { + hand.setAmount(hand.getAmount() - 1); + } else { + player.getInventory().remove(hand); + } + } else { + player.sendMessage(Lang.DRUGS + "" + ChatColor.RED + "Something went wrong internally, please tell a staff member."); + Vice.getInstance().getLogger().log(Level.SEVERE, "Unable to find weed drug (DrugPlacementListener)"); + } + } else { + player.sendMessage(Lang.DRUGS.f("&7Put some &2&lWeed &7in here to start smoking!")); + } + } + } else if (block.getType() == getCocaineBlock().getType() && block.getData() == getCocaineBlock().getData().getData()) { + event.setCancelled(true); + if (player.isSneaking()) { + + block.getWorld().dropItemNaturally(blockLocation, getCocaineBlock()); + block.setType(Material.AIR); + player.playSound(blockLocation, Sound.BLOCK_GLASS_BREAK, 3.0F, 3.0F); + } else { + block.setType(Material.AIR); + player.playSound(blockLocation, Sound.ENTITY_CAT_HISS, 1, 1); + Optional<Drug> cocaine = ((DrugService) Vice.getDrugManager().getService()).getDrug("cocaine"); + if (cocaine.isPresent()) { + cocaine.get().apply(player); + } else { + player.sendMessage(Lang.DRUGS.f("&7Unable to locate drug cocaine, report this bug to a staff member.")); + } + } + } else { + Block target = block.getWorld().getBlockAt(blockLocation.getBlockX(), + blockLocation.getBlockY() + 1, + blockLocation.getBlockZ()); + /*if (hand.getType() == getBongItem().getType() + && hand.getData().getData() == getBongItem().getData().getData()) { + if (target.getType() == Material.AIR) { + + target.setType(Material.BREWING_STAND); + if (hand.getAmount() > 1) { + hand.setAmount(hand.getAmount() - 1); + } else { + player.getInventory().remove(hand); + } + player.updateInventory(); + player.playSound(target.getLocation(), Sound.BLOCK_GLASS_PLACE, 3.0F, 3.0F); + } else if (target.getType() != Material.BREWING_STAND) { + player.sendMessage(Lang.VICE.f("&7Bong cannot be placed here!")); + } + } else if (hand.getType() == getCocaineItem().getType() + && hand.getData().getData() == getCocaineItem().getData().getData()) { + if (target.getType() == Material.AIR) { + + target.setType(getCocaineBlock().getType()); + target.setData(getCocaineBlock().getData().getData()); + if (hand.getAmount() > 1) { + hand.setAmount(hand.getAmount() - 1); + } else { + player.getInventory().remove(hand); + } + player.updateInventory(); + player.playSound(target.getLocation(), Sound.BLOCK_GLASS_PLACE, 3.0F, 3.0F); + } else if (target.getType() != getCocaineBlock().getType()) { + player.sendMessage(Lang.VICE.f("&7Bong cannot be placed here!")); + } + } + } +} + + } + + public ItemStack getWeedItem() { + return Vice.getItemManager().getItem("weed").getItem(); + } + + public ItemStack getBongItem() { + return Vice.getItemManager().getItem("bong").getItem(); + } + + public ItemStack getCocaineItem() { + return Vice.getItemManager().getItem("cocaine").getItem(); + } + + public ItemStack getCocaineBlock() { + return Vice.getItemManager().getItem("cocaineblock").getItem(); + }*/ +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/example/Alcohol.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/example/Alcohol.java new file mode 100644 index 0000000..5378a4b --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/example/Alcohol.java @@ -0,0 +1,94 @@ +package net.grandtheftmc.vice.drugs.example; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drugs.DrugEffect; +import net.grandtheftmc.vice.drugs.DrugService; +import net.grandtheftmc.vice.drugs.categories.examples.AAlcohol; +import net.grandtheftmc.vice.drugs.events.DrugUseEvent; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Item; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.util.Vector; + +import java.util.*; +import java.util.concurrent.ThreadLocalRandom; + +/** + * Created by Remco on 25-3-2017. + */ +public class Alcohol extends AAlcohol { + private final HashMap<UUID, List<Long>> drinkTimes = new HashMap<>(); + private static final int NEEDED_RATE = 3;//per X + private static final int TIMEFRAME = 300;//seconds + + public Alcohol() { + super("alcohol", 60); + } + + public boolean potentApply(Player p, boolean vodka) { + boolean[] failed = {false}; + UUID uuid = p.getUniqueId(); + DrugEffect effect = (drug, duration, player) -> { + final DrugService service = (DrugService) Vice.getInstance().getDrugManager().getService(); + player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_BURP, 1, 1); + int effectDuration = (int) Math.round(duration + (duration * ThreadLocalRandom.current().nextDouble(-.25, .25))) * 20; //to make it +/-5-25% + Bukkit.getPluginManager().callEvent(new DrugUseEvent(player, this)); + if (isPlayerDrunk(uuid)) { + ItemStack item = player.getInventory().getItemInMainHand(); + if (item != null) + if (item.getAmount() > 1) { + player.getInventory().getItemInMainHand().setAmount(item.getAmount() - 1); + } else { + player.getInventory().setItemInMainHand(null); + } + for (ItemStack is : player.getInventory().getStorageContents()) { + if (is != null && is.getType() != Material.CHEST && is.getType() != Material.WATCH) { + Item drop = player.getWorld().dropItemNaturally(player.getLocation().add(ThreadLocalRandom.current().nextDouble(-1, 1), 1, ThreadLocalRandom.current().nextDouble(-1, 1)), is); + Vector velocity = player.getEyeLocation().getDirection().normalize(); + velocity.multiply(1.01); + drop.setVelocity(velocity); + player.getInventory().remove(is); + } + } + player.sendMessage(Lang.DRUGS.f("&2&oYou dont feel so good...")); + } + + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SLOW, effectDuration, 2 + (vodka ? 1 : 0)))); + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.CONFUSION, effectDuration, 0))); + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, effectDuration, 1 + (vodka ? 1 : 1)))); + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.INCREASE_DAMAGE, effectDuration, 1 + (vodka ? 1 : 2)))); + }; + effect.apply(this, this.getDuration(), p); + return !failed[0]; + } + + @Override + public boolean apply(Player p) { + return potentApply(p, false); + } + + private boolean isPlayerDrunk(UUID uuid) { + if (drinkTimes.containsKey(uuid)) { + List<Long> tempTimes = new ArrayList<>(); + ArrayList<Long> times = new ArrayList<>(drinkTimes.get(uuid)); + times.add(System.currentTimeMillis()); + times.forEach(l -> { + if ((l + (TIMEFRAME * 1000)) <= System.currentTimeMillis()) { + tempTimes.add(l); + } + }); + + times.removeAll(tempTimes); + drinkTimes.put(uuid, times); + return times.size() >= NEEDED_RATE; + } + drinkTimes.put(uuid, Arrays.asList(System.currentTimeMillis())); + return false; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/example/Cocaine.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/example/Cocaine.java new file mode 100644 index 0000000..1889425 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/example/Cocaine.java @@ -0,0 +1,119 @@ +package net.grandtheftmc.vice.drugs.example; + +import de.slikey.effectlib.effect.TurnEffect; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drugs.DrugEffect; +import net.grandtheftmc.vice.drugs.DrugUtil; +import net.grandtheftmc.vice.drugs.categories.examples.Stimulants; +import net.grandtheftmc.vice.drugs.events.DrugUseEvent; +import net.grandtheftmc.vice.utils.TitleBuilder; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.HashSet; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; + +public class Cocaine extends Stimulants { + HashSet<UUID> unmoveable = new HashSet<>(); + + public Cocaine() { + super("cocaine", 120); + } + + @Override + public boolean apply(Player p) { + boolean[] failed = {false}; + UUID uuid = p.getUniqueId(); + DrugEffect effect = (drug, duration, player) -> { + player.playSound(player.getLocation(), Sound.ENTITY_CAT_HISS, 1, 1); + int effectDuration = (int) Math.round(duration + (duration * ThreadLocalRandom.current().nextDouble(-.25, .25))) * 20; //to make it +/-5-25% + + Bukkit.getPluginManager().callEvent(new DrugUseEvent(player, this)); + int roll = ThreadLocalRandom.current().nextInt(100); + + if (roll > 5 || Vice.getDrugManager().inOD(player.getUniqueId())) { + Vice.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SPEED, effectDuration / 2, 1))); + Vice.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.FAST_DIGGING, effectDuration, 0))); + Vice.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.INCREASE_DAMAGE, effectDuration, 1))); + } else { + Vice.getDrugManager().addOD(player.getUniqueId()); + Vice.getUserManager().getLoadedUser(player.getUniqueId()).setLastTag(System.currentTimeMillis()); + stageOne(player, System.currentTimeMillis()); + } + }; + effect.apply(this, this.getDuration(), p); + return !failed[0]; + } + + public boolean cantMove(UUID uuid) { + return unmoveable.contains(uuid); + } + + public void stageOne(Player player, long addTime){ + int speedLength = ThreadLocalRandom.current().nextInt(100, 200); + Vice.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SPEED, speedLength, 20))); + new BukkitRunnable() { + @Override + public void run() { + if (!Vice.getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) + return; + stageTwo(player, addTime); + } + }.runTaskLater(Vice.getInstance(), speedLength); + } + + public void stageTwo(Player player, long addTime){ + player.setPlayerTime(18000, false); + unmoveable.add(player.getUniqueId()); + TurnEffect turnEffect = new TurnEffect(Vice.getEffectLib()); + turnEffect.setEntity(player); + turnEffect.infinite(); + turnEffect.period = 2; + turnEffect.start(); + int stageLength = ThreadLocalRandom.current().nextInt(10, 16); + long endTime = System.currentTimeMillis() + (stageLength*1000); + player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, stageLength*20, 0)); + new BukkitRunnable() { + boolean flip = false; + @Override + public void run() { + if (System.currentTimeMillis() >= endTime || !Vice.getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) { + turnEffect.cancel(); + cancel(); + return; + } + if(flip){ + player.playSound(player.getLocation(), DrugUtil.getRandomParanoiaSound(), 1, 1); + } + flip = !flip; + new TitleBuilder().setTitleText(ChatColor.RED + "" + ChatColor.MAGIC + "asd" + ChatColor.RED + DrugUtil.getParanoiaMessage() + "" + ChatColor.MAGIC + "asd").setFadeIn(0).setDuration(10).setFadeOut(0).send(player); + } + }.runTaskTimer(Vice.getInstance(), 0, 15); + + new BukkitRunnable() { + @Override + public void run() { + dispose(player); + if (Vice.getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) { + stageThree(player); + return; + }} + }.runTaskLater(Vice.getInstance(), stageLength*20); + + } + + public void stageThree(Player player){ + Vice.getDrugManager().getEffectManager().addEffect(player, new PotionEffect(PotionEffectType.SLOW, 20 * 5, 2)); + } + + public void dispose(Player player) { + unmoveable.remove(player.getUniqueId()); + player.resetPlayerTime(); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/example/Heroin.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/example/Heroin.java new file mode 100644 index 0000000..26a660c --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/example/Heroin.java @@ -0,0 +1,78 @@ +package net.grandtheftmc.vice.drugs.example; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drugs.DrugEffect; +import net.grandtheftmc.vice.drugs.categories.examples.Opioids; +import net.grandtheftmc.vice.drugs.events.DrugUseEvent; +import org.bukkit.Bukkit; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; + +public class Heroin extends Opioids{ + + public Heroin() { + super("heroin", 15); + } + + @Override + public boolean apply(Player p) { + boolean[] failed = {false}; + UUID uuid = p.getUniqueId(); + DrugEffect effect = (drug, duration, player) -> { + int roll = ThreadLocalRandom.current().nextInt(100); + int effectDuration = (int) Math.round(duration + (duration * ThreadLocalRandom.current().nextDouble(-.25, .25))) * 20; //to make it +/-5-25% + + Bukkit.getPluginManager().callEvent(new DrugUseEvent(player, this)); + player.playSound(player.getLocation(), Sound.ENTITY_SILVERFISH_AMBIENT, 1, 1); + final long addTime = System.currentTimeMillis(); + if (roll > 6 || (Vice.getDrugManager().inOD(player.getUniqueId()))) { + Vice.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SPEED, effectDuration, 1))); + Vice.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.INCREASE_DAMAGE, effectDuration, 0))); + Vice.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.FIRE_RESISTANCE, effectDuration, 1))); + + new BukkitRunnable() { + @Override + public void run() { + if (!Vice.getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) { + cancel(); + return; + } + if (ThreadLocalRandom.current().nextInt(4) == 0) { + Vice.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.WEAKNESS, Integer.MAX_VALUE, 0))); + player.sendMessage(Lang.DRUGS.f("&7&oWhy does everything feel so heavy all of a sudden?")); + } + } + }.runTaskLater(Vice.getInstance(), effectDuration); + } else { + Vice.getDrugManager().addOD(player.getUniqueId()); + Vice.getUserManager().getLoadedUser(player.getUniqueId()).setLastTag(System.currentTimeMillis()); + player.sendMessage(Lang.DRUGS.f("&7&oThis doesn't feel right...")); + Vice.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.WITHER, 5 * 20, 1))); + Vice.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.BLINDNESS, 5 * 20, 0))); + Vice.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SLOW, 5 * 20, 0))); + new BukkitRunnable() { + @Override + public void run() { + Vice.getDrugManager().removeOD(player.getUniqueId()); + if (ThreadLocalRandom.current().nextBoolean() && Vice.getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) { + player.getActivePotionEffects().forEach(effect -> { + player.removePotionEffect(effect.getType()); + }); + player.damage(player.getHealth()); + player.sendMessage(Lang.DRUGS.f("&7&oIm never doing heroin again...")); + } + } + }.runTaskLater(Vice.getInstance(), 5 * 20); + } + }; + effect.apply(this, this.getDuration(), p); + return !failed[0]; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/example/Joint.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/example/Joint.java new file mode 100644 index 0000000..eaa119a --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/example/Joint.java @@ -0,0 +1,94 @@ +package net.grandtheftmc.vice.drugs.example; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drugs.DrugEffect; +import net.grandtheftmc.vice.drugs.DrugService; +import net.grandtheftmc.vice.drugs.DrugUtil; +import net.grandtheftmc.vice.drugs.categories.examples.Cannabinoids; +import net.grandtheftmc.vice.drugs.events.DrugUseEvent; +import org.bukkit.Bukkit; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.Collectors; + +public class Joint extends Cannabinoids { + + public Joint() { + super("joint", 120); + } + + @Override + public boolean apply(Player p) { + boolean[] failed = {false}; + UUID uuid = p.getUniqueId(); + DrugEffect effect = (drug, duration, player) -> { + final DrugService service = (DrugService) Vice.getInstance().getDrugManager().getService(); + int effectDuration = (int) Math.round(duration + (duration * ThreadLocalRandom.current().nextDouble(-.25, .25))) * 20; //to make it +/-5-25% + player.playSound(player.getLocation(), Sound.ENTITY_TNT_PRIMED, 1, 1); + Bukkit.getPluginManager().callEvent(new DrugUseEvent(player, this)); + final long addTime = System.currentTimeMillis(); + int roll = ThreadLocalRandom.current().nextInt(100); + + if (roll > 4 || Vice.getInstance().getDrugManager().inOD(player.getUniqueId())) { + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SLOW, effectDuration, 1))); + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SLOW_DIGGING, effectDuration, 0))); + new BukkitRunnable() { + @Override + public void run() { + if (!Vice.getInstance().getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) + return; + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.HUNGER, effectDuration, 1))); + player.sendMessage(Lang.DRUGS.f("&7&oDamn I could go for some McDonalds right now...")); + + } + }.runTaskLaterAsynchronously(Vice.getInstance(), 20 * 60 * 2); + final long startTime = System.currentTimeMillis(); + final Set<Player> nearby = player.getNearbyEntities(10, 10, 10).stream().filter(entity -> entity instanceof Player).map(entity -> (Player) entity).collect(Collectors.toSet()); + + new BukkitRunnable() { + @Override + public void run() { + if (startTime + (1000 * 2) <= System.currentTimeMillis()) cancel(); + for (int i = 0; i < 5; i++) { + double locX = player.getEyeLocation().getX() + (ThreadLocalRandom.current().nextDouble(0, 1) * (ThreadLocalRandom.current().nextBoolean() ? 1 : -1)); + double locZ = player.getEyeLocation().getZ() + (ThreadLocalRandom.current().nextDouble(0, 1) * (ThreadLocalRandom.current().nextBoolean() ? 1 : -1)); + double locY = player.getLocation().getY() + ThreadLocalRandom.current().nextDouble(1, 1.2); + nearby.forEach(p -> { + p.spawnParticle(Particle.FLAME, locX, locY, locZ, 1); + p.spawnParticle(Particle.SMOKE_NORMAL, locX, locY, locZ, 1); + }); + } + } + }.runTaskTimerAsynchronously(Vice.getInstance(), 0, 12); + } else { + Vice.getInstance().getDrugManager().addOD(player.getUniqueId()); + Vice.getUserManager().getLoadedUser(player.getUniqueId()).setLastTag(System.currentTimeMillis()); + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.BLINDNESS, effectDuration, 0))); + player.playSound(player.getLocation(), Sound.ENTITY_LIGHTNING_THUNDER, 10, 1); + final long endTime = System.currentTimeMillis() + (effectDuration / 20 * 1000); + new BukkitRunnable() { + @Override + public void run() { + if (System.currentTimeMillis() >= endTime || !Vice.getInstance().getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) { + Vice.getInstance().getDrugManager().removeOD(player.getUniqueId()); + cancel(); + } + player.playSound(player.getLocation(), DrugUtil.getRandomParanoiaSound(), 10, ThreadLocalRandom.current().nextFloat() * 2); + } + }.runTaskTimerAsynchronously(Vice.getInstance(), 5, 15); + player.sendMessage(Lang.DRUGS.f("&7&oUghhh... That must've been a bad batch of K2...")); + } + }; + effect.apply(this, this.getDuration(), p); + return !failed[0]; + } +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/example/LSD.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/example/LSD.java new file mode 100644 index 0000000..b3377ed --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/example/LSD.java @@ -0,0 +1,187 @@ +package net.grandtheftmc.vice.drugs.example; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drugs.DrugEffect; +import net.grandtheftmc.vice.drugs.DrugUtil; +import net.grandtheftmc.vice.drugs.categories.examples.Hallucinogens; +import net.grandtheftmc.vice.drugs.events.DrugUseEvent; +import org.bukkit.*; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitScheduler; + +import java.util.*; +import java.util.concurrent.ThreadLocalRandom; + +public class LSD extends Hallucinogens { + + private final Hashtable<UUID, HashSet<Location>> changedBlocks = new Hashtable<>(); + private final HashMap<UUID, Long> cooldown = new HashMap<>(); + private int task; + + public LSD() { + super("LSD",30); + } + + @Override + public boolean apply(Player p) { + boolean[] failed = {false}; + UUID uuid = p.getUniqueId(); + final long addTime = System.currentTimeMillis(); + final int stageDuration = getDuration() + (int)Math.round(getDuration()*ThreadLocalRandom.current().nextDouble(-.25, .25)); + + DrugEffect effect = (drug, duration, player) -> { + if (checkCooldown(uuid)) { + Bukkit.getPluginManager().callEvent(new DrugUseEvent(player, this)); + if (ThreadLocalRandom.current().nextInt(0, 100) <= 4 && !Vice.getInstance().getDrugManager().inOD(player.getUniqueId())) { + Vice.getUserManager().getLoadedUser(player.getUniqueId()).setLastTag(System.currentTimeMillis()); + Vice.getInstance().getDrugManager().addOD(player.getUniqueId()); + badTrip(player, addTime, duration); + return; + } + stageOne(player, addTime, stageDuration); + } else { + player.sendMessage(Lang.DRUGS.f("&7Hey man, I don't think that you should use it so soon, wait a while bro.")); + } + }; + effect.apply(this, this.getDuration(), p); + return !failed[0]; + } + + private void stageOne(Player player, long addTime, int length) { + if(player.isValid()) { + player.playSound(player.getLocation(), Sound.ENTITY_GENERIC_EAT, 1, 1); + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SLOW, length*2*20, 2))); + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.CONFUSION, length*2*20, 1))); + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.REGENERATION, length*2*20, 1))); + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, length*2*20, 1))); + player.setPlayerTime(18000, false); + new BukkitRunnable(){ + @Override + public void run() { + if(!Vice.getInstance().getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) + return; + stageTwo(player, addTime, length); + } + }.runTaskLater(Vice.getInstance(), length*20); + } + } + + private void stageTwo(Player player, long addTime, int length) { + if(player.isValid()) { + player.removePotionEffect(PotionEffectType.SLOW); + player.removePotionEffect(PotionEffectType.CONFUSION); + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SLOW_DIGGING, length*2*20, 1))); + final long endTime = System.currentTimeMillis() + (length*1000) + 10000; + BukkitScheduler scheduler = Vice.getInstance().getServer().getScheduler(); + scheduler.scheduleAsyncRepeatingTask(Vice.getInstance(), new Runnable() { + + @Override + public void run() { + if (System.currentTimeMillis()>=endTime || !Vice.getInstance().getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) { + scheduler.cancelTask(task); + player.resetPlayerTime(); + return; + } + player.playSound(player.getLocation(), DrugUtil.getRandomAmbientSound(), 3.0F, 1.0F); + } + }, 0, 20L); + new BukkitRunnable(){ + @Override + public void run() { + if(!Vice.getInstance().getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) + return; + stageThree(player, addTime, length); + } + }.runTaskLater(Vice.getInstance(), length*20); + } + } + + private void stageThree(Player player, long addTime, int length) { + final double stopTime = System.currentTimeMillis() + (length*1000); + new BukkitRunnable() { + @Override + public void run() { + if (System.currentTimeMillis()>=stopTime|| !Vice.getInstance().getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) { + if(player.isOnline() && changedBlocks.containsKey(player.getUniqueId())){ + changedBlocks.get(player.getUniqueId()).forEach(block -> { + player.sendBlockChange(block, block.getWorld().getBlockAt(block).getType(), block.getWorld().getBlockAt(block).getData()); + }); + } + changedBlocks.remove(player.getUniqueId()); + cancel(); + return; + } + + HashSet<Location> blocks = changedBlocks.containsKey(player.getUniqueId()) ? changedBlocks.get(player.getUniqueId()) : new HashSet<>(); + Collection<Block> nearbyBlocks = DrugUtil.getNearbyBlocks(player.getLocation(), 10); + + nearbyBlocks.forEach(block -> { + if(!blocks.contains(block.getLocation())){ + blocks.add(block.getLocation()); + } + player.sendBlockChange(block.getLocation(), Material.WOOL, (byte)ThreadLocalRandom.current().nextInt(0, 15)); + }); + changedBlocks.put(player.getUniqueId(), blocks); + } + }.runTaskTimer(Vice.getInstance(), 0, 20); + new BukkitRunnable(){ + @Override + public void run() { + if(!Vice.getInstance().getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) + return; + stageFive(player, addTime, length); + } + }.runTaskLater(Vice.getInstance(), length*20); + } + + private void stageFive(Player player, long addTime, int length) { + if(Vice.getInstance().getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) { + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.CONFUSION, length*20*2, 2))); + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.WEAKNESS, length*20*2, 1))); + } + + } + + public void badTrip(Player player, long addTime, int length) { + if(Vice.getInstance().getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) { + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.CONFUSION, length*4, 2))); + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.WEAKNESS, length*4, 1))); + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SLOW, length*4, 2))); + BukkitScheduler scheduler = Vice.getInstance().getServer().getScheduler(); + task = scheduler.scheduleAsyncRepeatingTask(Vice.getInstance(), new Runnable() { + int count = 0; + + @Override + public void run() { + count += 1; + if (count >= 70 || !Vice.getInstance().getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) { + scheduler.cancelTask(task); + Vice.getInstance().getDrugManager().removeOD(player.getUniqueId()); + return; + } + player.playSound(player.getLocation(), DrugUtil.getRandomParanoiaSound(), 3.0F, 1.0F); + player.playSound(player.getLocation(), DrugUtil.getRandomAmbientSound(), 3.0F, 1.0F); + player.playEffect(EntityEffect.WITCH_MAGIC); + player.playEffect(EntityEffect.ZOMBIE_TRANSFORM); + } + }, 10L, 20L); + } + } + + private boolean checkCooldown(UUID uuid){ + if(cooldown.containsKey(uuid)){ + if(System.currentTimeMillis()>=(cooldown.get(uuid)+(60*15*1000))){//cooldown has expired + cooldown.put(uuid, System.currentTimeMillis()); + return true; + } + return false; + } + cooldown.put(uuid, System.currentTimeMillis()); + return true; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/example/MDMA.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/example/MDMA.java new file mode 100644 index 0000000..27447f7 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/example/MDMA.java @@ -0,0 +1,92 @@ +package net.grandtheftmc.vice.drugs.example; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drugs.DrugEffect; +import net.grandtheftmc.vice.drugs.categories.examples.Hallucinogens; +import net.grandtheftmc.vice.drugs.events.DrugUseEvent; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Particle; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.ArrayList; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.Collectors; + +public class MDMA extends Hallucinogens { + + public MDMA() { + super("mdma", 120); + } + + private ArrayList<UUID> using = new ArrayList<>(); + + @Override + public boolean apply(Player p) { + boolean[] failed = {false}; + UUID uuid = p.getUniqueId(); + DrugEffect effect = (drug, duration, player) -> { + if (this.using.contains(player.getUniqueId())) { + failed[0] = true; + player.sendMessage(Lang.DRUGS + "" + ChatColor.RED + "I don't think its a good idea to do more than one..."); + return; + } + this.using.add(player.getUniqueId()); + int roll = ThreadLocalRandom.current().nextInt(100); + int effectDuration = (int) Math.round(duration + (duration * ThreadLocalRandom.current().nextDouble(-.25, .25))) * 20;//to make it +/-5-25% + Bukkit.getPluginManager().callEvent(new DrugUseEvent(player, this)); + + if (roll > 4 || !Vice.getDrugManager().inOD(player.getUniqueId())) { + final long addTime = System.currentTimeMillis(); + Vice.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SLOW, effectDuration, 0))); + //less anxiety? Or I might have to fool around with .setWalkSpeed etc + Vice.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.CONFUSION, effectDuration, 0))); + final Set<Player> nearby = player.getNearbyEntities(10, 10, 10).stream().filter(entity -> entity instanceof Player).map(entity -> (Player) entity).collect(Collectors.toSet()); + nearby.add(player); + + new BukkitRunnable() { + @Override + public void run() { + if (System.currentTimeMillis() >= (addTime + effectDuration / 20 * 1000) || !Vice.getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) { + cancel(); + using.remove(player.getUniqueId()); + return; + } + for (int i = 0; i < 5; i++) {//hopefully blinds the player's view with hearts. Haven't tested how many particles it will actually take. Could do a more systematic approach like draw a panel of hearts, but I think this is better. + double locX = player.getEyeLocation().getX() + (ThreadLocalRandom.current().nextDouble(-.5, .5)); + double locZ = player.getEyeLocation().getZ() + (ThreadLocalRandom.current().nextDouble(-.5, .5)); + double locY = player.getLocation().getY() + ThreadLocalRandom.current().nextDouble(2.1, 2.3); + nearby.forEach(p -> p.spawnParticle(Particle.HEART, locX, locY, locZ, 1)); + } + } + }.runTaskTimerAsynchronously(Vice.getInstance(), 0, 5); + + } else { + Vice.getDrugManager().addOD(player.getUniqueId()); + Vice.getUserManager().getLoadedUser(player.getUniqueId()).setLastTag(System.currentTimeMillis()); + Vice.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.CONFUSION, 25 * 20, 0))); + Vice.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.HUNGER, 25 * 20, 2))); + Vice.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.POISON, 25 * 20, 2))); + Vice.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.BLINDNESS, 25 * 20, 0))); + Vice.getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SPEED, 25 * 20, 2))); + //message + new BukkitRunnable() { + @Override + public void run() { + Vice.getDrugManager().removeOD(player.getUniqueId()); + using.remove(player.getUniqueId()); + } + }.runTaskLaterAsynchronously(Vice.getInstance(), 25 * 20); + } + }; + effect.apply(this, this.getDuration(), p); + return !failed[0]; + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/example/Meth.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/example/Meth.java new file mode 100644 index 0000000..7f2aae1 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/example/Meth.java @@ -0,0 +1,73 @@ +package net.grandtheftmc.vice.drugs.example; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drugs.DrugEffect; +import net.grandtheftmc.vice.drugs.categories.examples.Stimulants; +import net.grandtheftmc.vice.drugs.events.DrugUseEvent; +import org.bukkit.Bukkit; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; + +/** + * Created by Timothy Lampen on 2017-04-06. + */ +public class Meth extends Stimulants{ + private static final int ADDITIONAL_HALF_HEARTS = 10; + public Meth() { + super("meth", 120); + } + + @Override + public boolean apply(Player p) { + boolean[] failed = {false}; + UUID uuid = p.getUniqueId(); + DrugEffect effect = (drug, duration, player) -> { + Vice.getUserManager().getLoadedUser(player.getUniqueId()).setLastTag(System.currentTimeMillis()); + player.playSound(player.getLocation(), Sound.ENTITY_TNT_PRIMED, 1, 1); + int effectDuration = (int) Math.round(duration + (duration * ThreadLocalRandom.current().nextDouble(-.25, .25))) * 20; + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SPEED, effectDuration, 1))); + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.INCREASE_DAMAGE, effectDuration, 0))); + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.HEALTH_BOOST, effectDuration, 1))); + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, effectDuration, 0))); + long addTime = System.currentTimeMillis(); + new BukkitRunnable() { + @Override + public void run() { + if (!Vice.getInstance().getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) { + cancel(); + return; + } + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SLOW, effectDuration, 0))); + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.WEAKNESS, effectDuration, 0))); + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.WITHER, effectDuration, 0))); + long endTime = System.currentTimeMillis() + ((effectDuration / 20) * 1000); + new BukkitRunnable() { + @Override + public void run() { + if (System.currentTimeMillis() >= endTime || !Vice.getInstance().getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) { + player.setMaxHealth(20); + cancel(); + return; + } + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, new PotionEffect(PotionEffectType.BLINDNESS, ThreadLocalRandom.current().nextInt(2, 6) * 20, 0)); + } + }.runTaskTimer(Vice.getInstance(), 0, ThreadLocalRandom.current().nextInt(15, 41) * 20); + player.setMaxHealth(20); + player.sendMessage(Lang.DRUGS.f("&7&oUggh, I shouldn't have tried meth...")); + + } + }.runTaskLater(Vice.getInstance(), duration * 20); + + Bukkit.getPluginManager().callEvent(new DrugUseEvent(player, this)); + }; + effect.apply(this, this.getDuration(), p); + return !failed[0]; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/example/Steroids.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/example/Steroids.java new file mode 100644 index 0000000..5749638 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/example/Steroids.java @@ -0,0 +1,93 @@ +package net.grandtheftmc.vice.drugs.example; + +import com.j0ach1mmall3.jlib.player.JLibPlayer; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drugs.DrugEffect; +import net.grandtheftmc.vice.drugs.categories.examples.AnabolicSteroids; +import net.grandtheftmc.vice.drugs.events.DrugUseEvent; +import net.grandtheftmc.vice.users.ViceUser; +import org.bukkit.Bukkit; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.*; +import java.util.concurrent.ThreadLocalRandom; + +/** + * Created by Timothy Lampen on 2017-04-01. + */ +public class Steroids extends AnabolicSteroids{ + + private final HashMap<UUID, List<Long>> injectTimes = new HashMap<>(); + private static final int NEEDED_RATE = 3;//per X + private static final int TIMEFRAME = 10;//seconds + public Steroids() { + super("steroids", 120); + } + + @Override + public boolean apply(Player p) { + boolean[] failed = {false}; + UUID uuid = p.getUniqueId(); + DrugEffect effect = (drug, duration, player) -> { + player.playSound(player.getLocation(), Sound.BLOCK_NOTE_SNARE, 1, 1); + int effectDuration = (int) Math.round(duration + (duration * ThreadLocalRandom.current().nextDouble(-.25, .25))) * 20; + Bukkit.getPluginManager().callEvent(new DrugUseEvent(player, this)); + if (playerCanRage(uuid)) { + for (PotionEffect type : player.getActivePotionEffects()) { + player.removePotionEffect(type.getType()); + } + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.WEAKNESS, effectDuration / 2, 0))); + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SPEED, effectDuration / 2, 2))); + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.WITHER, effectDuration / 2, 1))); + Vice.getUserManager().getLoadedUser(player.getUniqueId()).setLastTag(System.currentTimeMillis()); + } else { + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SPEED, effectDuration, 0))); + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, effectDuration, 0))); + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.INCREASE_DAMAGE, effectDuration, 1))); + final long addTime = System.currentTimeMillis(); + new BukkitRunnable() { + @Override + public void run() { + new JLibPlayer(player).setWorldborderTint(100); + new BukkitRunnable() { + @Override + public void run() { + if (!Vice.getInstance().getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) { + cancel(); + return; + } + ViceUser user = Vice.getUserManager().getLoadedUser(uuid); + user.updateTintHealth(player, Core.getUserManager().getLoadedUser(player.getUniqueId())); + } + }.runTaskLater(Vice.getInstance(), effectDuration / 20); + } + }.runTaskLater(Vice.getInstance(), 1); + } + }; + effect.apply(this, this.getDuration(), p); + return !failed[0]; + } + + private boolean playerCanRage(UUID uuid){ + if(injectTimes.containsKey(uuid)){ + List<Long> tempTimes = new ArrayList<>(); + ArrayList<Long> times = new ArrayList<>(injectTimes.get(uuid)); + times.add(System.currentTimeMillis()); + times.stream().forEach((l) -> { + if((l+(TIMEFRAME*1000))<=System.currentTimeMillis()){ + tempTimes.add(l); + } + }); + times.removeAll(tempTimes); + injectTimes.put(uuid, times); + return times.size()>=NEEDED_RATE; + } + injectTimes.put(uuid, Arrays.asList(System.currentTimeMillis())); + return false; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/example/Weed.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/example/Weed.java new file mode 100644 index 0000000..e7489e4 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/example/Weed.java @@ -0,0 +1,84 @@ +package net.grandtheftmc.vice.drugs.example; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drugs.DrugEffect; +import net.grandtheftmc.vice.drugs.DrugUtil; +import net.grandtheftmc.vice.drugs.categories.examples.Cannabinoids; +import net.grandtheftmc.vice.drugs.events.DrugUseEvent; +import org.bukkit.Bukkit; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; + +public class Weed extends Cannabinoids { + + public Weed() { + super("weed", 120); + /*ShapelessRecipe rollingPaperRecipe = new ShapelessRecipe(Vice.getItemManager().getItem("rollingpaper").getItem()); + rollingPaperRecipe.addIngredient(3, Material.PAPER); + Bukkit.getServer().addRecipe(rollingPaperRecipe); + + ShapelessRecipe jointRecipe = new ShapelessRecipe(Vice.getItemManager().getItem("joint").getItem()); + jointRecipe.addIngredient(Vice.getItemManager().getItem("rollingpaper").getItem().getType()); + jointRecipe.addIngredient(Vice.getItemManager().getItem("groundweed").getItem().getType()); + Bukkit.getServer().addRecipe(jointRecipe);*/ + } + + @Override + public boolean apply(Player p) { + boolean[] failed = {false}; + UUID uuid = p.getUniqueId(); + DrugEffect effect = (drug, duration, player) -> { + int roll = ThreadLocalRandom.current().nextInt(100); + int effectDuration = (int) Math.round(duration + (duration * ThreadLocalRandom.current().nextDouble(-.25, .25))) * 20; + player.playSound(player.getLocation(), Sound.BLOCK_LAVA_POP, 1, 1); + Bukkit.getPluginManager().callEvent(new DrugUseEvent(player, this)); + final long addTime = System.currentTimeMillis(); + + if (roll > 4 || Vice.getInstance().getDrugManager().inOD(player.getUniqueId())) { + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SLOW, effectDuration, 1))); + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.SLOW_DIGGING, effectDuration, 0))); + new BukkitRunnable() { + @Override + public void run() { + if (!Vice.getInstance().getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) + return; + new BukkitRunnable() { + @Override + public void run() { + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.HUNGER, effectDuration, 1))); + } + }.runTask(Vice.getInstance()); + player.sendMessage(Lang.DRUGS.f("&7&oDamn I could go for some McDonalds right now...")); + + } + }.runTaskLaterAsynchronously(Vice.getInstance(), 20 * 60 * 2); + } else { + Vice.getInstance().getDrugManager().addOD(player.getUniqueId()); + Vice.getUserManager().getLoadedUser(player.getUniqueId()).setLastTag(System.currentTimeMillis()); + Vice.getInstance().getDrugManager().getEffectManager().addEffect(player, (new PotionEffect(PotionEffectType.BLINDNESS, effectDuration, 0))); + player.playSound(player.getLocation(), Sound.ENTITY_LIGHTNING_THUNDER, 10, 1); + final long endTime = System.currentTimeMillis() + (effectDuration / 20 * 1000); + new BukkitRunnable() { + @Override + public void run() { + if (System.currentTimeMillis() >= endTime || !Vice.getInstance().getDrugManager().getEffectManager().canRecieveOngoingEffect(player, addTime)) { + Vice.getInstance().getDrugManager().removeOD(player.getUniqueId()); + cancel(); + } + player.playSound(player.getLocation(), DrugUtil.getRandomParanoiaSound(), 10, ThreadLocalRandom.current().nextFloat() * 2); + } + }.runTaskTimerAsynchronously(Vice.getInstance(), 5, 15); + player.sendMessage(Lang.DRUGS.f("&7&oUghhh... That must've been a bad batch of K2...")); + } + }; + effect.apply(this, this.getDuration(), p); + return !failed[0]; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/internal/manager/Manager.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/internal/manager/Manager.java new file mode 100644 index 0000000..b8beaf6 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/internal/manager/Manager.java @@ -0,0 +1,46 @@ +package net.grandtheftmc.vice.drugs.internal.manager; + +import net.grandtheftmc.vice.drugs.internal.service.Service; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Created by Remco on 25-3-2017. + */ +public abstract class Manager <S extends Service> { + + private final S service; + private volatile String name; + private AtomicInteger id; + + public Manager(String name, AtomicInteger id, S service) { + this.service = service; + this.name = name; + this.id = id; + } + + public abstract void start(); + public abstract void stop(); + public abstract boolean destroy(); + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public AtomicInteger getId() { + return id; + } + + public void setId(AtomicInteger id) { + this.id = id; + } + + public S getService() { + return service; + } +} + diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/internal/service/Helper.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/internal/service/Helper.java new file mode 100644 index 0000000..970a3d6 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/internal/service/Helper.java @@ -0,0 +1,11 @@ +package net.grandtheftmc.vice.drugs.internal.service; + +/** + * Created by Remco on 25-3-2017. + */ +public interface Helper { + + String getHelperName(); + Class<? extends Service> getServiceClass(); + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/internal/service/Service.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/internal/service/Service.java new file mode 100644 index 0000000..e14b7b9 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/internal/service/Service.java @@ -0,0 +1,42 @@ +package net.grandtheftmc.vice.drugs.internal.service; + +/** + * Created by Remco on 25-3-2017. + */ +public abstract class Service { + + private volatile Service instance; + private volatile Helper helper; + + private final String name; + + public Service(String name, Helper helper) { + this.name = name; + this.helper = helper; + } + + protected synchronized void setHelper(Helper helper){ + this.helper = helper; + } + + protected Helper getHelper(){ + return helper; + } + + public String getName() { + return name; + } + + protected Service getInstance(){ + if(instance == null){ + synchronized(Service.class) { + try { + instance = Service.class.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + e.printStackTrace(); + } + } + } + return instance; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/items/DrugItem.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/items/DrugItem.java new file mode 100644 index 0000000..ba56bd9 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/drugs/items/DrugItem.java @@ -0,0 +1,107 @@ +package net.grandtheftmc.vice.drugs.items; + +import com.j0ach1mmall3.jlib.inventory.JLibItem; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drugs.Drug; +import net.grandtheftmc.vice.drugs.DrugService; +import net.minecraft.server.v1_12_R1.NBTTagCompound; +import net.minecraft.server.v1_12_R1.NBTTagString; +import org.bukkit.Material; +import org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack; +import org.bukkit.inventory.ItemStack; + +import java.util.Map; +import java.util.UUID; + +public class DrugItem { + + private final static DrugService drugService = (DrugService) Vice.getDrugManager().getService(); + + private ItemStack itemStack; + private Drug drug; + + public DrugItem(Material material, int amount, UUID owner, Drug drug) { + this.itemStack = new ItemStack(material, amount); + this.drug = drug; + apply(); + } + + public DrugItem(ItemStack itemStack, UUID owner, Drug drug) { + this.itemStack = itemStack.clone(); + this.drug = drug; + apply(); + } + + + public DrugItem(ItemStack itemStack, Drug drug) { + this.itemStack = itemStack.clone(); + this.drug = drug; + apply(); + } + + public DrugItem(JLibItem item, Drug drug) { + this.itemStack = item.getItemStack(); + this.drug = drug; + apply(); + } + + protected DrugItem(ItemStack itemStack) { + this.itemStack = itemStack.clone(); + } + + public final static DrugItem getByItemStack(ItemStack itemStack) { + ItemStack clone = itemStack.clone(); + clone.setAmount(1); + DrugItem base = new DrugItem(clone); + if (drugService.getDrugs().stream().anyMatch(base::isValid) || drugService.getItems().contains(base)) + return base; + return null; + } + + public static DrugItem getByDrug(Drug drug) { + if (drugService.getRawItems().rowMap().values().stream().anyMatch(drugItemDrugMap -> drugItemDrugMap.containsValue(drug))) { + Map<DrugItem, Drug> drugs = drugService.getRawItems().rowMap().values().stream().filter(drugItemDrugMap -> drugItemDrugMap.containsValue(drug)).findFirst().get(); + for (DrugItem item : drugs.keySet()) { + if (drugs.get(item).equals(drug)) { + return item; + } + } + } + return null; + } + + public void apply() { + if (!isValid(drug)) { + net.minecraft.server.v1_12_R1.ItemStack nmsCopy = CraftItemStack.asNMSCopy(itemStack); + NBTTagCompound tag = nmsCopy.hasTag() ? nmsCopy.getTag() : new NBTTagCompound(); + NBTTagString drugName = new NBTTagString(drug.getName()); + assert tag != null; + tag.set("drugName", drugName); + nmsCopy.setTag(tag); + this.itemStack = CraftItemStack.asBukkitCopy(nmsCopy); + + } + } + + public final ItemStack getItemStack() { + return itemStack; + } + + public boolean isValid(Drug drug) { + if (itemStack != null && drug != null) { + net.minecraft.server.v1_12_R1.ItemStack nmsCopy = CraftItemStack.asNMSCopy(itemStack); + if (nmsCopy != null) { + NBTTagCompound tag = nmsCopy.hasTag() ? nmsCopy.getTag() : new NBTTagCompound(); + if ((tag != null ? tag.get("drugName") : null) != null) { + String name = tag.getString("drugName"); + return drugService.getDrugs().stream().map(Drug::getName).anyMatch(item -> item.equalsIgnoreCase(name) && drug.getName().equalsIgnoreCase(item)); + } + } + } + return false; + } + + public Drug getDrug() { + return drug; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/durability/DurabilityItems.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/durability/DurabilityItems.java new file mode 100644 index 0000000..d30aaf9 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/durability/DurabilityItems.java @@ -0,0 +1,65 @@ +package net.grandtheftmc.vice.durability; + +import org.bukkit.Material; + +/** + * Created by ThatAbstractWolf on 2017-08-02. + */ +public enum DurabilityItems { + + LEATHER_HELMET(Material.LEATHER_HELMET, 56), + LEATHER_CHESTPLATE(Material.LEATHER_CHESTPLATE, 81), + LEATHER_LEGGINGS(Material.LEATHER_LEGGINGS, 76), + LEATHER_BOOTS(Material.LEATHER_BOOTS, 66), + + GOLD_HELMET(Material.GOLD_HELMET, 78), + GOLD_CHESTPLATE(Material.GOLD_CHESTPLATE, 113), + GOLD_LEGGINGS(Material.GOLD_LEGGINGS, 106), + GOLD_BOOTS(Material.GOLD_BOOTS, 92), + + CHAINMAIL_HELMET(Material.CHAINMAIL_HELMET, 166), + CHAINMAIL_CHESTPLATE(Material.CHAINMAIL_CHESTPLATE, 241), + CHAINMAIL_LEGGINGS(Material.CHAINMAIL_LEGGINGS, 226), + CHAINMAIL_BOOTS(Material.CHAINMAIL_BOOTS, 196), + + IRON_HELMET(Material.IRON_HELMET, 166), + IRON_CHESTPLATE(Material.IRON_CHESTPLATE, 241), + IRON_LEGGINGS(Material.IRON_LEGGINGS, 226), + IRON_BOOTS(Material.IRON_BOOTS, 66), + + DIAMOND_HELMET(Material.DIAMOND_HELMET, 364), + DIAMOND_CHESTPLATE(Material.DIAMOND_CHESTPLATE, 529), + DIAMOND_LEGGINGS(Material.DIAMOND_LEGGINGS, 496), + DIAMOND_BOOTS(Material.DIAMOND_BOOTS, 430), + + JETPACK(Material.GOLD_CHESTPLATE, 50, "Jetpack") + ; + + private Material material; + private int maximumDurability; + + private String displayName; + + DurabilityItems(Material material, int maximumDurability) { + this.material = material; + this.maximumDurability = maximumDurability; + } + + DurabilityItems(Material material, int maximumDurability, String displayName) { + this.material = material; + this.maximumDurability = maximumDurability; + this.displayName = displayName; + } + + public Material getMaterial() { + return material; + } + + public int getMaximumDurability() { + return maximumDurability; + } + + public String getDisplayName() { + return displayName; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/durability/DurabilityListener.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/durability/DurabilityListener.java new file mode 100644 index 0000000..b97fc56 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/durability/DurabilityListener.java @@ -0,0 +1,204 @@ +package net.grandtheftmc.vice.durability; + +import net.grandtheftmc.vice.events.ArmorEquipEvent; +import net.grandtheftmc.vice.utils.DurabilityUtil; +import org.bukkit.ChatColor; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByBlockEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.List; +import java.util.Optional; + +/** + * Created by ThatAbstractWolf on 2017-08-02. + */ +public class DurabilityListener implements Listener { + + @EventHandler + public void onDurabilityDecrease(EntityDamageEvent event) { + if (event.getEntity() instanceof Player) { + Player player = (Player) event.getEntity(); + if (event.isCancelled()) return; + + int durabilityDecreaseAmount = 0; + switch (event.getCause()) { + case ENTITY_ATTACK: + case ENTITY_EXPLOSION: + case ENTITY_SWEEP_ATTACK: + case BLOCK_EXPLOSION: + case FALLING_BLOCK: + case PROJECTILE: + case LIGHTNING: + case THORNS: + durabilityDecreaseAmount = 1; + break; + + default: + break; + } + + runDecreaseChecks(player, durabilityDecreaseAmount); + } + } + + @EventHandler + public void onBlockDamage(EntityDamageByBlockEvent event) { + + if (event.getDamager() == null || event.getEntity() == null || event.getCause() == null) return; + + if (event.getEntity() instanceof Player) { + Player player = (Player) event.getEntity(); + Block damager = event.getDamager(); + if (event.isCancelled()) return; + + int durabilityDecreaseAmount = 0; + switch (damager.getType()) { + case CACTUS: + case LAVA: + case STATIONARY_LAVA: + case MAGMA: + case FIRE: + durabilityDecreaseAmount = 1; + break; + + default: + break; + } + + runDecreaseChecks(player, durabilityDecreaseAmount); + } + } + + @EventHandler + public void onArmourEquip(ArmorEquipEvent event) { + if (event.getNewArmorPiece() != null) { + ItemStack item = event.getNewArmorPiece(); + + switch (item.getType()) { + case CHAINMAIL_LEGGINGS: + case IRON_LEGGINGS: + case IRON_BOOTS: + case DIAMOND_LEGGINGS: + case DIAMOND_BOOTS: + case GOLD_LEGGINGS: + case GOLD_BOOTS: + event.setCancelled(true); + return; + } + + if (DurabilityUtil.getDurability(item) == -1) { + Optional<DurabilityItems> durabilityItems = DurabilityUtil.getDurabilityItem(item); + if (!durabilityItems.isPresent()) return; + + if (item.getItemMeta() != null && !item.getItemMeta().isUnbreakable()) { + ItemMeta itemMeta = item.getItemMeta(); + itemMeta.setUnbreakable(true); + itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE); + item.setItemMeta(itemMeta); + } + + DurabilityItems durabilityItem = durabilityItems.get(); + DurabilityUtil.setDurabilityOnArmour(event.getPlayer(), item, durabilityItem.getMaximumDurability()); + } + } + } + + @EventHandler + public void onInventoryClick(InventoryClickEvent event) { + + if (!(event.getWhoClicked() instanceof Player)) return; + Player player = (Player) event.getWhoClicked(); + if (player.getItemOnCursor() != null) { + ItemStack item = player.getItemOnCursor(); + if (item != null ) { + ItemStack itemStack = applyDurabilitySpecifics(item); + if (itemStack != null) { + player.setItemOnCursor(itemStack); + } + } + } + for (int i = 0; i < player.getInventory().getSize(); i++) { + ItemStack item = player.getInventory().getContents()[i]; + if (item == null) continue; + ItemStack itemStack = applyDurabilitySpecifics(item); + if (itemStack == null) continue; + player.getInventory().setItem(i, itemStack); + } + } + + @EventHandler + public void onPickup(PlayerPickupItemEvent event) { + Player player = event.getPlayer(); + ItemStack item = event.getItem().getItemStack(); + if (item != null) { + ItemStack itemStack = applyDurabilitySpecifics(item); + if (itemStack != null) { + for (int i = 0; i < player.getInventory().getSize(); i++) { + ItemStack check = player.getInventory().getContents()[i]; + if (check != null && check == item) { + player.getInventory().setItem(i, itemStack); + break; + } + } + } + } + } + + private void runDecreaseChecks(Player player, int durabilityDecreaseAmount) { + if (player.getInventory().getHelmet() != null && player.getInventory().getHelmet().getItemMeta().getLore() != null && !hasDurable(player.getInventory().getHelmet())) + DurabilityUtil.decreaseDurability(player, player.getInventory().getHelmet(), durabilityDecreaseAmount); + if (player.getInventory().getChestplate() != null && player.getInventory().getChestplate().getItemMeta().getLore() != null && !hasDurable(player.getInventory().getChestplate())) + DurabilityUtil.decreaseDurability(player, player.getInventory().getChestplate(), durabilityDecreaseAmount); + if (player.getInventory().getLeggings() != null && player.getInventory().getLeggings().getItemMeta().getLore() != null && !hasDurable(player.getInventory().getLeggings())) + DurabilityUtil.decreaseDurability(player, player.getInventory().getLeggings(), durabilityDecreaseAmount); + if (player.getInventory().getBoots() != null && player.getInventory().getBoots().getItemMeta().getLore() != null && !hasDurable(player.getInventory().getBoots())) + DurabilityUtil.decreaseDurability(player, player.getInventory().getBoots(), durabilityDecreaseAmount); + } + + private ItemStack applyDurabilitySpecifics(ItemStack item) { + + if (DurabilityUtil.getDurability(item) == -1) { + Optional<DurabilityItems> durabilityItems = DurabilityUtil.getDurabilityItem(item); + + if (item == null || !durabilityItems.isPresent()) return null; + + if (item.getItemMeta() != null && !item.getItemMeta().isUnbreakable()) { + ItemMeta itemMeta = item.getItemMeta(); + itemMeta.setUnbreakable(true); + itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE); + item.setItemMeta(itemMeta); + } + + DurabilityItems durabilityItem = durabilityItems.get(); + ItemStack newArmour = DurabilityUtil.setDurability(item, durabilityItem.getMaximumDurability()); + DurabilityUtil.setDurabilityLore(newArmour, durabilityItem.getMaximumDurability(), durabilityItem); + return newArmour; + } + + return null; + } + + private boolean hasDurable(ItemStack item) { + + if (item.getItemMeta().getLore() == null) return false; + + List<String> lore = item.getItemMeta().getLore(); + + for (String lorePart : lore) { + if (ChatColor.stripColor(lorePart).contains("Durable")) { + return true; + } + } + + return false; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/events/ArmorEquipEvent.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/events/ArmorEquipEvent.java new file mode 100644 index 0000000..f7b8424 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/events/ArmorEquipEvent.java @@ -0,0 +1,141 @@ +package net.grandtheftmc.vice.events; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.bukkit.inventory.ItemStack; + +/** + * @Author Borlea + * @Github https://github.com/borlea/ + * @Website http://codingforcookies.com/ + * @since Jul 30, 2015 + */ +public final class ArmorEquipEvent extends PlayerEvent implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + private boolean cancel = false; + private final EquipMethod equipType; + private final EquipArmorType type; + private ItemStack oldArmorPiece, newArmorPiece; + + /** + * Constructor for the ArmorEquipEvent. + * + * @param player The player who put on / removed the armor. + * @param type The EquipArmorType of the armor added + * @param oldArmorPiece The ItemStack of the armor removed. + * @param newArmorPiece The ItemStack of the armor added. + */ + public ArmorEquipEvent(final Player player, final EquipMethod equipType, final EquipArmorType type, final ItemStack oldArmorPiece, final ItemStack newArmorPiece){ + super(player); + this.equipType = equipType; + this.type = type; + this.oldArmorPiece = oldArmorPiece; + this.newArmorPiece = newArmorPiece; + } + + /** + * Gets a list of handlers handling this event. + * + * @return A list of handlers handling this event. + */ + public final static HandlerList getHandlerList(){ + return handlers; + } + + /** + * Gets a list of handlers handling this event. + * + * @return A list of handlers handling this event. + */ + @Override + public final HandlerList getHandlers(){ + return handlers; + } + + /** + * Sets if this event should be cancelled. + * + * @param cancel If this event should be cancelled. + */ + public final void setCancelled(final boolean cancel){ + this.cancel = cancel; + } + + /** + * Gets if this event is cancelled. + * + * @return If this event is cancelled + */ + public final boolean isCancelled(){ + return cancel; + } + + public final EquipArmorType getType(){ + return type; + } + + /** + * Returns the last equipped armor piece, could be a piece of armor, {@link Material Air}, or null. + */ + public final ItemStack getOldArmorPiece(){ + return oldArmorPiece; + } + + public final void setOldArmorPiece(final ItemStack oldArmorPiece){ + this.oldArmorPiece = oldArmorPiece; + } + + /** + * Returns the newly equipped armor, could be a piece of armor, {@link Material Air}, or null. + */ + public final ItemStack getNewArmorPiece(){ + return newArmorPiece; + } + + public final void setNewArmorPiece(final ItemStack newArmorPiece){ + this.newArmorPiece = newArmorPiece; + } + + /** + * Gets the method used to either equip or unequip an armor piece. + */ + public EquipMethod getMethod(){ + return equipType; + } + + public enum EquipMethod{ + /** + * When you shift click an armor piece to equip or unequip + */ + SHIFT_CLICK, + /** + * When you drag and drop the item to equip or unequip + */ + DRAG, + /** + * When you right click an armor piece in the hotbar without the inventory open to equip. + */ + HOTBAR, + /** + * When you press the hotbar slot number while hovering over the armor slot to equip or unequip + */ + HOTBAR_SWAP, + /** + * When in range of a dispenser that shoots an armor piece to equip. + */ + DISPENSER, + /** + * When an armor piece breaks to unequip + */ + BROKE, + /** + * When you die causing all armor to unequip + */ + DEATH, + ; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/events/EquipArmorType.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/events/EquipArmorType.java new file mode 100644 index 0000000..1bd0ab5 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/events/EquipArmorType.java @@ -0,0 +1,60 @@ +package net.grandtheftmc.vice.events; + +import org.bukkit.inventory.ItemStack; + +/** + * Created by Timothy Lampen on 2017-08-11. + */ +public enum EquipArmorType { + + HELMET(5), CHESTPLATE(6), LEGGINGS(7), BOOTS(8); + + private final int slot; + + EquipArmorType(int slot){ + this.slot = slot; + } + + /** + * Attempts to match the ArmorType for the specified ItemStack. + * + * @param itemStack The ItemStack to parse the type of. + * @return The parsed ArmorType. (null if none were found.) + */ + public final static EquipArmorType matchType(final ItemStack itemStack){ + if(itemStack == null) { return null; } + switch (itemStack.getType()){ + case DIAMOND_HELMET: + case GOLD_HELMET: + case IRON_HELMET: + case CHAINMAIL_HELMET: + case LEATHER_HELMET: + return HELMET; + case DIAMOND_CHESTPLATE: + case GOLD_CHESTPLATE: + case IRON_CHESTPLATE: + case CHAINMAIL_CHESTPLATE: + case LEATHER_CHESTPLATE: + return CHESTPLATE; + case DIAMOND_LEGGINGS: + case GOLD_LEGGINGS: + case IRON_LEGGINGS: + case CHAINMAIL_LEGGINGS: + case LEATHER_LEGGINGS: + return LEGGINGS; + case DIAMOND_BOOTS: + case GOLD_BOOTS: + case IRON_BOOTS: + case CHAINMAIL_BOOTS: + case LEATHER_BOOTS: + return BOOTS; + default: + return null; + } + } + + public int getSlot(){ + return slot; + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/events/TPEvent.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/events/TPEvent.java new file mode 100644 index 0000000..60d4ed9 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/events/TPEvent.java @@ -0,0 +1,116 @@ +package net.grandtheftmc.vice.events; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class TPEvent extends Event { + private static final HandlerList HANDLERS = new HandlerList(); + + @Override + public HandlerList getHandlers() { + return HANDLERS; + } + + public static HandlerList getHandlerList() { + return HANDLERS; + } + + private Player sender; + private Player target; + private TPType type; + private String cancelMessage; + private Location targetLocation; + + public TPEvent(Player sender, TPType type) { + this.sender = sender; + this.type = type; + } + + public TPEvent(Player sender, Player target, TPType type) { + this.sender = sender; + this.target = target; + this.type = type; + } + + + public TPType getType() { + return this.type; + } + + public void setType(TPType type) { + this.type = type; + } + + public boolean isCancelled() { + return this.cancelMessage != null; + } + + public String getCancelMessage() { + return this.cancelMessage; + } + + public void setCancelled(String msg) { + this.cancelMessage = msg; + } + + public TPEvent call() { + Bukkit.getPluginManager().callEvent(this); + return this; + } + + public Location getTargetLocation() { + return this.targetLocation; + } + + public void setTargetLocation(Location targetLocation) { + this.targetLocation = targetLocation; + } + + public boolean targetLocationIsChanged() { + return this.targetLocation != null; + } + + + public Player getSender() { + return this.sender; + } + + public Player getPlayer() { + return this.sender; + } + + public void setSender(Player sender) { + this.sender = sender; + } + + + public Player getTarget() { + return this.target; + } + + public void setTarget(Player target) { + this.target = target; + } + + + public enum TPType { + TPA_REQ, + TPAHERE_REQ, + TPA_ACCEPT, + TPAHERE_ACCEPT, + TP_COMPLETE, + WARP, + VEHICLE_SEND_AWAY, + VEHICLE_CALL, + HOUSE_ENTER, + HOUSE_LEAVE, + PREMIUM_HOUSE_ENTER, + PREMIUM_HOUSE_LEAVE, + BACKUP + + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/holidays/Holiday.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/holidays/Holiday.java new file mode 100644 index 0000000..3c63887 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/holidays/Holiday.java @@ -0,0 +1,6 @@ +package net.grandtheftmc.vice.holidays; + +public abstract class Holiday { + + public abstract boolean isActive(); +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/holidays/HolidayManager.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/holidays/HolidayManager.java new file mode 100644 index 0000000..c6a001f --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/holidays/HolidayManager.java @@ -0,0 +1,16 @@ +package net.grandtheftmc.vice.holidays; + +import net.grandtheftmc.vice.holidays.easter.Easter; + +public class HolidayManager { + private Easter easter; + + public HolidayManager() { + this.easter = new Easter(); + } + + public Easter getEaster() { + if (this.easter == null) this.easter = new Easter(); + return this.easter; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/holidays/easter/Easter.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/holidays/easter/Easter.java new file mode 100644 index 0000000..4533660 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/holidays/easter/Easter.java @@ -0,0 +1,81 @@ +package net.grandtheftmc.vice.holidays.easter; + +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.holidays.Holiday; +import org.bukkit.Chunk; +import org.bukkit.Material; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Item; +import org.bukkit.entity.Rabbit; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.time.Month; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Optional; + +public class Easter extends Holiday { + private EasterTask easterTask; + + public Easter() { + new EasterListener(this); + if (this.isActive()) { + if (this.easterTask == null) this.easterTask = new EasterTask(this); + } + } + + public boolean isActive() { + return ViceUtils.getMonth() == Month.APRIL && ViceUtils.getDay() == 15 + || ViceUtils.getDay() == 16 || ViceUtils.getDay() == 17; + } + + public Optional<EasterTask> getEasterTask() { + return Optional.ofNullable(this.easterTask); + } + + public ItemStack getEasterEgg() { + ItemStack easterEgg = new ItemStack(Material.EGG); + ItemMeta meta = easterEgg.getItemMeta(); + meta.setDisplayName(Utils.f(ViceUtils.randomColor() + "&lEaster Egg")); + easterEgg.setItemMeta(meta); + return easterEgg; + } + + public ItemStack getChocolateBunny() { + ItemStack chocolateBunny = new ItemStack(Material.COOKED_RABBIT); + ItemMeta meta = chocolateBunny.getItemMeta(); + meta.setDisplayName(Utils.f(ViceUtils.randomColor() + "&lChocolate")); + chocolateBunny.setItemMeta(meta); + return chocolateBunny; + } + + public Rabbit.Type[] getAllowedTypes() { + Rabbit.Type[] allowed = {Rabbit.Type.BLACK, Rabbit.Type.BLACK_AND_WHITE, + Rabbit.Type.GOLD, Rabbit.Type.WHITE}; + return allowed; + } + + public Collection<Rabbit> getRabbitsByChunk(Chunk chunk) { + Collection<Rabbit> rabbits = new ArrayList<>(); + if (chunk == null || !chunk.isLoaded()) return rabbits; + for (Entity entity : chunk.getEntities()) { + if (entity.getType() != EntityType.RABBIT) continue; + rabbits.add((Rabbit) entity); + } + return rabbits; + } + + public Collection<Item> getItemsByChunk(Chunk chunk) { + Collection<Item> items = new ArrayList<>(); + if (chunk == null || !chunk.isLoaded()) return items; + for (Entity entity : chunk.getEntities()) { + if (entity.getType() != EntityType.DROPPED_ITEM) continue; + items.add((Item) entity); + } + return items; + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/holidays/easter/EasterListener.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/holidays/easter/EasterListener.java new file mode 100644 index 0000000..ee63847 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/holidays/easter/EasterListener.java @@ -0,0 +1,78 @@ +package net.grandtheftmc.vice.holidays.easter; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import org.bukkit.Bukkit; +import org.bukkit.Effect; +import org.bukkit.Sound; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.entity.Rabbit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.entity.EntitySpawnEvent; +import org.bukkit.event.player.PlayerEggThrowEvent; +import org.bukkit.event.player.PlayerItemConsumeEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import java.util.concurrent.ThreadLocalRandom; + +public class EasterListener implements Listener { + private Easter easter; + + public EasterListener(Easter easter) { +// Bukkit.getPluginManager().registerEvents(this, Vice.getInstance()); + this.easter = easter; + } + + @EventHandler + public void playerEggThrow(PlayerEggThrowEvent event) { + Player player = event.getPlayer(); + if (event.isHatching()) { + if (easter.isActive()) event.setHatchingType(EntityType.RABBIT); + if (player.getWorld().getName().equalsIgnoreCase("spawn") || !easter.isActive()) event.setHatching(false); + if (easter.getRabbitsByChunk(player.getLocation().getChunk()).size() > 50) event.setHatching(false); + player.playSound(event.getEgg().getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 5.0F, 5.0F); + player.playSound(event.getEgg().getLocation(), Sound.ENTITY_FIREWORK_BLAST, 5.0F, 5.0F); + player.getWorld().spigot().playEffect(event.getEgg().getLocation(), Effect.FIREWORKS_SPARK); + player.getWorld().dropItemNaturally(event.getEgg().getLocation(), ViceUtils.getRandomGameItem().getItem()); + } + } + + @EventHandler + public void playerItemConsume(PlayerItemConsumeEvent event) { + Player player = event.getPlayer(); + ItemStack item = event.getItem(); + if (item.getType() == easter.getChocolateBunny().getType()) { + Vice.getDrugManager().getEffectManager().cancelEffects(player); + player.addPotionEffect(new PotionEffect(PotionEffectType.ABSORPTION, 600, 1)); + player.setFoodLevel(20); + player.setSaturation(20); + player.setExhaustion(0); + } + } + + @EventHandler + public void entityDeath(EntityDeathEvent event) { + if (!easter.isActive()) return; + if (event.getEntity().getType() != EntityType.RABBIT) return; + if (event.getEntity().getKiller() == null) return; + event.getDrops().clear(); + event.getDrops().add(Vice.getHolidayManager().getEaster().getChocolateBunny()); + } + + @EventHandler + public void entitySpawn(EntitySpawnEvent event) { + if (!easter.isActive()) return; + if (event.getEntityType() != EntityType.RABBIT) return; + Rabbit rabbit = (Rabbit) event.getEntity(); + rabbit.setAdult(); + rabbit.setCustomName(""); + rabbit.setCustomNameVisible(false); + Rabbit.Type targetType = easter.getAllowedTypes()[ThreadLocalRandom.current().nextInt(easter.getAllowedTypes().length)]; + rabbit.setRabbitType(targetType); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/holidays/easter/EasterTask.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/holidays/easter/EasterTask.java new file mode 100644 index 0000000..f321894 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/holidays/easter/EasterTask.java @@ -0,0 +1,45 @@ +package net.grandtheftmc.vice.holidays.easter; + +import net.grandtheftmc.vice.Vice; +import org.bukkit.Location; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Rabbit; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.concurrent.ThreadLocalRandom; + +public class EasterTask extends BukkitRunnable { + private Easter easter; + + public EasterTask(Easter easter) { + this.easter = easter; +// if (this.easter.getEasterTask().isPresent()) return; +// this.runTaskTimer(Vice.getInstance(), 0, 4800); + } + + @Override + public void run() { +// if(Vice.getWorldManager().getWarpManager().getRandomWarp()==null) +// return; +// Location location = Vice.getWorldManager().getWarpManager().getRandomWarp().getLocation(); +// if (easter.getRabbitsByChunk(location.getChunk()).size() > 10) return; +// Rabbit rabbit = (Rabbit) location.getWorld().spawnEntity(location, EntityType.RABBIT); +// Rabbit.Type type = easter.getAllowedTypes()[ThreadLocalRandom.current().nextInt(easter.getAllowedTypes().length)]; +// rabbit.setRabbitType(type); +// rabbit.setCustomName(""); +// rabbit.setCustomNameVisible(false); +// rabbit.setAdult(); +// rabbit.setBreed(true); +// rabbit.setRemoveWhenFarAway(true); +// location.getWorld().getLivingEntities() +// .stream() +// .filter(livingEntity -> livingEntity.getType() == EntityType.RABBIT) +// .forEach(livingEntity -> { +// livingEntity.setRemoveWhenFarAway(true); +// if (easter.getItemsByChunk(livingEntity.getLocation().getChunk()).size() > 50) return; +// if (ThreadLocalRandom.current().nextInt(3) == 1) { +// livingEntity.getWorld().dropItemNaturally(livingEntity.getLocation(), easter.getEasterEgg()); +// } +// }); + } +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/hologram/CoreHologram.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/hologram/CoreHologram.java new file mode 100644 index 0000000..c7ad54e --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/hologram/CoreHologram.java @@ -0,0 +1,164 @@ +package net.grandtheftmc.vice.hologram; + +import com.comphenix.protocol.wrappers.WrappedDataWatcher; +import com.google.common.collect.Lists; +import net.grandtheftmc.core.wrapper.packet.out.WrapperPlayServerEntityDestroy; +import net.grandtheftmc.core.wrapper.packet.out.WrapperPlayServerEntityMetadata; +import net.grandtheftmc.core.wrapper.packet.out.WrapperPlayServerNamedEntitySpawn; +import net.grandtheftmc.vice.hologram.exception.HologramDuplicateNodeException; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Player; + +import java.util.List; + +public final class CoreHologram implements Hologram { + + private final int id; + private final Location origin; + + protected final List<HologramNode> nodes; + + public CoreHologram(int id, Location origin) { + this.id = id; + this.origin = origin; + this.nodes = Lists.newArrayList(); + } + + @Override + public int getId() { + return id; + } + + @Override + public Location getOrigin() { + return origin; + } + + @Override + public List<HologramNode> getNodes() { + return nodes; + } + + @Override + public HologramNode getNode(int id) { + return this.nodes.stream().filter(n -> n.getId() == id).findFirst().orElse(null); + } + + @Override + public void spawn(Player player) { +// for (HologramNode node : this.nodes) { +// if (node.getEntity() == null || node.getEntity().isDead() || !node.getEntity().isValid()) { +// System.out.println("Entity is null"); +// continue; +// } +// +// WrapperPlayServerNamedEntitySpawn spawn = new WrapperPlayServerNamedEntitySpawn(); +// spawn.setEntityID(node.getEntity().getEntityId()); +// spawn.setX(node.getEntity().getLocation().getX()); +// spawn.setY(node.getEntity().getLocation().getY()); +// spawn.setZ(node.getEntity().getLocation().getZ()); +// +// WrappedDataWatcher dataWatcher = new WrappedDataWatcher(); +// dataWatcher.setEntity(node.getEntity()); +// +// WrappedDataWatcher.Serializer byteSerializer = WrappedDataWatcher.Registry.get(Byte.class); +// WrappedDataWatcher.Serializer booleanSerializer = WrappedDataWatcher.Registry.get(Boolean.class); +// WrappedDataWatcher.Serializer stringSerializer = WrappedDataWatcher.Registry.get(String.class); +// +// dataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, byteSerializer), (byte) 0x20); //Invisible +// dataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(2, stringSerializer), node.getText()); // Set custom name +// dataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(3, booleanSerializer), false); // Set custom name visible +// +// spawn.setMetadata(dataWatcher); +// +// spawn.sendPacket(player); +// } + + refresh(); + } + + @Override + public void refresh() { + this.nodes.forEach(node -> refresh(node.getId())); + } + + @Override + public void refresh(int nodeId) { + HologramNode node = this.getNode(nodeId); + if (node == null) return; + if (node.getEntity() == null) return; + + WrapperPlayServerEntityMetadata packet = new WrapperPlayServerEntityMetadata(); + packet.setEntityID(node.getEntity().getEntityId()); + + for (Player player : Bukkit.getOnlinePlayers()) { + if (player == null) continue; + if (packet == null) continue; + if (node == null) continue; + if (node.getEntity() == null) continue; + if (!player.getLocation().getWorld().getName().equals(origin.getWorld().getName())) + continue; + + packet.sendPacket(player); + } + } + + @Override + public void refresh(Player player) { + this.nodes.forEach(node -> refresh(node.getId(), player)); + } + + @Override + public void refresh(int nodeId, Player player) { + HologramNode node = this.getNode(nodeId); + if (node == null) return; + if (node.getEntity() == null) return; + if (!player.getLocation().getWorld().getName().equals(origin.getWorld().getName())) + return; + + WrapperPlayServerEntityMetadata packet = new WrapperPlayServerEntityMetadata(); + packet.setEntityID(node.getEntity().getEntityId()); + + packet.sendPacket(player); + } + + @Override + public void destroy() { + for (HologramNode node : this.nodes) { + WrapperPlayServerEntityDestroy destroy = new WrapperPlayServerEntityDestroy(); + destroy.setEntityId(node.getEntity().getEntityId()); + for (Player player : Bukkit.getOnlinePlayers()) { + destroy.sendPacket(player); + } + node.getEntity().remove(); + } + nodes.clear(); + } + + @Override + public HologramNode addNode(int id) throws HologramDuplicateNodeException { + if (nodes.stream().anyMatch(n -> n.getId() == id)) + throw new HologramDuplicateNodeException(this, id); + + HologramNode node = new CoreHologramNode(id, origin.clone().subtract(0, id * 0.25, 0)); + nodes.add(node); + return node; + } + + @Override + public HologramNode addNode(int id, String text) throws HologramDuplicateNodeException { + HologramNode node = this.addNode(id); + node.setText(text); + return node; + } + + @Override + public HologramNode addNode(HologramNode node) throws HologramDuplicateNodeException { + if (nodes.stream().anyMatch(n -> n.getId() == id)) + throw new HologramDuplicateNodeException(this, id); + + nodes.add(node); + return node; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/hologram/CoreHologramNode.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/hologram/CoreHologramNode.java new file mode 100644 index 0000000..ab2abf1 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/hologram/CoreHologramNode.java @@ -0,0 +1,74 @@ +package net.grandtheftmc.vice.hologram; + +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.vice.Vice; +import org.bukkit.Location; +import org.bukkit.entity.ArmorStand; +import org.bukkit.metadata.FixedMetadataValue; + +import java.util.UUID; + +public final class CoreHologramNode implements HologramNode { + + private final int id; + private final ArmorStand entity; + private final Location location; + + private String text = UUID.randomUUID().toString(); + + protected CoreHologramNode(int id, Location location) { + this.id = id; + this.location = location; + this.entity = this.craftEntity(); + } + + protected CoreHologramNode(int id, Location location, String text) { + this(id, location); + this.text = text; + } + + @Override + public int getId() { + return id; + } + + @Override + public ArmorStand getEntity() { + return entity; + } + + @Override + public Location getLocation() { + return location; + } + + @Override + public String getText() { + return text; + } + + @Override + public void setText(String text) { + this.text = Utils.f(text); + this.entity.setCustomName(this.text); + } + + private ArmorStand craftEntity() { + HologramManager.CHUNKS.add(this.location.getChunk()); + this.location.getChunk().load(); + ArmorStand a = this.location.getWorld().spawn(this.location, ArmorStand.class); + a.setGravity(false); + a.setVisible(false); + a.setCustomName(this.text); + a.setCustomNameVisible(true); + a.setRemoveWhenFarAway(false); + a.setInvulnerable(true); + a.setAI(false); + a.setMarker(true); + a.setSmall(true); + + a.setMetadata("CoreHologram", new FixedMetadataValue(Vice.getInstance(), this)); + + return a; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/hologram/Hologram.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/hologram/Hologram.java new file mode 100644 index 0000000..f47fa9c --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/hologram/Hologram.java @@ -0,0 +1,27 @@ +package net.grandtheftmc.vice.hologram; + +import net.grandtheftmc.vice.hologram.exception.HologramDuplicateNodeException; +import org.bukkit.Location; +import org.bukkit.entity.Player; + +import java.util.List; + +public interface Hologram { + + int getId(); + Location getOrigin(); + + List<HologramNode> getNodes(); + HologramNode getNode(int id); + + void spawn(Player player); + void refresh(); + void refresh(int nodeId); + void refresh(Player player); + void refresh(int nodeId, Player player); + void destroy(); + + HologramNode addNode(int id) throws HologramDuplicateNodeException; + HologramNode addNode(int id, String text) throws HologramDuplicateNodeException; + HologramNode addNode(HologramNode node) throws HologramDuplicateNodeException; +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/hologram/HologramManager.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/hologram/HologramManager.java new file mode 100644 index 0000000..2d505f2 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/hologram/HologramManager.java @@ -0,0 +1,269 @@ +package net.grandtheftmc.vice.hologram; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.events.ListenerPriority; +import com.comphenix.protocol.events.PacketAdapter; +import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.wrappers.WrappedDataWatcher; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import com.massivecraft.factions.P; +import net.grandtheftmc.core.util.Component; +import net.grandtheftmc.core.wrapper.packet.out.WrapperPlayServerEntityDestroy; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.hologram.event.HologramReceiveEvent; +import net.grandtheftmc.vice.hologram.exception.HologramDuplicateException; +import net.grandtheftmc.vice.hologram.exception.HologramDuplicateNodeException; +import net.minecraft.server.v1_12_R1.PacketPlayOutEntityMetadata; +import org.bukkit.Bukkit; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +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.EntitySpawnEvent; +import org.bukkit.event.player.PlayerArmorStandManipulateEvent; +import org.bukkit.event.world.ChunkUnloadEvent; +import org.bukkit.plugin.java.JavaPlugin; + +import java.util.HashSet; +import java.util.List; +import java.util.UUID; + +public class HologramManager implements Component<HologramManager, Vice> { + + protected static final HashSet<Chunk> CHUNKS = Sets.newHashSet(); + private final List<Hologram> holograms; + + public HologramManager(JavaPlugin plugin) { + this.holograms = Lists.newArrayList(); + + Bukkit.getPluginManager().registerEvents(this, plugin); + ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(Vice.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Server.ENTITY_METADATA) { + @Override + public void onPacketSending(PacketEvent event) { + int id = event.getPacket().getIntegers().read(0); + HologramData data = getById(id); + if (data == null) { + ArmorStand found = getEntityById(id); + if (found == null) return; + if (found.getCustomName() == null) return; + + String[] components = found.getCustomName().split("-"); + if (components.length == 5) { + + if (found.hasMetadata("CoreHologram")) { + CoreHologramNode node = (CoreHologramNode) found.getMetadata("CoreHologram").get(0).value(); + if (node == null) { + System.out.println("Node is null!"); + return; + } + + System.out.println("Found - " + node.getText()); + return; + } + + System.out.println("Doesn't consist of 'CoreHologram' --- " + found.getCustomName()); + + WrapperPlayServerEntityDestroy destroy = new WrapperPlayServerEntityDestroy(); + destroy.setEntityId(found.getEntityId()); + for (Player player : Bukkit.getOnlinePlayers()) { + destroy.sendPacket(player); + } + found.remove(); + } + return; + } + + HologramReceiveEvent receiveEvent = new HologramReceiveEvent(event.getPlayer(), data.getHologram(), data.getNode()); + Bukkit.getPluginManager().callEvent(receiveEvent); + if (receiveEvent.isCancelled()) { + event.setCancelled(true); + WrapperPlayServerEntityDestroy destroy = new WrapperPlayServerEntityDestroy(); + destroy.setEntityId(id); + destroy.sendPacket(event.getPlayer()); + } + + WrappedDataWatcher dataWatcher = new WrappedDataWatcher(); + dataWatcher.setEntity(data.getNode().getEntity()); + + WrappedDataWatcher.Serializer byteSerializer = WrappedDataWatcher.Registry.get(Byte.class); + WrappedDataWatcher.Serializer booleanSerializer = WrappedDataWatcher.Registry.get(Boolean.class); + WrappedDataWatcher.Serializer stringSerializer = WrappedDataWatcher.Registry.get(String.class); + + dataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, byteSerializer), (byte) 0x20); //Invisible + dataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(2, stringSerializer), receiveEvent.getText()); // Set custom name + dataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(3, booleanSerializer), receiveEvent.doDisplay()); // Set custom name visible + + event.getPacket().getWatchableCollectionModifier().write(0, dataWatcher.getWatchableObjects()); + } + }); + } + + @Override + public HologramManager onDisable(Vice plugin) { + this.holograms.forEach(Hologram::destroy); + return this; + } + + /** + * Create a Hologram. + * + * @return Hologram + */ + public Hologram create(int id, Location origin, HologramNode... nodes) throws HologramDuplicateException { + if (this.holograms.stream().anyMatch(h -> h.getId() == id)) + throw new HologramDuplicateException(id); + + for (Entity entity : origin.getWorld().getNearbyEntities(origin, 0.5, 15, 0.5)) { + if (entity instanceof ArmorStand && entity.getCustomName() != null) { + String[] components = entity.getCustomName().split("-"); + if (components.length == 5) { + + WrapperPlayServerEntityDestroy destroy = new WrapperPlayServerEntityDestroy(); + destroy.setEntityId(entity.getEntityId()); + for (Player player : Bukkit.getOnlinePlayers()) { + destroy.sendPacket(player); + } + + entity.remove(); + } + } + } + + Hologram hologram = new CoreHologram(id, origin); + for (HologramNode node : nodes) { + try { + hologram.addNode(node); + } catch (HologramDuplicateNodeException e) { + e.printStackTrace(); + } + } + + this.holograms.add(hologram); + System.out.println("HOLOGRAM CREATED, ID " + hologram.getId()); + + return hologram; + } + + public Hologram getHologram(int id) { + return this.holograms.stream().filter(h -> h.getId() == id).findFirst().orElse(null); + } + + public HologramData getByUniqueId(UUID uuid) { + for (Hologram hologram : this.holograms) { + for (HologramNode node : hologram.getNodes()) { + if (node.getEntity() == null) continue; + if (node.getEntity().getUniqueId().equals(uuid)) { + return new HologramData(hologram, node); + } + } + } + return null; + } + + public HologramData getById(int entityId) { + for (Hologram hologram : this.holograms) { + for (HologramNode node : hologram.getNodes()) { + if (node.getEntity() == null) continue; + if (node.getEntity().getEntityId() == entityId) { + return new HologramData(hologram, node); + } + } + } + return null; + } + + public boolean isHologramEntity(ArmorStand entity) { + for (Hologram hologram : this.holograms) { + for (HologramNode node : hologram.getNodes()) { + if (node.getEntity() == null) continue; + if (node.getEntity().getUniqueId().equals(entity.getUniqueId())) { + return true; + } + } + } + return false; + } + + @EventHandler (ignoreCancelled = true) + protected final void onArmorstandManipulate(PlayerArmorStandManipulateEvent event) { + if (event.getRightClicked() == null) return; + if (this.isHologramEntity(event.getRightClicked())) { + event.setCancelled(true); + } + } + + @EventHandler (priority = EventPriority.HIGHEST) + protected final void onEntityDamage(EntityDamageEvent event) { + if (event.getEntity().getType() != EntityType.ARMOR_STAND) return; + + if (event.getCause() != EntityDamageEvent.DamageCause.CUSTOM && this.isHologramEntity(((ArmorStand) event.getEntity()))) { + event.setCancelled(true); + } + } + + @EventHandler (priority = EventPriority.HIGHEST) + protected final void onEntitySpawn(EntitySpawnEvent event) { + if (!event.isCancelled()) return; + if (event.getEntity().getType() != EntityType.ARMOR_STAND) return; + + if (this.isHologramEntity(((ArmorStand) event.getEntity()))) { + event.setCancelled(false); + } + } + + @EventHandler + protected final void onChunkUnload(ChunkUnloadEvent event) { + for (Chunk chunk : CHUNKS) { + if (event.getChunk().equals(chunk)) { + event.setCancelled(true); + break; + } + } + +// for (Hologram hologram : this.holograms) { +// for (HologramNode node : hologram.getNodes()) { +// if (node.getEntity() == null) continue; +// if (node.getEntity().getLocation().getChunk().equals(event.getChunk())) { +// event.setCancelled(false); +// break; +// } +// } +// } + } + + private class HologramData { + private final Hologram hologram; + private final HologramNode node; + + HologramData(Hologram hologram, HologramNode node) { + this.hologram = hologram; + this.node = node; + } + + Hologram getHologram() { + return hologram; + } + + HologramNode getNode() { + return node; + } + } + + public ArmorStand getEntityById(int id) { + for (World world : Bukkit.getWorlds()) { + for (ArmorStand armorStand : world.getEntitiesByClass(ArmorStand.class)) { + if (armorStand.getEntityId() == id) return armorStand; + } + } + + return null; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/hologram/HologramNode.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/hologram/HologramNode.java new file mode 100644 index 0000000..72aba7e --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/hologram/HologramNode.java @@ -0,0 +1,18 @@ +package net.grandtheftmc.vice.hologram; + +import net.grandtheftmc.core.Utils; +import org.bukkit.Location; +import org.bukkit.entity.ArmorStand; + +import java.util.UUID; + +public interface HologramNode { + + int getId(); + + ArmorStand getEntity(); + Location getLocation(); + String getText(); + + void setText(String text); +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/hologram/TypeWriter.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/hologram/TypeWriter.java new file mode 100644 index 0000000..86e3d94 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/hologram/TypeWriter.java @@ -0,0 +1,64 @@ +package net.grandtheftmc.vice.hologram; + +import java.util.ArrayList; +import java.util.Arrays; + +public class TypeWriter { + + private static final char[] COLORS = {'l', 'm', 'n', 'k', 'o', 'r', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + + private final String text; + private int progress = 0, waitTicks = 0; + + public TypeWriter(String text, int waitTicks) { + this.text = text; + this.waitTicks = waitTicks; + } + + public String next() { + if (this.progress >= this.text.length() - 1) { + if (this.progress >= (this.text.length() - 1) + this.waitTicks) { + this.progress = 0; + } else { + this.progress++; + return this.text; + } + } + + if (this.isColor(this.progress)) { + this.progress += 2; + return next(); + } + + return this.text.substring(0, this.progress++ + 1); + } + + private boolean isColor(int prog) { + char[] chars = this.text.toCharArray(); + if (chars[prog] == '&') { + char next = chars[prog + 1]; + for (char color : COLORS) { + if (next == color) { + return true; + } + } + } + + return false; + } + + public static void main(String[] args) { +// TypeWriter writer = new TypeWriter("&d&lVice&f&lMC Season &d&l2", 5); +// for (int i = 0; i < 50; i++) +// System.out.println(writer.next()); + + ArrayList<String> arrayList = new ArrayList<>(); + for (int i = 0; i < 63; i++) + arrayList.add("" + i); + + arrayList.subList(3, 27).clear(); + System.out.println(Arrays.toString(arrayList.toArray(new String[arrayList.size()]))); + + //CACTUS,COAL,AIR,RECORD_7,RECORD_7,AIR,AIR,CHEST,COAL,AIR,CHEST,CHEST,AIR,AIR,AIR,AIR,AIR,AIR,AIR,AIR,AIR,AIR,AIR,AIR,AIR,AIR,AIR,AIR,AIR,AIR,COAL,CHEST,AIR,AIR,AIR,AIR,AIR,AIR,WATCH + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/hologram/event/HologramReceiveEvent.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/hologram/event/HologramReceiveEvent.java new file mode 100644 index 0000000..61f208f --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/hologram/event/HologramReceiveEvent.java @@ -0,0 +1,64 @@ +package net.grandtheftmc.vice.hologram.event; + +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.events.CoreEvent; +import net.grandtheftmc.vice.hologram.Hologram; +import net.grandtheftmc.vice.hologram.HologramNode; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; + +public class HologramReceiveEvent extends CoreEvent implements Cancellable { + + private final Player player; + private final Hologram hologram; + private final HologramNode node; + + private String text; + private boolean c, display = true; + + public HologramReceiveEvent(Player player, Hologram hologram, HologramNode node) { + super(false); + this.player = player; + this.hologram = hologram; + this.node = node; + this.text = node.getText(); + } + + public Player getPlayer() { + return player; + } + + public Hologram getHologram() { + return hologram; + } + + public HologramNode getNode() { + return node; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = Utils.f(text); + } + + public boolean doDisplay() { + return display; + } + + public void setDisplay(boolean display) { + this.display = display; + } + + @Override + public boolean isCancelled() { + return this.c; + } + + @Override + public void setCancelled(boolean b) { + this.c = b; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/hologram/exception/HologramDuplicateException.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/hologram/exception/HologramDuplicateException.java new file mode 100644 index 0000000..bd631b4 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/hologram/exception/HologramDuplicateException.java @@ -0,0 +1,13 @@ +package net.grandtheftmc.vice.hologram.exception; + +public class HologramDuplicateException extends Exception { + + /** + * Constructs a new exception with the specified detail message. The + * cause is not initialized, and may subsequently be initialized by + * a call to {@link #initCause}. + */ + public HologramDuplicateException(int id) { + super("A Hologram with id " + id + " already exists!"); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/hologram/exception/HologramDuplicateNodeException.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/hologram/exception/HologramDuplicateNodeException.java new file mode 100644 index 0000000..dbe373d --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/hologram/exception/HologramDuplicateNodeException.java @@ -0,0 +1,15 @@ +package net.grandtheftmc.vice.hologram.exception; + +import net.grandtheftmc.vice.hologram.Hologram; + +public class HologramDuplicateNodeException extends Exception { + + /** + * Constructs a new exception with the specified detail message. The + * cause is not initialized, and may subsequently be initialized by + * a call to {@link #initCause}. + */ + public HologramDuplicateNodeException(Hologram hologram, int id) { + super("Hologram[" + hologram.getId() + "] already has a Node with id " + id); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/AmmoType.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/AmmoType.java new file mode 100644 index 0000000..001e79c --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/AmmoType.java @@ -0,0 +1,74 @@ +package net.grandtheftmc.vice.items; + +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +import net.grandtheftmc.vice.Vice; + +import java.util.Arrays; + +public enum AmmoType { + + PISTOL("pistolAmmo"), SMG("smgAmmo"), SHOTGUN("shotgunShell"), ASSAULT_RIFLE("assaultRifleAmmo"), MG( + "mgAmmo"), SNIPER("sniperRifleAmmo"), ROCKET("rocket"), MINIGUN("minigunAmmo"), GRENADE("grenade", true); + + private final String gameItem; + private final boolean inInventory; + + AmmoType(String gameItem) { + this.gameItem = gameItem; + this.inInventory = false; + } + + AmmoType(String gameItem, boolean inInventory) { + this.gameItem = gameItem; + this.inInventory = inInventory; + } + + public String getGameItemName() { + return this.gameItem; + } + + public GameItem getGameItem() { + return Vice.getItemManager().getItem(this.gameItem); + } + + public static AmmoType[] getTypes() { + return values(); + } + + public static AmmoType getAmmoType(Material material, short dataValue) { + for (AmmoType type : AmmoType.getTypes()) { + ItemStack item = type.getGameItem().getItem(); + if (material == item.getType() && dataValue == item.getDurability()) + return type; + } + return null; + } + + public static AmmoType getAmmoType(ItemStack itemStack) { + for (AmmoType type : AmmoType.getTypes()) { + ItemStack item = type.getGameItem().getItem(); + if (itemStack.getType() == item.getType() && itemStack.getDurability() == item.getDurability() && (itemStack.hasItemMeta() && itemStack.getItemMeta().hasDisplayName() && itemStack.getItemMeta().getDisplayName().contains("Ammo"))) + return type; + } + return null; + } + + public static AmmoType getAmmoType(String ammoType) { + return Arrays.stream(AmmoType.getTypes()).filter(type -> type.toString().equalsIgnoreCase(ammoType)).findFirst().orElse(null); + } + + public static AmmoType getAmmoTypeFriendly(String ammoType) { + return Arrays.stream(AmmoType.getTypes()).filter(type -> type.toString().equalsIgnoreCase(ammoType) || type.gameItem.equalsIgnoreCase(ammoType)).findFirst().orElse(null); + } + + public static boolean isAmmo(ItemStack item) { + return getAmmoType(item.getType(), item.getDurability()) != null; + } + + public boolean isInInventory() { + return this.inInventory; + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/ArmorType.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/ArmorType.java new file mode 100644 index 0000000..7033c3c --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/ArmorType.java @@ -0,0 +1,77 @@ +package net.grandtheftmc.vice.items; + +import net.grandtheftmc.core.util.Slot; +import org.bukkit.inventory.ItemStack; + +import java.util.Arrays; + +/** + * Created by Timothy Lampen on 7/6/2017. + */ +public enum ArmorType { + HELMET(Slot.HEAD, 5, "titaniumhelmet", "tacticalmask", "pimpcrown", "nightvisiongoggles", "baseballcap"), + CHESTPLATE(Slot.CHEST, 6, "titaniumvest", "ceramicvest", "kevlarvest", "shirt"), + LEGGINGS(Slot.LEGS, 7, "pants"), + BOOTS(Slot.FEET, 8, "nikes", "samurisairjordans"), + JETPACK(Slot.CHEST, 6, "jetpack"), + WINGSUIT(Slot.CHEST, 6, "wingsuit"); + + private final Slot slot; + private final String[] gameItems; + private final int rawSlot; + + ArmorType(Slot slot, int rawSlot, String... gameItems) { + this.slot = slot; + this.rawSlot =rawSlot; + this.gameItems = gameItems; + } + + public String getName() { + String[] a = this.toString().split("_"); + String s = ""; + for (int i = 0; i < a.length; ++i) { + s = s + a[i].charAt(0) + a[i].substring(1).toLowerCase() + (i == a.length - 1 ? "" : " "); + } + return s; + } + + + public Slot getSlot() { + return this.slot; + } + + public String[] getGameItems() { + return this.gameItems; + } + + public boolean hasGameItem(String gameItem) { + return Arrays.stream(this.gameItems).anyMatch(s -> s.equalsIgnoreCase(gameItem)); + } + + public static ArmorType getArmorType(String gameItem) { + return Arrays.stream(ArmorType.values()).filter(type -> type.hasGameItem(gameItem)).findFirst().orElse(null); + } + + public int getRawSlot() { + return rawSlot; + } + + public static ArmorType matchType(ItemStack is){ + if(is==null) + return null; + String type = is.getType().toString().toLowerCase(); + if(type.contains("chestplate")){ + return ArmorType.CHESTPLATE; + } + else if(type.contains("leggings")){ + return ArmorType.LEGGINGS; + } + else if(type.contains("boots")){ + return ArmorType.BOOTS; + } + else if(type.contains("helmet")){ + return ArmorType.HELMET; + } + return null; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/ArmorUpgrade.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/ArmorUpgrade.java new file mode 100644 index 0000000..e650e28 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/ArmorUpgrade.java @@ -0,0 +1,325 @@ +package net.grandtheftmc.vice.items; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.Attribute; +import net.grandtheftmc.core.util.AttributeModifier; +import net.grandtheftmc.core.util.ItemAttributes; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.ViceRank; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.*; + + +/** + * Created by Liam on 25/10/2016. + */ +public enum ArmorUpgrade { + + LIGHT(35000, ViceRank.THUG, UserRank.VIP, ArmorType.CHESTPLATE), + DURABLE(30000, ViceRank.DEALER, UserRank.VIP, ArmorType.HELMET, ArmorType.CHESTPLATE, ArmorType.LEGGINGS, ArmorType.BOOTS), + ULTRA_LIGHT(100000, ViceRank.DEALER, UserRank.PREMIUM, ArmorType.CHESTPLATE), + TANK(40000, ViceRank.DEALER, UserRank.PREMIUM, ArmorType.HELMET, ArmorType.CHESTPLATE, ArmorType.LEGGINGS, ArmorType.BOOTS), + REINFORCED(25000, ViceRank.DEALER, UserRank.ELITE, ArmorType.HELMET, ArmorType.CHESTPLATE, ArmorType.JETPACK, ArmorType.WINGSUIT),//do not change types of armor from other than chestplte slot. If you do you have to check the glitch checker in armorequip (that checks if the max health != 20 or 30 + BOMB_SQUAD(50000, ViceRank.DEALER, UserRank.ELITE, ArmorType.HELMET, ArmorType.CHESTPLATE), + EXOSKELETON(175000, ViceRank.DEALER, UserRank.SPONSOR, ArmorType.CHESTPLATE), + ENHANCED(125000, ViceRank.GODFATHER, UserRank.SUPREME, ArmorType.CHESTPLATE), + NEON(50000, null, UserRank.VIP, ArmorType.HELMET, ArmorType.CHESTPLATE, ArmorType.LEGGINGS, ArmorType.BOOTS, ArmorType.JETPACK, ArmorType.WINGSUIT), + LEAD_LINED(1000000, null, null, ArmorType.HELMET, ArmorType.CHESTPLATE, ArmorType.LEGGINGS, ArmorType.BOOTS, ArmorType.JETPACK, ArmorType.WINGSUIT); + + + private final double price; + private final ViceRank rank; + private final UserRank userRank; + private final ArmorType[] types; + + ArmorUpgrade(double price, ViceRank rank, UserRank userRank, ArmorType... types) { + this.price = price; + this.rank = rank; + this.userRank = userRank; + this.types = types; + } + + public static void reloadArmorUpgrades(Player player){ + player.getAttribute(org.bukkit.attribute.Attribute.GENERIC_MAX_HEALTH).setBaseValue(player.getAttribute(org.bukkit.attribute.Attribute.GENERIC_MAX_HEALTH).getDefaultValue()); + for (PotionEffect e : player.getActivePotionEffects()) { + if(e.getType()==PotionEffectType.NIGHT_VISION) + continue; + player.removePotionEffect(e.getType()); + } + new BukkitRunnable() { + @Override + public void run() { + for(ItemStack is : player.getInventory().getArmorContents()){ + for(ArmorUpgrade upgrade : ArmorUpgrade.getArmorUpgrades(is)){ + if(upgrade==ArmorUpgrade.ENHANCED){ + player.getAttribute(org.bukkit.attribute.Attribute.GENERIC_MAX_HEALTH).setBaseValue(player.getAttribute(org.bukkit.attribute.Attribute.GENERIC_MAX_HEALTH).getBaseValue()+10); + } + HashSet<PotionEffect> effects = upgrade.getPotionEffects(); + for (PotionEffect effect : effects) { + if(player.hasPotionEffect(effect.getType())){ + int base = player.getPotionEffect(effect.getType()).getAmplifier()==0 ? 1 : player.getPotionEffect(effect.getType()).getAmplifier(); + int effectAmp = effect.getAmplifier()==0 ? 1 : effect.getAmplifier(); + player.removePotionEffect(effect.getType()); + player.addPotionEffect(new PotionEffect(effect.getType(), Integer.MAX_VALUE, base+effectAmp)); + } + else{ + player.addPotionEffect(effect); + } + } + } + } + } + }.runTaskLater(Vice.getInstance(), 1); + } + + public double getPrice() { + return this.price; + } + + /* public double getPrice(GameItem item) { + Core.log(item.getSellPrice() + " / " + this.price); + return this.price * item.getSellPrice(); + }*/ + + public ViceRank getViceRank() { + return this.rank; + } + + public UserRank getUserRank() { + return this.userRank; + } + + public boolean canUseUpgrade(ViceRank rank, UserRank userRank) { + return this.rank == rank || rank.isHigherThan(this.rank) || this.userRank == userRank || userRank.isHigherThan(this.userRank) || (userRank==null && rank==null); + } + + public String getDisplayName() { + String[] a = this.toString().split("_"); + String s = ""; + for (int i = 0; i < a.length; ++i) { + s = s + a[i].charAt(0) + a[i].substring(1).toLowerCase() + (i == a.length - 1 ? "" : " "); + } + return s; + } + + public ArmorType[] getTypes() { + return this.types; + } + + public String getTypesString() { + String s = ""; + int length = this.types.length; + for (int i = 0; i < length; i++) { + ArmorType type = this.types[i]; + s += type.getName() + (i == length - 1 ? "" : i == length - 2 ? " or " : ", "); + } + return s; + } + + public static boolean isArmorUpgrade(String s) { + try { + ArmorUpgrade.valueOf(s); + } catch (IllegalArgumentException | NullPointerException e) { + return false; + } + return true; + } + + public static boolean playerHasArmorUpgrade(Player victim, ArmorUpgrade upgrade){ + ItemStack[] armor = victim.getInventory().getArmorContents(); + for (ItemStack itemStack : armor) { + if(itemStack==null) + continue; + HashSet<ArmorUpgrade> upgrades = ArmorUpgrade.getArmorUpgrades(itemStack); + if (upgrades.stream().anyMatch(up -> up == upgrade)) { + return true; + } + } + return false; + } + + //Does not return null when no upgrades, returns an empty set. + public static HashSet<ArmorUpgrade> getArmorUpgrades(ItemStack is) { + HashSet<ArmorUpgrade> returnSet = new HashSet<>(); + if (is==null || is.getItemMeta() == null || is.getItemMeta().getLore() == null) + return returnSet; + List<String> lore = is.getItemMeta().getLore(); + lore.stream().forEach(line -> { + line = ChatColor.stripColor(line); + if (line.equalsIgnoreCase("") || !ArmorUpgrade.isArmorUpgrade(line.toUpperCase().replace(" ", "_"))) + return; + returnSet.add(ArmorUpgrade.valueOf(line.toUpperCase().replace(" ", "_"))); + }); + + return returnSet; + } + + public boolean canBeUsedOn(ArmorType type) { + return Arrays.stream(this.types).anyMatch(t -> t == type); + } + + public boolean canBeUsedOn(String gameItem) { + return Arrays.stream(this.types).anyMatch(t -> t.hasGameItem(gameItem)); + } + + public HashSet<PotionEffect> getPotionEffects() { + HashSet<PotionEffect> effects = new HashSet<>(); + switch (this) { + case ULTRA_LIGHT: + effects.add(new PotionEffect(PotionEffectType.FAST_DIGGING, Integer.MAX_VALUE, 0)); + break; + case EXOSKELETON: + effects.add(new PotionEffect(PotionEffectType.REGENERATION, Integer.MAX_VALUE, 0)); + effects.add(new PotionEffect(PotionEffectType.INCREASE_DAMAGE, Integer.MAX_VALUE, 0)); + break; + case NEON: + effects.add(new PotionEffect(PotionEffectType.GLOWING, Integer.MAX_VALUE, 0, true, false)); + } + + return effects; + } + + public ItemStack getUpgradedItem(GameItem gameItem, ItemStack item) { + if (gameItem == null) return item; + ArmorType type = ArmorType.getArmorType(gameItem.getName()); + if (type == null) return item; + ItemAttributes att = new ItemAttributes(); + ItemMeta meta = item.getItemMeta(); + List<String> lore = new ArrayList<>(meta.hasLore() ? meta.getLore() : Collections.singletonList("")); + if (ArmorUpgrade.getArmorUpgrades(item).size() == 0) { + lore.add(Utils.f("&7Upgrades:")); + lore.add(" "); + } + lore.add(Utils.f("&b&l" + this.getDisplayName())); + meta.setLore(lore); + meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES); + meta.addItemFlags(ItemFlag.HIDE_ENCHANTS); + switch (this) { + case NEON: + case ENHANCED: + case LEAD_LINED: + case EXOSKELETON: + att.getFromStack(item); + item = att.apply(item); + break; + case LIGHT: + att.getFromStack(item); + att.addModifier(new AttributeModifier(Attribute.MOVEMENT_SPEED, "LightSpeed", type.getSlot(), 0, 0.02, UUID.randomUUID())); + item = att.apply(item); + meta.addEnchant(Enchantment.DEPTH_STRIDER, 1, true); + break; + case ULTRA_LIGHT: + att.getFromStack(item); + att.addModifier(new AttributeModifier(Attribute.MOVEMENT_SPEED, "UltraLightSpeed", type.getSlot(), 0, 0.04, UUID.randomUUID())); + item = att.apply(item); + meta.addEnchant(Enchantment.DEPTH_STRIDER, meta.getEnchantLevel(Enchantment.DEPTH_STRIDER) + 2, true); + meta.addEnchant(Enchantment.DIG_SPEED, meta.getEnchantLevel(Enchantment.DIG_SPEED) + 1, true); + break; + case TANK: { + att.getFromStack(item); + att.addModifier(new AttributeModifier(Attribute.MOVEMENT_SPEED, "TankSpeed", type.getSlot(), 0, -0.04, UUID.randomUUID())); + att.addModifier(new AttributeModifier(Attribute.KNOCKBACK_RESISTANCE, "TankKnockback", type.getSlot(), 0, .5d, UUID.randomUUID())); + item = att.apply(item); + meta.addEnchant(Enchantment.PROTECTION_ENVIRONMENTAL, 9, true); + break; + } + case REINFORCED: { + att.getFromStack(item); + item = att.apply(item); + meta.addEnchant(Enchantment.PROTECTION_ENVIRONMENTAL, 4, true); + break; + } + case DURABLE: + att.getFromStack(item); + item = att.apply(item); +// NOT NEEDED AS NEW DURABILITY UPDATE AUTO APPLIES UNBREAKABLE +// meta.addItemFlags(ItemFlag.HIDE_UNBREAKABLE); +// meta.spigot().setUnbreakable(true); + break; + case BOMB_SQUAD: + att.getFromStack(item); + att.addModifier(new AttributeModifier(Attribute.MOVEMENT_SPEED, "BombSquadSpeed", type.getSlot(), 0, -0.02, UUID.randomUUID())); + att.addModifier(new AttributeModifier(Attribute.KNOCKBACK_RESISTANCE, "BombSquadKnockback", type.getSlot(), 0, 0.5, UUID.randomUUID())); + item = att.apply(item); + meta.addEnchant(Enchantment.PROTECTION_EXPLOSIONS, 5, true); + meta.addEnchant(Enchantment.PROTECTION_FIRE, 5, true); + break; + } + item.setItemMeta(meta); + att.removeModifier(new AttributeModifier(Attribute.ARMOR)); + att.removeModifier(new AttributeModifier(Attribute.ARMOR_THOUGHNESS)); + att.addModifier(new AttributeModifier(Attribute.ARMOR, "darmor", type.getSlot(), 0, getDefaultArmorAttribute(item.getType()), UUID.randomUUID())); + att.addModifier(new AttributeModifier(Attribute.ARMOR_THOUGHNESS, "darmorthoughness", type.getSlot(), 0, getDefaultArmorToughness(item.getType()), UUID.randomUUID())); + item = att.apply(item); + //Utils.b(this.enchantment == null ? "null" : this.enchantment.getName()); + // item.addUnsafeEnchantment(this.enchantment, 1); + // for (Enchantment e : item.getEnchantments().keySet()) + // Utils.b(e.getName()); + return item; + } + + public static ArmorUpgrade getArmorUpgrade(String s) { + return Arrays.stream(ArmorUpgrade.values()).filter(u -> u.toString().equalsIgnoreCase(s)).findFirst().orElse(null); + } + + public static ArmorUpgrade getArmorUpgradeFromDisplayName(String s) { + return Arrays.stream(ArmorUpgrade.values()).filter(u -> u.toString().replace("_", " ").equalsIgnoreCase(s)).findFirst().orElse(null); + } + + private static int getDefaultArmorAttribute(Material material){ + switch (material){ + case IRON_BOOTS: + case LEATHER_LEGGINGS: + case CHAINMAIL_HELMET: + case GOLD_HELMET: + return 2; + case GOLD_CHESTPLATE: + case CHAINMAIL_CHESTPLATE: + case IRON_LEGGINGS: + return 5; + case GOLD_LEGGINGS: + case DIAMOND_HELMET: + case DIAMOND_BOOTS: + case LEATHER_CHESTPLATE: + return 3; + case CHAINMAIL_LEGGINGS: + return 4; + case LEATHER_BOOTS: + case LEATHER_HELMET: + case CHAINMAIL_BOOTS: + case IRON_HELMET: + case GOLD_BOOTS: + return 1; + case IRON_CHESTPLATE: + case DIAMOND_LEGGINGS: + return 6; + case DIAMOND_CHESTPLATE: + return 8; + } + return 0; + } + + private static int getDefaultArmorToughness(Material material){ + switch (material){ + case DIAMOND_CHESTPLATE: + case DIAMOND_LEGGINGS: + case DIAMOND_HELMET: + case DIAMOND_BOOTS: + return 2; + } + return 0; + } + +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/BackpackManager.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/BackpackManager.java new file mode 100644 index 0000000..c41a816 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/BackpackManager.java @@ -0,0 +1,121 @@ +package net.grandtheftmc.vice.items; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.users.CopRank; +import net.grandtheftmc.vice.users.ViceRank; +import net.grandtheftmc.vice.users.ViceUser; +import net.grandtheftmc.vice.users.storage.BooleanStorageType; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +public class BackpackManager implements Listener { + + private final Map<Integer, Inventory> corpses = new HashMap<>(); + + public void openBackpack(Player player) { + this.openBackpack(player, Vice.getUserManager().getLoadedUser(player.getUniqueId()), Core.getUserManager().getLoadedUser(player.getUniqueId())); + } + + public Inventory getBackpack(Player player, boolean monitor) { + ViceUser viceUser = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + User coreUser = Core.getUserManager().getLoadedUser(player.getUniqueId()); + int size = 9 * ViceUtils.getBackpackRows(coreUser.getUserRank()); + Inventory inv = Bukkit.createInventory(null, size, monitor ? Utils.f(player.getName()) : Utils.f("&6&lBackpack")); + ItemStack[] backpackContents = viceUser.getBackpackContents(); + if (backpackContents != null) + for (int i = 0; i < backpackContents.length && i < size; i++) + inv.setItem(i, backpackContents[i]); + return inv; + } + + public void openBackpack(Player player, ViceUser user, User u) { + if (user.isArrested()) { + player.sendMessage(Lang.JAIL.f("&7You can't open your backpack in jail!")); + return; + } + if (user.isInCombat()) { + player.sendMessage(Lang.COMBATTAG.f("&7You can't open your backpack in combat!")); + return; + } + if (user.getBooleanFromStorage(BooleanStorageType.BACKPACK_OPEN)) { + player.sendMessage(Lang.VICE.f("&7Your backpack may not be opened at this time!")); + return; + } + if (player.getOpenInventory() != null + && Objects.equals("Backpack", ChatColor.stripColor(player.getOpenInventory().getTitle()))) + return; + Inventory inv = this.getBackpack(player, false); + player.openInventory(inv); + user.setBooleanToStorage(BooleanStorageType.BACKPACK_OPEN, true); + } + + @EventHandler + public void onClose(InventoryCloseEvent e) { + Inventory inv = e.getInventory(); + if (!Objects.equals("Backpack", ChatColor.stripColor(inv.getTitle())) && Bukkit.getPlayer(inv.getTitle()) != null) { + Player target = Bukkit.getPlayer(inv.getTitle()); + if (target.getOpenInventory() != null && Objects.equals("Backpack", ChatColor.stripColor(target.getOpenInventory().getTitle()))) + target.getOpenInventory().close(); + ViceUser user = Vice.getUserManager().getLoadedUser(target.getUniqueId()); + user.setBackpackContents(inv.getContents()); + user.setBooleanToStorage(BooleanStorageType.BACKPACK_OPEN, false); + return; + } + if (!"backpack".equalsIgnoreCase(ChatColor.stripColor(inv.getTitle()))) + return; + Player player = (Player) e.getPlayer(); + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + user.setBackpackContents(inv.getContents()); + user.setBooleanToStorage(BooleanStorageType.BACKPACK_OPEN, false); + } + + private final int[] glassSlots = new int[]{0, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}; + private final ItemStack glass = Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a"); + + public void kitPreview(Player player, Kit kit) { + String name = kit.getName(); + UserRank ur = UserRank.getUserRankOrNull(kit.getName()); + ViceRank rank = ViceRank.getRankOrNull(kit.getName()); + CopRank copRank = CopRank.getRankOrNull(kit.getName()); + if (copRank != null) + name = copRank.getColoredNameBold(); + else if (ur != null) + name = ur.getColoredNameBold(); + else if (rank != null) + name = rank.getColoredNameBold(); + Inventory inv = Bukkit.createInventory(null, 54, Utils.f("&b&lKit Preview: " + name)); + + for (int i : this.glassSlots) + inv.setItem(i, this.glass); + inv.setItem(1, kit.getHelmet() == null ? this.glass : kit.getHelmet().getItem().getItem()); + inv.setItem(2, kit.getChestPlate() == null ? this.glass : kit.getChestPlate().getItem().getItem()); + inv.setItem(3, kit.getLeggings() == null ? this.glass : kit.getLeggings().getItem().getItem()); + inv.setItem(4, kit.getBoots() == null ? this.glass : kit.getBoots().getItem().getItem()); + inv.setItem(6, kit.getOffHand() == null ? this.glass : kit.getOffHand().getItem().getItem()); + for (int i = 0; i < kit.getItems().size(); i++) { + if (i < 9) + inv.setItem(45 + i, kit.getItems().get(i)); + else + inv.setItem(9 + i, kit.getItems().get(i)); + } + player.openInventory(inv); + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/GameItem.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/GameItem.java new file mode 100644 index 0000000..c231ac3 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/GameItem.java @@ -0,0 +1,328 @@ +package net.grandtheftmc.vice.items; + +import com.j0ach1mmall3.jlib.methods.Parsing; +import com.j0ach1mmall3.wastedvehicles.api.VehicleProperties; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.guns.weapon.Weapon; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drugs.Drug; +import net.grandtheftmc.vice.drugs.DrugService; +import net.grandtheftmc.vice.drugs.items.DrugItem; +import net.grandtheftmc.vice.utils.ItemStackUtil; +import org.bukkit.Material; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.*; + +public class GameItem { + + private final ItemType type; + private final String name; + private ItemStack item; + private String weaponOrVecicleOrDrug; + private String displayName; + private String shopCategory; + private double sellPrice; + private AmmoType ammoType; + private ArmorUpgrade armorUpgrade; + private boolean hideDurability; + private boolean canStack; + private int machineID; + + public GameItem(String name, ItemStack item, String displayName) { + this.type = ItemType.ITEMSTACK; + this.name = name; + this.item = item; + this.displayName = displayName; + this.hideDurability = false; + } + + public GameItem(String name, ItemStack item, String displayName, double sellPrice) { + this.type = ItemType.ITEMSTACK; + this.name = name; + this.item = item; + this.displayName = displayName; + this.sellPrice = sellPrice; + this.hideDurability = false; + } + + public GameItem(String name, ItemStack item, String displayName, double sellPrice, boolean hideDurability, boolean canStack, String category) { + this.type = ItemType.ITEMSTACK; + this.name = name; + this.shopCategory = category; + this.item = item; + this.displayName = displayName; + this.sellPrice = sellPrice; + this.hideDurability = hideDurability; + this.canStack = canStack; + } + + public GameItem(String name, ItemStack item, String displayName, double sellPrice, boolean hideDurability, boolean canStack) { + this.type = ItemType.ITEMSTACK; + this.name = name; + this.item = item; + this.displayName = displayName; + this.sellPrice = sellPrice; + this.hideDurability = hideDurability; + this.canStack = canStack; + } + + public GameItem(String name, ItemStack item, AmmoType type, String displayName, boolean hideDurability, boolean canStack) { + this.type = ItemType.AMMO; + this.name = name; + this.item = item; + this.ammoType = type; + this.displayName = displayName; + this.hideDurability = hideDurability; + this.canStack = canStack; + } + + public GameItem(String name, ItemStack item, AmmoType type, String displayName, double sellPrice, boolean hideDurability) { + this.type = ItemType.AMMO; + this.name = name; + this.item = item; + this.ammoType = type; + this.displayName = displayName; + this.sellPrice = sellPrice; + this.hideDurability = hideDurability; + } + + public GameItem(ItemType type, String name, String weaponOrVecicleOrDrug, String displayName) { + this.type = type; + this.name = name; + this.displayName = displayName; + this.weaponOrVecicleOrDrug = weaponOrVecicleOrDrug; + this.hideDurability = false; + this.getItem(); + } + + public GameItem(ItemType type, String name, String weaponOrVecicleOrDrug, String displayName, boolean hideDurability) { + this.type = type; + this.name = name; + this.displayName = displayName; + this.weaponOrVecicleOrDrug = weaponOrVecicleOrDrug; + this.hideDurability = hideDurability; + this.getItem(); + } + + public GameItem(ItemType type, String name, String weaponOrVecicleOrDrug, String displayName, double sellPrice) { + this.type = type; + this.name = name; + this.displayName = displayName; + this.weaponOrVecicleOrDrug = weaponOrVecicleOrDrug; + this.sellPrice = sellPrice; + this.hideDurability = false; + this.getItem(); + } + + public GameItem(ItemType type, String name, String weaponOrVecicleOrDrug, String displayName, double sellPrice, + boolean hideDurability) { + this.type = type; + this.name = name; + this.displayName = displayName; + this.weaponOrVecicleOrDrug = weaponOrVecicleOrDrug; + this.sellPrice = sellPrice; + this.hideDurability = hideDurability; + this.getItem(); + } + + /** + * @apiNote used soley for machines. + */ + public GameItem(String name, int machineID, String displayName, double sellPrice, boolean hideDurability) { + this.type = ItemType.MACHINE; + this.name = name; + this.displayName = displayName; + this.machineID = machineID; + this.sellPrice = sellPrice; + this.hideDurability = hideDurability; + this.getItem(); + } + + public GameItem(ItemType type, String name, String weaponOrVecicleOrDrug, String displayName, double sellPrice, + boolean hideDurability, boolean canStack) { + this.type = type; + this.name = name; + this.displayName = displayName; + this.weaponOrVecicleOrDrug = weaponOrVecicleOrDrug; + this.sellPrice = sellPrice; + this.hideDurability = hideDurability; + this.canStack = canStack; + this.getItem(); + } + + public GameItem(String name, ArmorUpgrade armorUpgrade, String displayName) { + this.type = ItemType.ARMOR_UPGRADE; + this.name = name; + this.armorUpgrade = armorUpgrade; + this.displayName = displayName; + this.hideDurability = false; + this.getItem(); + } + + public GameItem(String name, ArmorUpgrade armorUpgrade, String displayName, double sellPrice) { + this.type = ItemType.ARMOR_UPGRADE; + this.name = name; + this.displayName = displayName; + this.armorUpgrade = armorUpgrade; + this.sellPrice = sellPrice; + this.hideDurability = false; + this.getItem(); + } + + public GameItem(String name, ArmorUpgrade armorUpgrade, String displayName, double sellPrice, boolean hideDurability) { + this.type = ItemType.ARMOR_UPGRADE; + this.name = name; + this.displayName = displayName; + this.armorUpgrade = armorUpgrade; + this.sellPrice = sellPrice; + this.hideDurability = hideDurability; + this.getItem(); + }// + + public String getName() { + return this.name; + } + + public int getMachineID() { + return this.machineID; + } + + public ItemStack getItem() { + return getItem(1); + } + + public ItemStack getItem(int amount) { + switch (this.type) { + case WEAPON: { + Optional<Weapon<?>> opt = Vice.getWastedGuns().getWeaponManager().getWeapon(this.weaponOrVecicleOrDrug); + opt.ifPresent(weapon -> { + this.item = weapon.createItemStack(1, null); + }); + break; + } + case DRUG: { + Optional<Drug> drug = ((DrugService) Vice.getDrugManager().getService()).getDrug(this.weaponOrVecicleOrDrug); + if (drug.isPresent()) { + DrugItem drugItem = DrugItem.getByDrug(drug.get()); + if (drugItem != null) { + this.item = ItemStackUtil.makeStackable(drugItem.getItemStack(), 64); + } + } + else { + this.item = Parsing.parseItemStack(this.weaponOrVecicleOrDrug); + } + break; + } + case MACHINE: { + if(Vice.getInstance().getMachineManager()==null || Vice.getInstance().getMachineManager().getMachineItemById(this.machineID)==null) + this.item = new ItemStack(Material.STONE); + else + this.item = Vice.getInstance().getMachineManager().getMachineItemById(this.machineID); + break; + } + case VEHICLE: + Optional<VehicleProperties> opt = Vice.getWastedVehicles().getVehicle(this.weaponOrVecicleOrDrug); + opt.ifPresent(vehicleProperties -> { + this.item = vehicleProperties.getItem(); + }); + break; + case ARMOR_UPGRADE: + this.item = Utils.createItem(Material.LEATHER, "&e&l" + this.armorUpgrade.getDisplayName() + " Upgrade &a&lBUY&f: &a&l$" + this.armorUpgrade.getPrice()); + default: + break; + } + if (this.item == null) this.item = new ItemStack(Material.STONE); + if (this.canStack) this.item = ItemStackUtil.makeStackable(this.item, 64); + + if (this.hideDurability) { + ItemMeta itemMeta = this.item.getItemMeta(); + itemMeta.setUnbreakable(true); + itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE); + this.item.setItemMeta(itemMeta); + } + if (this.isScheduled()) { + ItemMeta itemMeta = this.item.getItemMeta(); + if (itemMeta.hasLore()) { + if (!Objects.equals(itemMeta.getLore().get(0), this.getSchedule().getDisp())) { + List<String> lore = new ArrayList<>(); + lore.add(this.getSchedule().getDisp()); + lore.addAll(itemMeta.getLore()); + itemMeta.setLore(lore); + } + } else itemMeta.setLore(Collections.singletonList(this.getSchedule().getDisp())); + this.item.setItemMeta(itemMeta); + } + ItemStack is = this.item.clone(); + is.setAmount(amount); + return is; + } + + public String getWeaponOrVehicleOrDrug() { + return this.weaponOrVecicleOrDrug; + } + + public String getDisplayName() { + if (this.displayName != null) + return this.displayName; + String name = (this.item.hasItemMeta() && this.item.getItemMeta().hasDisplayName()) ? this.item.getItemMeta().getDisplayName() + : this.item.getType().name(); + String amnt = this.item.getAmount() > 1 ? " &7x &a" + this.item.getAmount() : ""; + return name + amnt; + } + + public String getShopCategory() { + return this.shopCategory; + } + + public void setDisplayName(String s) { + this.displayName = s; + } + + public double getSellPrice() { + return this.sellPrice; + } + + public void setSellPrice(double i) { + this.sellPrice = i; + } + + public boolean canSell() { + return this.sellPrice > 0; + } + + public ItemType getType() { + return this.type; + } + + public AmmoType getAmmoType() { + return this.ammoType; + } + + public ArmorUpgrade getArmorUpgrade() { + return this.armorUpgrade; + } + + public boolean getHideDurability() { + return this.hideDurability; + } + + public boolean canStack() { + return canStack; + } + + public Schedule getSchedule() { + return Schedule.of(this.name); + } + + public boolean isScheduled() { + return this.getSchedule() != Schedule.NONE; + } + + public enum ItemType { + ITEMSTACK, WEAPON, VEHICLE, AMMO, ARMOR_UPGRADE, DRUG, MACHINE + } + +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/GameItemCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/GameItemCommand.java new file mode 100644 index 0000000..9dd3e49 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/GameItemCommand.java @@ -0,0 +1,523 @@ +package net.grandtheftmc.vice.items; + +import com.j0ach1mmall3.wastedvehicles.api.VehicleProperties; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.guns.weapon.Weapon; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drugs.Drug; +import net.grandtheftmc.vice.drugs.DrugService; +import net.grandtheftmc.vice.drugs.items.DrugItem; +import net.grandtheftmc.vice.items.GameItem.ItemType; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.Iterator; +import java.util.List; +import java.util.Optional; + +public class GameItemCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!s.hasPermission("command.gameitem")) { + s.sendMessage(Lang.NOPERM.s()); + return true; + } + + boolean consoleGive = false; + if (!(s instanceof Player)) { + if (!(args.length >= 1 && args[0].equalsIgnoreCase("give"))) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } else consoleGive = true; + } + +// Player player = (Player) s; + if (args.length == 0) { + s.sendMessage(Utils.f("&c/gameitem add <itemName> [displayName]")); + s.sendMessage(Utils.f("&c/gameitem adds <itemName> <sellPrice> [displayName]")); + s.sendMessage(Utils.f("&c/gameitem addweapon <itemName> <weapon> [displayName]")); + s.sendMessage(Utils.f("&c/gameitem addvehicle <itemName> <vehicle> [displayName]")); + s.sendMessage(Utils.f("&c/gameitem addarmorupgrade <itemName> <armorupgrade> [displayName]")); + s.sendMessage(Utils.f("&c/gameitem adddrug <itemName> <drug> [displayName]")); + s.sendMessage(Utils.f("&c/gameitem remove <itemName>")); + s.sendMessage(Utils.f("&c/gameitem displayName <itemName> [displayName]")); + s.sendMessage(Utils.f("&c/gameitem sellprice <itemName> <price>")); + s.sendMessage(Utils.f("&c/gameitem get <itemName> <amount>")); + s.sendMessage(Utils.f("&c/gameitem give <player> <itemName> <amount>")); + s.sendMessage(Utils.f("&c/gameitem list [page]")); + s.sendMessage(Utils.f("&c/gameitem load")); + s.sendMessage(Utils.f("&c/gameitem save")); + return true; + } + ItemManager im = Vice.getItemManager(); + switch (args[0].toLowerCase()) { + case "add": { + if (args.length < 2) { + s.sendMessage(Utils.f("&c/gameitem add <itemName> [displayName]")); + return true; + } + ItemStack item = ((Player) s).getInventory().getItemInMainHand(); + if (item == null) { + ((Player) s).sendMessage(Lang.GAMEITEMS.f("&cYou need to hold an item in your hand!")); + return true; + } + GameItem gi = im.getItem(args[1]); + if (gi != null) { + im.removeItem(gi); + ((Player) s).sendMessage(Lang.GAMEITEMS + .f("&7That item already existed, so it has been deleted and replaced with the new one.")); + } + + String displayName; + if (args.length > 2) { + displayName = args[2]; + for (int i = 3; i < args.length; i++) + displayName += ' ' + args[i]; + } else { + ItemMeta meta = item.getItemMeta(); + displayName = meta == null || meta.getDisplayName() == null ? item.getType().name() : meta.getDisplayName(); + + } + im.addItem(new GameItem(args[1], item, displayName)); + s.sendMessage(Lang.GAMEITEMS + .f("&7You added an item with name &a" + args[1] + "&7 and Display Name " + displayName + "&7!")); + return true; + } + case "adds": { + if (args.length < 3) { + s.sendMessage(Utils.f("&c/gameitem adds <itemName> <sellPrice> [displayName]")); + return true; + } + ItemStack item = ((Player) s).getInventory().getItemInMainHand(); + if (item == null) { + ((Player) s).sendMessage(Lang.GAMEITEMS.f("&cYou need to hold an item in your hand!")); + return true; + } + GameItem gi = im.getItem(args[1]); + if (gi != null) { + im.removeItem(gi); + ((Player) s).sendMessage(Lang.GAMEITEMS + .f("&7That item already existed, so it has been deleted and replaced with the new one.")); + } + double price; + try { + price = Double.parseDouble(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Lang.GAMEITEMS.f("&7The price must be a number! (double)")); + return true; + } + if (price < 0) { + s.sendMessage(Lang.GAMEITEMS.f("&7The price must be 0 or higher!")); + return true; + + } + String displayName; + if (args.length > 3) { + displayName = args[3]; + for (int i = 4; i < args.length; i++) + displayName = displayName + ' ' + args[i]; + } else { + ItemMeta meta = item.getItemMeta(); + displayName = meta == null || meta.getDisplayName() == null ? item.getType().name() : meta.getDisplayName(); + } + gi = im.addItem(new GameItem(args[1], item, displayName, price)); + s.sendMessage(Lang.GAMEITEMS.f("&7You added an item with name &a" + args[1] + "&7 and sell price &a$&l" + + gi.getSellPrice() + "&7 and Display Name " + displayName + "&7!")); + return true; + } + case "addweapon": { + if (args.length < 3) { + s.sendMessage(Utils.f("&c/gameitem addweapon <itemName> <weapon> [displayName]")); + return true; + } + GameItem gi = im.getItem(args[1]); + if (gi != null) { + im.removeItem(gi); + ((Player) s).sendMessage(Lang.GAMEITEMS + .f("&7That item already existed, so it has been deleted and replaced with the new one.")); + } + Optional<Weapon<?>> w = Vice.getWastedGuns().getWeaponManager().getWeapon(args[2]); + if (w == null || !w.isPresent()) { + s.sendMessage(Lang.GAMEITEMS.f("&7That weapon does not exist!")); + return true; + } + Weapon weapon = w.get(); + if (weapon == null) { + s.sendMessage(Lang.GAMEITEMS.f("&7That weapon does not exist!")); + return true; + } + String displayName; + if (args.length > 3) { + displayName = args[3]; + for (int i = 4; i < args.length; i++) + displayName = displayName + ' ' + args[i]; + } else { + ItemStack item = weapon.getBaseItemStack(); + ItemMeta meta = item.getItemMeta(); + displayName = meta == null || meta.getDisplayName() == null ? item.getType().name() : meta.getDisplayName(); + } + im.addItem(new GameItem(ItemType.WEAPON, args[1], weapon.getName(), displayName)); + s.sendMessage(Lang.GAMEITEMS.f("&7You added an item with name &a" + args[1] + "&7 and weapon &a" + + weapon.getUniqueIdentifier() + "&7 and Display Name " + displayName + "&7!")); + return true; + } + case "adddrug": { + if (args.length < 3) { + s.sendMessage(Utils.f("&c/gameitem addweapon <itemName> <weapon> [displayName]")); + return true; + } + GameItem gi = im.getItem(args[1]); + if (gi != null) { + im.removeItem(gi); + ((Player) s).sendMessage(Lang.GAMEITEMS + .f("&7That item already existed, so it has been deleted and replaced with the new one.")); + } + Optional<Drug> drug = ((DrugService) Vice.getInstance().getDrugManager().getService()).getDrug(args[2]); + if (drug.isPresent()) { + DrugItem drugItem = DrugItem.getByDrug(drug.get()); + if (drugItem == null) { + s.sendMessage(Lang.GAMEITEMS.f("&7That drug does not exist!")); + return true; + } + String displayName; + if (args.length > 3) { + displayName = args[3]; + for (int i = 4; i < args.length; i++) + displayName = displayName + ' ' + args[i]; + } else { + ItemStack item = drugItem.getItemStack(); + ItemMeta meta = item.getItemMeta(); + displayName = meta == null || meta.getDisplayName() == null ? item.getType().name() : meta.getDisplayName(); + } + im.addItem(new GameItem(ItemType.DRUG, args[1], drug.get().getName(), displayName)); + s.sendMessage(Lang.GAMEITEMS.f("&7You added an item with name &a" + args[1] + "&7 and drug &a" + + drug.get().getName() + "&7 and Display Name " + displayName + "&7!")); + } + return true; + } + case "addweapons": { + if (args.length < 4) { + s.sendMessage(Utils.f("&c/gameitem addweapons <itemName> <weapon> <sellPrice> [displayName]")); + return true; + } + GameItem gi = im.getItem(args[1]); + if (gi != null) { + im.removeItem(gi); + ((Player) s).sendMessage(Lang.GAMEITEMS + .f("&7That item already existed, so it has been deleted and replaced with the new one.")); + } + Optional<Weapon<?>> w = Vice.getWastedGuns().getWeaponManager().getWeapon(args[2]); + if (w == null || !w.isPresent()) { + s.sendMessage(Lang.GAMEITEMS.f("&7That weapon does not exist!")); + return true; + } + Weapon weapon = w.get(); + if (weapon == null) { + s.sendMessage(Lang.GAMEITEMS.f("&7That weapon does not exist!")); + return true; + } + double price; + try { + price = Double.parseDouble(args[3]); + } catch (NumberFormatException e) { + s.sendMessage(Lang.GAMEITEMS.f("&7The price must be a number! (double)")); + return true; + } + if (price < 0) { + s.sendMessage(Lang.GAMEITEMS.f("&7The price must be 0 or higher!")); + return true; + } + String displayName; + if (args.length > 4) { + displayName = args[4]; + for (int i = 5; i < args.length; i++) + displayName = displayName + ' ' + args[i]; + } else { + ItemStack item = weapon.getBaseItemStack(); + ItemMeta meta = item.getItemMeta(); + displayName = meta == null || meta.getDisplayName() == null ? item.getType().name() : meta.getDisplayName(); + } + im.addItem(new GameItem(ItemType.WEAPON, args[1], weapon.getName(), displayName)); + s.sendMessage(Lang.GAMEITEMS + .f("&7You added an item with name &a" + args[1] + "&7 and weapon &a" + weapon.getName() + + "&7 and sell price &a$&l" + price + "&7 and Display Name " + displayName + "&7!")); + return true; + } + case "addvehicle": { + if (args.length < 3) { + s.sendMessage(Utils.f("&c/gameitem addvehicle <itemName> <vehicle> [displayName]")); + return true; + } + GameItem gi = im.getItem(args[1]); + if (gi != null) { + im.removeItem(gi); + ((Player) s).sendMessage(Lang.GAMEITEMS + .f("&7That item already existed, so it has been deleted and replaced with the new one.")); + } + Optional<VehicleProperties> v = Vice.getWastedVehicles().getVehicle(args[2]); + if (v == null || !v.isPresent()) { + s.sendMessage(Lang.GAMEITEMS.f("&7That vehicle does not exist!")); + return true; + } + VehicleProperties vehicle = v.get(); + if (vehicle == null) { + s.sendMessage(Lang.GAMEITEMS.f("&7That vehicle does not exist!")); + return true; + } + String displayName; + if (args.length > 3) { + displayName = args[3]; + for (int i = 4; i < args.length; i++) + displayName += ' ' + args[i]; + } else { + ItemStack item = vehicle.getItem(); + ItemMeta meta = item.getItemMeta(); + displayName = meta == null || meta.getDisplayName() == null ? item.getType().name() : meta.getDisplayName(); + } + im.addItem(new GameItem(ItemType.VEHICLE, args[1], vehicle.getIdentifier(), displayName)); + s.sendMessage(Lang.GAMEITEMS.f("&7You added an item with name &a" + args[1] + "&7 and vehicle &a" + + vehicle.getIdentifier() + "&7 and Display Name " + displayName + "&7!")); + return true; + } +// case "addvehicles": { +// if (args.length < 3) { +// s.sendMessage(Utils.f("&c/gameitem addweapons <itemName> <vehicle> <sellPrice> [displayName]")); +// return true; +// } +// GameItem gi = im.getItem(args[1]); +// if (gi != null) { +// im.removeItem(gi); +// ((Player) s).sendMessage(Lang.GAMEITEMS +// .f("&7That item already existed, so it has been deleted and replaced with the new one.")); +// } +// Optional<VehicleProperties> v = Vice.getWastedVehicles().getVehicle(args[2]); +// if (v == null || !v.isPresent()) { +// s.sendMessage(Lang.GAMEITEMS.f("&7That vehicle does not exist!")); +// return true; +// } +// VehicleProperties vehicle = v.get(); +// if (vehicle == null) { +// s.sendMessage(Lang.GAMEITEMS.f("&7That vehicle does not exist!")); +// return true; +// } +// double price; +// try { +// price = Double.parseDouble(args[3]); +// } catch (NumberFormatException e) { +// s.sendMessage(Lang.GAMEITEMS.f("&7The price must be a number! (double)")); +// return true; +// } +// if (price < 0) { +// s.sendMessage(Lang.GAMEITEMS.f("&7The price must be 0 or higher!")); +// return true; +// } +// String displayName; +// if (args.length > 4) { +// displayName = args[4]; +// for (int i = 5; i < args.length; i++) +// displayName += ' ' + args[i]; +// } else { +// ItemStack item = vehicle.getItem(); +// ItemMeta meta = item.getItemMeta(); +// displayName = meta == null || meta.getDisplayName() == null ? item.getType().name() : meta.getDisplayName(); +// } +// im.addItem(new GameItem(ItemType.VEHICLE, args[1], vehicle.getIdentifier(), displayName, price, 0)); +// s.sendMessage(Lang.GAMEITEMS +// .f("&7You added an item with name &a" + args[1] + "&7 and vehicle &a" + vehicle.getIdentifier() +// + "&7 and sell price &a$&l" + price + "&7 and Display Name " + displayName + "&7!")); +// return true; +// } + case "addarmorupgrade": { + if (args.length < 3) { + s.sendMessage(Utils.f("&c/gameitem addarmorupgrade <itemName> <armorupgrade> [displayName]")); + return true; + } + GameItem gi = im.getItem(args[1]); + if (gi != null) { + im.removeItem(gi); + ((Player) s).sendMessage(Lang.GAMEITEMS + .f("&7That item already existed, so it has been deleted and replaced with the new one.")); + } + ArmorUpgrade upgrade = ArmorUpgrade.getArmorUpgrade(args[2]); + if (upgrade == null) { + s.sendMessage(Lang.GAMEITEMS.f("&7That vehicle does not exist!")); + return true; + } + String displayName = Utils.f("&b&l" + upgrade.getDisplayName() + " Armor Upgrade: &a" + upgrade.getDisplayName()); + im.addItem(new GameItem(args[1], upgrade, displayName)); + s.sendMessage(Lang.GAMEITEMS.f("&7You added an item with name &a" + args[1] + "&7 and armor upgrade &a" + + upgrade.getDisplayName() + "&7 and Display Name " + displayName + "&7!")); + return true; + } + case "remove": { + if (args.length < 2) { + s.sendMessage(Utils.f("&c/gameitem remove <itemName>")); + return true; + } + GameItem gi = im.getItem(args[1]); + if (gi == null) { + s.sendMessage(Lang.GAMEITEMS.f("&7That GameItem does not exist!")); + return true; + } + im.removeItem(gi); + s.sendMessage(Lang.GAMEITEMS.f("&7GameItem &a" + gi.getName() + "&7 was removed!")); + return true; + } + case "displayname": { + if (args.length < 2) { + s.sendMessage(Utils.f("&c/gameitem displayName <itemName> [displayName]")); + return true; + } + GameItem gi = im.getItem(args[1]); + if (gi == null) { + s.sendMessage(Lang.GAMEITEMS.f("&7That GameItem does not exist!")); + return true; + } + String displayName = args[2]; + for (int i = 3; i < args.length; i++) + displayName = displayName + ' ' + args[i]; + gi.setDisplayName(displayName); + s.sendMessage(Lang.GAMEITEMS.f("&7You set the display name of GameItem &a" + gi.getName() + "&7 to &a" + + gi.getDisplayName() + '!')); + return true; + } + case "sellprice": { + if (args.length < 2) { + s.sendMessage(Utils.f("&c/gameitem sellprice <itemName> <price>")); + return true; + } + GameItem gi = im.getItem(args[1]); + if (gi == null) { + s.sendMessage(Lang.GAMEITEMS.f("&7That GameItem does not exist!")); + return true; + } + double price; + try { + price = Double.parseDouble(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Lang.GAMEITEMS.f("&7The price must be a number! (double)")); + return true; + } + if (price < 0) { + s.sendMessage(Lang.GAMEITEMS.f("&7The price must be 0 or higher!")); + return true; + + } + gi.setSellPrice(price); + s.sendMessage(Lang.GAMEITEMS.f("&7You set the sell price of GameItem &a" + gi.getName() + "&7 to &a$&l" + + gi.getSellPrice() + '!')); + return true; + } + case "get": { + if (args.length < 2) { + s.sendMessage(Utils.f("&c/gameitem get <itemName> <amount>")); + return true; + } + GameItem gi = im.getItem(args[1]); + if (gi == null) { + s.sendMessage(Lang.GAMEITEMS.f("&7That GameItem does not exist!")); + return true; + } + ItemStack item = gi.getItem(); + if (args.length > 2) + try { + item.setAmount(Integer.parseInt(args[2])); + } catch (NumberFormatException e) { + s.sendMessage(Lang.GAMEITEMS.f("&7The amount must be a number! (integer)")); + return true; + } + ((Player) s).getInventory().addItem(item); + s.sendMessage(Lang.GAMEITEMS.f((args.length > 2 ? "&a" + args[2] + "&7 of " : "") + "&7GameItem &a" + + gi.getName() + "&7 was added to your inventory!")); + return true; + } + case "give": { + if (args.length < 3) { + s.sendMessage(Utils.f("&c/gameitem give <player> <itemName> <amount>")); + return true; + } + Player pl = Bukkit.getPlayer(args[1]); + if (pl == null) { + s.sendMessage(Lang.GAMEITEMS.f("&7That player is not online!")); + return true; + } + GameItem gi = im.getItem(args[2]); + if (gi == null) { + s.sendMessage(Lang.GAMEITEMS.f("&7That GameItem does not exist!")); + return true; + } + ItemStack item = gi.getItem(); + if (args.length > 3) + try { + item.setAmount(Integer.parseInt(args[3])); + } catch (NumberFormatException e) { + s.sendMessage(Lang.GAMEITEMS.f("&7The amount must be a number! (integer)")); + return true; + } + pl.getInventory().addItem(item); + s.sendMessage(Lang.GAMEITEMS.f("&7You gave " + (args.length > 3 ? "&a" + args[3] + "&7 of " : "") + + "GameItem &a" + gi.getName() + "&7 to &a" + pl.getName() + '!')); + return true; + } + case "list": + List<GameItem> items = Vice.getItemManager().getItems(); + int page = 1; + if (args.length > 1) { + try { + page = Integer.parseInt(args[1]); + } catch (NumberFormatException e) { + s.sendMessage(Lang.GAMEITEMS.f("&cThe page must be a number!")); + return true; + } + } + if (page < 1) { + s.sendMessage(Lang.GAMEITEMS.f("&7The page must be a positive number!")); + return true; + } + int pages = items.size() / 6 + 1; + s.sendMessage(Utils.f(" &7&m---------------&7[&a&l Game Items &7Page &a" + page + "&7/&a" + pages + + " &7&m]---------------")); + Iterator<GameItem> it = items.iterator(); + for (int i = 0; i < page * 6; i++) { + if (!it.hasNext()) + return true; + GameItem item = it.next(); + if (i < page * 6 - 6) + continue; + s.sendMessage(Utils.f("&a&l" + item.getType() + "&a " + item.getName() + + " &7| &7Display Name: &r" + item.getDisplayName() + + (item.getSellPrice() >= 0 ? "&7 Sell Price: &a$&l" + item.getSellPrice() : ""))); + } + return true; + case "load": + Vice.getSettings().setItemsConfig(Utils.loadConfig("items")); + Vice.getItemManager().loadItems(); + s.sendMessage(Lang.GAMEITEMS.f("&7Loaded GameItems!")); + return true; + case "save": + Vice.getItemManager().saveItems(); + s.sendMessage(Lang.GAMEITEMS.f("&7Saved GameItems!")); + return true; + default: + s.sendMessage(Utils.f("&c/gameitem add <itemName> [displayName]")); + s.sendMessage(Utils.f("&c/gameitem addweapon <itemName> [displayName]")); + s.sendMessage(Utils.f("&c/gameitem addvehicle <itemName> [displayName]")); + s.sendMessage(Utils.f("&c/gameitem remove <itemName>")); + s.sendMessage(Utils.f("&c/gameitem displayName <itemName> [displayName]")); + s.sendMessage(Utils.f("&c/gameitem sellprice <itemName> <price>")); + s.sendMessage(Utils.f("&c/gameitem get <itemName>")); + s.sendMessage(Utils.f("&c/gameitem give <player> <itemName>")); + s.sendMessage(Utils.f("&c/gameitem list [page]")); + s.sendMessage(Utils.f("&c/gameitem load")); + s.sendMessage(Utils.f("&c/gameitem save")); + return true; + } + } +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/Head.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/Head.java new file mode 100644 index 0000000..037dcb1 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/Head.java @@ -0,0 +1,245 @@ +package net.grandtheftmc.vice.items; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.users.ViceUser; +import net.grandtheftmc.vice.users.ViceUserDAO; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import java.util.Objects; +import java.util.UUID; + +/** + * Created by Liam on 4/10/2016. + */ +public class Head { + + private final UUID sellerUUID; + private final String sellerName; + private final String head; + private final long expiry; + private boolean done; + private boolean paid; + private boolean gaveHead; + private UUID bidderUUID; + private String bidderName; + private double bid = -1; + + public Head(UUID sellerUUID, String sellerName, String head) { + this.sellerUUID = sellerUUID; + this.sellerName = sellerName; + this.head = head; + this.expiry = System.currentTimeMillis() + 86400000; + +// Core.sql.updateAsyncLater("insert into " + Core.name() + "_heads(sellerUUID, sellerName, head, expiry) values ('" + this.sellerUUID + "','" + this.sellerName + "','" + this.head + "'," + this.expiry + ");"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.insertHead(sellerUUID, sellerName, head, expiry)); + } + + public Head(UUID sellerUUID, String sellerName, String head, long expiry, boolean done, boolean paid, boolean gaveHead, UUID bidderUUID, String bidderName, double bid) { + this.sellerUUID = sellerUUID; + this.sellerName = sellerName; + this.head = head; + this.expiry = expiry; + this.done = done; + this.paid = paid; + this.gaveHead = gaveHead; + this.bidderUUID = bidderUUID; + this.bidderName = bidderName; + this.bid = bid; + } + + public UUID getSellerUUID() { + return this.sellerUUID; + } + + public String getSellerName() { + return this.sellerName; + } + + public String getHead() { + return this.head; + } + + public long getExpiry() { + return this.expiry; + } + + public UUID getBidderUUID() { + return this.bidderUUID; + } + + public String getBidderName() { + return this.bidderName; + } + + public double getBid() { + return this.bid; + } + + public boolean hasBid() { + return this.bidderUUID != null; + } + + public boolean hasExpired() { + return this.hasBid() ? this.expiry < System.currentTimeMillis() : this.expiry - 82800000 < System.currentTimeMillis(); + } + + public boolean hasExpiredOverAWeekAgo() { + return this.expiry + 604800000 < System.currentTimeMillis(); + } + + public Long getTimeUntilExpiry() { + return this.expiry - System.currentTimeMillis(); + } + + public boolean isDone() { + return this.done; + } + + public boolean isPaid() { + return this.paid; + } + + public boolean gaveHead() { + return this.gaveHead; + } + + public ItemStack getItem() { + return Utils.setSkullOwner(Utils.createItem(Material.SKULL_ITEM, 3, "&e&l" + this.head + "'s Head", "&7Value: &a$&l" + (this.hasBid() ? "10,000" : this.bid), "&7Sell me in the sewer!"), this.head); + } + + public boolean giveHead() { + if (this.gaveHead) return false; + if (!this.hasBid()) { + this.gaveHead = true; + return true; + } + Player bidder = Bukkit.getPlayer(this.bidderUUID); + if (bidder == null) + return false; + + if (bidder.getInventory().firstEmpty() < 0) { + bidder.sendMessage(Lang.HEAD_AUCTION.f("&7The auction for &e&l" + this.head + "'s Head&7 has finished! Please clear a slot in your inventory and wait a few seconds.")); + return false; + } + bidder.getInventory().addItem(this.getItem()); + bidder.sendMessage(Lang.HEAD_AUCTION.f("&7The auction for &e&l" + this.head + "'s Head&7 has finished! Congratulations on winning the bid.")); + this.gaveHead = true; + return true; + } + + public boolean paySeller() { + if (this.paid) return false; + Player seller = Bukkit.getPlayer(this.sellerUUID); + if (seller == null) + return false; + ViceUser user = Vice.getUserManager().getLoadedUser(seller.getUniqueId()); + if (!this.hasBid()) { + seller.sendMessage(Lang.HEAD_AUCTION.f("&7The auction for &e&l" + this.head + "'s Head&7 has finished with no bids!")); + this.paid = true; + return true; + } + if (this.bid > 10000) + user.addMoney(this.bid - 10000); + ViceUtils.updateBoard(seller, user); + seller.sendMessage(Lang.HEAD_AUCTION.f("&7The auction for &e&l" + this.head + "'s Head&7 has finished with &a$&l" + this.bid + "&7! You received &a$&l" + (this.bid - 10000) + "&7 from &a&l" + this.bidderName + "&7!")); + this.paid = true; + return true; + } + + public boolean delete() { + if ((this.done && this.gaveHead && this.paid) || this.hasExpiredOverAWeekAgo()) { +// Core.sql.updateAsyncLater("delete from " + Core.name() + "_heads where sellerUUID='" + this.sellerUUID + "' and head='" + this.head + "' and expiry=" + this.expiry + ';'); + ServerUtil.runTaskAsync(() -> ViceUserDAO.deleteHead(sellerUUID, head, expiry)); + Vice.getShopManager().removeHead(this); + return true; + } + return false; + } + + public void update() { + if (!this.hasExpired()) + return; + boolean update = !this.done; + this.done = true; + if (this.giveHead()) update = true; + if (this.paySeller()) update = true; + if (this.delete()) update = true; + if (update) + this.updateDB(); + } + + + public void updateDB() { +// Core.sql.updateAsyncLater("update " + Core.name() + "_heads set paid=" + this.paid + ", gaveHead=" + this.gaveHead + ", done=" + this.done + ", bidderUUID=" + (this.bidderUUID == null ? null : "'" + this.bidderUUID + '\'') + ",bidderName = '" + +// this.bidderName + "', bid=" + this.bid + " where sellerUUID='" + this.sellerUUID + "' and head='" + this.head + "' and expiry=" + this.expiry + ';'); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + Core.name() + "_heads set paid=" + this.paid + ", gaveHead=" + this.gaveHead + ", done=" + this.done + ", bidderUUID=" + (this.bidderUUID == null ? null : "'" + this.bidderUUID + '\'') + ",bidderName = '" + + this.bidderName + "', bid=" + this.bid + " where sellerUUID='" + this.sellerUUID + "' and head='" + this.head + "' and expiry=" + this.expiry + ';')); + } + + public void returnBidderMoney() { + Player bidder = Bukkit.getPlayer(this.bidderUUID); + if (bidder == null) { +// Core.sql.updateAsyncLater("update " + Core.name() + " set bank=bank+" + this.bid + " where uuid='" + this.bidderUUID + "';"); + ServerUtil.runTaskAsync(() -> BaseDatabase.runCustomQuery("update " + Core.name() + " set bank=bank+" + this.bid + " where uuid='" + this.bidderUUID + "';")); + this.bidderName = null; + this.bidderUUID = null; + this.bid = -1; + return; + } + ViceUser user = Vice.getUserManager().getLoadedUser(bidder.getUniqueId()); + user.addMoney(this.bid); + ViceUtils.updateBoard(bidder, user); + bidder.sendMessage(Lang.HEAD_AUCTION.f("&7You were outbid for the &e&l" + this.head + "'s Head&7! Your bid of &a$&l" + this.bid + "&7 was returned to your bank account.")); + this.bidderName = null; + this.bidderUUID = null; + this.bid = -1; + } + + public void bid(Player player, ViceUser user, double bid) { + bid = Utils.round(bid); + if (this.hasExpired() || this.done) { + player.sendMessage(Lang.HEAD_AUCTION.f("&7The bidding has expired!")); + return; + } + if (!user.hasMoney(bid)) { + player.sendMessage(Lang.HEAD_AUCTION.f("&7You don't have &c$&l" + bid + "&7!")); + return; + } + + if (this.hasBid()) { + if (this.bid * 1.05 > bid) { + player.sendMessage(Lang.HEAD_AUCTION.f("&7You must bid at least &a&l5%&7 more than the current bid of &a$&l" + this.bid + "&7 (&a$&l" + (this.bid * 1.05) + "&7)!")); + return; + } + this.returnBidderMoney(); + } else if (bid < 10000) { + player.sendMessage(Lang.HEAD_AUCTION.f("&7You must bid at least the starting bid of &a$&l10,000&7!")); + return; + } + this.setBid(player, bid); + user.takeMoney(bid); + ViceUtils.updateBoard(player, user); + player.sendMessage(Lang.HEAD_AUCTION.f("&7You have bid &a$&l" + this.bid + "&7 for &e&l" + this.head + "'s Head&7! Please wait &c&l" + Utils.timeInMillisToText(this.getTimeUntilExpiry()) + "&7 for the auction to end.")); + Player seller = Bukkit.getPlayer(this.sellerUUID); + if (seller != null && !Objects.equals(seller, player)) + seller.sendMessage(Lang.HEAD_AUCTION.f("&a&l" + player.getName() + "&7 has bid &a$&l" + this.bid + "&7 on &e&l" + this.head + "'s Head&7!")); + } + + public void setBid(Player player, double bid) { + this.bidderUUID = player.getUniqueId(); + this.bidderName = player.getName(); + this.bid = bid; + this.updateDB(); + } + + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/ItemManager.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/ItemManager.java new file mode 100644 index 0000000..c0255ae --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/ItemManager.java @@ -0,0 +1,489 @@ +package net.grandtheftmc.vice.items; + +import com.j0ach1mmall3.jlib.methods.Parsing; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.items.GameItem.ItemType; +import net.grandtheftmc.vice.items.recipes.BottleCraftingRecipe; +import net.grandtheftmc.vice.items.recipetypes.BrewingRecipeItem; +import net.grandtheftmc.vice.items.recipetypes.CraftingRecipeItem; +import net.grandtheftmc.vice.items.recipetypes.RecipeItem; +import net.grandtheftmc.vice.users.CopRank; +import net.grandtheftmc.vice.users.ViceRank; +import net.grandtheftmc.vice.users.ViceUser; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import java.util.*; +import java.util.stream.Collectors; + +public class ItemManager { + + private List<GameItem> items = new ArrayList<>(); + private List<Kit> kits = new ArrayList<>(); + private HashMap<ItemStack, RecipeItem> customRecipes = new HashMap<>(); + private HashMap<ItemStack, ItemStack> replacedVanilla = new HashMap<>(); + private List<Material> bannedCraftingRecipes = new ArrayList<>(); + private HashSet<ItemStack> ingredients = new HashSet<>(); + public final static NamespacedKey NAMESPACED_KEY = new NamespacedKey(Vice.getInstance(), Vice.getInstance().getDescription().getName()); + private LinkedList<GameItem> shopItems = new LinkedList<>(); + + public ItemManager() { + this.loadItems(); + this.loadKits(); + this.loadReplacedVanilla(); + this.loadBannedCraftingRecipes(); + this.loadCraftingRecipes(); + } + + public void m(int i) { + Bukkit.broadcastMessage(String.valueOf(i)); + } + + public void m(String s) { + Bukkit.broadcastMessage(s); + } + + private void loadCraftingRecipes(){ + registerCustomRecipe(new BottleCraftingRecipe()); + } + + private void loadBannedCraftingRecipes() { + this.bannedCraftingRecipes.add(Material.LEATHER_LEGGINGS); + this.bannedCraftingRecipes.add(Material.LEATHER_BOOTS); + this.bannedCraftingRecipes.add(Material.CHAINMAIL_LEGGINGS); + this.bannedCraftingRecipes.add(Material.CHAINMAIL_BOOTS); + this.bannedCraftingRecipes.add(Material.GOLD_LEGGINGS); + this.bannedCraftingRecipes.add(Material.GOLD_BOOTS); + this.bannedCraftingRecipes.add(Material.IRON_LEGGINGS); + this.bannedCraftingRecipes.add(Material.IRON_BOOTS); + this.bannedCraftingRecipes.add(Material.DIAMOND_LEGGINGS); + this.bannedCraftingRecipes.add(Material.DIAMOND_BOOTS); + this.bannedCraftingRecipes.add(Material.WOOD_SWORD); + this.bannedCraftingRecipes.add(Material.STONE_SWORD); + this.bannedCraftingRecipes.add(Material.IRON_SWORD); + this.bannedCraftingRecipes.add(Material.GOLD_SWORD); + this.bannedCraftingRecipes.add(Material.DIAMOND_SWORD); + this.bannedCraftingRecipes.add(Material.SHIELD); + } + + private void loadReplacedVanilla() { + //this.replacedVanilla.put(new ItemStack(Material.CARROT_ITEM), getItem("opiumpoppies").getItem()); OLD VICE + this.replacedVanilla.put(new ItemStack(Material.SUGAR_CANE), getItem("marijuanaleaf").getItem()); + this.replacedVanilla.put(new ItemStack(Material.MELON), getItem("cocaleaf").getItem()); + this.replacedVanilla.put(new ItemStack(Material.CACTUS), getItem("humuluslupulusfruit").getItem()); + this.replacedVanilla.put(new ItemStack(Material.BEETROOT), getItem("ephedrasinica").getItem()); + this.replacedVanilla.put(new ItemStack(Material.NETHER_STALK), getItem("ergotfungi").getItem()); + this.replacedVanilla.put(new ItemStack(Material.BROWN_MUSHROOM), getItem("magicmushroombrown").getItem()); + this.replacedVanilla.put(new ItemStack(Material.RED_MUSHROOM), getItem("magicmushroomred").getItem()); + //this.replacedVanilla.put(new ItemStack(Material.CHORUS_FRUIT), getItem("safrole_oil").getItem()); OLD VICE + } + + + public void loadItems() { + this.items = new ArrayList<>(); + this.shopItems = new LinkedList<>(); + YamlConfiguration c = Vice.getSettings().getItemsConfig(); + if (c == null) + return; + for (String name : c.getKeys(false)) { + try { + String displayName = c.getString(name + ".displayName"); + double price = -1; + boolean hideDurability = false, canStack = false; + String shopCategory = ""; + + if (c.get(name + ".canStack") != null) canStack = c.getBoolean(name + ".canStack"); + if (c.get(name + ".sellPrice") != null) price = c.getDouble(name + ".sellPrice"); + if (c.get(name + ".hideDurability") != null) hideDurability = c.getBoolean(name + ".hideDurability"); + if(c.get(name + ".shopCategory") !=null) shopCategory = c.getString(name + ".shopCategory"); + if(c.get(name + ".machineID") !=null ) + this.items.add(new GameItem(name, c.getInt(name + ".machineID"), displayName, price, hideDurability)); + if (c.get(name + ".weapon") != null) + this.items.add(new GameItem(ItemType.WEAPON, name, c.getString(name + ".weapon"), displayName, price, hideDurability, canStack)); + else if (c.get(name + ".drug") != null) + this.items.add(new GameItem(ItemType.DRUG, name, c.getString(name + ".drug"), displayName, price, hideDurability, canStack)); + else if (c.get(name + ".vehicle") != null) + this.items.add(new GameItem(ItemType.VEHICLE, name, c.getString(name + ".vehicle"), displayName, price, hideDurability, canStack)); + else if (c.get(name + ".ammo") != null) + this.items.add(new GameItem(name, Parsing.parseItemStack(c.getString(name + ".item")), + AmmoType.getAmmoType(c.getString(name + ".ammo")), displayName, price, hideDurability)); + else if (c.get(name + ".armorupgrade") != null) { + ArmorUpgrade upgrade = ArmorUpgrade.getArmorUpgrade(c.getString(name + ".armorupgrade")); + if (upgrade == null) + Vice.error("Error while loading items " + name + ": " + c.getString(name + ".ammo") + " is not a valid ArmorUpgrade!"); + else + this.items.add(new GameItem(name, upgrade, displayName, price, hideDurability)); + } + else if(!shopCategory.equals("")) {//This is done so not all items have to be searched when generating the shop. + this.shopItems.add(new GameItem(name, Parsing.parseItemStack(c.getString(name + ".item")), displayName, price, hideDurability, canStack, shopCategory)); + this.items.add(new GameItem(name, Parsing.parseItemStack(c.getString(name + ".item")), displayName, price, hideDurability, canStack, shopCategory)); + } + else if (c.get(name + ".item") != null) + this.items.add(new GameItem(name, Parsing.parseItemStack(c.getString(name + ".item")), displayName, price, hideDurability, canStack)); + } catch (Exception e) { + Vice.error("Error while loading item " + name + '!'); + e.printStackTrace(); + } + } + } + + public void saveItems() { + YamlConfiguration c = Vice.getSettings().getItemsConfig(); + for (String s : c.getKeys(false)) + c.set(s, null); + for (GameItem item : this.items) { + String name = item.getName(); + if (item.canStack()) c.set(name + ".canStack", item.canStack()); + c.set(name + ".displayName", item.getDisplayName()); + if (item.getSellPrice() > 0) c.set(name + ".sellPrice", item.getSellPrice()); + + if (item.getHideDurability()) c.set(name + ".hideDurability", item.getHideDurability()); + + if(item.getShopCategory()!=null) c.set(name + ".shopCategory", item.getShopCategory()); + + if(item.getType() == ItemType.MACHINE) { + c.set(name + ".machineID", item.getMachineID()); + } + if (item.getType() == ItemType.WEAPON) { + c.set(name + ".weapon", item.getWeaponOrVehicleOrDrug()); + } else if (item.getType() == ItemType.DRUG) { + c.set(name + ".drug", item.getWeaponOrVehicleOrDrug()); + } else if (item.getType() == ItemType.VEHICLE) { + c.set(name + ".vehicle", item.getWeaponOrVehicleOrDrug()); + } else if (item.getType() == ItemType.AMMO) { + c.set(name + ".ammo", item.getAmmoType().toString().toLowerCase()); + c.set(name + ".item", Parsing.parseString(item.getItem())); + } else if (item.getType() == ItemType.ARMOR_UPGRADE) { + c.set(name + ".armorupgrade", item.getArmorUpgrade().toString().toLowerCase()); + } else { + c.set(name + ".item", Parsing.parseString(item.getItem())); + } + } + Utils.saveConfig(c, "items"); + } + + public void loadKits() { + YamlConfiguration c = Vice.getSettings().getKitsConfig(); + this.kits = new ArrayList<>(); + for (String name : c.getKeys(false)) { + try { + double cost = 0; + int delay = 60; + if (c.get(name + ".cost") != null) + cost = c.getDouble(name + ".cost"); + if (c.get(name + ".delay") != null) + delay = c.getInt(name + ".delay"); + List<KitItem> contents = c.getStringList(name + ".contents").stream().map(this::kitItemFromString).collect(Collectors.toList()); + KitItem helmet = this.kitItemFromString(c.getString(name + ".helmet")); + KitItem chestplate = this.kitItemFromString(c.getString(name + ".chestplate")); + KitItem leggings = this.kitItemFromString(c.getString(name + ".leggings")); + KitItem boots = this.kitItemFromString(c.getString(name + ".boots")); + KitItem offHand = this.kitItemFromString(c.getString(name + ".offHand")); + String perm = c.getString(name + ".permission"); + this.kits.add(new Kit(name, cost, delay, contents, helmet, chestplate, leggings, boots, offHand, perm)); + } catch (Exception e) { + Core.error("Error while loading kit " + name); + e.printStackTrace(); + } + } + } + + public KitItem kitItemFromString(String s) { + if (s == null) + return null; + String[] a = s.split(":"); + if (a.length == 0) + return null; + GameItem item = this.getItem(a[0]); + try { + return new KitItem(item, a.length > 1 ? Integer.parseInt(a[1]) : 1); + } catch (NumberFormatException e) { + Core.error("Error parsing kititem: " + s); + return null; + } + + } + + public void saveKits() { + YamlConfiguration c = Vice.getSettings().getKitsConfig(); + for (String s : c.getKeys(false)) + c.set(s, null); + for (Kit kit : this.kits) { + String name = kit.getName(); + try { + if (kit.getCost() > 0) + c.set(name + ".cost", kit.getCost()); + if (kit.getDelay() > 0) + c.set(name + ".delay", kit.getDelay()); + List<String> contents = kit.getContents().stream().map(this::kitItemToString).collect(Collectors.toList()); + c.set(name + ".contents", contents); + c.set(name + ".helmet", this.kitItemToString(kit.getHelmet())); + c.set(name + ".chestplate", this.kitItemToString(kit.getChestPlate())); + c.set(name + ".leggings", this.kitItemToString(kit.getLeggings())); + c.set(name + ".boots", this.kitItemToString(kit.getBoots())); + c.set(name + ".offHand", this.kitItemToString(kit.getOffHand())); + c.set(name + ".permission", kit.getPermission()); + } catch (Exception e) { + Core.error("Error while saving kit " + name); + e.printStackTrace(); + } + } + Utils.saveConfig(c, "kits"); + } + + public LinkedList<GameItem> getShopItems() { + return this.shopItems; + } + + public String kitItemToString(KitItem item) { + if (item == null || item.getGameItem() == null) + return null; + return item.getGameItem().getName() + (item.getAmount() > 1 ? ":" + item.getAmount() : ""); + } + + public GameItem getItem(String itemName) { + return this.items.stream().filter(item -> item.getName().equalsIgnoreCase(itemName)).findFirst().orElse(null); + + } + + public GameItem getItemFromDisplayName(String itemName) { + return this.items.stream().filter(item -> ChatColor.stripColor(Utils.f(item.getDisplayName())).equalsIgnoreCase(ChatColor.stripColor(Utils.f(itemName)))).findFirst().orElse(null); + } + + public GameItem getItem(ItemStack item) { + if (item != null) + return this.items.stream().filter(g -> { + boolean namesMatch = true; + if(g.getItem().hasItemMeta() && g.getItem().getItemMeta().hasDisplayName() && item.hasItemMeta() && item.getItemMeta().hasDisplayName()) { + if(g.getType()== ItemType.WEAPON && g.getItem().getItemMeta().getDisplayName().contains("»") && g.getItem().getItemMeta().getDisplayName().contains("«")) { + String a = ChatColor.stripColor(g.getItem().getItemMeta().getDisplayName()); + String b = ChatColor.stripColor(item.getItemMeta().getDisplayName()).replace("/0", ""); + if(!a.equalsIgnoreCase(b)) { + namesMatch = false; + } + } + } + return g.getItem().getType() == item.getType() && g.getItem().getDurability() == item.getDurability() && namesMatch; + }).findFirst().orElse(null); + return null; + } + + public GameItem getItem(Material material) { + return this.items.stream().filter(g -> g.getItem().getType() == material).findFirst().orElse(null); + } + + public GameItem getItemFromWeapon(String s) { + return this.items.stream().filter(g -> g.getType() == ItemType.WEAPON && g.getWeaponOrVehicleOrDrug().equalsIgnoreCase(s)).findFirst().orElse(null); + } + + public GameItem getItemFromVehicle(String s) { + return this.items.stream().filter(g -> g.getType() == ItemType.VEHICLE && g.getWeaponOrVehicleOrDrug().equalsIgnoreCase(s)).findFirst().orElse(null); + } + + public GameItem getItem(ArmorUpgrade upgrade) { + return this.items.stream().filter(g -> g.getType() == ItemType.ARMOR_UPGRADE && upgrade == g.getArmorUpgrade()).findFirst().orElse(null); + } + + /** + * @param damagableItem if the item can be damaged during normal use, ex. Armor + */ + public GameItem getSellableItem(ItemStack is, boolean damagableItem) { + return this.items.stream().filter(g -> g.canSell() && g.getItem().getType()==is.getType() && (damagableItem || g.getItem().getDurability() == is.getDurability())).findFirst().orElse(null); + } + + public GameItem getSellableItem(ItemStack is) { + return getSellableItem(is, false); + } + + + + public List<Kit> getKits() { + return this.kits; + } + + public boolean giveKit(Player player, User user, ViceUser viceUser, String kit){ + return giveKit(player, user, viceUser, this.getKit(kit)); + } + + public boolean giveKit(Player player, User user, ViceUser viceUser, Kit kit) { + if (viceUser.isArrested()) { + player.sendMessage(Lang.JAIL.f("&7You can't get a kit in jail!")); + return true; + } + if (kit == null) { + player.sendMessage(Utils.f(Lang.KITS.f("&cThat kit does not exist!"))); + return false; + } + if (kit.getPermission() != null && !player.hasPermission(kit.getPermission())) { + player.sendMessage(Lang.KITS.f("&7You don't have permission to use this kit!")); + return false; + } + UserRank ur = UserRank.getUserRankOrNull(kit.getName()); + ViceRank rank = ViceRank.getRankOrNull(kit.getName()); + CopRank copRank = CopRank.getRankOrNull(kit.getName()); + if (ur == null && copRank != null && !viceUser.isCopRank(copRank)) { + player.sendMessage(Lang.KITS.f("&7You need to be a " + copRank.getColoredNameBold() + + "&7 to use this kit!")); + return false; + } else if (ur != null && !(ur == user.getUserRank() + || (ur == UserRank.SUPREME && user.getUserRank().isHigherThan(UserRank.SUPREME)))) { + player.sendMessage( + Lang.KITS.f("&7You need to be " + ur.getColoredNameBold() + "&7 to use this kit!")); + return false; + } else if (rank != null && !(rank == ViceRank.JUNKIE || rank == viceUser.getRank())) { + player.sendMessage(Lang.KITS.f("&7You need to rank up to " + rank.getColoredNameBold() + + "&7 to use this kit!")); + return false; + } + if (kit.getCost() > 0 && !viceUser.hasMoney(kit.getCost())) { + player.sendMessage( + Lang.KITS.f("&7You do not have the &c$&l" + kit.getCost() + "&7 to pay for this kit!")); + return false; + } + if (!viceUser.canUseKit(kit.getName())) { + player.sendMessage(Lang.KITS.f("&7You need to wait &c" + + Utils.timeInMillisToText(viceUser.getKitExpiry(kit.getName()) - System.currentTimeMillis()) + + "&7 to use this kit again!")); + return false; + } + viceUser.setKitExpiry(kit.getName(), kit.getDelay()); + if (kit.getCost() > 0) { + viceUser.takeMoney(kit.getCost()); + player.sendMessage(Lang.MONEY_TAKE.toString() + kit.getCost()); + ViceUtils.updateBoard(player, user, viceUser); + } + player.sendMessage(Lang.KITS.f("&7You received the kit &b" + kit.getName() + "&7!")); + this.giveKitItems(player, viceUser, kit); + return true; + } + + public void giveKitItems(Player player, ViceUser viceUser, Kit kit) { + List<ItemStack> items = new ArrayList<>(kit.getItems()); + ItemStack helmet = this.kitItemToItemStack(kit.getHelmet()); + ItemStack chestPlate = this.kitItemToItemStack(kit.getChestPlate()); + ItemStack leggings = this.kitItemToItemStack(kit.getLeggings()); + ItemStack boots = this.kitItemToItemStack(kit.getBoots()); + ItemStack offHand = this.kitItemToItemStack(kit.getOffHand()); + if (helmet != null) + if (player.getInventory().getHelmet() == null) + player.getInventory().setHelmet(helmet); + else + items.add(helmet); + if (chestPlate != null) + if (player.getInventory().getChestplate() == null) + player.getInventory().setChestplate(chestPlate); + else + items.add(chestPlate); + if (leggings != null) + if (player.getInventory().getLeggings() == null) + player.getInventory().setLeggings(leggings); + else + items.add(leggings); + if (boots != null) + if (player.getInventory().getBoots() == null) + player.getInventory().setBoots(boots); + else + items.add(boots); + if (offHand != null) + if (player.getInventory().getItemInOffHand() == null) + player.getInventory().setItemInOffHand(offHand); + else + items.add(offHand); + for (ItemStack stack : new ArrayList<>(items)) { + AmmoType type = AmmoType.getAmmoType(stack.getType(), stack.getDurability()); + if (type != null && !type.isInInventory()) { + viceUser.addAmmo(type, stack.getAmount()); + player.sendMessage(Lang.AMMO_ADD.f(stack.getAmount() + "&7 " + type.getGameItem().getDisplayName())); + items.remove(stack); + } + } + if (Utils.giveItems(player, Utils.toArray(items))) + player.sendMessage(Utils.f(Lang.KITS + "&cYour inventory was full so some items were dropped on the ground!")); + } + + public ItemStack kitItemToItemStack(KitItem item) { + if (item == null || item.getGameItem() == null) + return null; + ItemStack i = item.getGameItem().getItem(); + i.setAmount(item.getAmount()); + return i; + } + + public Kit getKit(String name) { + return this.kits.stream().filter(kit -> kit.getName().equalsIgnoreCase(name)).findFirst().orElse(null); + } + + public GameItem addItem(GameItem gameItem) { + this.items.add(gameItem); + return gameItem; + } + + public void removeItem(GameItem gi) { + this.items.remove(gi); + + } + + public void addKit(Kit kit) { + this.kits.add(kit); + } + + public List<GameItem> getItems() { + return this.items; + } + + public HashMap<ItemStack, RecipeItem> getCustomRecipes() { + return this.customRecipes; + } + + public HashMap<ItemStack, ItemStack> getReplacedVanilla() { + return this.replacedVanilla; + } + + + @Deprecated + public void registerCustomRecipe(RecipeItem item) { + switch (item.getType()) { + case SHAPED_CRAFTING: + case FURNACE: + case SHAPELESS_CRAFTING: + //shaped / shapeless crafting doesnt work. + this.customRecipes.put(((CraftingRecipeItem) item).getRecipe().getResult(), item); + break; + case BREWING: + this.customRecipes.put(((BrewingRecipeItem) item).getResult(), item); + this.ingredients.add(((BrewingRecipeItem)item).getIngredient()); + break; + } + } + + public Optional<RecipeItem> getCraftingRecipe(ItemStack[] matrix) { + if (matrix == null) + return Optional.empty(); + return this.customRecipes.values().stream().filter(recipeItem -> { + if (!(recipeItem instanceof CraftingRecipeItem)) { + return false; + } + CraftingRecipeItem recipe = (CraftingRecipeItem) recipeItem; + return recipe.validate(matrix); + }).findFirst(); + } + + public List<Material> getBannedCraftingRecipes() { + return bannedCraftingRecipes; + } + + public HashSet<ItemStack> getPotionIngredients() { + return ingredients; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/Kit.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/Kit.java new file mode 100644 index 0000000..569df79 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/Kit.java @@ -0,0 +1,156 @@ +package net.grandtheftmc.vice.items; + +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.UserRank; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; +import java.util.List; + +public class Kit { + + private String name; + private double cost; + private int delay; + private List<KitItem> contents; + private KitItem helmet; + private KitItem chestPlate; + private KitItem leggings; + private KitItem boots; + private KitItem offHand; + + private String permission; + + public Kit(String name, double cost, int delay, List<KitItem> contents, KitItem helmet, KitItem chestPlate, + KitItem leggings, KitItem boots, KitItem offHand, String permission) { + this.name = name; + this.cost = cost; + this.delay = delay; + this.contents = contents; + this.helmet = helmet; + this.chestPlate = chestPlate; + this.leggings = leggings; + this.boots = boots; + this.offHand = offHand; + this.permission = permission; + } + + public List<ItemStack> getItems() { + List<ItemStack> items = new ArrayList<>(); + for (KitItem item : this.contents) { + GameItem g = item.getItem(); + if (g != null) { + ItemStack i = g.getItem(); + i.setAmount(item.getAmount()); + items.add(i); + } + } + return items; + + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public double getCost() { + return this.cost; + } + + public void setCost(double cost) { + this.cost = cost; + } + + public int getDelay() { + return this.delay; + } + + public void setDelay(int delay) { + this.delay = delay; + } + + public List<KitItem> getContents() { + return this.contents; + } + + public void setContents(List<KitItem> contents) { + this.contents = contents; + } + + public KitItem getHelmet() { + return this.helmet; + } + + public void setHelmet(KitItem helmet) { + this.helmet = helmet; + } + + public KitItem getChestPlate() { + return this.chestPlate; + } + + public void setChestPlate(KitItem chestPlate) { + this.chestPlate = chestPlate; + } + + public KitItem getLeggings() { + return this.leggings; + } + + public void setLeggings(KitItem leggings) { + this.leggings = leggings; + } + + public KitItem getBoots() { + return this.boots; + } + + public void setBoots(KitItem boots) { + this.boots = boots; + } + + public KitItem getOffHand() { + return this.offHand; + } + + public void setOffHand(KitItem offHand) { + this.offHand = offHand; + } + + public String getPermission() { + return this.permission; + } + + public void setPermission(String permission) { + this.permission = permission; + } + + public Material getMaterial() { + KitItem i = this.contents.get(0); + if (i == null) + return Material.STONE; + GameItem g = i.getItem(); + if (g == null) + return Material.STONE; + ItemStack it = g.getItem(); + if (it == null) + return Material.STONE; + return it.getType(); + } + + public String getDisplayName() { + UserRank rank = UserRank.getUserRankOrNull(this.name); + return Utils.f(rank == null ? "&e&l" + String.valueOf(this.name.charAt(0)).toUpperCase() + this.name.substring(1) + : rank.getColoredNameBold()); + } + + public boolean hasArmor() { + return this.helmet != null || this.chestPlate != null || this.leggings != null || this.boots != null; + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/KitCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/KitCommand.java new file mode 100644 index 0000000..b77d863 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/KitCommand.java @@ -0,0 +1,387 @@ +package net.grandtheftmc.vice.items; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.vice.Vice; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class KitCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (s instanceof Player && !s.hasPermission("command.kit")) { + MenuManager.openMenu((Player) s, "kits"); + return true; + } + if (args.length == 0) { + s.sendMessage(Utils.f("&c/kit add <name> <cost> <delay> [permission]")); + s.sendMessage(Utils.f("&c/kit setcost <name> <cost>")); + s.sendMessage(Utils.f("&c/kit setdelay <name> <delay>")); + s.sendMessage(Utils.f("&c/kit give <player> <kit>")); + s.sendMessage(Utils.f("&c/kit give [r=5] <kit> <x,y,z>")); + s.sendMessage(Utils.f("&c/kit setpermission <name> <permission/none>")); + s.sendMessage(Utils.f("&c/kit set <name>")); + s.sendMessage(Utils.f("&c/kit list [page]")); + s.sendMessage(Utils.f("&c/kit load")); + s.sendMessage(Utils.f("&c/kit save")); + return true; + } + ItemManager im = Vice.getItemManager(); + switch (args[0]) { + case "setcost": { + if (args.length < 3) { + s.sendMessage(Utils.f("&c/kit setcost <name> <cost>")); + return true; + } + String name = args[1]; + Kit kit = im.getKit(name); + if (kit == null) { + s.sendMessage(Lang.KITS.f("&7That kit does not exist!")); + return true; + } + double cost = 0; + try { + cost = Double.parseDouble(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Lang.KITS.f("&7The cost must be a number!")); + } + kit.setCost(cost); + s.sendMessage( + Lang.KITS.f("&7The cost of kit &a" + kit.getName() + "&7 has been set to &a$&l" + cost + "&7!")); + return true; + } + case "setdelay": { + if (args.length < 3) { + s.sendMessage(Utils.f("&c/kit setdelay <name> <delay>")); + return true; + } + String name = args[1]; + Kit kit = im.getKit(name); + if (kit == null) { + s.sendMessage(Lang.KITS.f("&7That kit does not exist!")); + return true; + } + int delay = 0; + try { + delay = Integer.parseInt(args[2]); + } catch (NumberFormatException e) { + s.sendMessage(Lang.KITS.f("&7The cost must be a number!")); + } + kit.setDelay(delay); + s.sendMessage( + Lang.KITS.f("&7The delay of kit &a" + kit.getName() + "&7 has been set to &a" + delay + "&7!")); + return true; + } + case "setpermission": { + if (args.length < 3) { + s.sendMessage(Utils.f("&c/kit setpermission <name> <permission/none>")); + return true; + } + String name = args[1]; + Kit kit = im.getKit(name); + if (kit == null) { + s.sendMessage(Lang.KITS.f("&7That kit does not exist!")); + return true; + } + kit.setPermission("none".equalsIgnoreCase(args[2]) ? null : args[2]); + s.sendMessage( + Lang.KITS.f("&7The delay of kit &a" + kit.getName() + "&7 has been set to &a" + args[2] + "&7!")); + return true; + } + case "set": { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + Player player = (Player)s; + if (args.length < 2) { + s.sendMessage(Utils.f("&c/kit set <name>")); + return true; + } + String name = args[1]; + Kit kit = im.getKit(name); + if (kit == null) { + s.sendMessage(Lang.KITS.f("&7That kit does not exist!")); + return true; + } + PlayerInventory inv = player.getInventory(); + List<KitItem> contents = new ArrayList<>(); + for (int i = 0; i <= 35; i++) { + ItemStack item = inv.getItem(i); + if (item == null || i == 16 || i == 17) + continue; + GameItem gameItem = im.getItem(item); + if (gameItem == null) { + s.sendMessage(Lang.KITS.f("&7The items in slot &a" + i + + "&7 of your inventory is not registered as a GameItem! Use &a/additem&7 or &a/addweapon&7 to add it!")); + return true; + } + contents.add(new KitItem(gameItem, item.getAmount())); + } + kit.setContents(contents); + if (inv.getHelmet() != null) { + GameItem item = im.getItem(inv.getHelmet()); + if (item == null) { + s.sendMessage(Lang.KITS.f( + "&7The items in your helmet slot is not registered as a GameItem! Use &a/additem&7 or &a/addweapon&7 to add it!")); + return true; + } + kit.setHelmet(new KitItem(item, inv.getHelmet().getAmount())); + } + if (inv.getChestplate() != null) { + GameItem item = im.getItem(inv.getChestplate()); + if (item == null) { + s.sendMessage(Lang.KITS.f( + "&7The items in your chestplate slot is not registered as a GameItem! Use &a/additem&7 or &a/addweapon&7 to add it!")); + return true; + } + kit.setChestPlate(new KitItem(item, inv.getChestplate().getAmount())); + } + if (inv.getLeggings() != null) { + GameItem item = im.getItem(inv.getLeggings()); + if (item == null) { + s.sendMessage(Lang.KITS.f( + "&7The items in your leggings slot is not registered as a GameItem! Use &a/additem&7 or &a/addweapon&7 to add it!")); + return true; + } + kit.setLeggings(new KitItem(item, inv.getLeggings().getAmount())); + } + if (inv.getBoots() != null) { + GameItem item = im.getItem(inv.getBoots()); + if (item == null) { + s.sendMessage(Lang.KITS.f( + "&7The items in your boots slot is not registered as a GameItem! Use &a/additem&7 or &a/addweapon&7 to add it!")); + return true; + } + kit.setBoots(new KitItem(item, inv.getBoots().getAmount())); + } + if (inv.getItemInOffHand() != null && inv.getItemInOffHand().getType() != Material.AIR) { + GameItem item = im.getItem(inv.getItemInOffHand()); + if (item == null) { + s.sendMessage(Lang.KITS.f( + "&7The items in your offhand items slot is not registered as a GameItem! Use &a/additem&7 or &a/addweapon&7 to add it!")); + return true; + } + kit.setOffHand(new KitItem(item, inv.getItemInOffHand().getAmount())); + } + s.sendMessage( + Lang.KITS.f("&7You set the contents, armor and offhand items for kit &a" + kit.getName() + "&7!")); + return true; + } + case "add": { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + Player player = (Player)s; + if (args.length < 4) { + s.sendMessage(Utils.f("&c/kit add <name> <cost> <delay> [permission]")); + return true; + } + String name = args[1]; + Kit kit = im.getKit(name); + if (kit != null) { + s.sendMessage(Lang.KITS.f("&7A kit with that names already exists!")); + return true; + } + double cost = 0; + int delay = 0; + try { + cost = Double.parseDouble(args[2]); + delay = Integer.parseInt(args[3]); + } catch (NumberFormatException e) { + s.sendMessage(Lang.KITS.f("&7The cost/delay must be a number!")); + } + String permission = args.length > 4 ? args[4] : null; + PlayerInventory inv = player.getInventory(); + List<KitItem> contents = new ArrayList<>(); + for (int i = 0; i <= 35; i++) { + ItemStack item = inv.getItem(i); + if (item == null || i == 16 || i == 17) + continue; + GameItem gameItem = im.getItem(item); + if (gameItem == null) { + s.sendMessage(Lang.KITS.f("&7The items in slot &a" + i + + "&7 of your inventory is not registered as a GameItem! Use &a/additem&7 or &a/addweapon&7 to add it!")); + return true; + } + contents.add(new KitItem(gameItem, item.getAmount())); + } + KitItem helmet = null; + KitItem chestPlate = null; + KitItem leggings = null; + KitItem boots = null; + KitItem offHand = null; + if (inv.getHelmet() != null) { + GameItem item = im.getItem(inv.getHelmet()); + if (item == null) { + s.sendMessage(Lang.KITS.f( + "&7The items in your helmet slot is not registered as a GameItem! Use &a/additem&7 or &a/addweapon&7 to add it!")); + return true; + } + helmet = new KitItem(item, inv.getHelmet().getAmount()); + } + if (inv.getChestplate() != null) { + GameItem item = im.getItem(inv.getChestplate()); + if (item == null) { + s.sendMessage(Lang.KITS.f( + "&7The items in your chestplate slot is not registered as a GameItem! Use &a/additem&7 or &a/addweapon&7 to add it!")); + return true; + } + chestPlate = new KitItem(item, inv.getChestplate().getAmount()); + } + if (inv.getLeggings() != null) { + GameItem item = im.getItem(inv.getLeggings()); + if (item == null) { + s.sendMessage(Lang.KITS.f( + "&7The items in your leggings slot is not registered as a GameItem! Use &a/additem&7 or &a/addweapon&7 to add it!")); + return true; + } + leggings = new KitItem(item, inv.getLeggings().getAmount()); + } + if (inv.getBoots() != null) { + GameItem item = im.getItem(inv.getBoots()); + if (item == null) { + s.sendMessage(Lang.KITS.f( + "&7The items in your boots slot is not registered as a GameItem! Use &a/additem&7 or &a/addweapon&7 to add it!")); + return true; + } + boots = new KitItem(item, inv.getBoots().getAmount()); + } + if (inv.getItemInOffHand() != null && inv.getItemInOffHand().getType() != Material.AIR) { + GameItem item = im.getItem(inv.getItemInOffHand()); + if (item == null) { + s.sendMessage(Lang.KITS.f( + "&7The items in your offhand items slot is not registered as a GameItem! Use &a/additem&7 or &a/addweapon&7 to add it!")); + return true; + } + offHand = new KitItem(item, inv.getItemInOffHand().getAmount()); + } + s.sendMessage(Lang.KITS.f("&7Your kit with name &a" + name + "&7 has been added!")); + im.addKit(new Kit(name, cost, delay, contents, helmet, chestPlate, leggings, boots, offHand, permission)); + return true; + } + case "list": + List<Kit> kits = Vice.getItemManager().getKits(); + int page = 1; + if (args.length > 1) { + try { + page = Integer.parseInt(args[1]); + } catch (NumberFormatException e) { + s.sendMessage(Lang.KITS.f("&cThe page must be a number!")); + return true; + } + } + if (page < 1) { + s.sendMessage(Lang.KITS.f("&7The page must be a positive number!")); + return true; + } + int pages = kits.size() / 6 + 1; + s.sendMessage(Utils.f( + " &7&m---------------&7[&a&l Kits &7Page &a" + page + "&7/&a" + pages + " &7&m]---------------")); + Iterator<Kit> it = kits.iterator(); + for (int i = 0; i < page * 6; i++) { + if (!it.hasNext()) + return true; + Kit kit = it.next(); + if (i < page * 6 - 6) + continue; + s.sendMessage(Utils + .f(kit.getDisplayName() + "&7 | Cost: &a$&l" + kit.getCost() + "&7 Delay: &a&l" + kit.getDelay() + + (kit.getPermission() == null ? "" : "&7 Permission: &a" + kit.getPermission()))); + } + return true; + case "load": + Vice.getSettings().setKitsConfig(Utils.loadConfig("kits")); + Vice.getItemManager().loadKits(); + s.sendMessage(Lang.KITS.f("&7Loaded Kits!")); + return true; + case "save": + Vice.getItemManager().saveKits(); + s.sendMessage(Lang.KITS.f("&7Saved Kits!")); + return true; + case "give": + if (args.length != 3) { + if(args[1].contains("[r=")) { + Kit kit = im.getKit(args[2]); + if (kit == null) { + s.sendMessage(Lang.KITS.f("&7That kit does not exist!")); + return true; + } + Location point = new Location(Bukkit.getWorld("minesantos"), 0, 0, 0); + int radius; + try { + String[] test = args[1].split("="); + radius = Integer.valueOf(test[1].replace("]", "")); + if(args.length == 4) { + String[] cords = args[3].split(","); + point.setX(Integer.valueOf(cords[0])); + point.setY(Integer.valueOf(cords[1])); + point.setZ(Integer.valueOf(cords[2])); + } else { + s.sendMessage(Utils.f("Error in your syntax")); + s.sendMessage(Utils.f("Example: /kit give [r=5] hobo x,y,z")); + return true; + } + } catch (Exception exception) { + s.sendMessage(Utils.f("Error in your syntax")); + return true; + } + for(LivingEntity entity : point.getWorld().getLivingEntities()) { + if(entity.getLocation().distance(point) > radius) continue; + if(entity.getType() == EntityType.PLAYER) { + Player target = (Player)entity; + im.giveKitItems(target, Vice.getUserManager().getLoadedUser(target.getUniqueId()), kit); + } + } + return true; + } else { + s.sendMessage(Utils.f("&c/kit give <player> <kit>")); + return true; + } + } + String name = args[2]; + Kit kit = im.getKit(name); + if (kit == null) { + s.sendMessage(Lang.KITS.f("&7That kit does not exist!")); + return true; + } + Player target = Bukkit.getPlayer(args[1]); + if(target == null) { + s.sendMessage(Lang.KITS.f("&7Player not found")); + return false; + } + im.giveKitItems(target, Vice.getUserManager().getLoadedUser(target.getUniqueId()), kit); + s.sendMessage(Lang.KITS.f("&7Kit " + kit.getDisplayName() + " &7has been given to " + target.getDisplayName())); + return true; + default: + s.sendMessage(Utils.f("&c/kit add <name> <cost> <delay> [permission]")); + s.sendMessage(Utils.f("&c/kit setcost <name> <cost>")); + s.sendMessage(Utils.f("&c/kit setdelay <name> <delay>")); + s.sendMessage(Utils.f("&c/kit give <player> <kit>")); + s.sendMessage(Utils.f("&c/kit give [r=5] <kit> <x,y,z>")); + s.sendMessage(Utils.f("&c/kit setpermission <name> <permission/none>")); + s.sendMessage(Utils.f("&c/kit set <name>")); + s.sendMessage(Utils.f("&c/kit list [page]")); + s.sendMessage(Utils.f("&c/kit load")); + s.sendMessage(Utils.f("&c/kit save")); + return true; + } + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/KitItem.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/KitItem.java new file mode 100644 index 0000000..6114f43 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/KitItem.java @@ -0,0 +1,45 @@ +package net.grandtheftmc.vice.items; + +import net.grandtheftmc.core.util.Utils; + +public class KitItem { + + private final GameItem item; + private int amount; + + public KitItem(GameItem item) { + this.item = item; + this.amount = 1; + } + + public KitItem(GameItem item, int amount) { + this.item = item; + this.amount = amount; + } + + public GameItem getItem() { + return this.item; + } + + public GameItem getGameItem() { + return this.item; + } + + public String getDescription() { + try { + return (this.amount > 1 ? "&7" + this.amount + "x " : "") + this.item == null ? "ERROR!!!" : this.item.getDisplayName(); + } catch (Exception e) { + Utils.b("amnt " + this.amount); + Utils.b("item " + this.item == null ? null : this.item.getName()); + return "ERROR!!! dsqd"; + } + } + + public int getAmount() { + return this.amount; + } + + public void setAmount(int amount) { + this.amount = amount; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/Schedule.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/Schedule.java new file mode 100644 index 0000000..90aecf1 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/Schedule.java @@ -0,0 +1,51 @@ +package net.grandtheftmc.vice.items; + +import net.grandtheftmc.core.util.Utils; + +public enum Schedule { + + // IF YOU CHANGE THE DISPLAY NAMES, THE OLD DISPLAY NAMES WILL STILL BE IN THE LORE OF OLD ITEMS AND THE NEW ONE WILL BE ADDED AS WELL! its fucky but whatevz + I("&cSchedule I", 1, 3.0, "magicmushroomred", "magicmushroombrown", "mdma", "lsd", "weed", "marijuanaflower", "joint", "potbrownie", "heroin", "heroinsyringe"), + II("&cSchedule II", 2, 2.0, "meth", "methbaggy", "cocaine", "opium"), + III("&cSchedule III", 3, 1.0, "steroids", "vodka", "alcohol"), + IV("&eSchedule IV", 4, 0.75), + V("&eSchedule V", 5, 0.5), + LIST_II("&eList II", 6, 0.5, "ergotfungi", "safrole", "ephedrasinica", "cocaleaves", "cocaseeds"), + LIST_I("&eList I", 7, 0.25, "opiumpoppies", "ephedrasinicaseeds", "ocoteacymbarum"), + NONE("", -1, 0);//"hop", "hopplant", "potato" + + private final String disp; + private final int priority; + private final double jailMultiplier; + private final String[] substances; + + Schedule(String disp, int priority, double jailMultiplier, String... substances) { + this.disp = Utils.f(disp); + this.priority = priority; + this.jailMultiplier = jailMultiplier; + this.substances = substances; + } + + public String getDisp() { + return this.disp; + } + + public int getPriority() { + return this.priority; + } + + public double getJailMultiplier() { + return this.jailMultiplier; + } + + public String[] getSubstances() { + return this.substances; + } + + public static Schedule of(String name) { + for (Schedule schedule : Schedule.values()) + for (String s : schedule.substances) + if (s.equalsIgnoreCase(name)) return schedule; + return Schedule.NONE; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/ShopCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/ShopCommand.java new file mode 100644 index 0000000..8f7e91a --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/ShopCommand.java @@ -0,0 +1,48 @@ +package net.grandtheftmc.vice.items; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class ShopCommand implements CommandExecutor { + + + @Override + public boolean onCommand(CommandSender s, Command c, String l, String[] args) { + if (!s.hasPermission("command.shop")) { + s.sendMessage(Lang.NOPERM.s()); + return true; + } + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + if (args.length == 0) { + s.sendMessage(Utils.f("&c/shop armorupgrade <armorupgrade>")); + s.sendMessage(Utils.f("&c/shop <items> <amount> <price>")); + return true; + } + switch (args[0].toLowerCase()) { + case "armorupgrade": + if (args.length != 2) { + s.sendMessage(Utils.f("&c/shop armorupgrade <armorupgrade>")); + return true; + } + Vice.getShopManager().addArmorUpgradeShop((Player) s, args[1]); + return true; + default: + if (args.length != 3) { + s.sendMessage(Utils.f("&c/shop <items> <amount> <price>")); + } + Vice.getShopManager().addShop((Player) s, args[0], Integer.parseInt(args[1]), Double.parseDouble(args[2])); + return true; + } + + } + +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/ShopManager.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/ShopManager.java new file mode 100644 index 0000000..4fed985 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/ShopManager.java @@ -0,0 +1,291 @@ +package net.grandtheftmc.vice.items; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.users.ViceUser; +import net.grandtheftmc.vice.users.LockedWeapon; +import net.grandtheftmc.vice.users.ViceUserDAO; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.scheduler.BukkitRunnable; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; +import java.util.stream.Collectors; + +public class ShopManager { + + public ShopManager() { + this.load(); + this.startSchedule(); + } + + + private List<Head> heads = new ArrayList<>(); + + private void load() { + new BukkitRunnable() { + @Override + public void run() { + List<Head> heads = ViceUserDAO.getHeads(); +// try (ResultSet rs = Core.sql.query("select * from " + Core.name() + "_heads;")) { +// while (rs.next()) { +// UUID sellerUUID = null; +// UUID bidderUUID = null; +// try { +// sellerUUID = rs.getString("sellerUUID") == null ? null : UUID.fromString(rs.getString("sellerUUID")); +// bidderUUID = rs.getString("bidderUUID") == null ? null : UUID.fromString(rs.getString("bidderUUID")); +// } catch (Exception ignored) { +// } +// heads.add(new Head(sellerUUID, rs.getString("sellerName"), +// rs.getString("head"), rs.getLong("expiry"), rs.getBoolean("done"), rs.getBoolean("paid"), rs.getBoolean("gaveHead"), bidderUUID, +// rs.getString("bidderName"), rs.getDouble("bid"))); +// } +// rs.close(); +// } catch (SQLException e) { +// e.printStackTrace(); +// } + + new BukkitRunnable() { + @Override + public void run() { + Vice.getShopManager().setHeads(heads); + } + }.runTask(Vice.getInstance()); + } + }.runTaskAsynchronously(Vice.getInstance()); + } + + private void startSchedule() { + new BukkitRunnable() { + @Override + public void run() { + new ArrayList<>(Vice.getShopManager().getHeads()).forEach(Head::update); + } + }.runTaskTimer(Vice.getInstance(), 200L, 200L); + } + + + public void setHeads(List<Head> list) { + this.heads = list; + } + + public List<Head> getHeads() { + return this.heads; + } + + public void removeHead(Head head) { + this.heads.remove(head); + } + + public List<Head> getNonExpiredHeads() { + return this.heads.stream().filter(h -> !h.hasExpired()).collect(Collectors.toList()); + } + + public Set<Head> getNonExpiredHeadsByBid() { + HashMap<Head, Double> unsortMap = new HashMap<>(); + this.heads.stream().filter(h -> !h.hasExpired()).collect(Collectors.toList()).forEach(h -> unsortMap.put(h, h.getBid())); + return sort(unsortMap).keySet(); + } + + public static Map<Head, Double> sort(Map<Head, Double> unsortMap) { + List<Map.Entry<Head, Double>> list = new LinkedList<>(unsortMap.entrySet()); + list.sort(Comparator.comparing(obj -> obj.getValue())); + Map<Head, Double> sortedMap = new LinkedHashMap<>(); + for (Map.Entry<Head, Double> entry : list) { + sortedMap.put(entry.getKey(), entry.getValue()); + } + return sortedMap; + } + + public Head getHead(String head) { + return this.heads.stream().filter(h -> h.getHead().equalsIgnoreCase(head)).findFirst().orElse(null); + } + + public Head getHead(String head, long expiry) { + return this.heads.stream().filter(h -> h.getHead().equalsIgnoreCase(head) && h.getExpiry() == expiry).findFirst().orElse(null); + } + + public Head auctionHead(Player seller, ViceUser user) { + ItemStack item = seller.getInventory().getItemInMainHand(); + if (item == null || item.getType() != Material.SKULL_ITEM || item.getDurability() != 3) { + seller.sendMessage(Lang.HEAD_AUCTION.f("&7That's not a player head!")); + return null; + } + if (item.getAmount() > 1) { + seller.sendMessage(Lang.HEAD_AUCTION.f("&7Please sell auction head at a time!")); + return null; + } + SkullMeta meta = (SkullMeta) item.getItemMeta(); + if (meta.getOwner() == null) { + seller.sendMessage(Lang.HEAD_AUCTION.f("&7That's not a player head!")); + return null; + } + Head head = new Head(seller.getUniqueId(), seller.getName(), meta.getOwner()); + this.heads.add(head); + seller.sendMessage(Lang.HEAD_AUCTION.f("&7You received &a$&l10,000&7 for putting up &e&l" + head.getHead() + "'s Head&7 for auction.")); + user.addMoney(10000); + ViceUtils.updateBoard(seller, user); + seller.getInventory().setItemInMainHand(null); + return head; + } + + public void buy(Player player, ItemStack i) { + if (i == null || !i.hasItemMeta() || !i.getItemMeta().hasDisplayName()) + return; + String disp = ChatColor.stripColor(i.getItemMeta().getDisplayName()).toLowerCase(); + if (!disp.contains("buy: $")) + return; + disp = disp.replace("buy: $", ""); + String[] array = disp.split(" "); + if (array.length == 1) + return; + int amount = 1; + double buyPrice; + boolean hasAmount = array[0].endsWith("x"); + StringBuilder itemName = new StringBuilder(array[hasAmount ? 1 : 0]); + for (int n = hasAmount ? 2 : 1; n < (array.length - 1); n++) + itemName.append(' ').append(array[n]); + try { + if (hasAmount) + amount = Integer.parseInt(array[0].replaceAll("x", "")); + buyPrice = Double.parseDouble(array[array.length - 1]); + } catch (NumberFormatException e) { + for (String anArray : array) player.sendMessage(anArray); + player.sendMessage(Utils.f(Lang.SHOP + + "&cThere was an error while parsing the prices for this shop. Please contact a staff member.")); + return; + } + GameItem item = Vice.getItemManager().getItemFromDisplayName(itemName.toString()); + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + if (user.isArrested()) { + player.sendMessage(Lang.JAIL.f("&7You can't buy items in jail!")); + return; + } + if(item==null) + return; + if (item.getType() == GameItem.ItemType.WEAPON) { + LockedWeapon l = LockedWeapon.getWeapon(item.getWeaponOrVehicleOrDrug()); + if (l != null && !l.canUseWeapon(user.getRank(), Core.getUserManager().getLoadedUser(player.getUniqueId()).getUserRank())) { + player.sendMessage(Lang.HEY.f("&7You need to rank up to " + l.getViceRank().getColoredNameBold() + "&7 or donate for " + l.getUserRank().getColoredNameBold() + "&7 at &a&lstore.grandtheftmc.net&7 to use the " + item.getDisplayName() + "&7!")); + return; + } + } else if (item.getType() == GameItem.ItemType.ARMOR_UPGRADE) { + player.sendMessage(Lang.HEY.f("&7There is an error with this shop. Please contact an administrator.")); + return; + } + if (user.hasMoney(buyPrice)) { + user.takeMoney(buyPrice); + } else { + + player.sendMessage(Lang.MONEY.f("&7You do not have enough money!")); + return; + + } + ViceUtils.updateBoard(player, Core.getUserManager().getLoadedUser(player.getUniqueId()), user); + switch (item.getType()) { + case VEHICLE: + user.setActionVehicle(item.getWeaponOrVehicleOrDrug()); + MenuManager.openMenu(player, "vehicleshop"); + return; + case AMMO: + AmmoType type = item.getAmmoType(); + if (type != null) + user.addAmmo(type, amount); + player.sendMessage(Lang.SHOP.f("&7You bought " + (amount > 1 ? "&a&l" + amount + "&7x " : "") + + item.getDisplayName() + "&7 for &a$&l" + buyPrice + "&7!")); + return; + case WEAPON: + case ITEMSTACK: + ItemStack stack = item.getItem(); + stack.setAmount(amount); + Utils.giveItems(player, stack); + player.sendMessage(Lang.SHOP.f("&7You bought " + (amount > 1 ? "&a&l" + amount + "&7x " : "") + + item.getDisplayName() + "&7 for &a$&l" + buyPrice + "&7!")); + break; + default: + break; + } + } + + public void buyArmorUpgrade(Player player, String disp) { + disp = disp.toLowerCase(); + disp = ChatColor.stripColor(disp); + ArmorUpgrade upgrade = ArmorUpgrade.getArmorUpgradeFromDisplayName(disp.split(" upgrade")[0]); + if (upgrade == null) return; + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + if (!upgrade.canUseUpgrade(user.getRank(), Core.getUserManager().getLoadedUser(player.getUniqueId()).getUserRank())) { + player.sendMessage(Lang.HEY.f("&7You need to rank up to " + upgrade.getViceRank().getColoredNameBold() + "&7 or donate for " + upgrade.getUserRank().getColoredNameBold() + "&7 at &a&lstore.grandtheftmc.net&7 to use the &b&l" + upgrade.getDisplayName() + " Armor Upgrade&7!")); + return; + } + ItemStack item = player.getInventory().getItemInMainHand(); + GameItem gameItem = item == null ? null : Vice.getItemManager().getItem(item.getType()); + if (item == null || gameItem == null || !upgrade.canBeUsedOn(gameItem.getName())) { + player.sendMessage(Lang.HEY.f("&7The &b&l" + upgrade.getDisplayName() + " Armor Upgrade&7 can be applied to the following types of items: " + upgrade.getTypesString() + "&7!")); + return; + } + for (Enchantment e : item.getEnchantments().keySet()) + Utils.b(e.getName()); + if (ArmorUpgrade.getArmorUpgrades(item).contains(upgrade)) { + player.sendMessage(Lang.ARMOR_UPGRADE.f("&7That piece of armor already has the &b&l" + upgrade.getDisplayName() + " Armor Upgrade&7!")); + return; + } + if (!user.hasMoney(upgrade.getPrice())) { + player.sendMessage(Lang.ARMOR_UPGRADE.f("&7You can't afford the &b&l" + upgrade.getDisplayName() + " Armor Upgrade&7!")); + return; + } + user.setBuyingArmorUpgrade(upgrade); + MenuManager.openMenu(player, "armorupgrade"); + } + + public void addShop(Player player, String itemName, int amount, double buyPrice) { + GameItem item = Vice.getItemManager().getItem(itemName); + if (item == null) { + player.sendMessage(Lang.SHOP.f("&cThat items does not exist!")); + return; + } + if (buyPrice < 0) { + player.sendMessage(Lang.SHOP.f("&7The price must be 0 or higher!")); + return; + } + ItemStack i = item.getItem().clone(); + ItemMeta meta = i.getItemMeta(); + meta.setDisplayName(Utils.f("&a&l" + amount + "&7x " + item.getDisplayName() + " &a&lBUY&f: &a$&l" + buyPrice)); + i.setItemMeta(meta); + i.setAmount(1); + player.getInventory().addItem(i); + player.sendMessage(Lang.SHOP.f("&7Please add the items into an itemframe to create a shop!")); + } + + public void addArmorUpgradeShop(Player player, String name) { + ArmorUpgrade armorUpgrade = ArmorUpgrade.getArmorUpgrade(name); + if (armorUpgrade == null) { + player.sendMessage(Lang.SHOP.f("&cThat armor upgrade does not exist!")); + return; + } + GameItem item = Vice.getItemManager().getItem(armorUpgrade); + if (item == null) { + player.sendMessage(Lang.SHOP.f("&cThat game items does not exist!")); + return; + } + ItemStack i = item.getItem().clone(); + ItemMeta meta = i.getItemMeta(); + meta.setDisplayName(Utils.f("&b&lArmor Upgrade: &a&l" + armorUpgrade.getDisplayName())); + i.setItemMeta(meta); + i.setAmount(1); + player.getInventory().addItem(i); + player.sendMessage(Lang.SHOP.f("&7Please add the items into an itemframe to create a shop!")); + } + + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/recipes/BottleCraftingRecipe.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/recipes/BottleCraftingRecipe.java new file mode 100644 index 0000000..c2631b7 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/recipes/BottleCraftingRecipe.java @@ -0,0 +1,24 @@ +package net.grandtheftmc.vice.items.recipes; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.items.recipetypes.OtherRecipeItem; +import net.grandtheftmc.vice.items.recipetypes.RecipeType; +import org.bukkit.Material; +import org.bukkit.inventory.FurnaceRecipe; +import org.bukkit.inventory.ItemStack; + +/** + * Created by Timothy Lampen on 2017-08-09. + */ +public class BottleCraftingRecipe extends OtherRecipeItem { + public BottleCraftingRecipe() { + super(RecipeType.FURNACE); + } + + @Override + protected void register() { + FurnaceRecipe hopPlantToHop = new FurnaceRecipe(new ItemStack(Material.GLASS_BOTTLE), Material.GLASS); + setRecipe(hopPlantToHop); + addIngredient(new ItemStack(Material.GLASS), 1); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/recipetypes/BrewingRecipeItem.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/recipetypes/BrewingRecipeItem.java new file mode 100644 index 0000000..bd93c06 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/recipetypes/BrewingRecipeItem.java @@ -0,0 +1,66 @@ +package net.grandtheftmc.vice.items.recipetypes; + +import net.grandtheftmc.vice.items.recipetypes.RecipeItem; +import net.grandtheftmc.vice.items.recipetypes.RecipeType; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.PotionMeta; +import org.bukkit.potion.PotionData; + +/** + * Created by Timothy Lampen on 7/11/2017. + */ +public abstract class BrewingRecipeItem extends RecipeItem { + + private ItemStack ingredient; + private ItemStack result; + private ItemStack child; + private String name; + + + public BrewingRecipeItem() { + super(RecipeType.BREWING); + } + + + public RecipeType getType() { + return RecipeType.BREWING; + } + + /** + * @param isActualPotion if the item is an actual Material potion + * @apiNote finalizeSetup() MUST be done after super() call in the item classes + */ + public void finalizeSetup(ItemStack result, String baseName, ItemStack ingredient, ItemStack child, boolean isActualPotion) { + this.result = result; + this.name = isActualPotion ? constructPotionName(result.getType(), baseName, ((PotionMeta)result.getItemMeta()).getBasePotionData()) : baseName; + this.ingredient = ingredient; + this.child = child; + } + + public ItemStack getIngredient() { + return ingredient; + } + + public ItemStack getChild() { + return child; + } + + + + public ItemStack getResult() { + return result; + } + + private String constructPotionName(Material mat, String baseName, PotionData data){ + String name = data.isExtended() ? "Extended " : " "; + name += mat==Material.SPLASH_POTION ? "Splash" : ""; + name += " Potion of " + baseName; + name += data.isUpgraded() ? " II" : ""; + return name; + } + + public String getName() { + return name; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/recipetypes/CraftingRecipeItem.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/recipetypes/CraftingRecipeItem.java new file mode 100644 index 0000000..95e3987 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/recipetypes/CraftingRecipeItem.java @@ -0,0 +1,32 @@ +package net.grandtheftmc.vice.items.recipetypes; + +import net.grandtheftmc.vice.Vice; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.inventory.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Created by Timothy Lampen on 7/10/2017. + */ +public abstract class CraftingRecipeItem extends RecipeItem{ + + protected Recipe recipe = null; + + public CraftingRecipeItem(RecipeType type){ + super(type); + register(); + } + + public Recipe getRecipe() { + return this.recipe; + } + + protected abstract void register(); + + public abstract boolean validate(ItemStack[] matrix); + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/recipetypes/OtherRecipeItem.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/recipetypes/OtherRecipeItem.java new file mode 100644 index 0000000..8db1400 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/recipetypes/OtherRecipeItem.java @@ -0,0 +1,66 @@ +package net.grandtheftmc.vice.items.recipetypes; + +import net.grandtheftmc.vice.Vice; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.inventory.*; + +import java.util.*; + +/** + * Created by Timothy Lampen on 2017-08-06. + */ +public abstract class OtherRecipeItem extends CraftingRecipeItem{ + private HashMap<ItemStack, Integer> ingredients; + public OtherRecipeItem(RecipeType type) { + super(type); + } + //This integrated validate method should only be used for shapeless and furnace recipes, NOT for shaped. + //this also assumes that the correct amount of each items is present. + public boolean validate(ItemStack[] matrix){ + if(ingredients.size()==0) + return false; + switch (this.getType()){ + case FURNACE: + return matrix.length==1 && ingredients.keySet().stream().anyMatch(itemStack -> itemStack.isSimilar(matrix[0])); + case SHAPELESS_CRAFTING: { + HashMap<ItemStack, Integer> ingredientsCopy = (HashMap<ItemStack, Integer>) this.ingredients.clone(); + for (ItemStack is : matrix) { + if(is==null || is.getType()== Material.AIR){ + continue; + } + ItemStack compareable = is.clone(); + compareable.setAmount(1); + if(ingredientsCopy.containsKey(compareable)){ + ingredientsCopy.put(compareable, ingredientsCopy.get(compareable)-1); + } + } + return ingredientsCopy.values().stream().allMatch(integer -> integer==0); + } + } + return false; + } + + protected void setRecipe(Recipe r){ + this.recipe = r; + if(getType()==RecipeType.FURNACE){ + Bukkit.addRecipe(r); + } + } + protected void addIngredient(ItemStack is, int amount){ + if(this.ingredients==null) + this.ingredients = new HashMap<>(); + switch (this.getType()){ + case SHAPELESS_CRAFTING: + ingredients.put(is, amount); + ((ShapelessRecipe)this.recipe).addIngredient(amount, is.getData()); + case FURNACE: { + ingredients.put(is, amount); + } + } + } + + public HashMap<ItemStack, Integer> getIngredients() { + return ingredients; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/recipetypes/RecipeItem.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/recipetypes/RecipeItem.java new file mode 100644 index 0000000..6b9f6f4 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/recipetypes/RecipeItem.java @@ -0,0 +1,17 @@ +package net.grandtheftmc.vice.items.recipetypes; + +/** + * Created by Timothy Lampen on 7/15/2017. + */ +public abstract class RecipeItem { + + private RecipeType type; + + public RecipeItem(RecipeType type){ + this.type = type; + } + + public RecipeType getType() { + return type; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/recipetypes/RecipeType.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/recipetypes/RecipeType.java new file mode 100644 index 0000000..c33ba95 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/recipetypes/RecipeType.java @@ -0,0 +1,8 @@ +package net.grandtheftmc.vice.items.recipetypes; + +/** + * Created by Timothy Lampen on 7/10/2017. + */ +public enum RecipeType { + SHAPELESS_CRAFTING, SHAPED_CRAFTING, FURNACE, BREWING +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/recipetypes/ShapedRecipeItem.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/recipetypes/ShapedRecipeItem.java new file mode 100644 index 0000000..6cd880b --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/recipetypes/ShapedRecipeItem.java @@ -0,0 +1,55 @@ +package net.grandtheftmc.vice.items.recipetypes; + +import net.grandtheftmc.vice.Vice; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.Recipe; +import org.bukkit.inventory.ShapedRecipe; + +import java.util.HashMap; + +/** + * Created by Timothy Lampen on 2017-08-06. + */ +public abstract class ShapedRecipeItem extends CraftingRecipeItem { + + private HashMap<Character, ItemStack> ingredients = new HashMap<>(); + + public ShapedRecipeItem() { + super(RecipeType.SHAPED_CRAFTING); + register(); + } + + public Recipe getRecipe() { + return this.recipe; + } + + public boolean validate(ItemStack[] matrix){ + ShapedRecipe sRecipe = (ShapedRecipe)recipe; + int pos; + for(int i = 0; i<sRecipe.getShape().length; i++){ + String line = sRecipe.getShape()[i]; + pos = i*3; + for(char id : line.toCharArray()){ + ItemStack compare = this.ingredients.get(id); + if(!compare.isSimilar(matrix[pos])) { + return false; + } + pos++; + } + } + return true; + } + + protected void setRecipe(ShapedRecipe r, SlotContainer... ingredients){ + this.ingredients = new HashMap<>(); + this.recipe = r; + for(SlotContainer container : ingredients){ + this.ingredients.put(container.getId(), container.getItemStack()); + } + } + + public HashMap<Character, ItemStack> getIngredients() { + return ingredients; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/recipetypes/SlotContainer.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/recipetypes/SlotContainer.java new file mode 100644 index 0000000..befd53e --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/items/recipetypes/SlotContainer.java @@ -0,0 +1,24 @@ +package net.grandtheftmc.vice.items.recipetypes; + +import org.bukkit.inventory.ItemStack; + +/** + * Created by Timothy Lampen on 2017-08-06. + */ +public class SlotContainer { + private char id; + private ItemStack is; + + public SlotContainer(char id, ItemStack is){ + this.id = id; + this.is = is; + } + + public char getId() { + return id; + } + + public ItemStack getItemStack() { + return is; + } +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/ArmorEquip.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/ArmorEquip.java new file mode 100644 index 0000000..6490211 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/ArmorEquip.java @@ -0,0 +1,30 @@ +package net.grandtheftmc.vice.listeners; + + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.events.EquipArmorType; +import net.grandtheftmc.vice.items.ArmorUpgrade; +import net.grandtheftmc.vice.events.ArmorEquipEvent; +import org.bukkit.attribute.Attribute; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; + +/** + * Created by Timothy Lampen on 7/6/2017. + */ +public class ArmorEquip implements Listener { + + @EventHandler + public void onArmorEquip(ArmorEquipEvent event) { + Player player = event.getPlayer(); + ArmorUpgrade.reloadArmorUpgrades(player); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/BlockDispense.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/BlockDispense.java new file mode 100644 index 0000000..d390eae --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/BlockDispense.java @@ -0,0 +1,23 @@ +package net.grandtheftmc.vice.listeners; + +import net.grandtheftmc.vice.Vice; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockDispenseEvent; + +/** + * Created by Timothy Lampen on 3/10/2018. + */ +public class BlockDispense implements Listener { + + @EventHandler + public void onDispense(BlockDispenseEvent event) { + Block b = event.getBlock(); + if(b.getType()== Material.DROPPER) { + if(Vice.getInstance().getMachineManager().getMachineByLocation(b.getLocation()).isPresent()) + event.setCancelled(true); + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/BlockPlace.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/BlockPlace.java new file mode 100644 index 0000000..8259c9b --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/BlockPlace.java @@ -0,0 +1,47 @@ +package net.grandtheftmc.vice.listeners; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.Utils; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.CreatureSpawner; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.inventory.ItemStack; + +/** + * Created by Timothy Lampen on 2017-08-09. + */ +public class BlockPlace implements Listener { + + @EventHandler + public void onPlace(BlockPlaceEvent event){ + Block b = event.getBlockPlaced(); + Player player = event.getPlayer(); + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + switch (b.getType()) { + case MOB_SPAWNER: { + ItemStack hand = event.getItemInHand(); + if(hand.hasItemMeta() && hand.getItemMeta().hasDisplayName()) { + EntityType type = EntityType.valueOf(ChatColor.stripColor(hand.getItemMeta().getDisplayName()).toUpperCase().replace(" SPAWNER", "").replace(" ", "_")); + CreatureSpawner spawner = (CreatureSpawner)b.getState(); + spawner.setSpawnedType(type); + spawner.update(); + } + } + } + + ItemStack item = event.getItemInHand(); + + if (item != null && item.getType() == Material.CHEST) { + if (item.getItemMeta() != null && item.getItemMeta().getDisplayName() != null && item.getItemMeta().getDisplayName().equals(Utils.f("&6&lBackpack"))) { + event.setCancelled(true); + } + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/BreakBlock.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/BreakBlock.java new file mode 100644 index 0000000..6508bfb --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/BreakBlock.java @@ -0,0 +1,62 @@ +package net.grandtheftmc.vice.listeners; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.State; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.CheatCode; +import net.grandtheftmc.vice.users.ViceUser; +import net.grandtheftmc.vice.utils.StringUtils; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.CreatureSpawner; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; +import net.grandtheftmc.vice.world.obsidianbreaker.BlockStatus; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +public class BreakBlock implements Listener{ + + @EventHandler(ignoreCancelled = true) + public void onBreak(BlockBreakEvent event) { + Block block = event.getBlock(); + Player player = event.getPlayer(); + switch (block.getType()) { + case CHEST: + if (Vice.getCrateManager().getCrate(block.getLocation()) == null) return; + event.setCancelled(true); + player.sendMessage(Lang.LOOTCRATES.f("&7You can't break this Loot Crate!")); + break; + case MOB_SPAWNER: { + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + if(user.getCheatCodeState(CheatCode.SILKSPAWNERS).getState()== State.ON) { + ItemStack hand = player.getInventory().getItemInMainHand(); + if(hand!=null && hand.containsEnchantment(Enchantment.SILK_TOUCH)){ + CreatureSpawner spawner = (CreatureSpawner)block.getState(); + ItemStack is = new ItemStack(Material.MOB_SPAWNER); + ItemMeta im = is.getItemMeta(); + im.setDisplayName(ChatColor.YELLOW + StringUtils.getCapitalized(spawner.getSpawnedType().toString().toLowerCase().replace("_", " ")) + ChatColor.GRAY + " spawner"); + is.setItemMeta(im); + player.getWorld().dropItemNaturally(block.getLocation(), is); + event.setExpToDrop(0); + } + } + } + default: + break; + } + if(!event.isCancelled()){ + BlockStatus status = Vice.getWorldManager().getObsidianManager().getDamageStorage().getBlockStatus(block, false); + if(status!=null){ + Vice.getWorldManager().getObsidianManager().getDamageStorage().removeBlockStatus(status); + Vice.getWorldManager().getObsidianManager().getNMSHandler().sendCrackEffect(block.getLocation(), -1); + } + + + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/CartelsComponent.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/CartelsComponent.java new file mode 100644 index 0000000..15ddfe7 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/CartelsComponent.java @@ -0,0 +1,62 @@ +package net.grandtheftmc.vice.listeners; + +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.Component; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.hologram.CoreHologram; +import net.grandtheftmc.vice.hologram.CoreHologramNode; +import net.grandtheftmc.vice.hologram.event.HologramReceiveEvent; +import net.grandtheftmc.vice.hologram.exception.HologramDuplicateNodeException; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.event.EventHandler; + +/** + * Created by Luke Bingham on 03/08/2017. + */ +public class CartelsComponent implements Component<CartelsComponent, Vice> { + +// private final Vice vice; +// private final TagManager<Vice> tagManager; +// +// public CartelsComponent(Vice vice, TagManager<Vice> tagManager) { +// this.vice = vice; +// this.tagManager = tagManager; +// Bukkit.getPluginManager().registerEvents(this, vice); +// } +// +// @EventHandler(priority = EventPriority.MONITOR) +// protected final void onCartelCreate(FactionCreateEvent event) { +// if(event.isCancelled()) return; +// Player player = event.getFPlayer().getPlayer(); +// +// Nametag nametag = tagManager.getPlayerNametag(player); +// if(nametag == null) return; +// +// Tag tag = tagManager.getTagByUid(player, 3); +// if(tag == null) { +// Tag parent = nametag.getTag(2).orElse(null); +// if(parent == null) return; +// tagManager.createTag(NMSVersion.MC_1_12, player, 3, event.getFactionTag(), parent); +// } +// else { +// tagManager.changeTag(player, 3, event.getFactionTag()); +// } +// +// tagManager.refreshAll(player); +// } +// +// @EventHandler(priority = EventPriority.MONITOR) +// protected final void onCartelTagChange(FactionRenameEvent event) { +// if(event.isCancelled()) return; +// Player player = event.getfPlayer().getPlayer(); +// +// Nametag nametag = tagManager.getPlayerNametag(player); +// if(nametag == null) return; +// +// Tag tag = tagManager.getTagByUid(player, 3); +// if(tag != null) nametag.delete(player, tag); +// +// this.tagManager.refreshAll(player); +// } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/ChangeWorld.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/ChangeWorld.java new file mode 100644 index 0000000..69590c6 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/ChangeWorld.java @@ -0,0 +1,31 @@ +package net.grandtheftmc.vice.listeners; + +import net.grandtheftmc.vice.Vice; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerChangedWorldEvent; +import org.bukkit.potion.PotionEffectType; + +import java.util.Objects; + +public class ChangeWorld implements Listener { + + @EventHandler + public void onSwitch(PlayerChangedWorldEvent e) { + Player player = e.getPlayer(); + if (Objects.equals(player.getWorld(), Vice.getWorldManager().getWarpManager().getSpawn().getLocation().getWorld())) { + player.setHealth(player.getMaxHealth()); + player.setFireTicks(0); + Vice.getDrugManager().getEffectManager().cancelEffects(player); + } else { + player.removePotionEffect(PotionEffectType.SPEED); + } + + for (Player online : Bukkit.getOnlinePlayers()) { + if (online.equals(player)) continue; + online.showPlayer(player); + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Chat.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Chat.java new file mode 100644 index 0000000..573ff44 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Chat.java @@ -0,0 +1,170 @@ +package net.grandtheftmc.vice.listeners; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.tasks.LotteryPlayer; +import net.grandtheftmc.vice.users.ViceUser; +import net.grandtheftmc.vice.users.storage.BooleanStorageType; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public class Chat implements Listener { + private final Map<String, Map<String, Integer>> recentChats = new HashMap<>(); + + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onChat(AsyncPlayerChatEvent e) { + Player player = e.getPlayer(); + UUID uuid = player.getUniqueId(); + String msg = e.getMessage(); + ViceUser user = Vice.getUserManager().getLoadedUser(uuid); + User coreUser = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (user.getBooleanFromStorage(BooleanStorageType.BRIBING)) { + e.setCancelled(true); + new BukkitRunnable() { + @Override + public void run() { + Player player = Bukkit.getPlayer(uuid); + if (player == null) + return; + ViceUser user = Vice.getUserManager().getLoadedUser(uuid); + if ("quit".equalsIgnoreCase(msg)) { + user.setBooleanToStorage(BooleanStorageType.BRIBING, false); + player.sendMessage(Lang.BRIBE.f("&7You canceled bribing the cop who arrested you.")); + return; + } + if (!user.isArrested()) { + user.setBooleanToStorage(BooleanStorageType.BRIBING, false); + player.sendMessage(Lang.BRIBE.f("&7You are not in jail!")); + return; + } + if (user.getJailTimer() < 5) { + user.setBooleanToStorage(BooleanStorageType.BRIBING, false); + player.sendMessage(Lang.BRIBE.f("&7You are already being released!")); + return; + } + Player cop = Bukkit.getPlayer(user.getJailCop()); + ViceUser copUser = cop == null ? null : Vice.getUserManager().getLoadedUser(cop.getUniqueId()); + if (cop == null || !copUser.isCop()) { + player.sendMessage(Lang.BRIBE.f("&7The cop who arrested you (&3&l" + user.getJailCopName() + "&7) is off duty!")); + return; + } + double amnt; + try { + amnt = Utils.round(Double.parseDouble(msg)); + } catch (NumberFormatException e1) { + player.sendMessage( + Utils.f(Lang.BRIBE + "&7Please enter a valid number or type &a\"quit\"&7!")); + return; + } + if (amnt < 5000) { + player.sendMessage(Lang.BRIBE.f("&7Bribes must be at least &a$&l5,000!")); + return; + } + if (user.getBribe() * 1.05 > amnt) { + player.sendMessage(Lang.BRIBE.f("&7You must raise the bribe by at least &a&l5%&7 of &a$&l" + user.getBribe() + "&7 (&a$&l" + (user.getBribe() * 1.05) + "&7)! Please enter a valid number or type &a\"quit\"&7!")); + return; + } + if (!user.hasMoney(amnt)) { + player.sendMessage(Lang.BRIBE.f("&7You don't have &c$&l" + amnt + "&7! Please enter a valid number or type &a\"quit\"&7!")); + return; + } + user.setBribe(amnt); + player.sendMessage(Lang.BRIBE.f("&7You sent a bribe offer of &a$&l" + amnt + "&7 to &3&l" + cop.getName() + "&7. You can negotiate with them using &a\"/msg " + cop.getName() + "\"&7!")); + cop.spigot().sendMessage(new ComponentBuilder(Lang.BRIBE.f("&7A bribe offer of &a$&l" + amnt + "&7 was sent to you by &3&l" + player.getName() + "&7!")).append(" [ACCEPT] ").color(ChatColor.GREEN).bold(true).event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/bribe accept " + player.getName())).append("[DENY]").color(ChatColor.DARK_RED).bold(true).event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/bribe deny " + player.getName())).create()); + } + }.runTask(Vice.getInstance()); + } else if (user.getBooleanFromStorage(BooleanStorageType.BUYING_LOTTERY_TICKETS)) { + e.setCancelled(true); + new BukkitRunnable() { + @Override + public void run() { + Player player = Bukkit.getPlayer(uuid); + if (player == null) + return; + ViceUser user = Vice.getUserManager().getLoadedUser(uuid); + if ("quit".equalsIgnoreCase(msg)) { + user.setBooleanToStorage(BooleanStorageType.BUYING_LOTTERY_TICKETS, false); + player.sendMessage(Utils.f(Lang.LOTTERY + "&7You cancelled buying lottery tickets!")); + MenuManager.openMenu(player, "lottery"); + return; + } + int amnt; + try { + amnt = Integer.parseInt(msg); + } catch (NumberFormatException e1) { + player.sendMessage(Utils.f(Lang.LOTTERY + "&7Please enter a valid number or type &a\"quit\"&7!")); + return; + } + if (amnt < 1) { + player.sendMessage(Utils.f(Lang.LOTTERY + + "&7The minimum amount is &e&l1&7! Enter a valid number or type &a\"quit\"&7!")); + return; + } + if (amnt > 100000) { + player.sendMessage(Utils.f(Lang.LOTTERY + + "&7The maximum amount is &e&l100000&7! Enter a valid number or type &a\"quit\"&7!")); + return; + } + if (!user.hasMoney(amnt * 500)) { + player.sendMessage(Lang.LOTTERY.f("&7You don't have &a$&l" + (amnt * 500) + + "&7 to buy &e&l" + amnt + " Tickets&7! Enter a valid amount or type &a\"quit\"&7!")); + return; + } + user.setBooleanToStorage(BooleanStorageType.BUYING_LOTTERY_TICKETS, false); + user.takeMoney(amnt * 500); + LotteryPlayer p = Vice.getLottery().getLotteryPlayer(uuid); + if (p == null){ p = new LotteryPlayer(uuid, player.getName()); + Vice.getLottery().addLotteryPlayer(p);} + p.addTickets(amnt); + ViceUtils.updateBoard(player, user); + player.sendMessage( + Utils.f(Lang.LOTTERY + "&7You bought &e&l" + amnt + " Tickets&7 for &a$&l" + (amnt * 500) + "&7!")); + } + }.runTask(Vice.getInstance()); + } + /*if (!coreUser.isRank(UserRank.MOD)) { + if (this.recentChats.containsKey(player.getName())) { + if (this.recentChats.get(player.getName()).containsKey(msg)) { + if (this.recentChats.get(player.getName()).get(msg) == 4) { + e.getRecipients().removeAll(e.getRecipients()); + e.getRecipients().add(player); + } else if (this.recentChats.get(player.getName()).get(msg) >= 5) { + e.setCancelled(true); + } + player.sendMessage(Lang.HEY.f("&7Slow down! Spamming can get you in trouble.")); + this.recentChats.get(player.getName()).put(msg, this.recentChats.get(player.getName()).get(msg) + 1); + } else { + this.recentChats.get(player.getName()).put(msg, 1); + } + } else { + this.recentChats.put(player.getName(), new HashMap<>()); + this.recentChats.get(player.getName()).put(msg, 1); + } + new BukkitRunnable() { + @Override + public void run() { + Chat.this.recentChats.get(player.getName()).remove(msg); + } + }.runTaskLater(Vice.getInstance(), 800); + }*/ + } +} + + diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/ChunkLoad.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/ChunkLoad.java new file mode 100644 index 0000000..d495582 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/ChunkLoad.java @@ -0,0 +1,36 @@ +package net.grandtheftmc.vice.listeners; + + +import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerTeleportEvent; + +/** + * Created by Timothy Lampen on 2017-08-09. + */ +public class ChunkLoad implements Listener { + + + @EventHandler + protected final void onWorldRender(PlayerTeleportEvent event) { + if(event.getCause() == PlayerTeleportEvent.TeleportCause.CHORUS_FRUIT) return; + if(event.getCause() == PlayerTeleportEvent.TeleportCause.SPECTATE) return; + + if(event.getTo() == null || event.getTo().getWorld() == null) return; + if(event.getFrom().getWorld().getName().equals(event.getTo().getWorld().getName())) return; + + if(Bukkit.getOnlinePlayers().stream().filter(p -> p.getWorld().getName().equals(event.getTo().getWorld().getName())).count() <= 1) + Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), "hd reload"); + } + + @EventHandler + protected final void onWorldRender(PlayerJoinEvent event) { + if(event.getPlayer() == null) return; + if(event.getPlayer().getLocation().getWorld() == null) return; + + if(Bukkit.getOnlinePlayers().stream().filter(p -> p.getWorld().getName().equals(event.getPlayer().getLocation().getWorld().getName())).count() <= 1) + Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), "hd reload"); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/CommandPreProcess.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/CommandPreProcess.java new file mode 100644 index 0000000..0a597d7 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/CommandPreProcess.java @@ -0,0 +1,44 @@ +package net.grandtheftmc.vice.listeners; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.CheatCode; +import net.grandtheftmc.vice.users.ViceUser; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; + +/** + * Created by Timothy Lampen on 2017-08-07. + */ +public class CommandPreProcess implements Listener { + + @EventHandler + public void onCommand(PlayerCommandPreprocessEvent event){ + Player player = event.getPlayer(); + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + String msg = event.getMessage().toLowerCase(); + + if(user.isArrested()){ + if(msg.contains("spawn") || msg.contains("home") || msg.contains("tp") || msg.contains("warp")){ + event.setCancelled(true); + player.sendMessage(Lang.COP.f("&7You cannot issue this command while you are arrested!")); + return; + } + } + + for(CheatCode code : CheatCode.values()) { + switch (code){ + case FEED: + case STACK: + continue; + } + if(msg.equalsIgnoreCase("/" + code.toString())) { + code.activate(Core.getUserManager().getLoadedUser(player.getUniqueId()), user, player, user.getCheatCodeState(code)); + event.setCancelled(true); + } + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/CraftItem.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/CraftItem.java new file mode 100644 index 0000000..db4da62 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/CraftItem.java @@ -0,0 +1,108 @@ +package net.grandtheftmc.vice.listeners; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.items.GameItem; +import net.grandtheftmc.vice.items.recipetypes.RecipeItem; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.inventory.PrepareItemCraftEvent; +import org.bukkit.inventory.CraftingInventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.Recipe; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.Optional; + +/** + * Created by Timothy Lampen on 7/10/2017. + */ +public class CraftItem implements Listener { + + @EventHandler + public void onCraft(PrepareItemCraftEvent event) { + Recipe recipe = event.getRecipe(); + if (recipe != null) { + if (Vice.getItemManager().getBannedCraftingRecipes().contains(recipe.getResult().getType()) && !recipe.getResult().hasItemMeta()) { + event.getInventory().setResult(new ItemStack(Material.AIR)); + return; + } + + for (ItemStack itemStack : event.getInventory().getMatrix()) { + if (itemStack != null && itemStack.getType() == Material.DIAMOND_SPADE && Vice.getItemManager().getItem(itemStack) != null && Vice.getItemManager().getItem(itemStack).getType() == GameItem.ItemType.DRUG) { + event.getInventory().setResult(new ItemStack(Material.AIR)); + return; + } + } + } + + } + + @EventHandler + public void onInteract(InventoryClickEvent event) { + Player player = (Player) event.getWhoClicked(); + if (event.getClickedInventory() != null && (event.getClickedInventory().getType() == InventoryType.WORKBENCH || event.getClickedInventory().getType() == InventoryType.CRAFTING) && event.getSlot() == 0) { + CraftingInventory inv = (CraftingInventory) event.getClickedInventory(); + Optional<RecipeItem> craftingRecipeItem = Vice.getItemManager().getCraftingRecipe(inv.getMatrix()); + if (!craftingRecipeItem.isPresent()) + return; + if (inv.getItem(0) == null) return; + int amt = 0; + event.setCancelled(true); + if (event.getClick().toString().contains("SHIFT")) { + for (int i = 0; i < (event.getClickedInventory().getType() == InventoryType.WORKBENCH ? 9 : 4); i++) { + ItemStack ingredient = inv.getMatrix()[i]; + if (ingredient == null || ingredient.getType() == Material.AIR) + continue; + if (amt == 0 || ingredient.getAmount() < amt) + amt = ingredient.getAmount(); + } + } + ItemStack result = inv.getItem(0).clone(); + if (amt == 0) + amt = 1; + result.setAmount(amt); + if (event.getClick().toString().contains("SHIFT")) { + if (player.getInventory().firstEmpty() == -1) { + return; + } + player.getInventory().addItem(result); + } else if (player.getItemOnCursor() != null && player.getItemOnCursor().getType() != Material.AIR) { + if (player.getItemOnCursor().isSimilar(result)) { + if ((result.getAmount() + player.getItemOnCursor().getAmount()) > result.getMaxStackSize()) { + return; + } else { + result.setAmount(result.getAmount() + player.getItemOnCursor().getAmount()); + player.setItemOnCursor(result); + } + } else { + return; + } + } else { + player.setItemOnCursor(result); + } + for (int i = 1; i < (inv.getType() == InventoryType.WORKBENCH ? 10 : 5); i++) { + ItemStack is = inv.getItem(i); + if (is == null || is.getType() == Material.AIR) + continue; + if (is.getAmount() > amt) { + is.setAmount(is.getAmount() - amt); + } else { + inv.setItem(i, null); + } + } + if (!Vice.getItemManager().getCraftingRecipe(inv.getMatrix()).isPresent()) { + inv.setResult(null); + } + new BukkitRunnable() { + @Override + public void run() { + player.updateInventory(); + } + }.runTaskLater(Vice.getInstance(), 5); + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Damage.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Damage.java new file mode 100644 index 0000000..2543364 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Damage.java @@ -0,0 +1,236 @@ +package net.grandtheftmc.vice.listeners; + +import com.j0ach1mmall3.wastedguns.api.events.explosives.ExplosionDamageEntityEvent; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.State; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.guns.weapon.ThrowableWeapon; +import net.grandtheftmc.guns.weapon.ranged.guns.LauncherWeapon; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drugs.Drug; +import net.grandtheftmc.vice.drugs.DrugService; +import net.grandtheftmc.vice.users.CheatCode; +import net.grandtheftmc.vice.users.ViceUser; +import org.bukkit.GameMode; +import org.bukkit.Material; +import org.bukkit.entity.*; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.entity.EntityRegainHealthEvent; +import org.bukkit.inventory.ItemStack; + +import java.util.List; +import java.util.Optional; +import java.util.concurrent.TimeUnit; + +public class Damage implements Listener { + + @EventHandler + public void onDamage(EntityDamageEvent e) { + Entity victimEntity = e.getEntity(); + if (!(victimEntity instanceof Player)) return; + Player victim = (Player) victimEntity; + if (victim.getGameMode() == GameMode.SPECTATOR || victim.getWorld().equals(Vice.getWorldManager().getWarpManager().getSpawn().getLocation().getWorld())) { + e.setCancelled(true); + } + else if (e.getCause() == EntityDamageEvent.DamageCause.ENTITY_EXPLOSION || e.getCause() == EntityDamageEvent.DamageCause.BLOCK_EXPLOSION) { + ViceUser user = Vice.getUserManager().getLoadedUser(victim.getUniqueId()); + if (user.hasTeleportProtection()) + e.setCancelled(true); + } + else if(e.getCause()== EntityDamageEvent.DamageCause.FALL) { + ViceUser user = Vice.getUserManager().getLoadedUser(victim.getUniqueId()); + if(user.getCheatCodeState(CheatCode.JELLYLEGS).getState()== State.ON){ + e.setCancelled(true); + } + } + } + + @EventHandler + public void onWeaponExplode(ExplosionDamageEntityEvent event){ + Entity entity = event.getProjectile(); + if(entity.hasMetadata("Rocket")){ + double range = ((LauncherWeapon)entity.getMetadata("Rocket").get(0).value()).getExplosionSize(); + Vice.getWorldManager().getObsidianManager().updateRange(range, entity, 1); + } + else if(entity.hasMetadata("ProximityExplosive")){ + double range = ((ThrowableWeapon)entity.getMetadata("ProximityExplosive").get(0).value()).getExplosionSize(); + Vice.getWorldManager().getObsidianManager().updateRange(range, entity, 1); + } + else if(entity.hasMetadata("StickyExplosive")){ + double range = ((ThrowableWeapon)entity.getMetadata("StickyExplosive").get(0).value()).getExplosionSize(); + Vice.getWorldManager().getObsidianManager().updateRange(range, entity, 1); + } + else if(entity.hasMetadata("Explosive")){ + double range = ((LauncherWeapon)entity.getMetadata("Explosive").get(0).value()).getExplosionSize(); + Vice.getWorldManager().getObsidianManager().updateRange(range, entity, 1); + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onExplode(EntityExplodeEvent event){ + Entity e = event.getEntity(); + if(!event.isCancelled() && event.getEntityType()==EntityType.PRIMED_TNT){ + Vice.getWorldManager().getObsidianManager().updateRange(3, e, 1); + } + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onDamageMonitor(EntityDamageEvent e) { + if (!(e.getEntity() instanceof Player)) return; + Player player = (Player) e.getEntity(); + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + user.updateTintHealth(player, Core.getUserManager().getLoadedUser(player.getUniqueId())); + } + + @EventHandler + public void onExplosionDamageEntityEvent(ExplosionDamageEntityEvent event) { + if (event.getLivingEntity().getType() != EntityType.PLAYER) return; + Player damager = (Player) event.getLivingEntity(); + for (LivingEntity livingEntity : event.getVictims()) { + if (livingEntity.getType() != EntityType.PLAYER) continue; + Player victim = (Player) livingEntity; + ViceUser victimGameUser = Vice.getUserManager().getLoadedUser(victim.getUniqueId()); + if (victimGameUser.hasTeleportProtection()) { + event.getVictims().remove(livingEntity); + return; + } + ViceUser damagerGameUser = Vice.getUserManager().getLoadedUser(damager.getUniqueId()); + if (damagerGameUser.hasTeleportProtection()) { + event.getVictims().remove(livingEntity); + return; + } + } + } + + @EventHandler(ignoreCancelled = true) + public void onDamageByEntity(EntityDamageByEntityEvent e) { + if (e.getDamager() == null) return; + Entity entity = e.getDamager(); + if (entity == null) return; + if (entity instanceof Projectile) { + entity = (Entity) ((Projectile) entity).getShooter(); + } else if (entity instanceof Tameable) { + entity = (Entity) ((Tameable) entity).getOwner(); + } + if (!(e.getEntity() instanceof Player && entity instanceof Player)) return; + Player damager = (Player) entity; + Player victim = (Player) e.getEntity(); + ViceUser victimGameUser = Vice.getUserManager().getLoadedUser(victim.getUniqueId()); + User coreVictimUser = Core.getUserManager().getLoadedUser(victim.getUniqueId()); + if (victimGameUser.hasTeleportProtection()) { + e.setCancelled(true); + long expires = TimeUnit.MILLISECONDS.toSeconds(victimGameUser.getTimeUntilTeleportProtectionExpires()); + if (expires <= 1) { + victimGameUser.setLastTeleport(0); + return; + } + damager.sendMessage(Lang.GTM.f(coreVictimUser.getColoredName(victim) + " &7has teleport protection for &a" + expires + "&7 seconds!")); + return; + } + ViceUser damagerGameUser = Vice.getUserManager().getLoadedUser(damager.getUniqueId()); + if (damagerGameUser.hasTeleportProtection()) { + e.setCancelled(true); + damagerGameUser.setLastTeleport(0); + damager.sendMessage(Lang.COMBATTAG.f("&7Your teleport protection has ended!")); + } + + + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onDamageByEntityMonitor(EntityDamageByEntityEvent e) { + Entity damager = e.getDamager(); + Entity entity = e.getEntity(); + switch (entity.getType()) { + case PLAYER: { + if (e.isCancelled()) + return; + Player player = (Player) entity; + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + if (damager == null) + return; + if (damager instanceof Projectile) + damager = (Entity) ((Projectile) damager).getShooter(); + else if (entity instanceof Tameable) + damager = (Entity) ((Tameable) entity).getOwner(); + if (!(damager instanceof Player && entity instanceof Player)) + return; + if (!user.isInCombat()) + player.sendMessage(Utils.f(Lang.COMBATTAG + "&7You are now in combat! Do not log out for 10 seconds!")); +// Core.getUserManager().getLoadedUser(player.getUniqueId()).hidePet(player); + user.setLastTag(System.currentTimeMillis()); + if (Vice.getWorldManager().getWarpManager().cancelTaxi(player, user)) + player.sendMessage(Utils.f(Lang.TAXI + "&eYour cab was cancelled!")); + Player dmger = (Player) damager; + ViceUser damagerUser = Vice.getUserManager().getLoadedUser(dmger.getUniqueId()); + if (!damagerUser.isInCombat()) + dmger.sendMessage(Utils.f(Lang.COMBATTAG + "&7You are now in combat! Do not log out for 20 seconds!")); +// Core.getUserManager().getLoadedUser(dmger.getUniqueId()).hidePet(dmger); + damagerUser.setLastTag(System.currentTimeMillis()); + if (Vice.getWorldManager().getWarpManager().cancelTaxi(dmger, damagerUser)) + player.sendMessage(Utils.f(Lang.TAXI + "&eYour cab was cancelled!")); + if (dmger.getInventory().getItemInMainHand() != null) { + Optional<Drug> heroin = ((DrugService) Vice.getDrugManager().getService()).getDrug("heroin"); + if (heroin.isPresent()) { + if (dmger.getInventory().getItemInMainHand().getDurability() == 5 && dmger.getInventory().getItemInMainHand().getType() == Material.FLINT_AND_STEEL) { + heroin.get().apply(player); + dmger.getInventory().setItemInMainHand(new ItemStack(Material.AIR)); + } + } + } + return; + + } + case ITEM_FRAME: { + if (!(damager instanceof Player)) + return; + Player player = (Player) damager; + ItemFrame frame = (ItemFrame) entity; + if (Core.getUserManager().getLoadedUser(player.getUniqueId()).hasEditMode()) + return; + ItemStack item = frame.getItem(); + if (item == null) + return; + Vice.getShopManager().buy(player, frame.getItem()); + return; + } + case VILLAGER: + if(!(damager instanceof Player)) + return; + NPC npc = (Villager)entity; + ViceUser viceUser = Vice.getUserManager().getLoadedUser(damager.getUniqueId()); + if(damager.getWorld().getName().equalsIgnoreCase("spawn") && !viceUser.isCop()) { + damager.sendMessage(Lang.COMBATTAG.f("&7You cannot pickup the items from this NPC as they are in spawn and you are not a cop!")); + return; + } + + List<ItemStack> contents = Vice.getCombatLogManager().getPlayerInventory(npc); + if(contents==null) + return; + for(ItemStack is : contents) + if(is!=null) + entity.getWorld().dropItemNaturally(entity.getLocation(), is); + Vice.getCombatLogManager().addDestroyedNPC(npc); + Vice.getCombatLogManager().removeNPC(npc); + npc.remove(); + return; + default: + break; + } + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onHealthChangeMonitor(EntityRegainHealthEvent e) { + if (!(e.getEntity() instanceof Player)) return; + Player player = (Player) e.getEntity(); + Vice.getUserManager().getLoadedUser(player.getUniqueId()).updateTintHealth(player, Core.getUserManager().getLoadedUser(player.getUniqueId())); + } + +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Death.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Death.java new file mode 100644 index 0000000..cb515f1 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Death.java @@ -0,0 +1,184 @@ +package net.grandtheftmc.vice.listeners; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.Pref; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.events.ArmorEquipEvent; +import net.grandtheftmc.vice.events.EquipArmorType; +import net.grandtheftmc.vice.users.ViceUser; +import net.grandtheftmc.vice.users.storage.BooleanStorageType; +import org.bukkit.*; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +import java.util.*; + +public class Death implements Listener { + + @EventHandler + public void onDeath(PlayerDeathEvent e) { + new ArrayList<>(e.getDrops()).stream().filter(stack -> stack != null && (stack.getType() == Material.WATCH || stack.getType() == Material.COMPASS || stack.getType() == Material.CHEST)).forEach(e.getDrops()::remove); + + Player victim = e.getEntity(); + Player killer = victim.getKiller(); + UUID victimUUID = victim.getUniqueId(); + ViceUser victimGameUser = Vice.getUserManager().getLoadedUser(victimUUID); + User victimUser = Core.getUserManager().getLoadedUser(victimUUID); + + Vice.getDrugManager().getEffectManager().cancelEffects(victim); + + victimGameUser.addDeaths(1); + victimGameUser.setLastTag(-1); + + Collection<Player> hiddenStaff = new ArrayList<>(); + victim.getNearbyEntities(30, 30, 30).forEach(entity -> { + if (entity.getType() != EntityType.PLAYER) return; + Player target = (Player) entity; + if (target.getGameMode() == GameMode.SPECTATOR) { + hiddenStaff.add(target); + victim.hidePlayer(target); + } + }); + + victimGameUser.setKillStreak(0); + if (Vice.getWorldManager().getWarpManager().cancelTaxi(victim, victimGameUser)) + victim.sendMessage(Utils.f(Lang.TAXI + "&eThe taxi was cancelled!")); + victim.setHealth(victim.getMaxHealth()); + victim.spigot().respawn(); + victim.setFireTicks(0); + for (PotionEffect p : victim.getActivePotionEffects()) { + victim.removePotionEffect(p.getType()); + } + + if(victimGameUser.getVehicleTaskId()!=-1) { + victimGameUser.cancelVehicleTeleport(); + victim.sendMessage(Lang.VEHICLES.f("&7You can't " + (victimGameUser.getBooleanFromStorage(BooleanStorageType.SEND_AWAY) ? "send away" : "call") + " while you're dead!")); + } + + victim.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 180, 0), false); + victim.setGameMode(GameMode.SPECTATOR); + victim.setVelocity(new Vector()); + victim.setFlying(true); + victim.setFoodLevel(20); + victim.playSound(victim.getLocation(), Sound.ENTITY_WITHER_SPAWN, 1, 0.5F); + victim.setFlySpeed(0); + ViceUtils.removeBoard(victim); + //new JLibPlayer(victim).setWorldborderTint(0); +// victimUser.removeCosmetics(victim); + new BukkitRunnable() { + @Override + public void run() { + Player victim = Bukkit.getPlayer(victimUUID); + if (victim == null) return; + User victimUser = Core.getUserManager().getLoadedUser(victim.getUniqueId()); + ViceUser victimGameUser = Vice.getUserManager().getLoadedUser(victim.getUniqueId()); + victim.teleport(Vice.getWorldManager().getWarpManager().getSpawn().getLocation()); + for (PotionEffect p : victim.getActivePotionEffects()) { + victim.removePotionEffect(p.getType()); + } + + hiddenStaff.forEach(target -> { + if (target == null || !target.isOnline()) return; + victim.showPlayer(target); + }); + + hiddenStaff.clear(); + victim.setFoodLevel(20); + victim.setGameMode(GameMode.SURVIVAL); + victim.setFlying(false); + victim.setFlySpeed(0.1F); + ViceUtils.giveGameItems(victim); + ViceUtils.updateBoard(victim, victimGameUser); +// victimUser.loadLastCosmetics(victim); + + for (Player player : Bukkit.getOnlinePlayers()) { + if (player.equals(victim)) continue; + player.showPlayer(victim); + } + } + }.runTaskLater(Vice.getInstance(), 150); + + Utils.sendTitle(victim, "&c&lWASTED", killer == null ? null : "&7" + ViceUtils.getMessageKilledBy(killer.getName()), 80, 50, 20); + + if (killer == null || killer.equals(victim)) { + e.setDeathMessage(Utils.f("&e" + victim.getName() + "&7 " + (victim.getLastDamageCause() instanceof EntityDamageByEntityEvent ? "was killed by &c" + ((EntityDamageByEntityEvent) victim.getLastDamageCause()).getDamager().getCustomName() + "&7!" : "died!"))); + return; + } + + if (Utils.calculateChance(10)) { + e.getDrops().add(Utils.setSkullOwner(Utils.createItem(Material.SKULL_ITEM, 3, "&e&l" + victim.getName() + "'s Head"), victim.getName())); + killer.sendMessage(Lang.HEY.f(victimUser.getColoredName(victim) + "&7's head dropped on the ground!")); + } + + e.setDeathMessage(Utils.f("&e" + victim.getName() + "&7 was killed by &c" + killer.getName() + "&7!")); + UUID killerUUID = killer.getUniqueId(); + ViceUser killerGameUser = Vice.getUserManager().getLoadedUser(killerUUID); + User killerUser = Core.getUserManager().getLoadedUser(killerUUID); + killerGameUser.addKills(1); + killerGameUser.addKillStreak(1); + ViceUtils.updateBoard(killer, killerGameUser); + victim.setBedSpawnLocation(Vice.getWorldManager().getWarpManager().getSpawn().getLocation(), true); + killer.setBedSpawnLocation(Vice.getWorldManager().getWarpManager().getSpawn().getLocation(), true); + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onDeathMonitor(PlayerDeathEvent e) { + for (Player player : Bukkit.getOnlinePlayers()) { + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (!user.getPref(Pref.DEATH_MESSAGES)) { + if (Objects.equals(player, e.getEntity())) { + player.sendMessage(e.getDeathMessage()); + } + continue; + } + player.sendMessage(e.getDeathMessage()); + } + + e.setDeathMessage(null); + + Player p = e.getEntity(); + for(ItemStack i : p.getInventory().getArmorContents()){ + if(i != null && !i.getType().equals(Material.AIR)){ + Bukkit.getServer().getPluginManager().callEvent(new ArmorEquipEvent(p, ArmorEquipEvent.EquipMethod.DEATH, EquipArmorType.matchType(i), i, null)); + } + } + + Iterator<ItemStack> iter = e.getDrops().iterator(); + while (iter.hasNext()) { + ItemStack is = iter.next(); + if(is==null) + continue; + + switch (is.getType()) { + case BOW: + iter.remove(); + break; + } + + if(!is.hasItemMeta()) continue; + + switch (ChatColor.stripColor(is.getItemMeta().getDisplayName())) { + case "Backpack": + case "Ammo Pouch": + case "Phone": { + iter.remove(); + break; + } + } + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Dispense.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Dispense.java new file mode 100644 index 0000000..7e5fd27 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Dispense.java @@ -0,0 +1,43 @@ +package net.grandtheftmc.vice.listeners; + +import net.grandtheftmc.vice.events.ArmorEquipEvent; +import net.grandtheftmc.vice.events.EquipArmorType; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockDispenseEvent; + +/** + * Created by Timothy Lampen on 2017-08-11. + */ +public class Dispense implements Listener { + + @EventHandler + public void onDispense(BlockDispenseEvent e){ + EquipArmorType type = EquipArmorType.matchType(e.getItem()); + if(EquipArmorType.matchType(e.getItem()) != null){ + Location loc = e.getBlock().getLocation(); + for(Player p : loc.getWorld().getPlayers()){ + if(loc.getBlockY() - p.getLocation().getBlockY() >= -1 && loc.getBlockY() - p.getLocation().getBlockY() <= 1){ + if(p.getInventory().getHelmet() == null && type.equals(EquipArmorType.HELMET) || p.getInventory().getChestplate() == null && type.equals(EquipArmorType.CHESTPLATE) || p.getInventory().getLeggings() == null && type.equals(EquipArmorType.LEGGINGS) || p.getInventory().getBoots() == null && type.equals(EquipArmorType.BOOTS)){ + org.bukkit.block.Dispenser dispenser = (org.bukkit.block.Dispenser) e.getBlock().getState(); + org.bukkit.material.Dispenser dis = (org.bukkit.material.Dispenser) dispenser.getData(); + BlockFace directionFacing = dis.getFacing(); + // Someone told me not to do big if checks because it's hard to read, look at me doing it -_- + if(directionFacing == BlockFace.EAST && p.getLocation().getBlockX() != loc.getBlockX() && p.getLocation().getX() <= loc.getX() + 2.3 && p.getLocation().getX() >= loc.getX() || directionFacing == BlockFace.WEST && p.getLocation().getX() >= loc.getX() - 1.3 && p.getLocation().getX() <= loc.getX() || directionFacing == BlockFace.SOUTH && p.getLocation().getBlockZ() != loc.getBlockZ() && p.getLocation().getZ() <= loc.getZ() + 2.3 && p.getLocation().getZ() >= loc.getZ() || directionFacing == BlockFace.NORTH && p.getLocation().getZ() >= loc.getZ() - 1.3 && p.getLocation().getZ() <= loc.getZ()){ + ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(p, ArmorEquipEvent.EquipMethod.DISPENSER, EquipArmorType.matchType(e.getItem()), null, e.getItem()); + Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent); + if(armorEquipEvent.isCancelled()){ + e.setCancelled(true); + } + return; + } + } + } + } + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Drop.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Drop.java new file mode 100644 index 0000000..1a4021c --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Drop.java @@ -0,0 +1,64 @@ +package net.grandtheftmc.vice.listeners; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.items.GameItem; +import org.bukkit.entity.Item; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntitySpawnEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.Objects; + +public class Drop implements Listener { + + @EventHandler + public void onDrop(PlayerDropItemEvent e) { + ItemStack item = e.getItemDrop().getItemStack().clone(); + switch (item.getType()) { + case CHEST: + case WATCH: + case COMPASS: + if(ViceUtils.isDefaultPlayerItem(item)) { + new BukkitRunnable() { + @Override + public void run() { + e.getItemDrop().remove(); + } + }.runTaskLater(Vice.getInstance(), 1); + ViceUtils.giveGameItems(e.getPlayer()); + } + break; + default: + if (Objects.equals(e.getPlayer().getWorld().getName(), "spawn")) { + GameItem gi = Vice.getItemManager().getItem(item); + if (gi != null && gi.isScheduled()) { + e.setCancelled(true); + e.getPlayer().sendMessage(Lang.DRUGS.f("&7You can't drop drugs here! Go sell them at the nearest drug dealer.")); + } + } + break; + } + } + + @EventHandler + protected final void onEntitySpawn(EntitySpawnEvent event) { + if (event.getEntity() == null) return; + if (!(event instanceof Item)) return; + + Item item = (Item) event.getEntity(); + switch (item.getItemStack().getType()) { + case CHEST: + case WATCH: + case COMPASS: + if (ViceUtils.isDefaultPlayerItem(item.getItemStack())) { + event.setCancelled(true); + } + break; + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Enchant.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Enchant.java new file mode 100644 index 0000000..5d50425 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Enchant.java @@ -0,0 +1,47 @@ +package net.grandtheftmc.vice.listeners; + +import org.bukkit.Material; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.enchantment.PrepareItemEnchantEvent; + +import java.util.Arrays; +import java.util.List; + +/** + * Created by Timothy Lampen on 7/29/2017. + */ +public class Enchant implements Listener { + private List<Material> list = Arrays.asList(Material.DIAMOND_BOOTS + , Material.DIAMOND_CHESTPLATE + , Material.DIAMOND_HELMET + , Material.DIAMOND_LEGGINGS + , Material.DIAMOND_SWORD + , Material.CHAINMAIL_BOOTS + , Material.CHAINMAIL_CHESTPLATE + , Material.CHAINMAIL_HELMET + , Material.CHAINMAIL_LEGGINGS + , Material.GOLD_BOOTS + , Material.GOLD_CHESTPLATE + , Material.GOLD_HELMET + , Material.GOLD_LEGGINGS + , Material.GOLD_SWORD + , Material.IRON_BOOTS + , Material.IRON_CHESTPLATE + , Material.IRON_HELMET + , Material.IRON_LEGGINGS + , Material.IRON_SWORD + , Material.LEATHER_BOOTS + , Material.LEATHER_CHESTPLATE + , Material.LEATHER_HELMET + , Material.LEATHER_LEGGINGS + , Material.STONE_SWORD + , Material.WOOD_SWORD); + + @EventHandler + public void onEnchant(PrepareItemEnchantEvent event) { + if (this.list.contains(event.getItem().getType())) + event.setCancelled(true); + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/FireListener.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/FireListener.java new file mode 100644 index 0000000..2c8d300 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/FireListener.java @@ -0,0 +1,29 @@ +package net.grandtheftmc.vice.listeners; + +import net.grandtheftmc.vice.tasks.PlayerTask; +import org.bukkit.Material; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBurnEvent; +import org.bukkit.event.block.BlockSpreadEvent; + +public class FireListener implements Listener { + + @EventHandler + public void blockBurnEvent(BlockBurnEvent event) { + event.setCancelled(true); + } + + @EventHandler + public void blockSpreadEvent(BlockSpreadEvent event) { + if (event.getSource().getType() == Material.FIRE) event.getSource().setType(Material.AIR); + event.setCancelled(true); + } + + public static void clearFire() { + PlayerTask.fireBlocks.forEach(block -> { + block.setType(Material.AIR); + PlayerTask.fireBlocks.remove(block); + }); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/FoodChange.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/FoodChange.java new file mode 100644 index 0000000..5afe7d2 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/FoodChange.java @@ -0,0 +1,28 @@ +package net.grandtheftmc.vice.listeners; + +import net.grandtheftmc.vice.Vice; +import org.bukkit.Material; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.FoodLevelChangeEvent; +import org.bukkit.event.player.PlayerItemConsumeEvent; + +import java.util.Objects; + +public class FoodChange implements Listener { + + @EventHandler + public void onFoodChange(FoodLevelChangeEvent event) { + if (Objects.equals(event.getEntity().getLocation().getWorld(), Vice.getWorldManager().getWarpManager().getSpawn().getLocation().getWorld())) { + event.setFoodLevel(20); + } + } + + @EventHandler + protected final void onItemConsume(PlayerItemConsumeEvent event) { + if(event.getItem() == null) return; + if(event.getItem().getType() != Material.CHORUS_FRUIT) return; + + event.setCancelled(true); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/GunTestingListener.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/GunTestingListener.java new file mode 100644 index 0000000..e2342b6 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/GunTestingListener.java @@ -0,0 +1,61 @@ +package net.grandtheftmc.vice.listeners; + +import net.grandtheftmc.core.util.Component; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.vice.Vice; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerToggleSneakEvent; +import org.bukkit.event.player.PlayerToggleSprintEvent; +import org.bukkit.inventory.ItemStack; + +public class GunTestingListener implements Component<GunTestingListener, Vice> { + + private final ItemStack[] states; + + public GunTestingListener() { + this.states = new ItemStack[] { + new ItemFactory(Material.STONE_SWORD).setDurability((short) 73).setUnbreakable(true).build(), + new ItemFactory(Material.STONE_SWORD).setDurability((short) 74).setUnbreakable(true).build(), + new ItemFactory(Material.STONE_SWORD).setDurability((short) 75).setUnbreakable(true).build(), + }; + Bukkit.getPluginManager().registerEvents(this, Vice.getInstance()); + } + + @Override + public GunTestingListener onEnable(Vice plugin) { + return this; + } + + @Override + public GunTestingListener onDisable(Vice plugin) { + return this; + } + + @EventHandler(ignoreCancelled = true) + protected final void onPlayerJoin(PlayerJoinEvent event) { + event.getPlayer().getInventory().setItem(0, states[0]); + event.getPlayer().updateInventory(); + } + + @EventHandler(ignoreCancelled = true) + protected final void onPlayerMove(PlayerToggleSneakEvent event) { + + if (event.isSneaking()) event.getPlayer().getInventory().setItem(0, states[2]); + else event.getPlayer().getInventory().setItem(0, states[0]); + event.getPlayer().updateInventory(); + } + + @EventHandler(ignoreCancelled = true) + protected final void onPlayerMove(PlayerToggleSprintEvent event) { +// PlayerToggleSprintEvent +// PlayerToggleSneakEvent + + if (event.isSprinting()) event.getPlayer().getInventory().setItem(0, states[1]); + else event.getPlayer().getInventory().setItem(0, states[0]); + event.getPlayer().updateInventory(); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Interact.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Interact.java new file mode 100644 index 0000000..3aba41f --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Interact.java @@ -0,0 +1,650 @@ +package net.grandtheftmc.vice.listeners; + +import com.j0ach1mmall3.jlib.methods.ReflectionAPI; +import com.massivecraft.factions.*; +import com.massivecraft.factions.struct.Relation; +import net.citizensnpcs.api.event.NPCDamageByEntityEvent; +import net.citizensnpcs.api.event.NPCDamageEvent; +import net.citizensnpcs.api.event.NPCRightClickEvent; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.State; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.areas.obj.Area; +import net.grandtheftmc.vice.drugs.Drug; +import net.grandtheftmc.vice.drugs.DrugService; +import net.grandtheftmc.vice.events.ArmorEquipEvent; +import net.grandtheftmc.vice.events.EquipArmorType; +import net.grandtheftmc.vice.items.ArmorType; +import net.grandtheftmc.vice.items.GameItem; +import net.grandtheftmc.vice.items.Kit; +import net.grandtheftmc.vice.lootcrates.LootCrate; +import net.grandtheftmc.vice.users.CheatCode; +import net.grandtheftmc.vice.users.ViceUser; +import net.grandtheftmc.vice.users.storage.BooleanStorageType; +import net.grandtheftmc.vice.utils.ParticleColor; +import net.grandtheftmc.vice.world.ZoneFlag; +import org.bukkit.*; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.BlockState; +import org.bukkit.block.Chest; +import org.bukkit.entity.*; +import org.bukkit.event.Event.Result; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractAtEntityEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.HashSet; +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; + +public class Interact implements Listener { + private static final Class BLOCK_POSITION_CLASS = ReflectionAPI.getNmsClass("BlockPosition"); + + @EventHandler + protected final void onNPCInteract(NPCRightClickEvent event) { + switch (ChatColor.stripColor(event.getNPC().getName()).toLowerCase()) { + case "carl": { + Player player = event.getClicker(); + User u = Core.getUserManager().getLoadedUser(player.getUniqueId()); + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + if (!user.isCop()) { + player.sendMessage(Lang.COPS.f("&7Hey! You're not a cop, why should I pay you?")); + return; + } + Vice.getItemManager().giveKit(player, u, user, "cop"); + if (user.getLastCopSalary() + 86400000 > System.currentTimeMillis()) { + player.sendMessage(Lang.COPS.f("&7Please wait &a" + Utils.timeInMillisToText(user.getLastCopSalary() + 86400000 - System.currentTimeMillis()) + "&7 before claiming your daily salary!")); + return; + } + user.setLastCopSalary(System.currentTimeMillis()); + user.addMoney(user.getCopRank().getSalary()); + player.sendMessage(Lang.COPS.f("&7You received your daily salary of &a$&l" + user.getCopRank().getSalary() + "&7!")); + } + default: + break; + } + } + + @EventHandler + protected final void onNPCDamage(NPCDamageEvent event) { + event.setCancelled(true); + } + + @EventHandler + protected final void onNPCDamage(NPCDamageByEntityEvent event) { + event.setCancelled(true); + } + + @EventHandler + public void armorEquipRunner(PlayerInteractEvent e) { + if (e.getAction() == Action.PHYSICAL) return; + if (e.getAction() == Action.RIGHT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_BLOCK) { + final Player player = e.getPlayer(); + ArmorType newArmorType = ArmorType.matchType(e.getItem()); + if (newArmorType != null) { + if (newArmorType.equals(ArmorType.HELMET) && e.getPlayer().getInventory().getHelmet() == null || newArmorType.equals(ArmorType.CHESTPLATE) && e.getPlayer().getInventory().getChestplate() == null || newArmorType.equals(ArmorType.LEGGINGS) && e.getPlayer().getInventory().getLeggings() == null || newArmorType.equals(ArmorType.BOOTS) && e.getPlayer().getInventory().getBoots() == null) { + ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(e.getPlayer(), ArmorEquipEvent.EquipMethod.HOTBAR, EquipArmorType.matchType(e.getItem()), null, e.getItem()); + Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent); + if (armorEquipEvent.isCancelled()) { + e.setCancelled(true); + player.updateInventory(); + } + } + } + } + } + + + @EventHandler(priority = EventPriority.HIGH) + public void onInteract(PlayerInteractEvent e) { + Player player = e.getPlayer(); + ViceUser viceUser = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + ItemStack item = player.getInventory().getItemInMainHand(); + if ((item != null && item.getType() == Material.FIREWORK) || (player.getInventory().getItemInOffHand() != null && player.getInventory().getItemInOffHand().getType() == Material.FIREWORK)) { + e.setCancelled(true); + return; + } + + if ((e.getItem() != null && item != null) && e.getAction() == Action.LEFT_CLICK_AIR || e.getAction() == Action.LEFT_CLICK_BLOCK && e.getItem().equals(item)) { + GameItem gameItem = Vice.getItemManager().getItem(item); + if (gameItem == null || !item.hasItemMeta() || !item.getItemMeta().getItemFlags().contains(ItemFlag.HIDE_UNBREAKABLE)) + return; + player.addPotionEffect(new PotionEffect(PotionEffectType.SLOW_DIGGING, 20 * 3, 2, false, false), true);//so if player tries to use drug as shovel, it doesn't work. + } + + if (item != null) { + switch (item.getType()) { + case GOLD_RECORD: + if (e.getClickedBlock() == null) return; + if (e.getClickedBlock().getType() == Material.JUKEBOX) return; + break; + case WATCH: + MenuManager.openMenu(player, "phone"); + return; + case RECORD_5: + if (e.getClickedBlock() != null && e.getClickedBlock().getType() == Vice.getItemManager().getItem("bong").getItem().getType()) { + if (item.getAmount() > 1) { + item.setAmount(item.getAmount() - 1); + player.getInventory().setItemInMainHand(item); + } else { + player.getInventory().remove(item); + } + Optional<Drug> weed = ((DrugService) Vice.getDrugManager().getService()).getDrug("weed"); + if (weed.isPresent()) { + weed.get().apply(player); + } else { + return; + } + Location blockLoc = e.getClickedBlock().getLocation(); + long startTime = System.currentTimeMillis(); + player.playSound(player.getLocation(), Sound.BLOCK_BREWING_STAND_BREW, 1, 1); + new BukkitRunnable() { + @Override + public void run() { + if (startTime + (1000 * 5) <= System.currentTimeMillis()) + this.cancel(); + double locX = blockLoc.getX() + (ThreadLocalRandom.current().nextDouble(-.15, .15) + .5); + double locZ = blockLoc.getZ() + (ThreadLocalRandom.current().nextDouble(-.15, .15) + .5); + double locY = blockLoc.getY() + 1.2; + ParticleColor color = ParticleColor.AQUA; + player.spigot().playEffect(new Location(blockLoc.getWorld(), locX, locY, locZ), Effect.SPELL, 1, 1, color.getRed(), color.getGreen(), color.getBlue(), 1, 1, 10); + } + }.runTaskTimerAsynchronously(Vice.getInstance(), 0, 1); + } + return; + default: + break; + } + } + if (e.getClickedBlock() == null) + return; + BlockState block = e.getClickedBlock().getState(); + if (viceUser.isCop() && ViceUtils.canPlantOn(ViceUtils.getSeedVersionOfMaterial(item.getType()), block.getType()) && Vice.getItemManager().getReplacedVanilla().keySet().stream().anyMatch(vanilla -> ViceUtils.getSeedVersionOfMaterial(vanilla.getType()) == item.getType())) { + e.setCancelled(true); + player.sendMessage(Utils.f(Lang.COP + "&7You can't plant drugs as a cop!")); + return; + } + switch (block.getType()) { + case CHEST: + + Inventory inventory = ((Chest) block).getBlockInventory(); + + if (ChatColor.stripColor(inventory.getTitle()).equals("Backpack")) { + e.setCancelled(true); + return; + } + + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + if (user.getBooleanFromStorage(BooleanStorageType.ADDING_LOOTCRATE)) { + try { + Chest chest = (Chest) block; +// Class<?> craftChestClass = ReflectionUtil.getOBCClass("block.CraftChest"); +// Object craftChest = craftChestClass.cast(chest); +// Method getTileEntity = craftChestClass.getMethod("getTileEntity"); +// Object tileEntity = getTileEntity.invoke(craftChest); +// Class<?> tileEntityClass = ReflectionUtil.getNMSClass("TileEntityChest"); +// Method setTitle = tileEntityClass.getMethod("a", String.class); +// setTitle.invoke(tileEntity, Utils.f("&e&lLoot Crate")); + chest.setCustomName(Utils.f("&e&lLoot Crate")); + chest.update(); + } catch (Exception ex) { + ex.printStackTrace(); + } + Vice.getCrateManager().addCrate(block.getLocation()); + player.sendMessage(Lang.LOOTCRATES.f("&7You added a loot crate at location &a" + + Utils.blockLocationToString(block.getLocation()) + "&7!")); + user.setBooleanToStorage(BooleanStorageType.ADDING_LOOTCRATE, false); + e.setCancelled(true); + return; + } else if (user.getBooleanFromStorage(BooleanStorageType.REMOVING_LOOTCRATE)) { + LootCrate crate = Vice.getCrateManager().getCrate(block.getLocation()); + if (crate == null) { + player.sendMessage(Lang.LOOTCRATES.f("&7This is not a Loot Crate!")); + user.setBooleanToStorage(BooleanStorageType.REMOVING_LOOTCRATE, false); + return; + } + Vice.getCrateManager().removeCrate(block.getLocation()); + player.sendMessage(Lang.LOOTCRATES.f("&7You removed a loot crate at location &a" + + Utils.blockLocationToString(block.getLocation()) + "&7!")); + user.setBooleanToStorage(BooleanStorageType.REMOVING_LOOTCRATE, false); + e.setCancelled(true); + return; + } else if (user.getBooleanFromStorage(BooleanStorageType.CHECKING_LOOTCRATE)) { + LootCrate crate = Vice.getCrateManager().getCrate(block.getLocation()); + if (crate == null) { + player.sendMessage(Lang.LOOTCRATES.f("&7This is not a Loot Crate!")); + user.setBooleanToStorage(BooleanStorageType.CHECKING_LOOTCRATE, false); + return; + } + player.sendMessage(Lang.LOOTCRATES.f("&7The Loot Crate at location &a" + + Utils.blockLocationToString(block.getLocation()) + "&7 will restock in &a" + + Utils.timeInSecondsToText(crate.getTimer()) + "&7! (+- 10s)")); + user.setBooleanToStorage(BooleanStorageType.CHECKING_LOOTCRATE, false); + e.setCancelled(true); + return; + } else if (user.getBooleanFromStorage(BooleanStorageType.RESTOCKING_LOOTCRATE)) { + LootCrate crate = Vice.getCrateManager().getCrate(block.getLocation()); + if (crate == null) { + player.sendMessage(Lang.LOOTCRATES.f("&7This is not a Loot Crate!")); + user.setBooleanToStorage(BooleanStorageType.RESTOCKING_LOOTCRATE, false); + return; + } + crate.restock(Area.DropType.DEFAULT); + player.sendMessage(Lang.LOOTCRATES.f("&7The Loot Crate at location &a" + + Utils.blockLocationToString(block.getLocation()) + "&7 was restocked.")); + user.setBooleanToStorage(BooleanStorageType.RESTOCKING_LOOTCRATE, false); + e.setCancelled(true); + return; + } + LootCrate crate = Vice.getCrateManager().getCrate(block.getLocation()); + if (crate == null) return; + if (!crate.isLooted()) { + crate.setLooted(true); + + int money = Utils.randomNumber(20, 150); + user.addMoney(money); + player.sendMessage(Lang.MONEY_ADD.f(money + ".00")); + } + return; + default: + break; + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void onInteractEntity(PlayerInteractEntityEvent e) { + if (e.getHand() != EquipmentSlot.HAND) return;//so it only gets triggered once + Player player = e.getPlayer(); + Entity en = e.getRightClicked(); + switch (en.getType()) { + case PLAYER: { + ItemStack i = player.getInventory().getItemInMainHand(); + GameItem gi = i == null ? null : Vice.getItemManager().getItem(i); + if (gi == null || !"handcuffs".equalsIgnoreCase(gi.getName())) return; + ViceUser viceUser = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + Player victim = (Player) en; + UUID victimUUID = victim.getUniqueId(); + ViceUser victimViceUser = Vice.getUserManager().getLoadedUser(victimUUID); + if (!viceUser.isCop()) return; + if (!Objects.equals("spawn", victim.getWorld().getName()) || ViceUtils.isInSpawnRange(victim, 10)) { + player.sendMessage(Lang.COPS.f("&7You have no jurisdiction in this area!")); + return; + } + if (victimViceUser.hasTeleportProtection()) { + e.setCancelled(true); + player.sendMessage(Lang.COMBATTAG.f("&7That player has teleport protection for &c&l" + Utils.timeInMillisToText(victimViceUser.getTimeUntilTeleportProtectionExpires()) + "&7!")); + return; + } + if (viceUser.hasTeleportProtection()) { + e.setCancelled(true); + player.sendMessage(Lang.COMBATTAG.f("&7Please wait &c&l" + Utils.timeInMillisToText(viceUser.getTimeUntilTeleportProtectionExpires()) + "&7!")); + return; + } + if (victimViceUser.isCop()) { + e.setCancelled(true); + player.sendMessage(Utils.f(Lang.HEY + "&cYou can't arrest cops!")); + return; + } + int timeInJail = ViceUtils.getTimeInJailForDrugs(victim); + if (timeInJail == 0) return; + ItemStack chestPlate = player.getInventory().getChestplate(); + if (chestPlate != null && chestPlate.getType() == Material.GOLD_CHESTPLATE && player.getLocation().getBlock().getRelative(BlockFace.DOWN).getType() == Material.AIR) { + player.sendMessage(Lang.COP_MODE.f("&fYou may not arrest criminals during flight!")); + return; + } + if (player.getVehicle() != null) { + player.sendMessage(Lang.COP_MODE.f("&fYou may not arrest criminals while in a Vehicle!")); + return; + } + if (Vice.getWorldManager().getZones(player.getLocation()).stream().anyMatch(zone -> zone.getFlags().contains(ZoneFlag.COP_CANT_ARREST))) { + player.sendMessage(Lang.COP_MODE.f("&7You may not arrest criminals in this area!")); + return; + } + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + User victimUser = Core.getUserManager().getLoadedUser(victimUUID); + victimViceUser.jail(timeInJail, player); + player.sendMessage(Lang.COP_MODE.f("&7You arrested &a" + victimUser.getColoredName(victim) + + "&7! He will go to jail for &a" + Utils.timeInSecondsToText(timeInJail) + "&7!")); + Utils.broadcastExcept(player, Lang.COP_MODE.f("&a" + victimUser.getColoredName(victim) + "&7 was arrested by &a" + + user.getColoredName(player) + "&7!")); + victimViceUser.addDeaths(1); + victimViceUser.setLastTag(-1); + victimViceUser.setKillStreak(0); + if (Vice.getWorldManager().getWarpManager().cancelTaxi(victim, victimViceUser)) + victim.sendMessage(Utils.f(Lang.TAXI + "&eThe taxi was cancelled!")); + victim.setHealth(victim.getMaxHealth()); + victim.spigot().respawn(); + victim.setFireTicks(0); + victim.setGameMode(GameMode.SPECTATOR); + victim.setFlying(true); + victim.getActivePotionEffects().clear(); + victim.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 180, 0), false); + victim.setFoodLevel(20); + victim.playSound(victim.getLocation(), Sound.ENTITY_WITHER_SPAWN, 1, 0.5F); + victim.setFlySpeed(0); + ViceUtils.removeBoard(victim); +// victimUser.removeCosmetics(victim); + new BukkitRunnable() { + @Override + public void run() { + Player victim = Bukkit.getPlayer(victimUUID); + if (victim == null) + return; + User victimUser = Core.getUserManager().getLoadedUser(victim.getUniqueId()); + ViceUser victimGameUser = Vice.getUserManager().getLoadedUser(victim.getUniqueId()); + victim.sendMessage(Lang.JAIL.f("&7You were arrested and have to stay in jail for &a" + + Utils.timeInSecondsToText(timeInJail) + "&7!")); + victim.teleport(Vice.getWorldManager().getWarpManager().getJail().getLocation()); + victim.setGameMode(GameMode.SURVIVAL); + victim.getActivePotionEffects().clear(); + victim.setFoodLevel(20); + victim.setFlying(false); + victim.setFlySpeed(0.1F); + ViceUtils.giveGameItems(victim); + ViceUtils.updateBoard(victim, victimGameUser); +// victimUser.loadLastCosmetics(victim); + } + }.runTaskLater(Vice.getInstance(), 150); + HashSet<ItemStack> bannedItems = new HashSet<>(); + for (ItemStack is : victim.getInventory().getContents()) { + if (Vice.getItemManager().getItem(is) != null && Vice.getItemManager().getItem(is).isScheduled()) { + bannedItems.add(is); + victim.getInventory().removeItem(is); + } + } + ViceUtils.giveGameItems(victim); + for (ItemStack item : bannedItems) + Utils.giveItems(player, item); + Utils.sendTitle(victim, "&c&lBUSTED", "&7Arrested by " + player.getName(), 80, 50, 20); + ViceUtils.updateBoard(player, user, viceUser); + return; + } + case ITEM_FRAME: + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (user.hasEditMode()) { + e.setCancelled(false); + return; + } + if (user.isInTutorial()) { + e.setCancelled(true); + return; + } + + e.setCancelled(true); + ItemFrame frame = (ItemFrame) en; + if (!Objects.equals("spawn", frame.getWorld().getName())) return; + ItemStack item = frame.getItem(); + if (item == null) + return; + switch (item.getType()) { + case PAPER: { + ViceUser viceUser = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + if (viceUser.isArrested()) { + if (viceUser.getJailTimer() < 5) { + player.sendMessage(Lang.BRIBE.f("&7You are already being released!")); + return; + } + Player cop = Bukkit.getPlayer(viceUser.getJailCop()); + ViceUser copUser = cop == null ? null : Vice.getUserManager().getLoadedUser(cop.getUniqueId()); + if (cop == null || !copUser.isCop()) { + player.sendMessage(Lang.BRIBE.f("&7The cop who arrested you (&3&l" + viceUser.getJailCopName() + "&7) is off duty!")); + return; + } + viceUser.setBooleanToStorage(BooleanStorageType.BRIBING, true); + player.sendMessage(Lang.BRIBE.f("&7Please type the amount you would like to offer as a bribe to &3&l" + viceUser.getJailCopName() + "&7 or type &a\"/quit\"&7!")); + return; + } + frame.setRotation(Rotation.NONE); + MenuManager.openMenu(player, "bank"); + break; + } + case ENDER_PEARL: + frame.setRotation(Rotation.NONE); + player.performCommand("/rtp"); + break; + case IRON_FENCE: + if (ViceUtils.getJailedPlayers().isEmpty()) { + player.sendMessage(Lang.JAIL.f("&7There are currently no prisoners in jail!")); + return; + } + MenuManager.openMenu(player, "jail"); + break; + case STORAGE_MINECART: + MenuManager.openMenu(player, "taxi"); + break; + case MINECART: { + String name = item.hasItemMeta() && item.getItemMeta().hasDisplayName() + ? ChatColor.stripColor(item.getItemMeta().getDisplayName()) : null; + if (name.startsWith("Buy Vehicle: ")) + name = name.replace("Buy Vehicle: ", ""); + else if (name.startsWith("Vehicle Shop: ")) + name = name.replace("Vehicle Shop: ", ""); + else if (name.startsWith("Buy ")) + name = name.replace("Buy ", ""); + else break; + GameItem gameItem = Vice.getItemManager().getItemFromDisplayName(name); + if (gameItem == null || gameItem.getType() != GameItem.ItemType.VEHICLE) return; + ViceUser viceUser = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + viceUser.setActionVehicle(gameItem.getWeaponOrVehicleOrDrug()); + MenuManager.openMenu(player, "vehicleshop"); + return; + } + case LEATHER: { + String name = item.hasItemMeta() && item.getItemMeta().hasDisplayName() + ? ChatColor.stripColor(frame.getItem().getItemMeta().getDisplayName()).toLowerCase() : null; + if (name != null && name.contains("upgrade buy: $")) { + Vice.getShopManager().buyArmorUpgrade(player, name); + return; + } + break; + } + case EMPTY_MAP: + case MAP: + frame.setRotation(Rotation.NONE); + MenuManager.openMenu(player, "lottery"); + break; + + default: + String name = item.hasItemMeta() && item.getItemMeta().hasDisplayName() + ? ChatColor.stripColor(frame.getItem().getItemMeta().getDisplayName()) : null; + if (name != null && Objects.equals("spawn", frame.getWorld().getName()) && name.startsWith("Floor")) { + if (name.toLowerCase().endsWith("up")) { + Location loc = player.getLocation(); + if (ViceUtils.ascendLevel(player)) { + player.sendMessage(Lang.VICE.f("&7Ascended a level.")); + } else { + player.sendMessage(Lang.VICE.f("&7No free spot above you found.")); + } + break; + } else if (name.toLowerCase().endsWith("down")) { + Location loc = player.getLocation(); + if (ViceUtils.descendLevel(player)) { + player.sendMessage(Lang.VICE.f("&7Descended a level.")); + } else { + player.sendMessage(Lang.VICE.f("&7No free spot below you found.")); + } + break; + } + } + if (name != null && name.startsWith("Preview Kit: ")) { + Kit kit = Vice.getItemManager().getKit(name.replace("Preview Kit: ", "")); + if (kit != null) + Vice.getBackpackManager().kitPreview(player, kit); + return; + } + Vice.getShopManager().buy(player, frame.getItem()); + break; + } + return; + case VILLAGER: + if (Vice.getCombatLogManager().getCombatLogNPCs().contains((NPC) e.getRightClicked())) { + e.setCancelled(true); + + return; + } + default: + break; + } + } + + @EventHandler + public void onInteractAtEntity(PlayerInteractAtEntityEvent e) { + Player player = e.getPlayer(); + ViceUser viceUser = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + Entity en = e.getRightClicked(); + if (en == null || e.getHand() != EquipmentSlot.HAND) { + e.setCancelled(true); + return; + }//so it only triggers once + switch (en.getType()) { + case ARMOR_STAND: + if (user.hasEditMode()) + break; + ArmorStand armorStand = (ArmorStand) e.getRightClicked(); + String name = ChatColor.stripColor(armorStand.getCustomName()); + if (name == null) break; + switch (name.toLowerCase()) { + case "mechanic": + MenuManager.openMenu(player, "mechanic"); + return; + case "cab driver": + MenuManager.openMenu(player, "taxi"); + return; + case "warden": + MenuManager.openMenu(player, "jail"); + return; + case "arms dealer": + MenuManager.openMenu(player, "weapons"); + return; + case "head salesman": + ItemStack item = player.getInventory().getItemInMainHand(); + MenuManager.openMenu(player, item != null && item.getType() == Material.SKULL_ITEM ? "auctionhead" : "heads"); + return; + default: + return; + } + + case VILLAGER: { + Villager villager = (Villager) en; + if (villager.hasMetadata("loggedplayer")) { + e.setCancelled(true); + return; + } + if (player.isSneaking() && viceUser.getCheatCodeState(CheatCode.VILLAGERJOB).getState() == State.ON) { + e.setCancelled(true); + if (user.isOnCooldown("villager_job_cc")) { + player.sendMessage(Lang.CHEAT_CODES.f("&7You must wait &a" + user.getFormattedCooldown("villager_job_cc") + " &7before using this cheatcode again!")); + return; + } + Faction cFac = Board.getInstance().getFactionAt(new FLocation(player.getLocation())); + FPlayer fPlayer = FPlayers.getInstance().getByPlayer(player); + + if (fPlayer.getRelationTo(cFac) == Relation.ENEMY) { + player.sendMessage(Lang.CHEAT_CODES.f("&7You cannot change the job of a villager in an enemy's faction!")); + return; + } + viceUser.setChangingJob(villager); + new BukkitRunnable() { + @Override + public void run() { + MenuManager.openMenu(player, "choose_villager_type"); + } + }.runTaskLater(Vice.getInstance(), 1); + return; + } + +// if (villager.getRecipes() == null || villager.getRecipes().isEmpty()) return; +// List<MerchantRecipe> filtered = new ArrayList<>(); +// for (int i = 0; i < villager.getRecipes().size(); i++) { +// MerchantRecipe recipe = villager.getRecipe(i); +// switch (recipe.getResult().getType()) { +// case WOOD_SWORD: +// case STONE_SWORD: +// case IRON_SWORD: +// case GOLD_SWORD: +// case DIAMOND_SWORD: +// +// case LEATHER_BOOTS: +// case LEATHER_LEGGINGS: +// case LEATHER_CHESTPLATE: +// case LEATHER_HELMET: +// case CHAINMAIL_BOOTS: +// case CHAINMAIL_LEGGINGS: +// case CHAINMAIL_CHESTPLATE: +// case CHAINMAIL_HELMET: +// case IRON_BOOTS: +// case IRON_LEGGINGS: +// case IRON_CHESTPLATE: +// case IRON_HELMET: +// case GOLD_BOOTS: +// case GOLD_LEGGINGS: +// case GOLD_CHESTPLATE: +// case GOLD_HELMET: +// case DIAMOND_BOOTS: +// case DIAMOND_LEGGINGS: +// case DIAMOND_CHESTPLATE: +// case DIAMOND_HELMET: +// +// case FLINT_AND_STEEL: +// break; +// default: +// filtered.add(recipe); +// break; +// } +// } +// +// villager.setRecipes(filtered); +// +// if (villager.getInventory() != null) +// player.openInventory(villager.getInventory()); +// break; + } + default: + break; + } + } + + @EventHandler + protected final void onSpawnerChange(PlayerInteractEvent event) { + if (event.getClickedBlock() != null && event.getItem() != null && + event.getClickedBlock().getType() == Material.MOB_SPAWNER && event.getItem().getType() == Material.MONSTER_EGG) { + event.setCancelled(true); + } + } + + // TODO remove as this is just to stop a dupe glitch of + // stacking similarly named items onto eachother to dupe them + @EventHandler(priority = EventPriority.HIGHEST) + public void onAnvilInteract(PlayerInteractEvent event) { + + // grab event variables + Player p = event.getPlayer(); + Action a = event.getAction(); + Block block = event.getClickedBlock(); + + if (block != null && block.getType() == Material.ANVIL) { + event.setCancelled(true); + event.setUseInteractedBlock(Result.DENY); + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/InventoryClick.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/InventoryClick.java new file mode 100644 index 0000000..2d7a871 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/InventoryClick.java @@ -0,0 +1,223 @@ +package net.grandtheftmc.vice.listeners; + +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.items.GameItem; +import net.grandtheftmc.vice.events.ArmorEquipEvent; +import net.grandtheftmc.vice.events.EquipArmorType; +import net.grandtheftmc.vice.users.ViceUser; +import net.grandtheftmc.vice.users.storage.BooleanStorageType; +import net.md_5.bungee.api.ChatColor; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryAction; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.player.PlayerSwapHandItemsEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +public class InventoryClick implements Listener { + + @EventHandler + public final void equipEventRunner(final InventoryClickEvent e){ + boolean shift = false, numberkey = false; + if(e.isCancelled()) return; + if(e.getClick().equals(ClickType.SHIFT_LEFT) || e.getClick().equals(ClickType.SHIFT_RIGHT)){ + shift = true; + } + + if(e.getClick().equals(ClickType.NUMBER_KEY)){ + numberkey = true; + } + + if(e.getSlotType() != InventoryType.SlotType.ARMOR && e.getSlotType() != InventoryType.SlotType.QUICKBAR && e.getSlotType() != InventoryType.SlotType.CONTAINER) return; + if(e.getClickedInventory() != null && !e.getClickedInventory().getType().equals(InventoryType.PLAYER)) return; + if (!e.getInventory().getType().equals(InventoryType.CRAFTING) && !e.getInventory().getType().equals(InventoryType.PLAYER)) return; + if(!(e.getWhoClicked() instanceof Player)) return; + if(e.getCurrentItem() == null) return; + EquipArmorType newEquipArmorType = EquipArmorType.matchType(shift ? e.getCurrentItem() : e.getCursor()); + if(!shift && newEquipArmorType != null && e.getRawSlot() != newEquipArmorType.getSlot()){ + // Used for drag and drop checking to make sure you aren't trying to place a helmet in the boots place. + return; + } + if(shift){ + newEquipArmorType = EquipArmorType.matchType(e.getCurrentItem()); + if(newEquipArmorType != null){ + boolean equipping = true; + if(e.getRawSlot() == newEquipArmorType.getSlot()){ + equipping = false; + } + if(newEquipArmorType.equals(EquipArmorType.HELMET) && (equipping ? e.getWhoClicked().getInventory().getHelmet() == null : e.getWhoClicked().getInventory().getHelmet() != null) || newEquipArmorType.equals(EquipArmorType.CHESTPLATE) && (equipping ? e.getWhoClicked().getInventory().getChestplate() == null : e.getWhoClicked().getInventory().getChestplate() != null) || newEquipArmorType.equals(EquipArmorType.LEGGINGS) && (equipping ? e.getWhoClicked().getInventory().getLeggings() == null : e.getWhoClicked().getInventory().getLeggings() != null) || newEquipArmorType.equals(EquipArmorType.BOOTS) && (equipping ? e.getWhoClicked().getInventory().getBoots() == null : e.getWhoClicked().getInventory().getBoots() != null)){ + ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent((Player) e.getWhoClicked(), ArmorEquipEvent.EquipMethod.SHIFT_CLICK, newEquipArmorType, equipping ? null : e.getCurrentItem(), equipping ? e.getCurrentItem() : null); + Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent); + if(armorEquipEvent.isCancelled()){ + e.setCancelled(true); + } + } + } + }else{ + ItemStack newArmorPiece = e.getCursor(); + ItemStack oldArmorPiece = e.getCurrentItem(); + if(numberkey){ + if(e.getClickedInventory().getType().equals(InventoryType.PLAYER)){// Prevents shit in the 2by2 crafting + // e.getClickedInventory() == The players inventory + // e.getHotBarButton() == key people are pressing to equip or unequip the item to or from. + // e.getRawSlot() == The slot the item is going to. + // e.getSlot() == Armor slot, can't use e.getRawSlot() as that gives a hotbar slot ;-; + ItemStack hotbarItem = e.getClickedInventory().getItem(e.getHotbarButton()); + if(hotbarItem != null){// Equipping + newEquipArmorType = EquipArmorType.matchType(hotbarItem); + newArmorPiece = hotbarItem; + oldArmorPiece = e.getClickedInventory().getItem(e.getSlot()); + }else{// Unequipping + newEquipArmorType = EquipArmorType.matchType(e.getCurrentItem() != null && e.getCurrentItem().getType() != Material.AIR ? e.getCurrentItem() : e.getCursor()); + } + } + }else{ + // e.getCurrentItem() == Unequip + // e.getCursor() == Equip + newEquipArmorType = EquipArmorType.matchType(e.getCurrentItem() != null && e.getCurrentItem().getType() != Material.AIR ? e.getCurrentItem() : e.getCursor()); + } + if(newEquipArmorType != null && e.getRawSlot() == newEquipArmorType.getSlot()){ + ArmorEquipEvent.EquipMethod method = ArmorEquipEvent.EquipMethod.DRAG; + if(e.getAction().equals(InventoryAction.HOTBAR_SWAP) || numberkey) method = ArmorEquipEvent.EquipMethod.HOTBAR_SWAP; + ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent((Player) e.getWhoClicked(), method, newEquipArmorType, oldArmorPiece, newArmorPiece); + Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent); + if(armorEquipEvent.isCancelled()){ + e.setCancelled(true); + } + } + } + } + + @EventHandler + public void onClick(InventoryClickEvent e) { + Player player = (Player) e.getWhoClicked(); + Inventory inv = e.getInventory(); + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + ItemStack clicked = e.getCurrentItem(); + ClickType click = e.getClick(); + if (e.getClickedInventory() == null) + return; + + if (user.getBooleanFromStorage(BooleanStorageType.BACKPACK_OPEN)) { +// if(e.getClick()==ClickType.NUMBER_KEY){ +// e.setCancelled(true); +// return; +// } +// ItemStack drug = click.isShiftClick() ? e.getCurrentItem() : e.getCursor(); +// if(drug!=null){ +// if(drug.getType().toString().endsWith("SHULKER_BOX")){ +// e.setCancelled(true); +// return; +// } +// else{ +// GameItem item = Vice.getItemManager().getItem(drug); +// if(item !=null && item.canSell() && (click.isShiftClick() || e.getClickedInventory().getType()==InventoryType.CHEST)){ +// e.setCancelled(true); +// return; +// } +// } +// } +// System.out.println("TEST"); + } + + if(inv.getType()==InventoryType.ENDER_CHEST) { + if(e.getClick()==ClickType.NUMBER_KEY){ + e.setCancelled(true); + return; + } + GameItem gi = Vice.getItemManager().getItem(click.isShiftClick() ? e.getCurrentItem() : e.getCursor()); + if(gi!=null && (gi.isScheduled() || gi.getItem().getType()==Material.WATCH || gi.getItem().getType()==Material.CHEST)) { + if (click.isShiftClick() && e.getClickedInventory().getType() == InventoryType.PLAYER) { + e.setCancelled(true); + } else if (!click.isShiftClick() && e.getClickedInventory().equals(inv)) + e.setCancelled(true); + } + } + if (e.getClickedInventory().getType() == InventoryType.PLAYER && (click==ClickType.LEFT || click==ClickType.RIGHT)) { + if (e.getSlot() == 17) { + Vice.getBackpackManager().openBackpack(player); + e.setCancelled(true); + return; + } else if (e.getSlot() == 16) { + MenuManager.openMenu(player, "ammopouch"); + e.setCancelled(true); + return; + } + } + String title = ChatColor.stripColor(e.getClickedInventory().getTitle()); + if (title.startsWith("Kit Preview: ")) { + e.setCancelled(true); + return; + } + if (title.endsWith("Corpse") && e.getCurrentItem().getType() == Material.STAINED_GLASS_PANE) { + e.setCancelled(true); + return; + } + + if (ViceUtils.isDefaultPlayerItem(clicked) && e.getClick() == ClickType.DOUBLE_CLICK) { + e.setCancelled(true); + player.updateInventory(); + } + } + + @EventHandler + public void onBackpackTransfer(InventoryClickEvent event) { + + ItemStack item = event.getCurrentItem(); + boolean shift = false; + + if(event.getClick() == ClickType.SHIFT_LEFT || event.getClick() == ClickType.SHIFT_RIGHT) shift = true; + + if (event.getClick() == ClickType.NUMBER_KEY) { + + if (item == null || item.getItemMeta() == null || item.getItemMeta().getDisplayName() == null) return; + + switch (ChatColor.stripColor(item.getItemMeta().getDisplayName())) { + case "Phone": + case "Ammo Pouch": + case "Backpack": + event.setCancelled(true); + break; + } + } + + if (shift) { + + if (item == null || item.getItemMeta() == null || item.getItemMeta().getDisplayName() == null) return; + + switch (ChatColor.stripColor(item.getItemMeta().getDisplayName())) { + case "Phone": + case "Ammo Pouch": + case "Backpack": + event.setCancelled(true); + break; + } + } else { + + ItemStack cursor = event.getCursor(); + Inventory inventory = event.getClickedInventory(); + + if (inventory == null) return; + + if (cursor == null) return; + + if (cursor.getItemMeta() != null && cursor.getItemMeta().getDisplayName() != null && ChatColor.stripColor(cursor.getItemMeta().getDisplayName()).equals("Phone") && cursor.getType() == Material.WATCH) { + event.setResult(Event.Result.DENY); + } + } + } + + @EventHandler + public void onSwitchToOffhand(PlayerSwapHandItemsEvent e) { + e.setCancelled(true); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/InventoryOpen.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/InventoryOpen.java new file mode 100644 index 0000000..c5c95f4 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/InventoryOpen.java @@ -0,0 +1,67 @@ +package net.grandtheftmc.vice.listeners; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.items.AmmoType; +import net.grandtheftmc.vice.users.ViceUser; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryOpenEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.player.PlayerPickupItemEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class InventoryOpen implements Listener { + + private final static List<Material> BANNED_MATERIALS = new ArrayList<>(Arrays.asList(Material.WOOD_SWORD, Material.STONE_SWORD, Material.IRON_SWORD, Material.GOLD_SWORD, Material.DIAMOND_SWORD, Material.LEATHER_BOOTS, Material.LEATHER_LEGGINGS, Material.CHAINMAIL_BOOTS, Material.CHAINMAIL_LEGGINGS, Material.GOLD_BOOTS, Material.GOLD_LEGGINGS, Material.IRON_BOOTS, Material.IRON_LEGGINGS, Material.DIAMOND_BOOTS, Material.DIAMOND_LEGGINGS)); + @EventHandler + public void onOpen(InventoryOpenEvent e) { + Inventory inv = e.getInventory(); + Player player = (Player) e.getPlayer(); + + String disp = ChatColor.stripColor(e.getInventory().getTitle()); + if(inv.getHolder()==null) + return; + for(ItemStack is : inv.getStorageContents()) { + if(is!=null && is.getDurability()==0 && BANNED_MATERIALS.contains(is.getType())) { + inv.removeItem(is); + } + } + + if (!"Loot Crate".equalsIgnoreCase(disp)) + return; + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + for (int i = 0; i < inv.getSize(); i++) { + ItemStack item = inv.getItem(i); + if (item == null) + continue; + AmmoType type = AmmoType.getAmmoType(item.getType(),item.getDurability()); + if (type == null||type.isInInventory()) + continue; + user.addAmmo(type, item.getAmount()); + player.sendMessage(Lang.AMMO_ADD.f(item.getAmount() + "&7 " + type.getGameItem().getDisplayName())); + inv.setItem(i, null); + } + } + + @EventHandler + protected final void onItemPickup(PlayerPickupItemEvent event) { + Player player = (Player) event.getPlayer(); + ItemStack itemStack = event.getItem().getItemStack(); + + if(itemStack != null && itemStack.getDurability()==0 && BANNED_MATERIALS.contains(itemStack.getType())) { + event.getItem().remove(); + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/InventoryPickupItem.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/InventoryPickupItem.java new file mode 100644 index 0000000..1643687 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/InventoryPickupItem.java @@ -0,0 +1,35 @@ +package net.grandtheftmc.vice.listeners; + +import net.grandtheftmc.vice.Vice; +import org.bukkit.entity.Item; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryPickupItemEvent; +import org.bukkit.inventory.ItemStack; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +/** + * Created by Timothy Lampen on 2017-08-07. + */ +public class InventoryPickupItem implements Listener { + + @EventHandler + public void onPickup(InventoryPickupItemEvent event){ + ItemStack item = event.getItem().getItemStack(); + HashMap<ItemStack, ItemStack> replacedVanillaItems = Vice.getItemManager().getReplacedVanilla(); + if(replacedVanillaItems.keySet().stream().anyMatch(value -> value.isSimilar(item))) { + Optional<Map.Entry<ItemStack, ItemStack>> optItemStack = replacedVanillaItems.entrySet().stream().filter(map -> map.getKey().isSimilar(item)).findFirst(); + if (optItemStack.isPresent()) { + event.setCancelled(true); + event.getItem().remove(); + ItemStack newItem = optItemStack.get().getValue(); + newItem.setAmount(item.getAmount()); + Item newI = event.getItem().getWorld().dropItem(event.getItem().getLocation(), newItem); + newI.setPickupDelay(0); + } + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/ItemBreak.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/ItemBreak.java new file mode 100644 index 0000000..3ca7198 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/ItemBreak.java @@ -0,0 +1,49 @@ +package net.grandtheftmc.vice.listeners; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.events.ArmorEquipEvent; +import net.grandtheftmc.vice.events.EquipArmorType; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerItemBreakEvent; +import org.bukkit.inventory.ItemStack; + +/** + * Created by Timothy Lampen on 7/24/2017. + */ +public class ItemBreak implements Listener { + + @EventHandler + public void armorEquipRunner(PlayerItemBreakEvent e) { + Player p = e.getPlayer(); + ItemStack is = e.getBrokenItem(); + if(is.getAmount()>1 && ViceUtils.isTool(is.getType())) { + is.setAmount(is.getAmount()-1); + is.setDurability((short)0); + return; + } + EquipArmorType type = EquipArmorType.matchType(e.getBrokenItem()); + if(type != null){ + ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(p, ArmorEquipEvent.EquipMethod.BROKE, type, e.getBrokenItem(), null); + Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent); + if(armorEquipEvent.isCancelled()){ + ItemStack i = is.clone(); + i.setAmount(1); + i.setDurability((short) (i.getDurability() - 1)); + if(type.equals(EquipArmorType.HELMET)){ + p.getInventory().setHelmet(i); + }else if(type.equals(EquipArmorType.CHESTPLATE)){ + p.getInventory().setChestplate(i); + }else if(type.equals(EquipArmorType.LEGGINGS)){ + p.getInventory().setLeggings(i); + }else if(type.equals(EquipArmorType.BOOTS)){ + p.getInventory().setBoots(i); + } + } + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/ItemComponent.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/ItemComponent.java new file mode 100644 index 0000000..d630885 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/ItemComponent.java @@ -0,0 +1,42 @@ +package net.grandtheftmc.vice.listeners; + +import net.grandtheftmc.core.util.Component; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.items.GameItem; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +public class ItemComponent implements Component<ItemComponent, Vice> { + + public ItemComponent() { + Bukkit.getPluginManager().registerEvents(this, Vice.getInstance()); + } + + @EventHandler + protected final void onItemRaname(InventoryClickEvent event) { + if (event.getInventory() == null) return; + if (event.getInventory().getType() != InventoryType.ANVIL) return; + if (event.getRawSlot() != event.getView().convertSlot(event.getRawSlot())) return; + if (event.getRawSlot() != 2) return; + + if (event.getInventory().getItem(0) == null) return; + if (event.getInventory().getItem(0).getType() == Material.AIR) return; + + if (event.getInventory().getItem(2) == null) return; + if (event.getInventory().getItem(2).getType() == Material.AIR) return; + + ItemStack itemStack = event.getInventory().getItem(0); + for (GameItem gameItem : Vice.getItemManager().getItems()) { + if (gameItem.getItem().isSimilar(itemStack)) { + event.setCancelled(true); + break; + } + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/ItemSpawn.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/ItemSpawn.java new file mode 100644 index 0000000..7079f74 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/ItemSpawn.java @@ -0,0 +1,30 @@ +package net.grandtheftmc.vice.listeners; + +import org.bukkit.ChatColor; +import org.bukkit.entity.Item; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.ItemSpawnEvent; +import org.bukkit.inventory.ItemStack; + +public class ItemSpawn implements Listener { + @EventHandler + public void onItemSpawn(ItemSpawnEvent e) { + Item item = e.getEntity(); + ItemStack stack = item.getItemStack(); + + if (stack != null) { + if (stack.hasItemMeta()) { + switch (ChatColor.stripColor(stack.getItemMeta().getDisplayName())) { + case "Backpack": + case "Ammo Pouch": + case "Phone": { + item.remove(); + + break; + } + } + } + } + } +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/ItemStack.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/ItemStack.java new file mode 100644 index 0000000..39d58ec --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/ItemStack.java @@ -0,0 +1,19 @@ +package net.grandtheftmc.vice.listeners; + +import net.grandtheftmc.core.events.ItemStackEvent; +import org.bukkit.Material; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +/** + * Created by Timothy Lampen on 3/10/2018. + */ +public class ItemStack implements Listener { + + @EventHandler + public void onStack(ItemStackEvent event) { + org.bukkit.inventory.ItemStack is = event.getItemStack(); + if(is!=null && is.getType()== Material.PRISMARINE_SHARD) + event.setCancelled(true); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/JetpackFuelUse.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/JetpackFuelUse.java new file mode 100644 index 0000000..642b6a5 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/JetpackFuelUse.java @@ -0,0 +1,47 @@ +package net.grandtheftmc.vice.listeners; + +import com.j0ach1mmall3.wastedvehicles.api.events.FuelUseEvent; +import com.massivecraft.factions.*; +import com.massivecraft.factions.struct.Relation; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.State; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.CheatCode; +import net.grandtheftmc.vice.users.ViceUser; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +/** + * Created by Timothy Lampen on 8/22/2017. + */ +public class JetpackFuelUse implements Listener { + + @EventHandler + public void onFuelUse(FuelUseEvent event){ + Player player = event.getPlayer(); + if(player.isOnline() && player.isValid()){ + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + if(user.getCheatCodeState(CheatCode.NOFUEL).getState()== State.ON) { + FPlayer fPlayer = FPlayers.getInstance().getByPlayer(player); + boolean badPlayersNearby = Bukkit.getOnlinePlayers().stream().anyMatch(target -> { + if(!target.getWorld().equals(player.getWorld()) || target.getLocation().distance(player.getLocation())>100) { + return false; + } + FPlayer fTarget = FPlayers.getInstance().getByPlayer(target); + if(fTarget.getRelationTo(fPlayer)==Relation.ENEMY) + return true; + return false; + }); + if(badPlayersNearby) {//there are enemies nearby so the fuel is going to be used. + return; + } + Faction cFac = Board.getInstance().getFactionAt(new FLocation(player.getLocation())); + if (cFac.isWilderness() || cFac.equals(fPlayer.getFaction()) || fPlayer.getFaction().getRelationTo(cFac) != Relation.ENEMY) { + event.setCancelled(true); + } + } + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Join.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Join.java new file mode 100644 index 0000000..f49b433 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Join.java @@ -0,0 +1,200 @@ +package net.grandtheftmc.vice.listeners; + +import com.google.common.collect.Maps; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.achivements.Achievement; +import net.grandtheftmc.core.resourcepack.ResourcePack; +import net.grandtheftmc.core.resourcepack.ResourcePackEvent; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.NMSVersion; +import net.grandtheftmc.core.util.State; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.combatlog.CombatLogger; +import net.grandtheftmc.vice.commands.AntiAuraCommand; +import net.grandtheftmc.vice.hologram.HologramManager; +import net.grandtheftmc.vice.items.ArmorUpgrade; +import net.grandtheftmc.vice.items.Head; +import net.grandtheftmc.vice.users.CheatCode; +import net.grandtheftmc.vice.users.ViceUser; +import net.grandtheftmc.vice.users.storage.BooleanStorageType; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Material; +import org.bukkit.Statistic; +import org.bukkit.entity.NPC; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.*; + +public class Join implements Listener { + + private final HashMap<UUID, Integer> resourcePackTries; + private final HologramManager hologramManager; +// private final BeerBottle beerBottle; + + public Join(HologramManager hologramManager) { + resourcePackTries = Maps.newHashMap(); + this.hologramManager = hologramManager; +// this.beerBottle = new BeerBottle(); + } + +// @EventHandler +// protected final void onCraft(PrepareItemCraftEvent event) { +// this.beerBottle.getAttribute().onEvent(event); +// } + + @EventHandler + public void onJoin(PlayerJoinEvent e) { + Player player = e.getPlayer(); + e.setJoinMessage(null); + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + ViceUser viceUser = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + ViceUtils.giveGameItems(player); + viceUser.setBooleanToStorage(BooleanStorageType.KICKED, false); + if (viceUser.getPlaytime() == 0L) { + int playOneTick = player.getStatistic(Statistic.PLAY_ONE_TICK); + viceUser.setPlaytime(Long.valueOf(playOneTick / 20)); + } + viceUser.setJointime(System.currentTimeMillis()); + if (player.hasPermission("antiaura.admin") && !AntiAuraCommand.TOGGLED_PLAYERS.contains(player.getName())) { + AntiAuraCommand.TOGGLED_PLAYERS.add(player.getName()); + } + + //Force gamemode SURVIVAL + player.setGameMode(GameMode.SURVIVAL); + + if (player.getGameMode() == GameMode.SPECTATOR) { + player.getActivePotionEffects().clear(); + player.setFoodLevel(20); + player.setFlying(false); + player.setFlySpeed(0.1F); + if (!viceUser.isArrested()) + player.teleport(Vice.getWorldManager().getWarpManager().getSpawn().getLocation()); + } + + ViceUtils.sendJoinMessage(player, user); + if (!player.hasPlayedBefore()) { + Utils.broadcastExcept(player, + Lang.VICE.f("&7Welcome " + user.getColoredName(player) + "&7 to &7&lGrand Theft Minecart&r!")); + player.teleport(Vice.getWorldManager().getWarpManager().getSpawn().getLocation()); + player.chat("/tutorial start Vice"); + } else if (viceUser.isArrested()) + player.teleport(Vice.getWorldManager().getWarpManager().getJail().getLocation()); + Head head = Vice.getShopManager().getHead(player.getName()); + if (head != null && head.getBidderUUID() != null && !Objects.equals(head.getBidderUUID(), player.getUniqueId()) && !head.isDone()) + player.sendMessage(Lang.HEAD_AUCTION.f("&7Your head is currently being auctioned by &a&l" + head.getSellerName() + "&7! The last bidder was &a&l" + head.getBidderName() + "&7 for &a$&l" + head.getBid() + "&7!")); + + // Vice.getLottery().joinCheck(player, user, viceUser); + + ViceUtils.updateBoard(player, viceUser); + player.setWalkSpeed(0.2F); + if (Objects.equals(player.getUniqueId().toString(), "0e4a6028-3d9a-4a2e-9797-eb1ddcb0aca9")) { + Bukkit.getOnlinePlayers().forEach(target -> { + User targetUser = Core.getUserManager().getLoadedUser(target.getUniqueId()); + targetUser.addAchievement(Achievement.Witness); + }); + } + NMSVersion version = NMSVersion.getVersion(player); + if (version == NMSVersion.MC_1_8) { + Utils.sendTitle(player, "&4&lTexturepack Load Fail", "&cRecommended: 1.9.4+", 20, 120, 20); + player.sendMessage(""); + player.sendMessage(Utils.f("&4&lUnable to load the texture pack for the version that you have joined with. Use 1.9.4+ for an optimal experience.")); + player.sendMessage(""); + } else { + sendPack(player, Vice.getResourcePackManager().getResourcePack(version)); + } + + NPC spawnedLoggerNPC = Vice.getCombatLogManager().getSpawnedNPCFromPlayer(player.getUniqueId()); + if (spawnedLoggerNPC != null) { + Vice.getCombatLogManager().removeNPC(spawnedLoggerNPC); + spawnedLoggerNPC.remove(); + } + + Optional<CombatLogger> logger = Vice.getCombatLogManager().getDestroyedCombatLogger(player.getUniqueId()); + if (logger.isPresent()) { + List<ItemStack> contents; + if (logger.get().getContents() == null) { + contents = new ArrayList<>(); + for (ItemStack is : player.getInventory().getContents()) { + if (is == null || is.getType() == Material.AIR || is.getType() == Material.WATCH) + continue; + if (ViceUtils.isDefaultPlayerItem(is)) + continue; + if (logger.get().isFromSpawn() && (Vice.getItemManager().getItem(is) == null || !Vice.getItemManager().getItem(is).isScheduled())) + continue; + contents.add(is); + } + } else { + contents = logger.get().getContents(); + } + for (ItemStack is : contents) { + if (is != null) + player.getInventory().removeItem(is); + } + for (int i = 36; i < 40; i++) { + ItemStack is = player.getInventory().getItem(i); + if (is == null || is.getType() == Material.AIR) + continue; + if (contents.contains(is)) { + player.getInventory().setItem(i, null); + } + } + player.updateInventory(); + Vice.getCombatLogManager().clearRemovedItems(player.getUniqueId()); + player.sendMessage(Lang.COMBATTAG.f("&e&lYour combatlog NPC was killed so items were removed from your inventory.")); + player.teleport(Vice.getWorldManager().getWarpManager().getSpawn().getLocation()); + } + ArmorUpgrade.reloadArmorUpgrades(player); + if (viceUser.getCheatCodeState(CheatCode.NIGHTVIS).getState() == State.ON) { + player.addPotionEffect(new PotionEffect(PotionEffectType.NIGHT_VISION, Integer.MAX_VALUE, 0)); + } + } + + private void sendPack(Player player, ResourcePack pack) { + UUID uuid = player.getUniqueId(); + new BukkitRunnable() { + @Override + public void run() { + Player p = Bukkit.getPlayer(uuid); + if (p == null || !p.isOnline()) return; + + if (!p.isValid()) sendPack(p, pack); + + if (pack != null) { + p.setResourcePack(pack.getPack()); + } + } + }.runTaskLater(Vice.getInstance(), 20L); + } + + @EventHandler + protected final void onResourcePack(ResourcePackEvent event) { + Player player = event.getPlayer(); + if (player == null) return; + + ViceUser viceUser = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + if (viceUser == null) return; + + player.sendTitle(Utils.f("&d&lWelcome to &oVice City!"), + "", + 60, + 30, + 40); + + if (viceUser.getKills() < player.getStatistic(Statistic.PLAYER_KILLS)) + viceUser.setKills(player.getStatistic(Statistic.PLAYER_KILLS)); + if (viceUser.getDeaths() < player.getStatistic(Statistic.DEATHS)) + viceUser.setDeaths(player.getStatistic(Statistic.DEATHS)); + viceUser.checkAchievements(); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Leave.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Leave.java new file mode 100644 index 0000000..b529e35 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Leave.java @@ -0,0 +1,72 @@ +package net.grandtheftmc.vice.listeners; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.commands.SpectatorCommand; +import net.grandtheftmc.vice.users.PersonalVehicle; +import net.grandtheftmc.vice.users.ViceUser; +import net.grandtheftmc.vice.users.storage.BooleanStorageType; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerKickEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +public class Leave implements Listener { + + @EventHandler + public void onKick(PlayerKickEvent e) { + Player player = e.getPlayer(); + ViceUser user = Vice.getUserManager().getLoadedUser(e.getPlayer().getUniqueId()); + user.setBooleanToStorage(BooleanStorageType.KICKED, true); + Vice.getCombatLogManager().spawnNPC(player, player.getWorld().getName().equals("spawn"), e.getReason().contains("spam")); + } + + @EventHandler + public void onLeave(PlayerQuitEvent e) { + Player player = e.getPlayer(); + UUID uuid = player.getUniqueId(); + ViceUser user = Vice.getUserManager().getLoadedUser(uuid); + Long leaveTime = System.currentTimeMillis(); + Long playtimeSeconds = TimeUnit.MILLISECONDS.toSeconds(leaveTime - user.getJoinTime()); + user.setPlaytime(user.getPlaytime() + playtimeSeconds); + if (player.getGameMode() == GameMode.SPECTATOR) { + player.getActivePotionEffects().clear(); + player.setFoodLevel(20); + player.setGameMode(GameMode.SURVIVAL); + player.setFlying(false); + player.setFlySpeed(0.1F); + if (user.isArrested()) { + player.teleport(Vice.getWorldManager().getWarpManager().getJail().getLocation()); + } else { + player.teleport(Vice.getWorldManager().getWarpManager().getSpawn().getLocation()); + } + } + Location loc = player.getLocation(); + User u = Core.getUserManager().getLoadedUser(uuid); +// u.removeCosmetics(player, CosmeticType.HAT); + if (user.hasPersonalVehicle()) { + PersonalVehicle vehicle = user.getPersonalVehicle(); + if (vehicle.onMap()) + vehicle.updateVehicleInDatabase(player, 0); + } + if (SpectatorCommand.getActiveStaff().contains(player.getName())) { + player.setGameMode(GameMode.SURVIVAL); + SpectatorCommand.getActiveStaff().remove(player.getName()); + } + Vice.getCombatLogManager().spawnNPC(player, player.getWorld().getName().equals("spawn")); + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onLeaveMonitor(PlayerQuitEvent e) { + Vice.getUserManager().unloadUser(e.getPlayer().getUniqueId()); + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Login.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Login.java new file mode 100644 index 0000000..871b890 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Login.java @@ -0,0 +1,42 @@ +package net.grandtheftmc.vice.listeners; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.ViceUser; +import net.grandtheftmc.vice.users.storage.BooleanStorageType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerPreLoginEvent; +import org.bukkit.event.player.PlayerLoginEvent; +import org.bukkit.event.player.PlayerLoginEvent.Result; + +import java.util.UUID; + +public class Login implements Listener { + + @EventHandler + public void onLogin(AsyncPlayerPreLoginEvent e) { + ViceUser user = Vice.getUserManager().getLoadedUser(e.getUniqueId()); + user.dataCheck(e.getName(), Core.getUserManager().getLoadedUser(e.getUniqueId()).getUserRank()); + if (!user.updateDataFromDb()) + e.disallow(org.bukkit.event.player.AsyncPlayerPreLoginEvent.Result.KICK_OTHER, + "&cAn error occured while trying to fetch your data from the database. Please try again in a few seconds!"); + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onLoginMonitor(PlayerLoginEvent e) { + Player player = e.getPlayer(); + UUID uuid = player.getUniqueId(); + ViceUser user = Vice.getUserManager().getLoadedUser(uuid); + if (!user.getBooleanFromStorage(BooleanStorageType.HAS_UPDATED)) + e.disallow(PlayerLoginEvent.Result.KICK_OTHER, Utils.f("&cThe server is still restarting! Please try again in a few seconds!")); + if (e.getResult() == Result.ALLOWED) + return; + Vice.getUserManager().unloadUser(uuid); + + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/MenuListener.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/MenuListener.java new file mode 100644 index 0000000..8accd0d --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/MenuListener.java @@ -0,0 +1,1634 @@ +package net.grandtheftmc.vice.listeners; + +import com.j0ach1mmall3.wastedvehicles.api.VehicleProperties; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.events.MoneyEvent; +import net.grandtheftmc.core.menus.Menu; +import net.grandtheftmc.core.menus.MenuClickEvent; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.menus.MenuOpenEvent; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.State; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.guns.weapon.Weapon; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.items.*; +import net.grandtheftmc.vice.tasks.LotteryPlayer; +import net.grandtheftmc.vice.users.*; +import net.grandtheftmc.vice.users.storage.BooleanStorageType; +import net.grandtheftmc.vice.utils.StringUtils; +import net.grandtheftmc.vice.world.warps.Warp; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.entity.Villager; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.text.NumberFormat; +import java.util.*; +import java.util.stream.Collectors; + + +public class MenuListener implements Listener { + + private static final int[] DEFAULT_PHONE_OPEN_SLOTS = new int[]{11,13,15,29,31,33,47,49,51}; + + @EventHandler(priority = EventPriority.HIGH) + public void onMenuOpen(MenuOpenEvent e) { + Player player = e.getPlayer(); + UUID uuid = player.getUniqueId(); + Menu menu = e.getMenu(); + switch (menu.getName()) { + case "choose_villager_type": { + this.setPhoneDefaults(e); + ViceUser viceUser = Vice.getUserManager().getLoadedUser(uuid); + if(viceUser.getChangingJob()==null) { + player.sendMessage(Lang.CHEAT_CODES.f("&7Cannot open this menu because you do not have a villager selected!")); + return; + } + int counter = 0; + for(Villager.Profession p : Villager.Profession.values()) { + ItemStack is = new ItemStack(Material.DIRT); + switch (p) { + case HUSK: + case NORMAL: + continue; + case BLACKSMITH: + is.setType(Material.ANVIL); + break; + case BUTCHER: + is.setType(Material.PORK); + break; + case LIBRARIAN: + is.setType(Material.BOOK); + break; + case FARMER: + is.setType(Material.WOOD_HOE); + break; + case PRIEST: + is.setType(Material.GOLDEN_APPLE); + break; + case NITWIT: + is.setType(Material.CARROT_STICK); + break; + } + ItemMeta im = is.getItemMeta(); + im.setDisplayName(Utils.f("&6&lJob: &b&l" + StringUtils.getCapitalized(p.toString().toLowerCase()))); + is.setItemMeta(im); + e.setItem(DEFAULT_PHONE_OPEN_SLOTS[counter], is); + counter++; + } + return; + } + case "cheatcodes": { + this.setPhoneDefaults(e); + int[] slots = new int[]{11, 12, 14, 15, 20, 21, 23, 24, 29, 30, 32, 33, 39, 40, 41}; + for (int i = 0; i < CheatCode.values().length; i++) {//will only work with a max of 9 codes + int slot = slots[i]; + CheatCode code = CheatCode.values()[i]; + State state = Vice.getUserManager().getLoadedUser(uuid).getCheatCodeState(code).getState(); + e.setItem(slot, code.getDisplayItem(Core.getUserManager().getLoadedUser(uuid), state)); + } + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the contacts page!")); + e.setItem(51, Utils.createItem(Material.BOOK, "&2&lActivating Cheatcodes", "&7You can activate cheatcodes by clicking the item in this menu,", "&7by using &a&l/<cheatcode>&7, and &a&l/cheatcode <cheatcode>&7!")); + return; + } + case "phone": + this.setPhoneDefaults(e); + e.setItem(11, + Utils.createItem(Material.ENDER_CHEST, "&e&lCosmetics", "&7Stand out from the crowd!")); + e.setItem(15, Utils.createItem(Material.MINECART, "&c&lVehicles", "&7Ride in style!")); + e.setItem(29, Utils.createItem(Material.EMPTY_MAP, "&a&lRanks", "&7Working my way to the top!")); + e.setItem(31, Utils.createItem(Material.NETHER_STAR, "&d&lMy Account", "&7Stats, Ranks and Prefs!")); + e.setItem(33, Utils.createItem(Material.CHEST, "&b&lKits", "&7Gear up!")); + e.setItem(47, Utils.createItem(Material.BOOK, "&6&lContacts", "&7Call your associates!")); + e.setItem(49, Utils.createItem(Material.EMERALD, "&a&lStore", "&7Support the server!")); + e.setItem(51, Utils.createItem(Material.EXP_BOTTLE, "&a&lRewards", "&7Voting, daily and donor bonuses!")); + return; + case "cosmetics": + case "rewards": + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the home page!")); + return; + case "vote": + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the rewards page!")); + return; + case "account": + this.setPhoneDefaults(e); + e.setItem(22, Utils.createItem(Material.NAME_TAG, "&6&lUnlocked Tags", "&7Change your name prefix!")); + e.setItem(11, Utils.createItem(Material.BOOK, "&d&lStats", "&7You got skills!")); + e.setItem(15, Utils.createItem(Material.REDSTONE_COMPARATOR, "&5&lPreferences", "&7Toggle your shit!")); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the home page!")); + e.setItem(49, Utils.createItem(Material.NETHER_STAR, "&d&lMy Account", "&7Take care of your biz!")); + return; + case "prefs": + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the account page!")); + return; + case "ranks": { + this.setPhoneDefaults(e); + int[] viceRankSlots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24}; + int[] donorSlots = new int[]{38, 39, 40, 41, 42}; + int i = 0; + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + for (ViceRank rank : ViceRank.values()) { + List<String> lore = new ArrayList<>(); + lore.add(""); + if (rank.getPrice() > 0) { + lore.add("&7Price: &a$&l" + rank.getPrice()); + lore.add(""); + } + lore.add("&aPerks:"); + lore.add(""); + lore.add("&bKit " + rank.getColoredNameBold() + "&7!"); + switch (rank) { + case JUNKIE: + lore.add("&7Drivers License! (&a&lCars&7)"); + lore.add("&a&l1x&7 /home set!"); + break; + case FALCON: + lore.add("&7Team up! (Join a &a&lCartel&7)"); + lore.add("&7Unlock &e&lMarksman Pistol&7!"); + lore.add("&7Auction &a&l1&7 item! (&aComing soon&7!)"); + lore.add("&7Call a &6&lCab&7! (&a/tpa&7)"); + break; + case THUG: + lore.add("&7Unlock &e&lHeavy Shotgun&7!"); + lore.add("&7Auction &a&l2&7 items! (&aComing soon&7!)"); + lore.add("&7Craft items on the go! (&a/workbench&7)"); + break; + case DEALER: + lore.add("&7Apply for &3&lCop&7!"); + lore.add("&7Unlock &e&lChainsaw&7!"); + lore.add("&7Unlock &e&lGusenberg Sweeper&7!"); + break; + case GROWER: + lore.add("&7Create your own &e&lCartel&7!"); + lore.add("&a&l2x&7 /home set!"); + lore.add("&7Unlock &e&lRPG&7!"); + break; + case SMUGGLER: + lore.add("&7Unlock &e&lHeavy Sniper&7!"); + break; + case CHEMIST: + lore.add("&7Unlock &e&lSpecial Carbine&7!"); + lore.add("&7Auction &a&l3&7 items! (&aComing soon&7!)"); + break; + case DRUGLORD: + lore.add("&7Unlock &e&lGrenade Launcher&7!"); + lore.add("&7Auction &a&l4&7 items! (&aComing soon&7!)"); + lore.add("&7Up, up and away! (&4&lJetpack&7)"); + break; + case KINGPIN: + lore.add("&7Unlock &e&lCombat MG&7!"); + lore.add("&a&l3x&7 /home set!"); + break; + case GODFATHER: + lore.add("&7Unlock &e&lHoming Launcher&7!"); + lore.add("&7Unlock &e&lMinigun&7!"); + lore.add("&7Auction &a&l5&7 items! (&aComing soon&7!)"); + lore.add("&7Enderchest anywhere! (&a/echest&7)"); + break; + default: + lore.add("&7Rank up for cool perks!"); + } + e.setItem(viceRankSlots[i], + Utils.createItem(rank.getMaterial(), rank.getColoredNameBold(), Utils.f(lore))); + i++; + } + i = 0; + for (UserRank rank : new UserRank[]{UserRank.VIP, UserRank.PREMIUM, UserRank.ELITE, UserRank.SPONSOR, UserRank.SUPREME}) { + List<String> lore = new ArrayList<>(); + // TODO + lore.add(""); + lore.add("&7Price: &a$&l" + rank.getPrice()); + lore.add(""); + lore.add("&aPerks:"); + lore.add(""); + lore.add("&a+ &e&l" + rank.getMonthlyTokens() + " Tokens &a&lmonthly&7!"); + lore.add("&bKit " + rank.getColoredNameBold() + "&7!"); + lore.add("&a&l" + ViceUtils.getBackpackRows(rank) + "&6&l Backpack &7rows!"); + lore.add("&a+ $&l" + ViceUtils.getStartingMoney(rank) + "&7 in-game money!"); + lore.add("&a+ " + ViceUtils.getWarpDelay(rank) + "&7s delay &6&lTaxi Service&7!"); + lore.add("&a+ " + ViceUtils.getSetHomes(rank) + "x&7 /home set!"); + lore.add("&a+ &l"+ Math.round(ViceUtils.getDrugSellModifier(rank) *100) + "&a%&7 sell multiplier!"); + if (rank.isHigherThan(UserRank.VIP)) { + lore.add("&a+ Instantly&7 teleport anywhere from spawn!"); + lore.add("&a+ &7Join &c&lFull&7 servers!"); + } + if (rank.isHigherThan(UserRank.PREMIUM)) { + lore.add("&a+ &7Pick up your friend! (&a&l/tpahere&7)"); + lore.add("&a+ &7Apply for &3&lCop&7!"); + } + if (rank.isHigherThan(UserRank.ELITE)) { + lore.add("&a+ &7Quick sell Cheatcode"); + lore.add("&a+ &7Satisfy yourself! (&a&l/feed&7)"); + lore.add("&a+ &7Up, up and away! (&4&lJetpack&7)"); + } + for (LockedWeapon w : LockedWeapon.values()) { + if (w.getUserRank() == rank || rank.isHigherThan(w.getUserRank())) { + GameItem g = Vice.getItemManager().getItemFromWeapon(w.toString()); + if (g != null) + lore.add("&a+ &7Unlock " + g.getDisplayName() + "&7 instantly!"); + } + } + e.setItem(donorSlots[i], Utils.createItem(rank.getMaterial(), rank.getColoredNameBold(), lore)); + i++; + + } + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to my account!")); + ViceRank next = user.getRank().getNext(); + if (next != null) + e.setItem(31, Utils.createItem(Material.PAPER, "&a&lRankup to " + next.getColoredNameBold() + "&a&l!", + "&7Price: &" + (user.hasMoney(next.getPrice()) ? "a" : "c") + "$&l" + next.getPrice())); + return; + } + case "vicestats": { + this.setPhoneDefaults(e); + ViceUser u = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + e.setItem(11, Utils.createItem(Material.PAPER, "&a&lMoney: &f" + Utils.round(u.getMoney()))); + e.setItem(15, Utils.createItem(Material.EMPTY_MAP, "&3&lBonds: &f" + u.getBonds())); + e.setItem(29, Utils.createItem(Material.IRON_SWORD, "&e&lKills: &f" + u.getKills())); + e.setItem(31, Utils.createItem(Material.SKULL_ITEM, "&c&lDeaths: &f" + u.getDeaths())); + e.setItem(33, Utils.createItem(Material.IRON_SWORD, "&a&lK/D Ratio: &f" + u.getKDR())); + e.setItem(49, Utils.createItem(Material.BOOK_AND_QUILL, "&6&lKillstreak: &f" + u.getKillStreak())); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to my account!")); + return; + } + + case "kits": { + this.setPhoneDefaults(e); + ViceUser viceUser = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the home page!")); + int[] grSlots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24}; + int[] otherSlots = new int[]{29, 30, 31, 32, 33}; + int[] urSlots = new int[]{38, 39, 40, 41, 42}; + int i = 0; + ViceRank viceRank = viceUser.getRank(); + for (ViceRank rank : ViceRank.values()) { + Kit kit = Vice.getItemManager().getKit(rank.getName().toLowerCase()); + if (kit == null) { + continue; + } + List<String> lore = new ArrayList<>(); + lore.add(""); + if (rank != viceRank) + lore.add("&cRequires " + rank.getName()); + if (kit.getCost() > 0) + lore.add("&7Cost: &a$&l" + kit.getCost()); + if (kit.getDelay() > 0) + lore.add(viceUser.canUseKit(kit.getName()) + ? "&7Delay: &a&l" + Utils.timeInSecondsToText(kit.getDelay()) + : "&cTime Left: &l" + Utils.timeInMillisToText( + viceUser.getKitExpiry(kit.getName()) - System.currentTimeMillis())); + lore.add(""); + lore.addAll(kit.getContents().stream().map(KitItem::getDescription).collect(Collectors.toList())); + if (kit.getHelmet() != null) + lore.add("&7Helmet: " + kit.getHelmet().getDescription()); + if (kit.getChestPlate() != null) + lore.add("&7Chestplate: " + kit.getChestPlate().getDescription()); + if (kit.getLeggings() != null) + lore.add("&7Leggings: " + kit.getLeggings().getDescription()); + if (kit.getBoots() != null) + lore.add("&7Boots: " + kit.getBoots().getDescription()); + if (kit.getOffHand() != null) + lore.add("&7Offhand: " + kit.getOffHand().getDescription()); + ItemStack item = Utils.createItem(rank.getMaterial(), rank.getColoredNameBold(), lore); + e.setItem(grSlots[i], item); + i++; + } + i = 0; + for (UserRank rank : UserRank.getDonorRanks()) { + Kit kit = Vice.getItemManager().getKit(rank.getName().toLowerCase()); + if (kit == null) { + i++; + continue; + } + List<String> lore = new ArrayList<>(); + lore.add(""); + if (!(rank == user.getUserRank() + || (rank == UserRank.SUPREME && user.getUserRank().isHigherThan(UserRank.SUPREME)))) + lore.add("&cRequires " + rank.getColoredNameBold()); + if (kit.getCost() > 0) + lore.add("&7Cost: &a$&l" + kit.getCost()); + if (kit.getDelay() > 0) + lore.add(viceUser.canUseKit(kit.getName()) + ? "&7Delay: &a&l" + Utils.timeInSecondsToText(kit.getDelay()) + : "&cTime Left: &l" + Utils.timeInMillisToText( + viceUser.getKitExpiry(kit.getName()) - System.currentTimeMillis())); + lore.add(""); + lore.addAll(kit.getContents().stream().map(KitItem::getDescription).collect(Collectors.toList())); + if (kit.getHelmet() != null) + lore.add("&7Helmet: " + kit.getHelmet().getDescription()); + if (kit.getChestPlate() != null) + lore.add("&7Chestplate: " + kit.getChestPlate().getDescription()); + if (kit.getLeggings() != null) + lore.add("&7Leggings: " + kit.getLeggings().getDescription()); + if (kit.getBoots() != null) + lore.add("&7Boots: " + kit.getBoots().getDescription()); + if (kit.getOffHand() != null) + lore.add("&7Offhand: " + kit.getOffHand().getDescription()); + ItemStack item = Utils.createItem(rank.getMaterial(), rank.getColoredNameBold(), lore); + e.setItem(urSlots[i], item); + i++; + } + i = 0; + for (Kit kit : Vice.getItemManager().getKits()) { + if (net.grandtheftmc.vice.users.ViceRank.getRankOrNull(kit.getName()) != null || UserRank.getUserRankOrNull(kit.getName()) != null + || CopRank.getRankOrNull(kit.getName()) != null || i>=5) + continue; + List<String> lore = new ArrayList<>(); + lore.add(""); + if (kit.getPermission() != null && !player.hasPermission(kit.getPermission())) + lore.add("&cRequires permission " + kit.getPermission()); + if (kit.getCost() > 0) + lore.add("&7Cost: &a$&l" + kit.getCost()); + if (kit.getDelay() > 0) + lore.add(viceUser.canUseKit(kit.getName()) + ? "&7Delay: &a&l" + Utils.timeInMillisToText((long) kit.getDelay() * 1000) + : "&cTime Left: &l" + Utils.timeInMillisToText( + viceUser.getKitExpiry(kit.getName()) - System.currentTimeMillis())); + lore.add(""); + lore.addAll(kit.getContents().stream().map(KitItem::getDescription).collect(Collectors.toList())); + + ItemStack item = Utils.createItem(kit.getMaterial(), "&b&l" + kit.getName(), lore); + e.setItem(otherSlots[i], item); + i++; + if (i > otherSlots.length) + break; + } + return; + + } + case "contacts": { + this.setPhoneDefaults(e); + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + e.setItem(11, Utils.createItem(Material.STORAGE_MINECART, "&e&lTaxi Service", "&7Click to select a destination!")); + e.setItem(13, Utils.createItem(Material.SKULL_ITEM, 2, user.isCop() ? "&3&lBackup" : "&3&lPolice", user.isCop() ? "&7Click to request help from fellow officers!" : "&7Click to call the cops to your location!")); + e.setItem(29, Utils.createItem(Material.ANVIL, "&2&lCheat Codes", "&7Become a cheater and rule the game!")); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the home page!")); + e.setItem(49, Utils.createItem(Material.WATCH, "&c&l911 Emergency", "&7Click to teleport out of here!")); + return; + } + case "taxi": + this.setPhoneDefaults(e); + e.setItem(11, Utils.createItem(Material.SKULL_ITEM, 3, "&e&lPlayer", "&7Click to select a player!")); + e.setItem(13, Utils.createItem(Material.ENDER_PEARL, "&e&lWarp", "&7Click to select a warp!")); + e.setItem(15, Utils.createItem(Material.IRON_DOOR, "&3&lHouse", "&7Click to select a house!")); + e.setItem(29, Utils.createItem(Material.ANVIL, "&2&lCheat Codes", "&7Become a cheater and rule the game!")); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the contacts page!")); + e.setItem(49, Utils.createItem(Material.STORAGE_MINECART, "&e&lTaxi Service", + "&7Click a button to select your destination!")); + return; + case "taxiplayers": { + this.setPhoneDefaults(e); + List<Player> players = Bukkit.getOnlinePlayers().stream().filter(bp -> !Objects.equals(player.getUniqueId(), bp.getUniqueId())).collect(Collectors.toList()); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + Iterator<Player> it = players.iterator(); + User u = Core.getUserManager().getLoadedUser(player.getUniqueId()); + for (int i = 0; i < 20; i++) { + if (!it.hasNext()) + break; + Player p = it.next(); + e.setItem( + slots[i], Utils + .setSkullOwner( + Utils.createItem(Material.SKULL_ITEM, 3, + "&e&l" + p.getName(), u.isPremium() + ? "&7Click to send teleport request!" : "&cRequires PREMIUM!"), + p.getName())); + } + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the taxi page!")); + e.setItem(49, Utils.createItem(Material.STORAGE_MINECART, "&e&lTaxi Service: Players", "&7Page 1")); + if (players.size() > 20) + e.setItem(50, Utils.createItem(Material.ARROW, "&e&lNext Page", "&7Page 2")); + return; + } + + case "taxiwarps": { + this.setPhoneDefaults(e); + User u = Core.getUserManager().getLoadedUser(uuid); + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + List<Warp> warps = Vice.getWorldManager().getWarpManager().getWarps(); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + Iterator<Warp> it = warps.iterator(); + for (int i = 0; i < 20; i++) { + if (!it.hasNext()) + break; + Warp warp = it.next(); + e.setItem(slots[i], Utils.createItem(Material.ENDER_PEARL, "&e&l" + warp.getName(), + u.isRank(UserRank.ELITE) ? "&7Click to teleport!" : "&7Click to teleport for &a$&l200&7!")); + } + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the taxi page!")); + e.setItem(49, Utils.createItem(Material.STORAGE_MINECART, "&e&lTaxi Service: Warps", "&7Page 1")); + if (warps.size() > 20) + e.setItem(50, Utils.createItem(Material.ARROW, "&e&lNext Page", "&7Page 2")); + return; + } + + case "ammopouch": { + ViceUser user = Vice.getUserManager().getLoadedUser(uuid); + int i = 0; + for (AmmoType type : AmmoType.getTypes()) { + if (type.isInInventory()) + continue; + ItemStack item = type.getGameItem().getItem(); + int a = user.getAmmo(type); + ItemMeta meta = item.getItemMeta(); + meta.setLore(Collections.singletonList(Utils.f("&7Amount: &a&l" + a))); + item.setItemMeta(meta); + if (a > 1) item.setAmount(a >= 127 ? 127 : a); + e.setItem(i, item); + e.setItem(i + 9, Utils.createItem(Material.REDSTONE, "&c&lDrop " + 50, 50)); + e.setItem(i + 18, Utils.createItem(Material.REDSTONE, "&c&lDrop " + 10, 10)); + e.setItem(i + 27, Utils.createItem(Material.REDSTONE, "&c&lDrop " + 1, 1)); + i++; + } + ItemStack grayGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a"); + for (int n : new int[]{8, 17, 26, 35}) + e.setItem(n, grayGlass); + return; + + } + case "jail": { + this.setPhoneDefaults(e); + ViceUser user = Vice.getUserManager().getLoadedUser(uuid); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + List<Player> jailedPlayers = ViceUtils.getJailedPlayers(); + Iterator<Player> it = jailedPlayers.iterator(); + for (int i = 0; i < 20; i++) { + if (!it.hasNext()) + break; + Player p = it.next(); + ViceUser u = Vice.getUserManager().getLoadedUser(p.getUniqueId()); + if (!u.isArrested()) + continue; + List<String> lore = new ArrayList<>(); + lore.add("&7Time Left: &a&l" + Utils.timeInSecondsToText(u.getJailTimer())); + if (user.isCop()) + lore.add("&7Click to release!"); + e.setItem(slots[i], Utils.setSkullOwner( + Utils.createItem(Material.SKULL_ITEM, 3, "&e&l" + p.getName(), lore), p.getName())); + } + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lClose", "&7Click to close this menu!")); + e.setItem(49, Utils.createItem(Material.IRON_FENCE, "&c&lPrisoner List", "&7Page 1")); + if (jailedPlayers.size() > 20) + e.setItem(50, Utils.createItem(Material.ARROW, "&c&lNext Page", "&7Page 2")); + return; + } + case "vehicles": { + this.setPhoneDefaults(e); + ViceUser user = Vice.getUserManager().getLoadedUser(uuid); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + List<PersonalVehicle> vehicles = new ArrayList<>(user.getVehicles()); + if (user.hasPersonalVehicle()) + vehicles.remove(user.getPersonalVehicle()); + Iterator<PersonalVehicle> it = vehicles.iterator(); + for (int i = 0; i < 20; i++) { + if (!it.hasNext()) + break; + PersonalVehicle vehicle = it.next(); + ItemStack stack = vehicle.getVehicleProperties().getItem().clone(); + ItemMeta meta = stack.getItemMeta(); + meta.spigot().setUnbreakable(true); + meta.addItemFlags(ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ATTRIBUTES); + List<String> lore = new ArrayList<>(meta.getLore()); + lore.add(Utils.f("&7Health: " + vehicle.getFormattedHealth())); + lore.add(Utils.f("&aClick to get this vehicle!")); + lore.add(Utils.f("&7Price: &a$&l200")); + meta.setLore(lore); + stack.setItemMeta(meta); + e.setItem(slots[i], stack); + } + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the home page!")); + if (user.hasPersonalVehicle()) { + PersonalVehicle vehicle = user.getPersonalVehicle(); + ItemStack stack = vehicle.getVehicleProperties().getItem().clone(); + ItemMeta meta = stack.getItemMeta(); + List<String> lore = new ArrayList<>(meta.getLore()); + lore.add(Utils.f("&7Health: " + vehicle.getFormattedHealth())); + lore.add(Utils.f("&aClick to view your personal vehicle!")); + meta.setLore(lore); + stack.setItemMeta(meta); + e.setItem(49, Utils.addGlow(stack)); + } else { + e.setItem(49, Utils.createItem(Material.MINECART, "&4&lVehicles", "&7Please select your personal vehicle!")); + } + if (vehicles.size() > 20) + e.setItem(50, Utils.createItem(Material.ARROW, "&4&lNext Page", "&7Page 2")); + return; + } + case "vehicleshop": { + this.setPhoneDefaults(e); + ViceUser user = Vice.getUserManager().getLoadedUser(uuid); + Optional<VehicleProperties> opt = Vice.getWastedVehicles().getVehicle(user.getActionVehicle()); + GameItem item = Vice.getItemManager().getItemFromVehicle(user.getActionVehicle()); + if (opt == null || !opt.isPresent() || item == null) { + player.sendMessage(Lang.VEHICLES.f("&7That vehicle does not exist!")); + return; + } + if (item.getSellPrice() <= 0) { + player.sendMessage(Lang.VEHICLES.f("&7You can't buy this vehicle!")); + player.closeInventory(); + return; + } + VehicleProperties vehicle = opt.get(); + String buyPrice = NumberFormat.getNumberInstance(Locale.US).format(Utils.round(item.getSellPrice() * 2)); + String sellPrice = NumberFormat.getNumberInstance(Locale.US).format(Utils.round(item.getSellPrice())); + e.setItem(11, Utils.createItem(Material.MINECART, "&4&lSpeed: &a&l" + vehicle.getMaxSpeed())); + e.setItem(13, Utils.createItem(Material.PAPER, "&4&lPrice: &a$&l" + buyPrice)); + if (vehicle.getWastedGunsWeapon() != null) { + Optional<Weapon<?>> o = Vice.getWastedGuns().getWeaponManager().getWeapon(vehicle.getWastedGunsWeapon()); + o.ifPresent(weapon -> e.setItem(29, weapon.createItemStack())); + } + if (!vehicle.getAllowedWeapons().isEmpty()) { + List<String> lore = vehicle.getAllowedWeapons().stream().map(s -> Vice.getItemManager().getItemFromWeapon(s)).filter(Objects::nonNull).map(GameItem::getDisplayName).collect(Collectors.toList()); + e.setItem(33, Utils.createItem(Material.WOOD_SWORD, "&4&lAllowed Weapons", lore)); + } + if (user.hasVehicle(vehicle.getIdentifier())) { + e.setItem(31, Utils.createItem(Material.INK_SACK, 1, "&c&lSell Vehicle", "&7Reward: &a$&l" + sellPrice)); + } else + e.setItem(31, Utils.createItem(Material.SLIME_BALL, "&a&lBuy Vehicle", "&7Price: &a$&l" + buyPrice)); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lClose", "&7Click to close this menu!")); + e.setItem(49, vehicle.getItem()); + return; + } + case "buyvehicle": { + this.setPhoneDefaults(e); + ViceUser user = Vice.getUserManager().getLoadedUser(uuid); + Optional<VehicleProperties> opt = Vice.getWastedVehicles().getVehicle(user.getActionVehicle()); + GameItem item = Vice.getItemManager().getItemFromVehicle(user.getActionVehicle()); + if (opt == null || !opt.isPresent() || item == null) { + player.sendMessage(Lang.VEHICLES.f("&7That vehicle does not exist!")); + return; + } + VehicleProperties vehicle = opt.get(); + if (item.getSellPrice() <= 0) { + player.sendMessage(Lang.VEHICLES.f("&7You can't buy this vehicle!")); + player.closeInventory(); + return; + } + if (user.hasVehicle(vehicle.getIdentifier())) { + player.sendMessage(Lang.VEHICLES.f("&7You already own this vehicle!")); + MenuManager.openMenu(player, "vehicles"); + return; + } + this.setConfirmDefaults(e, "&a&lBuy " + vehicle.getItem().getItemMeta().getDisplayName() + "&a&l for &a$&l" + Utils.round(item.getSellPrice() * 2), "&c&lCancel"); + return; + } + case "sellvehicle": { + this.setPhoneDefaults(e); + ViceUser user = Vice.getUserManager().getLoadedUser(uuid); + PersonalVehicle vehicle = user.getPersonalVehicle(user.getActionVehicle()); + if (vehicle == null) return; + double price = vehicle.getSellPrice(); + if (price <= 0) { + player.sendMessage(Lang.VEHICLES.f("&7You can't sell this vehicle!")); + player.closeInventory(); + return; + } + this.setConfirmDefaults(e, "&a&lSell " + vehicle.getDisplayName() + "&a&l for &a$&l" + Utils.round(price), "&c&lCancel"); + return; + } + case "repairvehicle": { + this.setPhoneDefaults(e); + ViceUser user = Vice.getUserManager().getLoadedUser(uuid); + if (user.getActionVehicle() == null) return; + PersonalVehicle vehicle = user.getPersonalVehicle(user.getActionVehicle()); + if (vehicle == null) return; + double price = vehicle.getRepairPrice(); + if (price <= 0) { + player.sendMessage(Lang.VEHICLES.f("&7You can't repair this vehicle!")); + player.closeInventory(); + return; + } + this.setConfirmDefaults(e, "&a&lRepair " + vehicle.getDisplayName() + "&a&l for &a$&l" + Utils.round(price), "&c&lCancel"); + return; + } + case "personalvehicle": { + this.setPhoneDefaults(e); + ViceUser user = Vice.getUserManager().getLoadedUser(uuid); + PersonalVehicle vehicle = user.getPersonalVehicle(); + if (vehicle == null) { + MenuManager.openMenu(player, "vehicles"); + return; + } + VehicleProperties vehicleProperties = vehicle.getVehicleProperties(); + if (vehicleProperties == null) return; + e.setItem(11, Utils.createItem(Material.MINECART, "&4&lStats", "&7Speed: &a&l" + vehicleProperties.getMaxSpeed(), "&7Health: " + vehicle.getFormattedHealth())); + e.setItem(13, Utils.createItem(Material.PAPER, "&4&lPrice: &a$&l" + Utils.round(vehicle.getPrice()))); + if (vehicle.getRepairPrice() > 0 && !vehicle.onMap()) + e.setItem(15, Utils.createItem(Material.WORKBENCH, "&4&lRepair", "&7Call the mechanic!", "&7Price: &a$&l" + Utils.round(vehicle.getRepairPrice()))); + else if (vehicle.onMap()) + e.setItem(15, Utils.createItem(Material.ENDER_PEARL, "&4&lSend Away", "&7Click to send away your vehicle!", "&7Price: &a$&l200")); + else + e.setItem(15, Utils.createItem(Material.ENDER_PEARL, "&4&lCall Vehicle", "&7Click to send your vehicle to yourself!", "&7Price: &a$&l200")); + if (vehicleProperties.getWastedGunsWeapon() != null) { + Optional<Weapon<?>> o = Vice.getWastedGuns().getWeaponManager().getWeapon(vehicleProperties.getWastedGunsWeapon()); + o.ifPresent(weapon -> e.setItem(29, weapon.createItemStack())); + } + if (!vehicleProperties.getAllowedWeapons().isEmpty()) { + List<String> lore = vehicleProperties.getAllowedWeapons().stream().map(s -> Vice.getItemManager().getItemFromWeapon(s)).filter(Objects::nonNull).map(GameItem::getDisplayName).collect(Collectors.toList()); + e.setItem(33, Utils.createItem(Material.WOOD_SWORD, "&4&lAllowed Weapons", lore)); + } + e.setItem(31, Utils.createItem(Material.INK_SACK, 1, "&c&lSell Vehicle", "&7Reward: &a$&l" + Utils.round(vehicle.getSellPrice()))); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the vehicles page!")); + ItemStack stack = vehicle.getVehicleProperties().getItem().clone(); + ItemMeta meta = stack.getItemMeta(); + meta.spigot().setUnbreakable(true); + meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE); + List<String> lore = new ArrayList<>(meta.getLore()); + lore.add(Utils.f("&7Health: " + vehicle.getFormattedHealth())); + lore.add(Utils.f("&aClick to send your vehicle to yourself!")); + lore.add(Utils.f("&7Price: &a$&l200")); + stack.setItemMeta(meta); + e.setItem(49, Utils.addGlow(stack)); + break; + } + case "mechanic": { + this.setPhoneDefaults(e); + ViceUser user = Vice.getUserManager().getLoadedUser(uuid); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + List<PersonalVehicle> vehicles = new ArrayList<>(user.getVehicles()); + new ArrayList<>(vehicles).stream().filter(vehicle -> vehicle.getRepairPrice() <= 0).forEach(vehicles::remove); + Iterator<PersonalVehicle> it = vehicles.iterator(); + for (int i = 0; i < 20; i++) { + if (!it.hasNext()) + break; + PersonalVehicle vehicle = it.next(); + if (!vehicle.isDestroyed()) + continue; + ItemStack stack = vehicle.getVehicleProperties().getItem().clone(); + ItemMeta meta = stack.getItemMeta(); + meta.spigot().setUnbreakable(true); + meta.addItemFlags(ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ATTRIBUTES); + List<String> lore = new ArrayList<>(meta.getLore()); + lore.add(Utils.f("&7Health: " + vehicle.getFormattedHealth())); + lore.add(Utils.f("&7Repair Price: &a&l$" + NumberFormat.getNumberInstance(Locale.US).format(vehicle.getRepairPrice()))); + lore.add(Utils.f("&7Click to repair this vehicle!")); + meta.setLore(lore); + stack.setItemMeta(meta); + e.setItem(slots[i], Objects.equals(vehicle, user.getPersonalVehicle()) ? Utils.addGlow(stack) : stack); + } + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lClose", "&7Click to close this menu!")); + e.setItem(49, Utils.createItem(Material.WORKBENCH, "&4&lMechanic", "&7Repair your vehicles!")); + if (vehicles.size() > 20) + e.setItem(50, Utils.createItem(Material.ARROW, "&4&lNext Page", "&7Page 2")); + return; + } + + case "armorupgrade": { + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + ArmorUpgrade upgrade = user.getBuyingArmorUpgrade(); + if (upgrade == null) { + player.closeInventory(); + return; + } + if (!upgrade.canUseUpgrade(user.getRank(), Core.getUserManager().getLoadedUser(player.getUniqueId()).getUserRank())) { + player.closeInventory(); + player.sendMessage(Lang.HEY.f("&7You need to rank up to " + upgrade.getViceRank().getColoredNameBold() + "&7 or donate for " + upgrade.getUserRank().getColoredNameBold() + "&7 at &a&lstore.grandtheftmc.net&7 to use the &b&l" + upgrade.getDisplayName() + " Armor Upgrade&7!")); + return; + } + ItemStack item = player.getInventory().getItemInMainHand(); + GameItem gameItem = item == null ? null : Vice.getItemManager().getItem(item.getType()); + if (item == null || gameItem == null || !upgrade.canBeUsedOn(gameItem.getName())) { + player.closeInventory(); + player.sendMessage(Lang.HEY.f("&7The &b&l" + upgrade.getDisplayName() + " Armor Upgrade&7 can only be applied to the following types of items: " + upgrade.getTypesString() + "&7!")); + return; + } + HashSet<ArmorUpgrade> upgradesOnItem = ArmorUpgrade.getArmorUpgrades(item); + if (upgradesOnItem.contains(upgrade)) { + player.closeInventory(); + player.sendMessage(Lang.ARMOR_UPGRADE.f("&7That piece of armor already has the &b&l" + upgrade.getDisplayName() + " Armor Upgrade&7!")); + return; + } + if ((upgradesOnItem.contains(ArmorUpgrade.LIGHT) && upgrade == ArmorUpgrade.ULTRA_LIGHT) || (upgradesOnItem.contains(ArmorUpgrade.ULTRA_LIGHT) && upgrade == ArmorUpgrade.LIGHT)) { + player.closeInventory(); + player.sendMessage(Lang.ARMOR_UPGRADE.f("&7This upgrade cannot be added to the armor piece due to conflicting upgrades.")); + return; + } + double price = upgrade.getPrice(); + + if (!user.hasMoney(upgrade.getPrice())) { + player.closeInventory(); + player.sendMessage(Lang.ARMOR_UPGRADE.f("&7You can't afford the &b&l" + upgrade.getDisplayName() + " Armor Upgrade&7!")); + return; + } + this.setConfirmDefaults(e, "&a&lBuy &b&l" + upgrade.getDisplayName() + " Armor Upgrade", "&c&lCancel", + Collections.singletonList("&7Price: &a$&l" + price), Collections.singletonList("&7Item: &a&l" + (item.getItemMeta().hasDisplayName() ? item.getItemMeta().getDisplayName() : item.getType().name()))); + return; + } + case "lottery": { + this.setPhoneDefaults(e); + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + LotteryPlayer p = Vice.getLottery().getLotteryPlayer(player.getUniqueId()); + int[] slots = new int[]{12, 13, 14, 21, 22, 23, 30, 31, 32, 39, 40}; + int[] amnts = new int[]{1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000}; + for (int i = 0; i < 11; i++) + e.setItem(slots[i], Utils.createItem(Material.EMPTY_MAP, + (user.hasMoney(amnts[i] * 500) ? "&e" : "&c") + "&l" + amnts[i] + " Tickets", "&7Price: &a$&l" + (amnts[i] * 500), "&7Click to buy tickets!")); + e.setItem(41, + Utils.createItem(Material.BOOK_AND_QUILL, "&e&lCustom Amount", "&7Click to choose an amount!")); + e.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lClose", "&7Click to close this menu!")); + e.setItem(49, Utils.createItem(Material.GOLD_INGOT, "&e&lLottery", "&7Your tickets: &e&l" + (p == null ? 0 : p.getTickets()), "&7Go big or go home!")); + LotteryPlayer winner1 = Vice.getLottery().getWinner(0); + LotteryPlayer winner2 = Vice.getLottery().getWinner(1); + LotteryPlayer winner3 = Vice.getLottery().getWinner(2); + e.setItem(51, Utils.setSkullOwner(Utils.createItem(Material.SKULL_ITEM, 3, + "&e&lLast week's winners", + winner1 == null ? "" : "&a#&l1&7: &r" + winner1.getName() + " &a" + Utils.formatMoney(winner1.getAmount()) + "&7 (&a70%&7 of the pot)", + winner2 == null ? "" : "&a#&l2&7: &r" + winner2.getName() + " &a" + Utils.formatMoney(winner2.getAmount()) + "&7 (&a20%&7 of the pot", + winner3 == null ? "" : "&a#&l2&7: &r" + winner3.getName() + " &a" + Utils.formatMoney(winner3.getAmount()) + "&7 (&a10%&7 of the pot)"), winner1 == null ? "Presidentx" : winner1.getName())); + return; + } + default: + break; + } + + + } + + public void setPhoneDefaults(MenuOpenEvent e) { + ItemStack whiteGlass = Utils.createItem(Material.STAINED_GLASS_PANE, "&a"); + ItemStack grayGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a"); + ItemStack blackGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 15, "&a"); + ItemStack lightGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 8, "&a"); + for (int i : new int[]{1, 10, 19, 28, 37, 46, 7, 16, 25, 34, 43, 52}) e.setItem(i, whiteGlass); + for (int i : new int[]{2, 3, 4, 5, 6}) e.setItem(i, blackGlass); + for (int i : new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42, 47, 48, + 49, 50, 51}) + e.setItem(i, grayGlass); + for (int i : new int[]{0, 8, 9, 17, 18, 26, 27, 35, 36, 44, 45, 53}) e.setItem(i, lightGlass); + } + + public void setPhoneDefaults(Inventory inv) { + ItemStack whiteGlass = Utils.createItem(Material.STAINED_GLASS_PANE, "&a"); + ItemStack grayGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a"); + ItemStack blackGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 15, "&a"); + ItemStack lightGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 8, "&a"); + for (int i : new int[]{1, 10, 19, 28, 37, 46, 7, 16, 25, 34, 43, 52}) inv.setItem(i, whiteGlass); + for (int i : new int[]{2, 3, 4, 5, 6}) inv.setItem(i, blackGlass); + for (int i : new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42, 47, 48, + 49, 50, 51}) + inv.setItem(i, grayGlass); + for (int i : new int[]{0, 8, 9, 17, 18, 26, 27, 35, 36, 44, 45, 53}) inv.setItem(i, lightGlass); + } + + private void setConfirmDefaults(MenuOpenEvent e) { + this.setConfirmDefaults(e, "&a&lConfirm", "&c&lCancel"); + } + + private void setConfirmDefaults(MenuOpenEvent e, String confirmMessage, String cancelMessage) { + ItemStack whiteGlass = Utils.createItem(Material.STAINED_GLASS_PANE, "&a"); + ItemStack grayGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a"); + ItemStack blackGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 15, "&a"); + ItemStack lightGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 8, "&a"); + ItemStack greenGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 5, confirmMessage); + ItemStack redGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 14, cancelMessage); + for (int i : new int[]{1, 10, 19, 28, 37, 46, 7, 16, 25, 34, 43, 52}) e.setItem(i, whiteGlass); + for (int i : new int[]{2, 3, 4, 5, 6}) e.setItem(i, blackGlass); + for (int i : new int[]{13, 22, 31, 40, 49,}) e.setItem(i, grayGlass); + for (int i : new int[]{0, 8, 9, 17, 18, 26, 27, 35, 36, 44, 45, 53}) e.setItem(i, lightGlass); + for (int i : new int[]{11, 12, 20, 21, 29, 30, 38, 39, 47, 48}) e.setItem(i, greenGlass); + for (int i : new int[]{14, 15, 23, 24, 32, 33, 41, 42, 50, 51}) e.setItem(i, redGlass); + } + + private void setConfirmDefaults(MenuOpenEvent e, String confirmMessage, String cancelMessage, List<String> confirmLore, List<String> cancelLore) { + ItemStack whiteGlass = Utils.createItem(Material.STAINED_GLASS_PANE, "&a"); + ItemStack grayGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a"); + ItemStack lightGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 8, "&a"); + ItemStack blackGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 15, "&a"); + ItemStack greenGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 5, confirmMessage, confirmLore == null ? new ArrayList<>() : confirmLore); + ItemStack redGlass = Utils.createItem(Material.STAINED_GLASS_PANE, 14, cancelMessage, cancelLore == null ? new ArrayList<>() : cancelLore); + for (int i : new int[]{1, 10, 19, 28, 37, 46, 7, 16, 25, 34, 43, 52}) e.setItem(i, whiteGlass); + for (int i : new int[]{2, 3, 4, 5, 6}) e.setItem(i, blackGlass); + for (int i : new int[]{13, 22, 31, 40, 49,}) e.setItem(i, grayGlass); + for (int i : new int[]{0, 8, 9, 17, 18, 26, 27, 35, 36, 44, 45, 53}) e.setItem(i, lightGlass); + for (int i : new int[]{11, 12, 20, 21, 29, 30, 38, 39, 47, 48}) e.setItem(i, greenGlass); + for (int i : new int[]{14, 15, 23, 24, 32, 33, 41, 42, 50, 51}) e.setItem(i, redGlass); + } + + @EventHandler(priority = EventPriority.HIGH) + public void onMenuClick(MenuClickEvent e) { + Player player = e.getPlayer(); + UUID uuid = player.getUniqueId(); + Menu menu = e.getMenu(); + ViceUser user = Vice.getUserManager().getLoadedUser(uuid); + ItemStack item = e.getItem(); + User coreUser = Core.getUserManager().getLoadedUser(uuid); + Inventory inv = e.getInv(); + if (item == null || item.getType() == Material.AIR) + return; + switch (menu.getName()) { + case "choose_villager_type": { + if(user.getChangingJob()==null) { + player.sendMessage(Lang.CHEAT_CODES.f("&7Cannot open this menu because you do not have a villager selected!")); + return; + } + if(item.getType()==Material.STAINED_GLASS_PANE) + return; + Villager.Profession p = Villager.Profession.valueOf(ChatColor.stripColor(item.getItemMeta().getDisplayName()).split(" ")[1].toUpperCase()); + Villager v = user.getChangingJob(); + v.setProfession(p); + player.closeInventory(); + player.sendMessage(Utils.f("&7You have changed the profession of the villager to a &e" + p.toString())); + user.setChangingJob(null); + coreUser.addCooldown("villager_job_cc", 60*60, false, true); + return; + } + case "cheatcodes": { + if(item.getType()==Material.REDSTONE) { + MenuManager.openMenu(player, "contacts"); + return; + } + Optional<CheatCode> optCode = CheatCode.getCheatCodeFromItemStack(item); + if(!optCode.isPresent()) + return; + CheatCodeState cState = user.getCheatCodeState(optCode.get()); + if(cState.getState()==State.LOCKED) { + player.sendMessage(Lang.CHEAT_CODES.f(optCode.get().getLockedLore())); + return; + } + optCode.get().activate(coreUser, user, player, cState); + MenuManager.openMenu(player, "cheatcodes");//refresh + return; + } + case "phone": + switch (item.getType()) { + case ENDER_CHEST: + MenuManager.openMenu(player, "cosmetics"); + return; + case MINECART: + if (Vice.getUserManager().getLoadedUser(uuid).hasPersonalVehicle()) { + MenuManager.openMenu(player, "personalvehicle"); + return; + } + MenuManager.openMenu(player, "vehicles"); + return; + case NETHER_STAR: + MenuManager.openMenu(player, "account"); + return; + case BOOK: + MenuManager.openMenu(player, "contacts"); + return; + case EMERALD: + player.closeInventory(); + player.sendMessage(Lang.VICE.f("&7Go to &a&lstore.grandtheftmc.net&7 to buy Ranks, Bonds, Money and other packages!")); + return; + case EXP_BOTTLE: + MenuManager.openMenu(player, "rewards"); + return; + case CHEST: + MenuManager.openMenu(player, "kits"); + return; + case EMPTY_MAP: + MenuManager.openMenu(player, "ranks"); + return; + case ANVIL: + MenuManager.openMenu(player, "cheatcodes"); + default: + return; + } + case "cosmetics": + switch (item.getType()) { + case REDSTONE: + MenuManager.openMenu(player, "phone"); + return; + default: + return; + } + case "rewards": + switch (item.getType()) { + case REDSTONE: + MenuManager.openMenu(player, "phone"); + return; + default: + return; + } + case "vote": + switch (item.getType()) { + case REDSTONE: + MenuManager.openMenu(player, "reward"); + return; + default: + return; + } + case "account": + switch (item.getType()) { + case NAME_TAG: + MenuManager.openMenu(player, "chooseeventtag"); + return; + case BOOK: + MenuManager.openMenu(player, "vicestats"); + return; + case REDSTONE_COMPARATOR: + MenuManager.openMenu(player, "prefs"); + return; + case REDSTONE: + MenuManager.openMenu(player, "phone"); + default: + return; + } + case "ranks": + switch (item.getType()) { + case REDSTONE: + MenuManager.openMenu(player, "account"); + return; + case PAPER: + User u = Core.getUserManager().getLoadedUser(uuid); + user.rankup(player, u); + return; + default: + return; + } + case "vicestats": + switch (item.getType()) { + case REDSTONE: + MenuManager.openMenu(player, "account"); + return; + default: + return; + } + + case "kits": + switch (item.getType()) { + case REDSTONE: + MenuManager.openMenu(player, "phone"); + return; + default: + if (item.hasItemMeta() && item.getItemMeta().hasDisplayName() + && item.getType() != Material.STAINED_GLASS_PANE) { + Vice.getItemManager().giveKit(player, Core.getUserManager().getLoadedUser(uuid), + Vice.getUserManager().getLoadedUser(uuid), + ChatColor.stripColor(item.getItemMeta().getDisplayName())); + MenuManager.updateMenu(player, "kits"); + } + return; + } + case "contacts": + switch (item.getType()) { + case REDSTONE: + MenuManager.openMenu(player, "phone"); + return; + case ANVIL: + MenuManager.openMenu(player, "cheatcodes"); + return; + case STORAGE_MINECART: + MenuManager.openMenu(player, "taxi"); + return; + case SKULL_ITEM: + if (user.isCop()) + player.sendMessage(Lang.COP_MODE.f("&7You have called for backup! All officers have been notified, and they can teleport to you for 1 minute!")); + else { + player.sendMessage(Lang.VICE.f("&7You have called the police! All officers have been notified, and they can teleport to you for 1 minute!")); + } + user.setLastBackupRequest(System.currentTimeMillis()); + for (ViceUser u : ViceUtils.getCops()) { + Player p = Bukkit.getPlayer(u.getUUID()); + if (!Objects.equals(player, p)) + p.spigot().sendMessage(new ComponentBuilder(Lang.COP_MODE.f((user.isCop() ? "&3&lCop " : "&7Citizen") + Core.getUserManager().getLoadedUser(p.getUniqueId()).getColoredName(p))).append(" is requesting " + (user.isCop() ? "backup" : "police assistance") + "! Teleport: ").color(net.md_5.bungee.api.ChatColor.GRAY). + append(" [ACCEPT] ").color(net.md_5.bungee.api.ChatColor.GREEN).bold(true).event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/backup " + player.getName())).create()); + + } + return; + case WATCH: + Vice.getWorldManager().getWarpManager().warp(player, Core.getUserManager().getLoadedUser(uuid), Vice.getUserManager().getLoadedUser(uuid), new TaxiTarget(Vice.getWorldManager().getWarpManager().getSpawn()), 0, -1); + return; + default: + return; + } + case "taxi": + switch (e.getItem().getType()) { + case SKULL_ITEM: + MenuManager.openMenu(player, "taxiplayers"); + return; + case BED: + Vice.getWorldManager().getWarpManager().warp(player, Core.getUserManager().getLoadedUser(uuid), + Vice.getUserManager().getLoadedUser(uuid), new TaxiTarget(Vice.getWorldManager().getWarpManager().getSpawn()), 0, + -1); + player.closeInventory(); + return; + case IRON_DOOR: + MenuManager.openMenu(player, "taxihouses"); + return; + case REDSTONE: + MenuManager.openMenu(player, "contacts"); + return; + case ENDER_PEARL: + MenuManager.openMenu(player, "taxiwarps"); + return; + default: + return; + } + case "taxiplayers": + switch (item.getType()) { + case ARROW: + int page = Integer + .parseInt(ChatColor.stripColor(item.getItemMeta().getLore().get(0)).replace("Page ", "")); + this.setPhoneDefaults(inv); + User u = Core.getUserManager().getLoadedUser(uuid); + List<Player> players = new ArrayList<>(Bukkit.getOnlinePlayers()); + players.remove(player); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, + 42}; + Iterator<? extends Player> it = players.iterator(); + for (int i = 0; i < page * 20; i++) { + if (!it.hasNext()) + break; + Player p = it.next(); + if (i < (page - 1) * 20) + continue; + + inv.setItem(slots[i - (page - 1) * 20], Utils.setSkullOwner( + Utils.createItem(Material.SKULL_ITEM, 3, "&e&l" + p.getName(), + u.isPremium() ? "&7Click to send teleport request!" : "&cRequires PREMIUM!"), + p.getName())); + } + inv.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the taxi page!")); + if (page > 1) + inv.setItem(48, Utils.createItem(Material.ARROW, "&e&lPrevious Page", "&7Page " + (page - 1))); + inv.setItem(49, + Utils.createItem(Material.STORAGE_MINECART, "&e&lTaxi Service: Players", "&7Page " + page)); + if (players.size() > (20 * page)) + inv.setItem(50, Utils.createItem(Material.ARROW, "&e&lNext Page", "&7Page " + (page + 1))); + return; + case SKULL_ITEM: + Player target = Bukkit.getPlayer(ChatColor.stripColor(item.getItemMeta().getDisplayName())); + player.closeInventory(); + Vice.getWorldManager().getWarpManager().tpa(player, Core.getUserManager().getLoadedUser(uuid), + Vice.getUserManager().getLoadedUser(uuid), target); + return; + case REDSTONE: + MenuManager.openMenu(player, "taxi"); + return; + default: + return; + } + + case "taxiwarps": + switch (item.getType()) { + case ARROW: + int page = Integer + .parseInt(ChatColor.stripColor(item.getItemMeta().getLore().get(0)).replace("Page ", "")); + this.setPhoneDefaults(inv); + ViceUser viceUser = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + List<Warp> warps = Vice.getWorldManager().getWarpManager().getWarps(); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, + 42}; + Iterator<Warp> it = warps.iterator(); + for (int i = 0; i < page * 20; i++) { + if (!it.hasNext()) + break; + Warp warp = it.next(); + if (i < (page - 1) * 20) + continue; + inv.setItem(slots[i - (page - 1) * 20], Utils.createItem(Material.ENDER_PEARL, + "&e&l" + warp.getName(), "&7Click to teleport for &a$&l200&7!")); + } + inv.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the taxi page!")); + if (page > 1) + inv.setItem(48, Utils.createItem(Material.ARROW, "&e&lPrevious Page", "&7Page " + (page - 1))); + inv.setItem(49, + Utils.createItem(Material.STORAGE_MINECART, "&e&lTaxi Service: Warps", "&7Page " + page)); + if (warps.size() > (20 * page)) + inv.setItem(50, Utils.createItem(Material.ARROW, "&e&lNext Page", "&7Page " + (page + 1))); + return; + case ENDER_PEARL: + Warp warp = Vice.getWorldManager().getWarpManager().getWarp(ChatColor.stripColor(item.getItemMeta().getDisplayName())); + if (warp == null) { + player.sendMessage(Lang.TAXI.f("&7That warp does not exist!")); + return; + } + player.closeInventory(); + Vice.getWorldManager().getWarpManager().warp(player, Core.getUserManager().getLoadedUser(uuid), + Vice.getUserManager().getLoadedUser(uuid), new TaxiTarget(warp), 200, -1); + return; + case REDSTONE: + MenuManager.openMenu(player, "taxi"); + return; + default: + return; + } + + case "ammopouch": + switch (item.getType()) { + case REDSTONE: + int slot = e.getSlot(); + int i = 0; + while (slot > 8) { + slot -= 9; + i++; + } + int toDrop = i == 1 ? 50 : i == 2 ? 10 : i == 3 ? 1 : 0; + AmmoType type = AmmoType.getTypes()[slot]; + int ammo = user.getAmmo(type); + if (ammo <= 0) { + player.sendMessage(Lang.AMMO.f("&7You have none of this type of ammo left!")); + return; + } + if (ammo < toDrop) + toDrop = ammo; + ItemStack stack = type.getGameItem().getItem(); + stack.setAmount(toDrop); + user.removeAmmo(type, toDrop); + player.getWorld().dropItemNaturally(Utils.getInFrontOf(player.getLocation()), stack); + player.sendMessage(Lang.AMMO_TAKE.f(toDrop + "&7 " + type.getGameItem().getDisplayName() + "&7!")); + MenuManager.updateMenu(player, "ammopouch"); + return; + default: + return; + } + case "jail": + switch (item.getType()) { + case ARROW: + int page = Integer + .parseInt(ChatColor.stripColor(item.getItemMeta().getLore().get(0)).replace("Page ", "")); + this.setPhoneDefaults(inv); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, + 42}; + List<Player> jailedPlayers = ViceUtils.getJailedPlayers(); + Iterator<Player> it = jailedPlayers.iterator(); + for (int i = 0; i < page * 20; i++) { + if (!it.hasNext()) + break; + Player p = it.next(); + if (i < (page - 1) * 20) + continue; + + ViceUser u = Vice.getUserManager().getLoadedUser(p.getUniqueId()); + if (!u.isArrested()) + continue; + List<String> lore = new ArrayList<>(); + lore.add("&7Time Left: &a&l" + Utils.timeInSecondsToText(u.getJailTimer())); + if (user.isCop() && Objects.equals(u.getJailCop(), player.getUniqueId())) + lore.add("&7Click to release!"); + inv.setItem(slots[i - (page - 1) * 20], Utils.setSkullOwner( + Utils.createItem(Material.SKULL_ITEM, 3, "&e&l" + p.getName(), lore), p.getName())); + } + if (page > 1) + inv.setItem(48, Utils.createItem(Material.ARROW, "&c&lPrevious Page", "&7Page " + (page - 1))); + inv.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lClose", "&7Click to close this menu!")); + inv.setItem(49, Utils.createItem(Material.IRON_FENCE, "&c&lPrisoner List", "&7Page " + page)); + if (jailedPlayers.size() > (20 * page)) + inv.setItem(50, Utils.createItem(Material.ARROW, "&c&lNext Page", "&7Page " + (page + 1))); + return; + case SKULL_ITEM: + Player p = Bukkit.getPlayer(ChatColor.stripColor(e.getItem().getItemMeta().getDisplayName())); + if (p == null) { + player.sendMessage(Lang.JAIL.f("&7That player is not online!")); + MenuManager.updateMenu(player, "jail"); + return; + } + if (!Vice.getUserManager().getLoadedUser(uuid).isCop()) return; + ViceUser u = Vice.getUserManager().getLoadedUser(p.getUniqueId()); + if (!u.isArrested()) { + player.sendMessage(Lang.JAIL.f("&7That player is not in jail!")); + MenuManager.updateMenu(player, "jail"); + return; + } + if (u.getJailTimer() <= 5) { + player.sendMessage(Lang.JAIL.f("&7That prisoners is already being released!")); + return; + } + if (!Vice.getUserManager().getLoadedUser(uuid).isCop()) { + player.sendMessage(Lang.JAIL.f("&7You must be a cop to release prisoners!")); + return; + } + if (!Objects.equals(u.getJailCop(), player.getUniqueId())) { + player.sendMessage(Lang.JAIL.f("&7You can only release prisoners that you put in jail!")); + return; + } + u.setJailTimer(5); + player.sendMessage(Lang.JAIL.f("&7You released prisoners &e&l" + + Core.getUserManager().getLoadedUser(p.getUniqueId()).getColoredName(p) + "&7!")); + p.sendMessage(Lang.JAIL.f("&7You are being released by &a" + + Core.getUserManager().getLoadedUser(player.getUniqueId()).getColoredName(player) + "&7!")); + MenuManager.updateMenu(player, "jail"); + return; + case REDSTONE: + player.closeInventory(); + return; + default: + return; + } + case "vehicles": + switch (item.getType()) { + case ARROW: + int page = Integer + .parseInt(ChatColor.stripColor(item.getItemMeta().getLore().get(0)).replace("Page ", "")); + this.setPhoneDefaults(inv); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + List<PersonalVehicle> vehicles = new ArrayList<>(user.getVehicles()); + if (user.hasPersonalVehicle()) + vehicles.remove(user.getPersonalVehicle()); + Iterator<PersonalVehicle> it = vehicles.iterator(); + for (int i = 0; i < page * 20; i++) { + if (!it.hasNext()) + break; + PersonalVehicle vehicle = it.next(); + if (i < (page - 1) * 20) + continue; + ItemStack stack = vehicle.getVehicleProperties().getItem().clone(); + ItemMeta meta = stack.getItemMeta(); + List<String> lore = new ArrayList<>(meta.getLore()); + lore.add(Utils.f("&7Health: " + vehicle.getFormattedHealth())); + lore.add(Utils.f("&aClick to get this vehicle!")); + lore.add(Utils.f("&7Price: &a$&l200")); + meta.setLore(lore); + stack.setItemMeta(meta); + inv.setItem(slots[i - (page - 1) * 20], stack); + } + if (page > 1) + inv.setItem(48, Utils.createItem(Material.ARROW, "&4&lPrevious Page", "&7Page " + (page - 1))); + inv.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the property page!")); + if (user.hasPersonalVehicle()) { + PersonalVehicle vehicle = user.getPersonalVehicle(); + ItemStack stack = vehicle.getVehicleProperties().getItem().clone(); + ItemMeta meta = stack.getItemMeta(); + List<String> lore = new ArrayList<>(meta.getLore()); + lore.add(Utils.f("&7Health: " + vehicle.getFormattedHealth())); + lore.add(Utils.f("&aClick to view your personal vehicle!")); + meta.setLore(lore); + stack.setItemMeta(meta); + inv.setItem(49, Utils.addGlow(stack)); + + } else + inv.setItem(49, Utils.createItem(Material.MINECART, "&4&lVehicles", "&7Please select your personal vehicle!")); + if (vehicles.size() > (20 * page)) + inv.setItem(50, Utils.createItem(Material.ARROW, "&4&lNext Page", "&7Page " + (page + 1))); + return; + case REDSTONE: + MenuManager.openMenu(player, "phone"); + return; + default: + if (!item.hasItemMeta() || !item.getItemMeta().hasDisplayName()) return; + GameItem gameItem = Vice.getItemManager().getItemFromDisplayName(item.getItemMeta().getDisplayName()); + if (gameItem == null) return; + PersonalVehicle vehicle = user.getPersonalVehicle(gameItem.getWeaponOrVehicleOrDrug()); + if (vehicle == null) return; + if (Objects.equals(vehicle, user.getPersonalVehicle())) { + MenuManager.openMenu(player, "personalvehicle"); + return; + } + user.setPersonalVehicle(player, Core.getUserManager().getLoadedUser(uuid), vehicle); + player.closeInventory(); + return; + } + + case "vehicleshop": + switch (item.getType()) { + case REDSTONE: + player.closeInventory(); + return; + case SLIME_BALL: + if (user.hasVehicle(user.getActionVehicle())) { + player.sendMessage(Lang.VEHICLES.f("&7You already own this vehicle!")); + MenuManager.openMenu(player, "vehicles"); + return; + } + MenuManager.openMenu(player, "buyvehicle"); + return; + case INK_SACK: + if (!user.hasVehicle(user.getActionVehicle())) { + player.sendMessage(Lang.VEHICLES.f("&7You don't own this vehicle!")); + MenuManager.openMenu(player, "vehicles"); + return; + } + MenuManager.openMenu(player, "sellvehicle"); + return; + default: + return; + } + case "buyvehicle": + switch (item.getType()) { + case STAINED_GLASS_PANE: + switch (item.getDurability()) { + case 5: + Optional<VehicleProperties> opt = Vice.getWastedVehicles().getVehicle(user.getActionVehicle()); + GameItem gameItem = Vice.getItemManager().getItemFromVehicle(user.getActionVehicle()); + if (opt == null || !opt.isPresent() || gameItem == null) { + if (gameItem == null) + Utils.b("GameItem for " + user.getActionVehicle() + " is null"); + player.sendMessage(Lang.VEHICLES.f("&7That vehicle does not exist!")); + return; + } + VehicleProperties vehicle = opt.get(); + double price = gameItem.getSellPrice() * 2; + if (price <= 0) { + player.closeInventory(); + player.sendMessage(Lang.VEHICLES.f("&7You can't buy this vehicle!")); + return; + } + if (user.hasVehicle(vehicle.getIdentifier())) { + player.closeInventory(); + player.sendMessage(Lang.VEHICLES.f("&7You already own this vehicle!")); + return; + } + if (!user.hasMoney(price)) { + player.closeInventory(); + player.sendMessage(Lang.VEHICLES.f("&7You don't have the &c$&l" + Utils.round(price) + "&7 to pay for this vehicle!")); + return; + } + user.setActionVehicle(null); + user.takeMoney(price); + ViceUtils.updateBoard(player, user); + user.giveVehiclePerm(player, vehicle); + player.sendMessage(Lang.VEHICLES.f("&7You bought vehicle " + vehicle.getItem().getItemMeta().getDisplayName() + "&7 for &a$&l" + Utils.round(price) + "&7!")); + MenuManager.openMenu(player, "vehicles"); + return; + case 14: + MenuManager.openMenu(player, "vehicleshop"); + return; + default: + return; + } + + default: + return; + } + case "sellvehicle": + switch (item.getType()) { + case STAINED_GLASS_PANE: + switch (item.getDurability()) { + case 5: + PersonalVehicle vehicle = user.getPersonalVehicle(user.getActionVehicle()); + if (vehicle == null) return; + if (vehicle.onMap()) { + player.sendMessage(Lang.VEHICLES.f("&7Please send the driver to pick up your vehicle first!")); + return; + } + double price = vehicle.getSellPrice(); + if (price <= 0) { + player.closeInventory(); + player.sendMessage(Lang.VEHICLES.f("&7You can't sell this vehicle!")); + return; + } + user.setActionVehicle(null); + user.removeVehiclePerm(player, vehicle.getVehicleProperties()); + user.addMoney(price); + ViceUtils.updateBoard(player, user); + player.sendMessage(Lang.VEHICLES.f("&7You sold vehicle " + vehicle.getDisplayName() + "&7 for &a$&l" + Utils.round(price) + "&7!")); + MenuManager.openMenu(player, "vehicles"); + return; + case 14: + MenuManager.openMenu(player, "personalvehicle"); + return; + default: + return; + } + + default: + return; + } + case "repairvehicle": + switch (item.getType()) { + case STAINED_GLASS_PANE: + switch (item.getDurability()) { + case 5: + PersonalVehicle vehicle = user.getPersonalVehicle(user.getActionVehicle()); + if (vehicle == null) return; + if (vehicle.onMap()) { + player.sendMessage(Lang.VEHICLES.f("&7Please send the driver to pick up your vehicle first!")); + return; + } + double price = vehicle.getRepairPrice(); + if (price <= 0) { + player.closeInventory(); + player.sendMessage(Lang.VEHICLES.f("&7You can't repair this vehicle!")); + return; + } + if (!user.hasMoney(price)) { + player.sendMessage(Lang.VEHICLES.f("&7You can't afford to pay &c$&l" + price + "&7 to repair this vehicle!")); + return; + } + user.setActionVehicle(null); + user.takeMoney(price); + ViceUtils.updateBoard(player, user); + double health = vehicle.getVehicleProperties().getMaxHealth(); + vehicle.setHealth(health); + vehicle.updateVehicleInDatabase(player, health); + player.sendMessage(Lang.VEHICLES.f("&7You repaired vehicle " + vehicle.getDisplayName() + "&7 for &a$&l" + Utils.round(price) + "&7!")); + MenuManager.openMenu(player, "personalvehicle"); + return; + case 14: + MenuManager.openMenu(player, "personalvehicle"); + return; + default: + return; + } + default: + return; + } + case "personalvehicle": + switch (item.getType()) { + case REDSTONE: + MenuManager.openMenu(player, "vehicles"); + return; + case INK_SACK: { + PersonalVehicle vehicle = user.getPersonalVehicle(); + if (vehicle == null) { + MenuManager.openMenu(player, "vehicles"); + return; + } + user.setActionVehicle(vehicle.getVehicle()); + MenuManager.openMenu(player, "sellvehicle"); + return; + } + case ENDER_PEARL: { + PersonalVehicle vehicle = user.getPersonalVehicle(); + if (vehicle == null) { + MenuManager.openMenu(player, "vehicles"); + return; + } + if (vehicle.onMap()) { + vehicle.sendAway(player, Core.getUserManager().getLoadedUser(uuid), user); + } else { + vehicle.call(player, Core.getUserManager().getLoadedUser(uuid), user); + } + return; + } + case WORKBENCH: { + PersonalVehicle vehicle = user.getPersonalVehicle(); + if (vehicle == null) { + MenuManager.openMenu(player, "vehicles"); + return; + } + if (vehicle.getRepairPrice() <= 0) { + player.sendMessage(Lang.VEHICLES.f("&7You can't repair this vehicle!")); + return; + } + user.setActionVehicle(vehicle.getVehicle()); + MenuManager.openMenu(player, "repairvehicle"); + return; + } + default: + PersonalVehicle vehicle = user.getPersonalVehicle(); + if (vehicle == null) { + MenuManager.openMenu(player, "vehicles"); + return; + } + if (!item.hasItemMeta() || !item.getItemMeta().hasDisplayName() || !Objects.equals(item.getItemMeta().getDisplayName(), vehicle.getDisplayName())) + return; + vehicle.call(player, Core.getUserManager().getLoadedUser(uuid), user); + return; + } + case "mechanic": + switch (item.getType()) { + case ARROW: + int page = Integer + .parseInt(ChatColor.stripColor(item.getItemMeta().getLore().get(0)).replace("Page ", "")); + this.setPhoneDefaults(inv); + int[] slots = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + List<PersonalVehicle> vehicles = new ArrayList<>(user.getVehicles()); + new ArrayList<>(vehicles).stream().filter(vehicle -> vehicle.getRepairPrice() <= 0).forEach(vehicles::remove); + Iterator<PersonalVehicle> it = vehicles.iterator(); + for (int i = 0; i < page * 20; i++) { + if (!it.hasNext()) + break; + PersonalVehicle vehicle = it.next(); + if (i < (page - 1) * 20) + continue; + ItemStack stack = vehicle.getVehicleProperties().getItem().clone(); + ItemMeta meta = stack.getItemMeta(); + List<String> lore = new ArrayList<>(meta.getLore()); + lore.add(Utils.f("&7Health: " + vehicle.getFormattedHealth())); + lore.add(Utils.f("&7Repair Price: &a&l$" + NumberFormat.getNumberInstance(Locale.US).format(vehicle.getRepairPrice()))); + lore.add(Utils.f("&aClick to repair this vehicle!")); + meta.setLore(lore); + stack.setItemMeta(meta); + inv.setItem(slots[i - (page - 1) * 20], Objects.equals(vehicle, user.getPersonalVehicle()) ? Utils.addGlow(stack) : stack); + } + if (page > 1) + inv.setItem(48, Utils.createItem(Material.ARROW, "&4&lPrevious Page", "&7Page " + (page - 1))); + inv.setItem(47, Utils.createItem(Material.REDSTONE, "&c&lBack", "&7Return to the property page!")); + inv.setItem(49, Utils.createItem(Material.WORKBENCH, "&4&lMechanic", "&7Repair your vehicles!")); + if (vehicles.size() > (20 * page)) + inv.setItem(50, Utils.createItem(Material.ARROW, "&4&lNext Page", "&7Page " + (page + 1))); + return; + case REDSTONE: + player.closeInventory(); + return; + default: + if (!item.hasItemMeta() || !item.getItemMeta().hasDisplayName()) return; + GameItem gameItem = Vice.getItemManager().getItemFromDisplayName(item.getItemMeta().getDisplayName()); + if (gameItem == null) return; + PersonalVehicle vehicle = user.getPersonalVehicle(gameItem.getWeaponOrVehicleOrDrug()); + if (vehicle == null) return; + if (vehicle.onMap()) { + player.sendMessage(Lang.VEHICLES.f("&7Please send the driver to pick up your vehicle first!")); + return; + } + double price = vehicle.getRepairPrice(); + if (price <= 0) { + player.closeInventory(); + player.sendMessage(Lang.VEHICLES.f("&7You can't repair this vehicle!")); + return; + } + if (!user.hasMoney(price)) { + player.sendMessage(Lang.VEHICLES.f("&7You can't afford to pay &c$&l" + price + "&7 to repair this vehicle!")); + return; + } + user.setActionVehicle(null); + user.takeMoney(price); + ViceUtils.updateBoard(player, user); + double health = vehicle.getVehicleProperties().getMaxHealth(); + vehicle.setHealth(health); + vehicle.updateVehicleInDatabase(player, health); + player.sendMessage(Lang.VEHICLES.f("&7The Mechanic repaired vehicle " + vehicle.getDisplayName() + "&7 for &a$&l" + Utils.round(price) + "&7!")); + player.closeInventory(); + return; + } + + case "armorupgrade": + switch (item.getType()) { + case STAINED_GLASS_PANE: + switch (item.getDurability()) { + case 5: + player.closeInventory(); + ArmorUpgrade upgrade = user.getBuyingArmorUpgrade(); + if (upgrade == null) { + return; + } + if (!upgrade.canUseUpgrade(user.getRank(), Core.getUserManager().getLoadedUser(player.getUniqueId()).getUserRank())) { + player.sendMessage(Lang.HEY.f("&7You need to rank up to " + upgrade.getViceRank().getColoredNameBold() + "&7 or donate for " + upgrade.getUserRank().getColoredNameBold() + "&7 at &a&lstore.grandtheftmc.net&7 to use the &b&l" + upgrade.getDisplayName() + " Armor Upgrade&7!")); + return; + } + ItemStack i = player.getInventory().getItemInMainHand(); + GameItem gameItem = item == null ? null : Vice.getItemManager().getItem(i.getType()); + if (i == null || gameItem == null || !upgrade.canBeUsedOn(gameItem.getName())) { + player.sendMessage(Lang.HEY.f("&7The &b&l" + upgrade.getDisplayName() + " Armor Upgrade&7 can be applied to the following types of items: " + upgrade.getTypesString() + "&7!")); + return; + } + if (ArmorUpgrade.getArmorUpgrades(item).contains(upgrade)) { + player.sendMessage(Lang.ARMOR_UPGRADE.f("&7That piece of armor already has the &b&l" + upgrade.getDisplayName() + " Armor Upgrade&7!")); + return; + } + double price = upgrade.getPrice(); + if (!user.hasMoney(upgrade.getPrice())) { + player.sendMessage(Lang.ARMOR_UPGRADE.f("&7You can't afford the &b&l" + upgrade.getDisplayName() + " Armor Upgrade&7!")); + return; + } + Bukkit.getPluginManager().callEvent(new MoneyEvent(player.getUniqueId(), MoneyEvent.MoneyEventType.TAKE, price)); + player.getInventory().setItemInMainHand(upgrade.getUpgradedItem(gameItem, i)); + player.sendMessage(Lang.ARMOR_UPGRADE.f("&7You applied the &b&l" + upgrade.getDisplayName() + " Armor Upgrade&7 to your " + (i.getItemMeta().hasDisplayName() ? i.getItemMeta().getDisplayName() : i.getType().name()) + "&7 for &a$&l" + price + "&7!")); + return; + case 14: + player.closeInventory(); + return; + default: + return; + } + default: + return; + } + case "lottery": + switch (item.getType()) { + case EMPTY_MAP: + int amnt = Integer.parseInt(ChatColor.stripColor(item.getItemMeta().getDisplayName()) + .replace(" Tickets", "")); + if (!user.hasMoney(amnt * 500)) { + player.sendMessage(Lang.BANK.f("&7You don't have &c$&l" + (amnt * 500) + " &con you!")); + return; + } + user.takeMoney(amnt * 500); + LotteryPlayer p = Vice.getLottery().getLotteryPlayer(uuid); + if (p == null) { + p = new LotteryPlayer(uuid, player.getName()); + Vice.getLottery().addLotteryPlayer(p); + } + p.addTickets(amnt); + ViceUtils.updateBoard(player, user); + player.sendMessage(Lang.LOTTERY.f("&7You bought &e&l" + amnt + " Tickets&7 for &a$&l" + (amnt * 500) + "&7!")); + player.closeInventory(); + return; + case BOOK_AND_QUILL: + user.setBooleanToStorage(BooleanStorageType.BUYING_LOTTERY_TICKETS, true); + player.closeInventory(); + player.sendMessage(Utils.f(Lang.BANK + + "&7Please type (in chat) the amount of tickets you would like to buy for &a$&l500&7 each, or type&a \"quit\"&7!")); + return; + case REDSTONE: + MenuManager.openMenu(player, "bank"); + return; + default: + return; + } + } + } +} + + + + + diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/MobSpawn.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/MobSpawn.java new file mode 100644 index 0000000..92f4a16 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/MobSpawn.java @@ -0,0 +1,32 @@ +package net.grandtheftmc.vice.listeners; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.event.entity.EntitySpawnEvent; + +/** + * Created by Timothy Lampen on 2017-08-17. + */ +public class MobSpawn implements Listener { + + @EventHandler + public void onSpawn(CreatureSpawnEvent event){ + LivingEntity e = event.getEntity(); + if(event.getSpawnReason()!= CreatureSpawnEvent.SpawnReason.CUSTOM && e.getLocation().getWorld().getName().equals("spawn")) + event.setCancelled(true); + } + + // HIGHEST to override any other plugins, currently works if not disabled by another plugin. + @EventHandler (priority = EventPriority.HIGHEST) + public void onWitherSpawn(EntitySpawnEvent event) { + Entity entity = event.getEntity(); + if (entity.getType() == EntityType.WITHER) { + event.setCancelled(true); + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Move.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Move.java new file mode 100644 index 0000000..d6df49f --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Move.java @@ -0,0 +1,94 @@ +package net.grandtheftmc.vice.listeners; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.drugs.Drug; +import net.grandtheftmc.vice.drugs.DrugService; +import net.grandtheftmc.vice.drugs.example.Cocaine; +import net.grandtheftmc.vice.world.ViceSelection; +import net.grandtheftmc.vice.world.events.PlayerEnterZoneEvent; +import net.grandtheftmc.vice.world.events.PlayerLeaveZoneEvent; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.util.Vector; + +import java.util.List; +import java.util.Optional; + +public class Move implements Listener { + + + @EventHandler + public void onMove(PlayerMoveEvent event) { + + + Location to = event.getTo(), from = event.getFrom(); + + if (to.getBlockX() == from.getBlockX() && to.getBlockY() == from.getBlockY() && to.getBlockZ() == from.getBlockZ()) { + //Player has not moved block + return; + } + + Player player = event.getPlayer(); + + Optional<Drug> cocaine = ((DrugService) Vice.getDrugManager().getService()).getDrug("cocaine"); + if (cocaine.isPresent()) { + if (((Cocaine) cocaine.get()).cantMove(player.getUniqueId())) { + event.setCancelled(true); + return; + } + } + + + List<ViceSelection> pastZones = Vice.getWorldManager().getZones(from); + + List<ViceSelection> currentZones = Vice.getWorldManager().getZones(to); + if(!pastZones.equals(currentZones)) { + + pastZones.forEach(zone -> { + if (!currentZones.contains(zone)) {//player left zone + PlayerLeaveZoneEvent e = new PlayerLeaveZoneEvent(player, zone); + Bukkit.getPluginManager().callEvent(e); + if (e.isCancelled()) { + Vector velocity = player.getLocation().getDirection(); + velocity.setY(0.3); + player.setVelocity(velocity.multiply(-0.5)); + } + } else + currentZones.remove(zone); + }); + for (ViceSelection entered : currentZones) { + PlayerEnterZoneEvent e = new PlayerEnterZoneEvent(player, entered); + Bukkit.getPluginManager().callEvent(e); + if (e.isCancelled()) { + Vector velocity = player.getLocation().getDirection(); + velocity.setY(0.3); + player.setVelocity(velocity.multiply(-0.5)); + } + } + } + + if (!player.getWorld().getName().equalsIgnoreCase("spawn") && Vice.getWorldManager().getWarpManager().cancelTaxi(player, Vice.getUserManager().getLoadedUser(player.getUniqueId()))) { + player.sendMessage(Lang.TAXI.f("&eYou moved! Teleportation cancelled!")); + return; + } + +// if (player.isGliding()) { +// if (!player.isSneaking() || player.getLocation().getY() > 200) return; +// double pitch = -event.getTo().getPitch(); +// if (pitch < 10 || pitch > 90) return; +// Vector vector = player.getLocation().getDirection(); +// player.setVelocity(vector.multiply(1.6)); +// player.getWorld().playSound(event.getFrom(), Sound.ENTITY_ARROW_SHOOT, 1.0F, 2.0F); +// return; +// } + + + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/NametagComponent.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/NametagComponent.java new file mode 100644 index 0000000..6e913bc --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/NametagComponent.java @@ -0,0 +1,38 @@ +package net.grandtheftmc.vice.listeners; + +import net.grandtheftmc.core.util.Component; +import net.grandtheftmc.vice.Vice; + +/** + * Created by Luke Bingham on 03/08/2017. + */ +public class NametagComponent implements Component<NametagComponent, Vice> { + +// private final TagManager<Vice> tagManager; +// +// public NametagComponent(Vice plugin, TagManager<Vice> tagManager) { +// this.tagManager = tagManager; +// Bukkit.getPluginManager().registerEvents(this, plugin); +// } +// +// @EventHandler(priority = EventPriority.MONITOR) +// protected final void onPlayerJoin(PlayerJoinEvent event) { +// Player player = event.getPlayer(); +// UserRank userRank = Core.getUserManager().getLoadedUser(player.getUniqueId()).getUserRank(); +// ViceRank viceRank = Vice.getUserManager().getLoadedUser(player.getUniqueId()).getRank(); +// +// StringBuilder name = new StringBuilder(); +// name.append(userRank.isHigherThan(UserRank.DEFAULT) ? userRank.getColoredNameBold() + "&r " : "&r"); +// name.append(player.getDisplayName() == null ? player.getName() : player.getDisplayName()).append("&r "); +// name.append(viceRank.getColoredNameBold() + "&r"); +// +// Tag tag1 = this.tagManager.createTag(NMSVersion.MC_1_12, player, 1, "&c❤&r &c" + player.getHealth(), null); +// Tag tag2 = this.tagManager.createTag(NMSVersion.MC_1_12, player, 2, name.toString(), tag1); +// +// FPlayer fPlayer = FPlayers.getInstance().getByPlayer(player); +// if(fPlayer != null && fPlayer.hasFaction()) +// this.tagManager.createTag(NMSVersion.MC_1_12, player, 3, fPlayer.getFaction().getTag(), tag2); +// +// this.tagManager.refreshAll(player); +// } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/PetListener.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/PetListener.java new file mode 100644 index 0000000..eb98f05 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/PetListener.java @@ -0,0 +1,29 @@ +package net.grandtheftmc.vice.listeners; + +/* com.dsh105.echopet.compat.api.event.PetInteractEvent; +import com.dsh105.echopet.compat.api.event.PetTeleportEvent; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.ViceUser; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler;*/ +import org.bukkit.event.Listener; + +public class PetListener implements Listener { + + /*@EventHandler + public void onTeleport(PetTeleportEvent e) { + Player player = e.getPet().getOwner(); + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + if (user.isInCombat() || user.isArrested()) + e.setCancelled(true); + } + + @EventHandler + public void onPetInteract(PetInteractEvent e) { + Player player = e.getPet().getOwner(); + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + if (user.isInCombat() || user.isArrested()) + e.setCancelled(true); + }*/ + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Pickup.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Pickup.java new file mode 100644 index 0000000..638ecd8 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Pickup.java @@ -0,0 +1,95 @@ +package net.grandtheftmc.vice.listeners; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.items.AmmoType; +import net.grandtheftmc.vice.users.ViceUser; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Item; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryPickupItemEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +public class Pickup implements Listener { + + public void m(int i) { + Bukkit.broadcastMessage(String.valueOf(i)); + } + + @EventHandler + public void onPickup(PlayerPickupItemEvent e) { + Player player = e.getPlayer(); + ItemStack item = e.getItem().getItemStack(); + if (player.isInsideVehicle() || e.getItem().getItemStack().getType() == Material.ARROW) { + e.setCancelled(true); + return; + } + switch (item.getType()) { + case PAPER: + ItemMeta im = item.getItemMeta(); + if (im == null || !im.hasDisplayName()) + return; + String disp = ChatColor.stripColor(item.getItemMeta().getDisplayName()).replace("$", ""); + double amnt; + try { + amnt = Double.parseDouble(disp); + } catch (NumberFormatException ex) { + return; + } + amnt *= item.getAmount(); + + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + user.addMoney(amnt); + player.sendMessage(Utils.f(Lang.MONEY_ADD.toString() + amnt)); + e.getItem().remove(); + e.setCancelled(true); + Utils.kaching(player); + ViceUtils.updateBoard(player, user); + return; + default: + break; + } + AmmoType type = AmmoType.getAmmoType(item); + if (type != null) { + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + if (type.isInInventory()) { + user.updateAmmoLater(); + return; + } + int i = item.getAmount() + e.getRemaining(); + user.addAmmo(type, i); + e.setCancelled(true); + e.getItem().remove(); + player.sendMessage(Lang.AMMO_ADD.f(i + "&7 " + type.getGameItem().getDisplayName())); + } + + + HashMap<ItemStack, ItemStack> replacedVanillaItems = Vice.getItemManager().getReplacedVanilla(); + if(replacedVanillaItems.keySet().stream().anyMatch(value -> value.isSimilar(item))) { + Optional<Map.Entry<ItemStack, ItemStack>> optItemStack = replacedVanillaItems.entrySet().stream().filter(map -> map.getKey().isSimilar(item)).findFirst(); + if (optItemStack.isPresent()) { + ItemStack newItem = optItemStack.get().getValue(); + newItem.setAmount(item.getAmount()); + Item newI = player.getWorld().dropItemNaturally(e.getItem().getLocation(), newItem); + newI.setPickupDelay(0); + e.getItem().remove(); + e.setCancelled(true); + + } + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/PlayerEnterZone.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/PlayerEnterZone.java new file mode 100644 index 0000000..af43d1d --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/PlayerEnterZone.java @@ -0,0 +1,41 @@ +package net.grandtheftmc.vice.listeners; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.ViceUser; +import net.grandtheftmc.vice.world.ViceSelection; +import net.grandtheftmc.vice.world.ZoneFlag; +import net.grandtheftmc.vice.world.events.PlayerEnterZoneEvent; +import net.grandtheftmc.vice.world.warps.Warp; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +/** + * Created by Timothy Lampen on 2017-08-28. + */ +public class PlayerEnterZone implements Listener { + + @EventHandler + public void onZoneEnter(PlayerEnterZoneEvent event) { + Player player = event.getPlayer(); + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + ViceSelection zone = event.getZone(); + for(ZoneFlag flag : zone.getFlags()) { + switch (flag) { + case COP_TELEPORT_STATION: { + if (user.isCop()) { + Warp w = Vice.getWorldManager().getWarpManager().getWarp("police-station"); + if (w == null) { + Core.error("Attempted to TP cop to station, but couldnt as warp police-station hasnt been set."); + return; + } + player.teleport(w.getLocation()); + player.sendMessage(Lang.COP_MODE.f("&7You have been teleported to the police station because you are not allowed in this area!")); + } + } + } + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/PlayerLeaveZone.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/PlayerLeaveZone.java new file mode 100644 index 0000000..8b96098 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/PlayerLeaveZone.java @@ -0,0 +1,36 @@ +package net.grandtheftmc.vice.listeners; + +import net.grandtheftmc.core.util.State; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.CheatCode; +import net.grandtheftmc.vice.users.ViceUser; +import net.grandtheftmc.vice.world.ViceSelection; +import net.grandtheftmc.vice.world.ZoneFlag; +import net.grandtheftmc.vice.world.events.PlayerLeaveZoneEvent; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +/** + * Created by Timothy Lampen on 2017-08-28. + */ +public class PlayerLeaveZone implements Listener{ + + @EventHandler + public void onLeaveZone(PlayerLeaveZoneEvent event) { + Player player = event.getPlayer(); + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + ViceSelection zone = event.getZone(); + for(ZoneFlag flag : zone.getFlags()) { + switch (flag) { + case COP_CANT_ARREST: {//player is leaving the safezone + if(user.getCheatCodeState(CheatCode.SNEAKY).getState()== State.ON) { + player.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, 20*5, 0)); + } + } + } + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/PortalEnter.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/PortalEnter.java new file mode 100644 index 0000000..21ec591 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/PortalEnter.java @@ -0,0 +1,79 @@ +package net.grandtheftmc.vice.listeners; + +import com.massivecraft.factions.Board; +import com.massivecraft.factions.FLocation; +import com.massivecraft.factions.Faction; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.TaxiTarget; +import net.grandtheftmc.vice.users.ViceUser; +import org.bukkit.*; +import org.bukkit.block.Biome; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityPortalEnterEvent; +import org.bukkit.event.player.PlayerPortalEvent; + +import java.util.concurrent.ThreadLocalRandom; + +public class PortalEnter implements Listener { + + @EventHandler(ignoreCancelled = true) + public void playerPortalEvent(EntityPortalEnterEvent event) { + if (event.getEntityType() != EntityType.PLAYER) return; + Player player = (Player) event.getEntity(); + + ViceUser viceUser = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + if (viceUser.getTaxiTarget() != null) return; + + if (event.getLocation().getWorld().getName().equalsIgnoreCase("spawn")) { +// User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); +// Warp randomWarp = Vice.getWarpManager().getRandomWarp(); +// player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1F, 1F); +// Vice.getWarpManager().warp(player, user, Vice.getUserManager().getLoadedUser(player.getUniqueId()), +// new TaxiTarget(randomWarp), 0, user.isPremium() ? 1 : 10); + + //Random teleport. + World world = Bukkit.getWorld("world"); + boolean unfit = true; + int tries = 0; + Location loc = new Location(world, 0, 0, 0); + while (unfit) { + if (tries > 100) { + player.sendMessage(Lang.TAXI.f("&7Could not find suitable location to teleport you to. Please try again.")); + return; + } + loc = new Location(world, + ThreadLocalRandom.current().nextInt(5000), + 0, + ThreadLocalRandom.current().nextInt(5000)); + loc.setY(world.getHighestBlockYAt(loc)); + Faction factionAt = Board.getInstance().getFactionAt(new FLocation(loc)); + Biome biome = world.getBiome(loc.getBlockX(), loc.getBlockZ()); + Material material = loc.getWorld().getHighestBlockAt(loc).getType(); + unfit = !factionAt.isWilderness() + || biome == Biome.OCEAN || biome == Biome.DEEP_OCEAN + || biome == Biome.FROZEN_OCEAN || biome == Biome.SKY + || biome == Biome.VOID || biome == Biome.RIVER || material == Material.WATER || material == Material.STATIONARY_WATER || material == Material.LAVA || material == Material.STATIONARY_LAVA || material == Material.CACTUS; + tries += 1; + } + loc.setY(loc.getY() + 0.5); + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + viceUser.setLastRTP(); + Vice.getWorldManager().getWarpManager().warp(player, user, viceUser, new TaxiTarget(loc), 0, -1, + "&eYou called a taxi to take you to &a" + loc.getBlockX() + "&e, &a" + loc.getBlockY() + "&e, &a" + loc.getBlockZ() + "&e in the wilderness.."); + return; + } + } + + @EventHandler(ignoreCancelled = true) + protected final void onPortalEnter(PlayerPortalEvent event) { + if(event.getFrom() != null && event.getFrom().getWorld() != null && + event.getFrom().getWorld().getName().equalsIgnoreCase("spawn")) + event.setCancelled(true); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/RenameComponent.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/RenameComponent.java new file mode 100644 index 0000000..ef29e72 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/RenameComponent.java @@ -0,0 +1,40 @@ +package net.grandtheftmc.vice.listeners; + +import com.google.common.collect.Sets; +import net.grandtheftmc.core.util.Component; +import net.grandtheftmc.vice.Vice; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.event.EventHandler; +import org.bukkit.event.inventory.PrepareAnvilEvent; +import org.bukkit.inventory.ItemStack; + +import java.util.Set; + +public class RenameComponent implements Component<RenameComponent, Vice> { + + private static final Set<Material> BLACKLIST; + + static { + BLACKLIST = Sets.newHashSet(); + BLACKLIST.add(Material.MOB_SPAWNER); + BLACKLIST.add(Material.CHEST); + BLACKLIST.add(Material.DIAMOND_SWORD); + } + + public RenameComponent(Vice vice) { + Bukkit.getPluginManager().registerEvents(this, vice); + } + + @EventHandler + protected final void onItemRename(PrepareAnvilEvent event) { + if (event.getInventory() == null) return; + if (event.getResult() == null) return; + if (event.getResult().getType() == Material.AIR) return; + + if (BLACKLIST.contains(event.getResult().getType())) { + event.setResult(new ItemStack(Material.AIR)); + } + + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/SmeltItem.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/SmeltItem.java new file mode 100644 index 0000000..44f7abe --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/SmeltItem.java @@ -0,0 +1,26 @@ + +package net.grandtheftmc.vice.listeners; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.items.recipetypes.CraftingRecipeItem; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.FurnaceSmeltEvent; +import org.bukkit.inventory.ItemStack; + +/** + * Created by Timothy Lampen on 7/10/2017. + */ +public class SmeltItem implements Listener{ + @EventHandler + public void onSmelt(FurnaceSmeltEvent event){ + ItemStack result = event.getResult(); + CraftingRecipeItem craftingRecipeItem = (CraftingRecipeItem)Vice.getItemManager().getCustomRecipes().getOrDefault(result, null); + if(craftingRecipeItem ==null) + return; + if(!craftingRecipeItem.validate(new ItemStack[]{event.getSource()})){ + event.setCancelled(true); + return; + } + } +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/SwapHandItems.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/SwapHandItems.java new file mode 100644 index 0000000..5d351df --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/SwapHandItems.java @@ -0,0 +1,41 @@ +package net.grandtheftmc.vice.listeners; + +import com.j0ach1mmall3.wastedvehicles.api.events.VehicleEnterEvent; +import com.j0ach1mmall3.wastedvehicles.api.vehicles.WastedVehicle; +import net.grandtheftmc.core.events.PlayerFActionEvent; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +import java.util.Set; + +public class SwapHandItems implements Listener { + + @EventHandler + public void onPlayerFAction(PlayerFActionEvent event) { + Player player = event.getPlayer(); + Block targetBlock; + if (player.getTargetBlock((Set<Material>) null, 1).getType() != Material.AIR) { + targetBlock = player.getTargetBlock((Set<Material>) null, 1); + } else if (player.getTargetBlock((Set<Material>) null, 2).getType() != Material.AIR) { + targetBlock = player.getTargetBlock((Set<Material>) null, 2); + } else { + targetBlock = player.getTargetBlock((Set<Material>) null, 3); + } + player.getWorld().getNearbyEntities(targetBlock.getLocation(), 2, 2, 2).forEach(entity -> { + if (entity.getType() != EntityType.ARMOR_STAND) return; + if (entity.hasMetadata("WastedVehicle")) { + WastedVehicle wastedVehicle = (WastedVehicle) entity.getMetadata("WastedVehicle").get(0).value(); + VehicleEnterEvent vehicleEnterEvent = new VehicleEnterEvent(wastedVehicle, player, (ArmorStand) entity); + Bukkit.getPluginManager().callEvent(vehicleEnterEvent); + if (!vehicleEnterEvent.isCancelled()) wastedVehicle.onRightClick((ArmorStand) entity, player); + } + }); + + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Target.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Target.java new file mode 100644 index 0000000..f71dd25 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Target.java @@ -0,0 +1,39 @@ +package net.grandtheftmc.vice.listeners; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.ViceUser; +import org.bukkit.entity.Player; +import org.bukkit.entity.Tameable; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityTargetEvent; + +import java.util.UUID; + +public class Target implements Listener { + + @EventHandler + public void onTarget(EntityTargetEvent e) { + if (!(e.getTarget() instanceof Player)) + return; + + if (e.getTarget().getWorld().getName().equals("spawn")) { + e.setCancelled(true); + return; + } + + if (e.getEntity() instanceof Tameable) { + Tameable t = (Tameable) e.getEntity(); + + if (!(t.getOwner() instanceof Player)) + return; + + Player player = (Player) t.getOwner(); + UUID uuid = player.getUniqueId(); + ViceUser user = Vice.getUserManager().getLoadedUser(uuid); + Player target = (Player) e.getTarget(); + UUID targetUuid = target.getUniqueId(); + ViceUser targetUser = Vice.getUserManager().getLoadedUser(targetUuid); + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Teleport.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Teleport.java new file mode 100644 index 0000000..60091ff --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/Teleport.java @@ -0,0 +1,18 @@ +package net.grandtheftmc.vice.listeners; + +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerTeleportEvent; + +/** + * Created by ThatAbstractWolf on 2017-08-24. + */ +public class Teleport implements Listener { + + @EventHandler + public void onTeleport(PlayerTeleportEvent event) { + + if (event.getPlayer().getWorld().getName().equals("spawn") && event.getCause() == PlayerTeleportEvent.TeleportCause.ENDER_PEARL) + event.setCancelled(true); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/UpdateListener.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/UpdateListener.java new file mode 100644 index 0000000..fefd3a0 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/UpdateListener.java @@ -0,0 +1,298 @@ +package net.grandtheftmc.vice.listeners; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.events.*; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.voting.Reward; +import net.grandtheftmc.core.voting.events.PlayerVoteEvent; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.drugs.Drug; +import net.grandtheftmc.vice.drugs.DrugService; +import net.grandtheftmc.vice.drugs.items.DrugItem; +import net.grandtheftmc.vice.events.TPEvent; +import net.grandtheftmc.vice.items.GameItem; +import net.grandtheftmc.vice.items.Head; +import net.grandtheftmc.vice.items.ItemManager; +import net.grandtheftmc.vice.items.Kit; +import net.grandtheftmc.vice.users.ViceUser; +import net.grandtheftmc.vice.utils.Stats; +import net.md_5.bungee.api.chat.*; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.WordUtils; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.*; + +public class UpdateListener implements Listener { + private final Map<UUID, Integer> voteCounts = new HashMap<>(); + + @EventHandler + public void voteEvent(PlayerVoteEvent event) { + UUID uuid = event.getUUID(); + Player player = Bukkit.getPlayer(uuid); + if (player == null) return; + this.voteCounts.put(uuid, this.voteCounts.getOrDefault(uuid, 0) + 1); + ViceUser viceUser = Vice.getUserManager().getLoadedUser(uuid); + User user = Core.getUserManager().getLoadedUser(uuid); + Kit kit = Vice.getItemManager().getKit("vote"); + if (this.voteCounts.get(uuid) == 5) { + player.sendMessage(Lang.VOTE.f("&7Thank you for voting on all 5 sites! Here is a special vote kit!")); + Vice.getItemManager().giveKitItems(player, viceUser, kit); + user.addCrowbars(1); + } + } + + @EventHandler + public void tpEvent(TPEvent event) { + if (event.getType() == TPEvent.TPType.HOUSE_ENTER + || event.getType() == TPEvent.TPType.PREMIUM_HOUSE_ENTER) { + Player player = event.getPlayer(); + ViceUser viceUser = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + if (viceUser.isInCombat()) { + event.setCancelled(Utils.f("&7You cannot enter a house while in combat!")); + } + } + } + + @EventHandler + public void serverSaveEvent(ServerSaveEvent event) { + Vice.getShopManager().getHeads().forEach(Head::update); + Vice.getUserManager().getLoadedUsers().forEach(gtmUser -> { + if (gtmUser == null) return; + gtmUser.checkAchievements(); + }); + } + + @EventHandler + public void chatEvent(ChatEvent event) { + Player player = event.getSender(); + TextComponent message = event.getTextComponent(); + List<String> hover = Stats.getInstance().getStats(player); + String url = ""; + + for (String string : message.getText().split(" ")) { + if (ViceUtils.isValidURL(string)) { + url = string; + break; + } + + if (ViceUtils.getUser(player).isRank(UserRank.VIP) && (string.equalsIgnoreCase(":hand:") + || string.equalsIgnoreCase(":items:") || string.equalsIgnoreCase(":item:"))) { + if (player.getInventory().getItemInMainHand() == null) continue; + ItemStack hand = player.getInventory().getItemInMainHand().clone(); + String json = ViceUtils.convertItemStackToJson(hand); + if (json == null) continue; + if (!hand.hasItemMeta() || !hand.getItemMeta().hasDisplayName()) { + ItemMeta meta = hand.getItemMeta(); + meta.setDisplayName(WordUtils.capitalize(hand.getType().name().toLowerCase().replace("_", " "))); + hand.setItemMeta(meta); + } + message.setText(message.getText().replace(string, + hand.getItemMeta().getDisplayName() + message.getColor())); + message.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, new BaseComponent[]{ + new TextComponent(json) + })); + break; + } + } + + if (url.isEmpty()) { + message.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/msg " + player.getName() + ' ')); + } else { + message.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, url)); + } + if (message.getHoverEvent() == null) { + message.setHoverEvent( + new HoverEvent(HoverEvent.Action.SHOW_TEXT, + new ComponentBuilder(StringUtils.join(hover, "\n")) + .create())); + } + event.setTextComponent(message); + } + + @EventHandler + public void onDisplayNameUpdate(DisplayNameUpdateEvent e) { + Player player = e.getPlayer(); + ViceUser u = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + e.setPrefix(u.isCop() ? u.getCopRank().getColoredNameBold() : u.getRank().getColoredNameBold()); + } + + @EventHandler + public void onGetPerms(GetPermsEvent e) { + ViceUser user = Vice.getUserManager().getLoadedUser(e.getUUID()); + if (user != null && user.getRank() != null) { + user.getRank().getAllPerms().forEach(e::addPerm); + if (user.isCop()) user.getCopRank().getAllPerms().forEach(e::addPerm); + } + } + + @EventHandler + public void onNametagChange(NametagUpdateEvent e) { + Player player = e.getPlayer(); + if (player == null) + return; + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + ViceUser viceUser = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + + // TODO achievements + } + + @EventHandler + public void onTutorialEvent(TutorialEvent e) { + Player player = e.getPlayer(); + switch (e.getType()) { + case PRE_START: + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + if (user.isInCombat()) { + e.setCancelled("&7You can't join tutorials in combat!"); + return; + } + if (user.isArrested()) { + e.setCancelled("&7You can't join tutorials in jail!"); + return; + } + if (!Objects.equals("spawn", player.getWorld().getName())) { + e.setCancelled("&7You can only join tutorials at spawn!"); + return; + } + break; + case START: + ViceUtils.removeBoard(player); + break; + default: + break; + } + + } + + @EventHandler + public void onReward(RewardEvent e) { + Player player = e.getPlayer(); + Reward reward = e.getReward(); + if (reward.getCustomType() != null) + switch (reward.getCustomType()) { + case "drug": { + Optional<Drug> drug = ((DrugService) Vice.getDrugManager().getService()).getDrug(reward.getCustomName()); + if (drug.isPresent()) { + DrugItem item = DrugItem.getByDrug(drug.get()); + if (item != null) { + Utils.giveItems(player, item.getItemStack()); + } else { + player.sendMessage(Lang.GTM + "" + ChatColor.RED + "Unable to give you the drug " + reward.getCustomName() + ", couldn't find it."); + } + } + return; + } + case "item": { + String[] a = reward.getCustomName().split(":"); + GameItem item = Vice.getItemManager().getItem(a[0]); + if (item == null) + return; + ItemStack stack = item.getItem(); + if (a.length > 1) + try { + stack.setAmount(Integer.parseInt(a[1])); + } catch (NumberFormatException ignored) { + } + if (Utils.giveItems(player, stack)) + player.sendMessage( + Utils.f(Lang.VOTE + "&7Your inventory was full so the item was dropped on the ground!")); + e.setSuccessfull(true); + return; + } + case "items": + ItemManager im = Vice.getItemManager(); + boolean successfull = true; + List<ItemStack> items = new ArrayList<>(); + for (String s : reward.getCustomList()) { + String[] a = s.split(":"); + GameItem item = im.getItem(a[0]); + if (item == null) { + successfull = false; + continue; + } + ItemStack stack = item.getItem(); + if (a.length > 1) + try { + stack.setAmount(Integer.parseInt(a[1])); + } catch (NumberFormatException ignored) { + } + items.add(stack); + } + if (Utils.giveItems(player, Utils.toArray(items))) + player.sendMessage( + Utils.f(Lang.VOTE + "&7Your inventory was full so some items were dropped on the ground!")); + e.setSuccessfull(successfull); + return; + case "kit": + Kit kit = Vice.getItemManager().getKit(reward.getCustomName()); + if (kit != null) { + Vice.getItemManager().giveKitItems(player, Vice.getUserManager().getLoadedUser(player.getUniqueId()), kit); + e.setSuccessfull(true); + } + return; + case "bonds": + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + user.giveBonds((int) reward.getAmount()); + e.setSuccessfull(true); + return; + default: + break; + } + } + + @EventHandler + public void onMoneyEvent(MoneyEvent e) { + ViceUser user = Vice.getUserManager().getLoadedUser(e.getUUID()); + switch (e.getType()) { + case ADD: + user.addMoney(e.getAmount()); + e.setSuccessfull(); + break; + case BALANCE: + e.setBalance(user.getMoney()); + break; + case TAKE: + user.takeMoney(e.getAmount()); + e.setSuccessfull(); + break; + } + ViceUtils.updateBoard(Bukkit.getPlayer(e.getUUID()), user); + } + + @EventHandler + public void onUpdate(UpdateEvent e) { + switch (e.getReason()) { + case BOARD: + case MONEY: + case OTHER: + case RANK: + ViceUtils.updateBoard(e.getPlayer(), Vice.getUserManager().getLoadedUser(e.getPlayer().getUniqueId())); + break; + case PREF: + switch (e.getPref()) { + case USE_SCOREBOARD: + ViceUtils.updateBoard(e.getPlayer(), Vice.getUserManager().getLoadedUser(e.getPlayer().getUniqueId())); + break; + case TINT_HEALTH: + Vice.getUserManager().getLoadedUser(e.getPlayer().getUniqueId()).updateTintHealth(e.getPlayer(), Core.getUserManager().getLoadedUser(e.getPlayer().getUniqueId())); + break; + default: + break; + } + default: + break; + } + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/VehicleUse.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/VehicleUse.java new file mode 100644 index 0000000..c739718 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/VehicleUse.java @@ -0,0 +1,117 @@ +package net.grandtheftmc.vice.listeners; + +import com.j0ach1mmall3.wastedvehicles.api.events.JetpackFlyEvent; +import com.j0ach1mmall3.wastedvehicles.api.events.VehicleDestroyEvent; +import com.j0ach1mmall3.wastedvehicles.api.events.VehicleEnterEvent; +import com.j0ach1mmall3.wastedvehicles.api.events.VehiclePassengerEnterEvent; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.PersonalVehicle; +import net.grandtheftmc.vice.users.ViceRank; +import net.grandtheftmc.vice.users.ViceUser; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +import java.util.Objects; + +public class VehicleUse implements Listener { + + @EventHandler + public void onVehiclePassengerEnter(VehiclePassengerEnterEvent event) { + if (Bukkit.getPlayer(event.getVehicle().getCreator()) == null) return; + Player passenger = event.getPlayer(); + Player owner = Bukkit.getPlayer(event.getVehicle().getCreator()); + ViceUser passengerUser = Vice.getUserManager().getLoadedUser(passenger.getUniqueId()); + ViceUser ownerUser = Vice.getUserManager().getLoadedUser(owner.getUniqueId()); + // TODO replace the Gang check with a Cartel check :p + /* if (ownerUser.getGang() == null || passengerUser.getGang() == null) { + passenger.sendMessage(Lang.VEHICLES.f("&fYou must be in the same gang as the Vehicle Driver to enter!")); + event.setCancelled(true); + } else + if (ownerUser.getGang() != passengerUser.getGang()) { + passenger.sendMessage(Lang.VEHICLES.f("&fYou must be in the same gang as the Vehicle Driver to enter!")); + event.setCancelled(true); + } else { + event.setCancelled(false); + }*/ + + } + + @EventHandler + public void onVehicleEnter(VehicleEnterEvent e) { + Player player = e.getPlayer(); + if (Objects.equals("spawn", player.getWorld().getName())) { + player.sendMessage(Lang.HEY.f("&7You can't enter vehicles in spawn!")); + e.setCancelled(true); + return; + } + ViceUser viceUser = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + if (viceUser.isArrested()) { + player.sendMessage(Lang.JAIL.f("&7You can't enter vehicles in jail!")); + e.setCancelled(true); + } + if (e.getVehicle().getCreator() == null) return; + Player creator = Bukkit.getPlayer(e.getVehicle().getCreator()); + if (creator != null) { + User u = Core.getUserManager().getLoadedUser(creator.getUniqueId()); + ViceUser user = Vice.getUserManager().getLoadedUser(creator.getUniqueId()); + PersonalVehicle vehicle = user.getPersonalVehicle(); + if (vehicle == null) return; + if (Objects.equals(creator, player)) { + if (!vehicle.isStolen()) return; + vehicle.setStolen(false); + player.sendMessage(Lang.VEHICLES.f("&7You recovered your stolen " + vehicle.getDisplayName() + "&7!")); + return; + } + if (!Objects.equals(e.getArmorStand().getUniqueId(), vehicle.getEntityUUID()) || e.getArmorStand().getPassenger() != null || vehicle.isStolen()) + return; + vehicle.setStolen(true); + vehicle.updateVehicleInDatabase(creator, e.getArmorStand().getHealth()); + creator.sendMessage(Lang.VEHICLES.f("&7Your &c&l" + vehicle.getDisplayName() + "&7 was stolen!")); + player.sendMessage(Lang.VEHICLES.f("&7You stole " + u.getColoredName(creator) + "&7's " + vehicle.getDisplayName() + "&7!")); + } + } + + @EventHandler + public void onVehicleDestroy(VehicleDestroyEvent e) { + Player creator = Bukkit.getPlayer(e.getVehicle().getCreator()); + if (creator != null) { + ViceUser user = Vice.getUserManager().getLoadedUser(creator.getUniqueId()); + PersonalVehicle vehicle = user.getPersonalVehicle(); + if (vehicle == null || !e.getVehicle().getVehicleProperties().getIdentifier().equalsIgnoreCase(vehicle.getVehicle())) + return; + vehicle.updateVehicleInDatabase(creator, 0); + creator.sendMessage(Lang.VEHICLES.f("&7Your &c&l" + vehicle.getDisplayName() + "&7 was destroyed!")); + } + } + + @EventHandler + public void onJetpackFly(JetpackFlyEvent e) { + Player p = e.getPlayer(); + ViceUser user = Vice.getUserManager().getLoadedUser(e.getPlayer().getUniqueId()); + if (p.isSprinting() && p.isFlying()) { + p.setSprinting(false); + } + if (p.getWorld().getName().equalsIgnoreCase("spawn")) { + if (user.getLastJetpackCancel() + 2000 < System.currentTimeMillis()) { + user.setLastJetpackCancel(System.currentTimeMillis()); + e.getPlayer().sendMessage(Lang.VEHICLES.f("&7You cannot fly in the spawn area!")); + e.setCancelled(true); + } + return; + } + + if (!user.isRank(ViceRank.DRUGLORD) && !Core.getUserManager().getLoadedUser(e.getPlayer().getUniqueId()).isRank(UserRank.SPONSOR)) { + e.setCancelled(true); + if (user.getLastJetpackCancel() + 2000 < System.currentTimeMillis()) { + user.setLastJetpackCancel(System.currentTimeMillis()); + e.getPlayer().sendMessage(Lang.VEHICLES.f("&7You need to rank up to " + ViceRank.DRUGLORD.getColoredNameBold() + "&7 or donate for " + UserRank.SPONSOR.getColoredNameBold() + "&7 at &a&lstore.grandtheftmc.net&7 to use the jetpack!")); + } + } + } +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/VoteReward.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/VoteReward.java new file mode 100644 index 0000000..736950a --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/VoteReward.java @@ -0,0 +1,52 @@ +package net.grandtheftmc.vice.listeners; + +import com.j0ach1mmall3.wastedvehicles.api.VehicleProperties; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.voting.Reward; +import net.grandtheftmc.core.voting.events.RewardCheckEvent; +import net.grandtheftmc.core.voting.events.RewardGiveEvent; +import net.grandtheftmc.core.voting.events.RewardInfoEvent; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.ViceUser; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +import java.util.Optional; + +public class VoteReward implements Listener { + + @EventHandler + public void rewardGiveEvent(RewardGiveEvent event) { + Player player = event.getPlayer(); + ViceUser viceUser = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + String identifier = event.getIdentifier(); + if (event.getRewardType() == Reward.RewardType.VEHICLE) { + Optional<VehicleProperties> vehicleOptional = Vice.getWastedVehicles().getVehicle(identifier); + if (!vehicleOptional.isPresent()) return; + viceUser.giveVehiclePerm(player, vehicleOptional.get()); + player.sendMessage(Lang.REWARDS.f("&4&l" + identifier)); + } + } + + @EventHandler + public void rewardCheckEvent(RewardCheckEvent event) { + ViceUser viceUser = Vice.getUserManager().getLoadedUser(event.getPlayer().getUniqueId()); + String identifier = event.getIdentifier(); + if (event.getRewardType() == Reward.RewardType.VEHICLE) { + Optional<VehicleProperties> vehicleOptional = Vice.getWastedVehicles().getVehicle(identifier); + if (!vehicleOptional.isPresent()) return; + event.setResult(viceUser.hasVehicle(identifier)); + } + } + + @EventHandler + public void rewardInfoEvent(RewardInfoEvent event) { + String identifier = event.getIdentifier(); + if (event.getRewardType() == Reward.RewardType.VEHICLE) { + Optional<VehicleProperties> vehicleOptional = Vice.getWastedVehicles().getVehicle(identifier); + if (!vehicleOptional.isPresent()) return; + event.setDisplayItem(vehicleOptional.get().getItem()); + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/WeaponShoot.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/WeaponShoot.java new file mode 100644 index 0000000..681ff17 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/WeaponShoot.java @@ -0,0 +1,43 @@ +package net.grandtheftmc.vice.listeners; + +import com.j0ach1mmall3.wastedguns.api.events.ranged.RangedWeaponShootEvent; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.guns.weapon.Weapon; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +import java.util.Arrays; +import java.util.List; + +public class WeaponShoot implements Listener { + private final List<String> carGuns = Arrays.asList("Pistol", "CombatPistol", "HeavyPistol", "MarksmanPistol", + "TearGas", "StickyBomb", "Grenade", "MolotovCocktail", "ProximityMine", "MicroSMG", "SMG"); + + @EventHandler(ignoreCancelled = true) + public void onRangedWeaponShootEvent(RangedWeaponShootEvent event) { + if (event.getLivingEntity().getType() != EntityType.PLAYER) return; + Weapon weapon = event.getWeapon(); + String weaponName = weapon.getName(); + Player shooter = (Player) event.getLivingEntity(); + boolean inCar = shooter.getVehicle() != null && shooter.getVehicle().hasMetadata("WastedVehiclePassenger"); +// if (weapon.getItemStack().getDurability() != 0) { +// if (weapon.getName().equalsIgnoreCase("GoldMinigun") +// || weapon.getName().equalsIgnoreCase("Flamethrower")) return; +// weapon.getItemStack().setDurability((short) 0); +// } + if(inCar && !carGuns.contains(weaponName)) { + shooter.sendMessage(Lang.HEY.f("&7Weapon cannot be used in Car")); + event.setCancelled(true); + return; + } + if (weaponName.contains("NetLauncher")) { + if(shooter.getWorld().getName().equalsIgnoreCase("spawn")) { + shooter.sendMessage(Lang.HEY.f("&7The Net Launcher cannot be used in spawn")); + event.setCancelled(true); + } + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/WeaponUse.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/WeaponUse.java new file mode 100644 index 0000000..3843c7c --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/listeners/WeaponUse.java @@ -0,0 +1,386 @@ +package net.grandtheftmc.vice.listeners; + +import com.j0ach1mmall3.wastedguns.api.events.WeaponDamageEvent; +import com.j0ach1mmall3.wastedguns.api.events.WeaponRightClickEvent; +import com.j0ach1mmall3.wastedguns.api.events.WeaponSneakEvent; +import com.j0ach1mmall3.wastedguns.api.events.ranged.AmmoUpdateEvent; +import com.j0ach1mmall3.wastedguns.api.events.ranged.RangedWeaponReloadEvent; +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.FPlayers; +import com.massivecraft.factions.struct.Relation; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.servers.ServerType; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.guns.weapon.Weapon; +import net.grandtheftmc.guns.weapon.attribute.RankedWeapon; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.items.AmmoType; +import net.grandtheftmc.vice.users.LockedWeapon; +import net.grandtheftmc.vice.users.ViceUser; +import net.grandtheftmc.vice.world.ZoneFlag; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.*; +import java.util.concurrent.ThreadLocalRandom; + +public class WeaponUse implements Listener { + private final List<String> spawnBlocked = Arrays.asList("grenade", "molotovcocktail", "teargas", "stickybomb", + "proximitymine", "grenadelauncher", "hominglauncher", "rpg"); + private final List<String> jetpackAllowed = Arrays.asList("Pistol", "CombatPistol", "HeavyPistol", "MarksmanPistol", + "TearGas", "SawedoffShotgun", "MicroSMG"); + private final List<String> jetpackDisallowedHeavy = Arrays.asList("CombatMG", "MG", "Minigun", "RPG", + "HomingLauncher", "HeavySniper", "Flamethrower", "GoldMinigun", "NetLauncher"); + private final List<String> wingsuitDisallowed = Arrays.asList("Minigun", "GoldMinigun", "RPG", + "SniperRifle", "HeavySniper", "NetLauncher", "HomingLauncher", "GrenadeLauncher", + "CombatMG", "MG", "Flamethrower"); + + private Collection<String> recentKatanaChops = new ArrayList<>(); + + @EventHandler(priority = EventPriority.HIGHEST) + public void onAmmoChange(AmmoUpdateEvent e) { + ViceUser user = Vice.getUserManager().getLoadedUser(e.getPlayer().getUniqueId()); + for (AmmoType type : AmmoType.getTypes()) + e.getAmmo().put(type.name(), user.getAmmo(type)); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onReload(RangedWeaponReloadEvent e) { + Weapon weapon = e.getWeapon(); + if (weapon.getAmmoType() == null || !(e.getLivingEntity() instanceof Player)) + return; + + AmmoType type = AmmoType.getAmmoType(weapon.getAmmoType().getType()); + if (type == null) return; + + Player player = (Player) e.getLivingEntity(); + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + LockedWeapon l = LockedWeapon.getWeapon(weapon.getCompactName()); + if (e.getWeapon() instanceof RankedWeapon) { + UserRank required = ((RankedWeapon) e.getWeapon()).requiredRank(), current = Core.getUserManager().getLoadedUser(player.getUniqueId()).getUserRank(); + if (required != null && (!current.isHigherThan(required) && current != required)) { + player.sendMessage(Lang.HEY.f("&7You need to rank up to " + l.getViceRank().getColoredNameBold() + "&7 or donate for " + l.getUserRank().getColoredNameBold() + "&7 at &a&lstore.grandtheftmc.net&7 to use this weapon!")); + e.setCancelled(true); + return; + } + } + + int ammo = user.getAmmo(type); + if (ammo <= 0) { + e.setCancelled(true); + player.sendMessage(Lang.AMMO.f("&7You are out of ammo for this weapon!")); + } + else if (ammo < e.getAmmoToReload()) { + e.setAmmoToReload(ammo); + user.removeAmmo(type, ammo); + } + else { + user.removeAmmo(type, e.getAmmoToReload()); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onWeaponUse(WeaponRightClickEvent e) { + if (!(e.getLivingEntity() instanceof Player)) + return; + + Player player = (Player) e.getLivingEntity(); + Weapon weapon = e.getWeapon(); + if (Objects.equals("spawn", player.getWorld().getName())) { + if (this.spawnBlocked.contains(weapon.getCompactName().toLowerCase())) { + e.setCancelled(true); + return; + } + } + + ViceUser viceUser = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + LockedWeapon lockedWeapon = LockedWeapon.getWeapon(e.getWeapon().getCompactName().toUpperCase()); + if (lockedWeapon != null && !lockedWeapon.canUseWeapon(viceUser.getRank(), Core.getUserManager().getLoadedUser(player.getUniqueId()).getUserRank())) { + player.sendMessage(Lang.HEY.f("&7You need to rank up to " + lockedWeapon.getViceRank().getColoredNameBold() + "&7 or donate for " + lockedWeapon.getUserRank().getColoredNameBold() + "&7 at &a&lstore.grandtheftmc.net&7 to use this weapon!")); + e.setCancelled(true); + return; + } + +// if(e.getWeapon() instanceof RankedWeapon) { +// System.out.println("RankedWeapon: " + true); +// UserRank required = ((RankedWeapon) e.getWeapon()).requiredRank(), current = Core.getUserManager().getLoadedUser(player.getUniqueId()).getUserRank(); +// System.out.println(required.name() + " - " + current.name()); +// if (!current.isHigherThan(required) && current != required) { +// player.sendMessage(Lang.HEY.f("&7You need to rank up to " + ViceRank.JUNKIE.getColoredNameBold() + "&7 or donate for " + required.getColoredNameBold() + "&7 at &a&lstore.grandtheftmc.net&7 to use this weapon!")); +// e.setCancelled(true); +// return; +// } +// } + + if (viceUser.isArrested()) { + player.sendMessage(Lang.JAIL.f("&7You can't use weapons in jail!")); + e.setCancelled(true); + return; + } + + if (viceUser.hasTeleportProtection()) { + e.setCancelled(true); + player.sendMessage(Lang.COMBATTAG.f("&7Please wait &c&l" + Utils.timeInMillisToText(viceUser.getTimeUntilTeleportProtectionExpires()) + "&7!")); + return; + } + + boolean elytra = player.getInventory().getChestplate() != null && player.getInventory().getChestplate().getType() == Material.ELYTRA; + if (elytra) { + if (this.wingsuitDisallowed.contains(e.getWeapon().getCompactName())) { + player.sendMessage(Lang.VEHICLES.f("&7This weapon cannot be used in a wingsuit!")); + e.setCancelled(true); + return; + } + } + + ItemStack chestPlate = player.getInventory().getChestplate(); + if (chestPlate != null && chestPlate.getType() == Material.GOLD_CHESTPLATE + && !this.jetpackAllowed.contains(e.getWeapon().getCompactName()) + && player.isFlying()) { + player.sendMessage(Lang.VEHICLES.f("&7You can't use this weapon in a jetpack!")); + e.setCancelled(true); + return; + } + + if (chestPlate != null && chestPlate.getType() == Material.GOLD_CHESTPLATE + && this.jetpackDisallowedHeavy.contains(e.getWeapon().getCompactName())) { + player.sendMessage(Lang.VEHICLES.f("&7You can't use this weapon in a jetpack!")); + e.setCancelled(true); + return; + } + } + + + @EventHandler(priority = EventPriority.HIGHEST) + public void onWeaponUse(WeaponSneakEvent e) { + if (!(e.getLivingEntity() instanceof Player)) + return; + Player player = (Player) e.getLivingEntity(); + Weapon weapon = e.getWeapon(); + if (Objects.equals("spawn", player.getWorld().getName())) { + if (this.spawnBlocked.contains(weapon.getCompactName().toLowerCase())) { + e.setCancelled(true); + return; + } + } + ViceUser viceUser = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + LockedWeapon l = LockedWeapon.getWeapon(weapon.getCompactName()); + if (e.getWeapon() instanceof RankedWeapon) { + UserRank required = ((RankedWeapon) e.getWeapon()).requiredRank(), current = Core.getUserManager().getLoadedUser(player.getUniqueId()).getUserRank(); + if (required != null && (!current.isHigherThan(required) && current != required)) { + player.sendMessage(Lang.HEY.f("&7You need to rank up to " + l.getViceRank().getColoredNameBold() + "&7 or donate for " + l.getUserRank().getColoredNameBold() + "&7 at &a&lstore.grandtheftmc.net&7 to use this weapon!")); + e.setCancelled(true); + return; + } + } + if (viceUser.isArrested()) { + player.sendMessage(Lang.JAIL.f("&7You can't use weapons in jail!")); + e.setCancelled(true); + return; + } + if (viceUser.hasTeleportProtection()) { + e.setCancelled(true); + player.sendMessage(Lang.COMBATTAG.f("&7Please wait &c&l" + Utils.timeInMillisToText(viceUser.getTimeUntilTeleportProtectionExpires()) + "&7!")); + return; + } + ItemStack chestPlate = player.getInventory().getChestplate(); + if (chestPlate != null && chestPlate.getType() == Material.GOLD_CHESTPLATE && player.getLocation().getBlock().getRelative(BlockFace.DOWN).getType() == Material.AIR && !this.jetpackAllowed.contains(e.getWeapon().getCompactName())) { + e.setCancelled(true); + return; + } + } + + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void onShoot(WeaponDamageEvent e) { + Weapon weapon = e.getWeapon(); + if (!(e.getLivingEntity() instanceof Player) || !(e.getEntity() instanceof Player)) + return; + Player player = (Player) e.getLivingEntity(); + ViceUser viceUser = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + Player victim = (Player) e.getEntity(); + UUID victimUUID = victim.getUniqueId(); + ViceUser victimViceUser = Vice.getUserManager().getLoadedUser(victimUUID); + if (victimViceUser.hasTeleportProtection()) { + e.setCancelled(true); + player.sendMessage(Lang.COMBATTAG.f("&7That player has teleport protection for &c&l" + Utils.timeInMillisToText(victimViceUser.getTimeUntilTeleportProtectionExpires()) + "&7!")); + return; + } + + if (viceUser.hasTeleportProtection()) { + e.setCancelled(true); + player.sendMessage(Lang.COMBATTAG.f("&7Please wait &c&l" + Utils.timeInMillisToText(viceUser.getTimeUntilTeleportProtectionExpires()) + "&7!")); + return; + } + + // TODO make sure players in the same cartel cant shoot eachother + FPlayer fPlayer = FPlayers.getInstance().getByPlayer(player), fVictim = FPlayers.getInstance().getByPlayer(victim); + if (fPlayer != null && fVictim != null) { + if ((fPlayer.getFaction() != null || fVictim.getFaction() != null) && (fPlayer.getFactionId().equalsIgnoreCase(fVictim.getFactionId()) || fPlayer.getFaction().getRelationWish(fVictim.getFaction()) == Relation.ALLY)) { + player.sendMessage(Utils.f(" &a&lCARTELS&8&l> &7You can't hurt players that are in your gang!")); + } + } + /* + Gang victimGang = victimViceUser.getGang(); + Gang damagerGang = viceUser.getGang(); + if (victimGang != null && damagerGang != null && !Objects.equals(victim, player)) { + if (Objects.equals(victimGang, damagerGang)) { + e.setCancelled(true); + player.sendMessage(Lang.GANGS.f("&7You can't hurt players that are in your gang!")); + return; + } + if (victimGang.isAllied(damagerGang.getName())) { + e.setCancelled(true); + player.sendMessage(Lang.GANGS.f("&7You can't hurt players that are in an allied gang!")); + return; + } + }*/ + if (!Objects.equals("spawn", e.getEntity().getWorld().getName())) { + if ("stungun".equalsIgnoreCase(weapon.getCompactName()) && viceUser.isCop()) { + player.sendMessage(Lang.COPS.f("&7You have no jurisdiction in this area!")); + return; + } + if ("flamethrower".equalsIgnoreCase(weapon.getCompactName())) { + victim.setFireTicks(victim.getFireTicks() + 20); + victim.getNearbyEntities(5, 0, 5).forEach(entity -> { + if (Objects.equals(entity, victim) || entity.getType() != EntityType.PLAYER) return; + Player target = (Player) entity; + if (target.getGameMode() != GameMode.ADVENTURE && target.getGameMode() != GameMode.SURVIVAL) return; + target.setFireTicks(target.getFireTicks() + 10); + }); + return; + } + if ("katana".equalsIgnoreCase(weapon.getCompactName())) { + if (this.recentKatanaChops.contains(victim.getName())) return; + if (ThreadLocalRandom.current().nextInt(30) < 5) { + ItemStack skull = Utils.setSkullOwner(Utils.createItem(Material.SKULL_ITEM, 3, + "&e&l" + victim.getName() + "'s Decapitated Head"), + victim.getName()); + victim.getWorld().dropItemNaturally(victim.getLocation(), skull); + victim.setHealth(0); + this.recentKatanaChops.add(victim.getName()); + } + } + if (!viceUser.isCop()) return; + if (victimViceUser.isCop()) { + e.setCancelled(true); + player.sendMessage(Utils.f(Lang.HEY + "&cYou can't kill cops!")); + return; + } + if ("nightstick".equalsIgnoreCase(weapon.getCompactName())) { + victim.addPotionEffect(new PotionEffect(PotionEffectType.CONFUSION, 80, 1)); + victim.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 50, 1)); + } + } else if ("stungun".equalsIgnoreCase(weapon.getCompactName())) { + if (!viceUser.isCop()) return; + if (ViceUtils.isInSpawnRange(victim, 10)) { + player.sendMessage(Lang.COPS.f("&7You have no jurisdiction in this area!")); + return; + } + if (victimViceUser.isCop()) { + e.setCancelled(true); + player.sendMessage(Utils.f(Lang.HEY + "&cYou can't arrest cops!")); + return; + } + int timeInJail = ViceUtils.getTimeInJailForDrugs(victim); + if (timeInJail == 0) return; + if (victim.getLastDamageCause() == null || victim.getLastDamageCause().getCause() != EntityDamageEvent.DamageCause.DRAGON_BREATH) + return; + ItemStack chestPlate = player.getInventory().getChestplate(); + if (chestPlate != null && chestPlate.getType() == Material.GOLD_CHESTPLATE && player.getLocation().getBlock().getRelative(BlockFace.DOWN).getType() == Material.AIR) { + player.sendMessage(Lang.COP_MODE.f("&fYou may not arrest criminals during flight!")); + return; + } + if (player.getVehicle() != null) { + player.sendMessage(Lang.COP_MODE.f("&fYou may not arrest criminals while in a Vehicle!")); + return; + } + if (Vice.getWorldManager().getZones(player.getLocation()).stream().anyMatch(zone -> zone.getFlags().contains(ZoneFlag.COP_CANT_ARREST))) { + player.sendMessage(Lang.COP_MODE.f("&7You may not arrest criminals in this area!")); + return; + } + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + User victimUser = Core.getUserManager().getLoadedUser(victimUUID); + + victimViceUser.jail(timeInJail, player); + player.sendMessage(Lang.COP_MODE.f("&7You arrested &a" + victimUser.getColoredName(victim) + + "&7! He will go to jail for &a" + Utils.timeInSecondsToText(timeInJail) + "&7!")); + Utils.broadcastExcept(player, Lang.COP_MODE.f("&a" + victimUser.getColoredName(victim) + "&7 was arrested by &a" + + user.getColoredName(player) + "&7!")); + victimViceUser.addDeaths(1); + victimViceUser.setLastTag(-1); + victimViceUser.setKillStreak(0); + if (Vice.getWorldManager().getWarpManager().cancelTaxi(victim, victimViceUser)) + victim.sendMessage(Utils.f(Lang.TAXI + "&eThe taxi was cancelled!")); + + if (Core.getSettings().getType() == ServerType.VICE) { + victim.setHealth(0); + } else { + victim.setHealth(victim.getMaxHealth()); + victim.spigot().respawn(); + } + + victim.setFireTicks(0); + victim.setGameMode(GameMode.SPECTATOR); + victim.setFlying(true); + victim.getActivePotionEffects().clear(); + victim.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 180, 0), false); + victim.setFoodLevel(20); + victim.playSound(victim.getLocation(), Sound.ENTITY_WITHER_SPAWN, 1, 0.5F); + victim.setFlySpeed(0); + ViceUtils.removeBoard(victim); +// victimUser.removeCosmetics(victim); + new BukkitRunnable() { + @Override + public void run() { + Player victim = Bukkit.getPlayer(victimUUID); + if (victim == null) + return; + User victimUser = Core.getUserManager().getLoadedUser(victim.getUniqueId()); + ViceUser victimGameUser = Vice.getUserManager().getLoadedUser(victim.getUniqueId()); + victim.sendMessage(Lang.JAIL.f("&7You were arrested and have to stay in jail for &a" + + Utils.timeInSecondsToText(timeInJail) + "&7!")); + victim.teleport(Vice.getWorldManager().getWarpManager().getJail().getLocation()); + victim.setGameMode(GameMode.SURVIVAL); + victim.getActivePotionEffects().clear(); + victim.setFoodLevel(20); + victim.setFlying(false); + victim.setFlySpeed(0.1F); + ViceUtils.giveGameItems(victim); + ViceUtils.updateBoard(victim, victimGameUser); +// victimUser.loadLastCosmetics(victim); + } + }.runTaskLater(Vice.getInstance(), 150); + HashSet<ItemStack> bannedItems = new HashSet<>(); + for (ItemStack is : victim.getInventory().getContents()) { + if (Vice.getItemManager().getItem(is) != null && Vice.getItemManager().getItem(is).isScheduled()) { + bannedItems.add(is); + victim.getInventory().removeItem(is); + } + } + ViceUtils.giveGameItems(victim); + for (ItemStack item : bannedItems) + Utils.giveItems(player, item); + Utils.sendTitle(victim, "&c&lBUSTED", "&7Arrested by " + player.getName(), 80, 50, 20); + ViceUtils.updateBoard(player, user, viceUser); + } + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/lootcrates/CrateManager.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/lootcrates/CrateManager.java new file mode 100644 index 0000000..d41abe9 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/lootcrates/CrateManager.java @@ -0,0 +1,188 @@ +package net.grandtheftmc.vice.lootcrates; + +import com.google.common.collect.Maps; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.areas.obj.Area; +import net.grandtheftmc.vice.drugs.DrugService; +import net.grandtheftmc.vice.drugs.items.DrugItem; +import net.grandtheftmc.vice.items.GameItem; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +public class CrateManager { + + public CrateManager() { + this.loadCrates(); + this.startSchedule(); + } + + protected HashMap<Area.DropType, List<LootItem>> dropItems = Maps.newHashMap(); + private List<LootItem> items = new ArrayList<>(); + private List<LootCrate> crates = new ArrayList<>(); + private int cooldown = 30; // in MINUTES + + private int taskId = -1; + + public List<LootItem> getItems() { + return this.items; + } + + public List<LootCrate> getCrates() { + return this.crates; + } + + + public void loadCrates() { + YamlConfiguration c = Vice.getSettings().getLootConfig(); + this.items = new ArrayList<>(); + for (String s : c.getKeys(false)) { + try { + GameItem item = Vice.getItemManager().getItem(s); + if (item == null) { + Core.error("Error loading game items '" + s + "' for Loot Crates!"); + continue; + } + double chance = 100; + if (c.getString(s + ".chance") != null) + chance = c.getDouble(s + ".chance"); + int min = 1; + if (c.getString(s + ".min") != null) + min = c.getInt(s + ".min"); + int max = 64; + if (c.getString(s + ".max") != null) + max = c.getInt(s + ".max"); + + Area.DropType type = Area.DropType.DEFAULT; + if (c.getString(s + ".type") != null) + type = Area.DropType.valueOf(c.getString(s + ".type")); + + this.items.add(new LootItem(s, chance, min, max, false, type)); + } catch (Exception e) { + Core.error("Error loading loot items '" + s + "' for Loot Crates!"); + } + } + +// for(DrugItem drugItem : ((DrugService)Vice.getInstance().getDrugManager().getService()).getAllDrugItems()){ +// this.items.add(new LootItem(drugItem.getDrug().getName(), 8, 1, 5, true)); +// } + + for (Area.DropType dropType : Area.DropType.values()) { + List<LootItem> temp = new ArrayList<>(); + YamlConfiguration config = Utils.loadConfig(dropType.name() + "_loot"); + for (String s : c.getKeys(false)) { + try { + GameItem item = Vice.getItemManager().getItem(s); + if (item == null) { + Core.error("Error loading game items '" + s + "' for Loot Crates!"); + continue; + } + double chance = 100; + if (c.getString(s + ".chance") != null) + chance = c.getDouble(s + ".chance"); + int min = 1; + if (c.getString(s + ".min") != null) + min = c.getInt(s + ".min"); + int max = 64; + if (c.getString(s + ".max") != null) + max = c.getInt(s + ".max"); + + Area.DropType type = Area.DropType.DEFAULT; + if (c.getString(s + ".type") != null) + type = Area.DropType.valueOf(c.getString(s + ".type")); + + temp.add(new LootItem(s, chance, min, max, false, type)); + } catch (Exception e) { + Core.error("Error loading loot items '" + s + "' for Loot Crates!"); + } + } + + this.dropItems.put(dropType, temp); + } + + c = Vice.getSettings().getLootCratesConfig(); + this.crates = new ArrayList<>(); + if (c.get("lootcrates") != null) + this.crates.addAll(c.getStringList("lootcrates").stream().map(s -> new LootCrate(Utils.blockLocationFromString(s))).collect(Collectors.toList())); + this.cooldown = c.getInt("cooldown"); + } + + public void saveCrates() { + YamlConfiguration c = Vice.getSettings().getLootConfig(); + for (String s : c.getKeys(false)) + c.set(s, null); + for (LootItem item : this.items) { + if(!item.isDrug()) { + String s = item.getItem(); + c.set(s + ".chance", item.getChance()); + c.set(s + ".min", item.getMin()); + c.set(s + ".max", item.getMax()); + c.set(s + ".type", item.getDropType().name()); + } + } + Utils.saveConfig(c, "loot"); + + c = Vice.getSettings().getLootCratesConfig(); + List<String> list = this.crates.stream().map(crate -> Utils.blockLocationToString(crate.getLocation())).collect(Collectors.toList()); + c.set("lootcrates", list); + c.set("cooldown", this.cooldown); + Utils.saveConfig(c, "lootcrates"); + } + + public void startSchedule() { + if (this.taskId != -1) Bukkit.getScheduler().cancelTask(this.taskId); + this.taskId = new BukkitRunnable() { + @Override + public void run() { + Vice.getCrateManager().getCrates().forEach(LootCrate::tick); + } + }.runTaskTimer(Vice.getInstance(), 20, 20).getTaskId(); + } + + public LootCrate getCrate(Location location) { + return this.crates.stream().filter(crate -> Objects.equals(crate.getLocation(), location)).findFirst().orElse(null); + } + + public void addCrate(Location location) { + if (this.getCrate(location) == null) + this.crates.add(new LootCrate(location)); + } + + public void removeCrate(Location location) { + LootCrate crate = this.getCrate(location); + if (crate != null) { + crate.removeHologram(); + this.crates.remove(crate); + } + } + + public int getCooldown() { + return this.cooldown; + } + + public void setCooldown(int i) { + this.cooldown = i; + } + + public void addItem(LootItem lootItem) { + this.items.add(lootItem); + } + + public LootItem getItem(GameItem gameItem) { + return this.items.stream().filter(item -> Objects.equals(item.getGameItem(), gameItem)).findFirst().orElse(null); + } + + public void removeItem(LootItem lootItem) { + this.items.remove(lootItem); + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/lootcrates/LootCrate.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/lootcrates/LootCrate.java new file mode 100644 index 0000000..a702c97 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/lootcrates/LootCrate.java @@ -0,0 +1,157 @@ +package net.grandtheftmc.vice.lootcrates; + +import com.gmail.filoghost.holographicdisplays.api.Hologram; +import com.gmail.filoghost.holographicdisplays.api.HologramsAPI; +import com.gmail.filoghost.holographicdisplays.api.VisibilityManager; +import com.gmail.filoghost.holographicdisplays.api.line.TextLine; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.areas.obj.Area; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.block.Chest; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +public class LootCrate { + + private Location location; + private long timer; + private Hologram hologram; + private final List<TextLine> textLines = new ArrayList<>(); + private boolean looted = false; + + public LootCrate(Location location) { + this.location = location; + this.timer = 60; + } + + public Location getLocation() { + return this.location; + } + + public void setLocation(Location location) { + this.location = location; + } + + public long getTimer() { + return this.timer; + } + + public void resetTimer() { + this.timer = Vice.getCrateManager().getCooldown() * 60L; + } + + public void tick() { +// if (this.timer > 0) { +// this.updateHologram("&7Start a Dropship to refill!"); +// this.timer--; +// } else if (this.timer == 0) +// this.restock(); + + if (this.looted) { + this.updateHologram("&f&oStart a Dropship to refill!"); + } else { + this.updateHologram("&6&lRestocked!"); + } + + this.updateVisibility(); + } + + public void restock(Area.DropType type) { + this.closeOutViewers(); //Close out inventory viewers before restocking. + + BlockState state = this.location.getBlock().getState(); + if (!(state instanceof Chest)) { + Vice.log("Loot Chest at location " + Utils.blockLocationToString(this.location) + " is not a Chest!"); + this.updateHologram("&c&lERROR: Please contact an admin!"); +// this.timer = -1; + return; + } + + Chest chest = (Chest) state; +// try { +// Class<?> craftChestClass = ReflectionUtil.getOBCClass("block.CraftChest"); +// Object craftChest = craftChestClass.cast(chest); +// Method getTileEntity = craftChestClass.getMethod("getTileEntity"); +// Object tileEntity = getTileEntity.invoke(craftChest); +// Class<?> tileEntityClass = ReflectionUtil.getNMSClass("TileEntityChest"); +// Method setTitle = tileEntityClass.getMethod("a", String.class); +// setTitle.invoke(tileEntity, Utils.f("&e&lLoot Crate")); +// } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { +// e.printStackTrace(); +// } + chest.setCustomName(Utils.f("&e&lLoot Crate")); + chest.update(); + + Inventory inv = chest.getBlockInventory(); + inv.clear(); + + List<LootItem> items = Vice.getCrateManager().dropItems.get(type).stream().filter(item -> Utils.calculateChance(item.getChance())).collect(Collectors.toList()); + items.forEach(item -> { + ItemStack stack = item.getGameItem().getItem(); + stack.setAmount(Utils.randomNumber(item.getMin(), item.getMax())); + Utils.putItemInInventoryRandomly(inv, stack); + }); + + this.setLooted(false); +// this.updateHologram("&7Restocked!"); +// this.timer = -1; + } + + private void updateHologram(String text) { + if (this.hologram == null) { + this.hologram = HologramsAPI.createHologram(Vice.getInstance(), this.location.clone().add(0.5, 2, 0.5)); + this.textLines.add(this.hologram.appendTextLine(Utils.f("&e&lDropship Crate"))); + this.textLines.add(this.hologram.appendTextLine(Utils.f(text))); + this.hologram.getVisibilityManager().setVisibleByDefault(false); + } else + this.textLines.get(1).setText(Utils.f(text)); + + } + + private void updateVisibility() { + VisibilityManager v = this.hologram.getVisibilityManager(); + for (Player player : Bukkit.getOnlinePlayers()) { + if (Objects.equals(player.getWorld(), this.location.getWorld()) + && player.getLocation().distanceSquared(this.location) < 225) { + if (!v.isVisibleTo(player)) + v.showTo(player); + } else if (v.isVisibleTo(player)) + v.hideTo(player); + } + } + + public void removeHologram() { + this.hologram.delete(); + this.hologram = null; + this.textLines.clear(); + + } + + private void closeOutViewers() { + if (this.location == null) return; + Block block = this.location.getBlock(); + if (block.getType() != Material.CHEST) return; + Chest chest = (Chest) block.getState(); + chest.getInventory().getViewers().forEach(HumanEntity::closeInventory); + } + + public void setLooted(boolean looted) { + this.looted = looted; + } + + public boolean isLooted() { + return looted; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/lootcrates/LootCrateCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/lootcrates/LootCrateCommand.java new file mode 100644 index 0000000..0bfe020 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/lootcrates/LootCrateCommand.java @@ -0,0 +1,190 @@ +package net.grandtheftmc.vice.lootcrates; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.areas.obj.Area; +import net.grandtheftmc.vice.items.GameItem; +import net.grandtheftmc.vice.users.ViceUser; +import net.grandtheftmc.vice.users.storage.BooleanStorageType; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.Iterator; +import java.util.List; +import java.util.UUID; + +public class LootCrateCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (!(s instanceof Player)) { + s.sendMessage(Lang.NOTPLAYER.s()); + return true; + } + Player player = (Player) s; + if (!player.hasPermission("lootcrate.admin")) { + player.sendMessage(Lang.NOPERM.s()); + return true; + } + UUID uuid = player.getUniqueId(); + ViceUser user = Vice.getUserManager().getLoadedUser(uuid); + if (args.length == 0) { + s.sendMessage(Utils.f("&c/lootcrates add")); + s.sendMessage(Utils.f("&c/lootcrates remove")); + s.sendMessage(Utils.f("&c/lootcrates cooldown <minutes> ")); + s.sendMessage(Utils.f("&c/lootcrates check")); + s.sendMessage(Utils.f("&c/lootcrates restock")); + s.sendMessage(Utils.f("&c/lootcrates list [page]")); + + s.sendMessage(Utils.f("&c/lootcrates items <itemName> <chance> <min> <max>")); + s.sendMessage(Utils.f("&c/lootcrates removeitem <itemName>")); + s.sendMessage(Utils.f("&c/lootcrates load")); + s.sendMessage(Utils.f("&c/lootcrates save")); + return true; + } + switch (args[0].toLowerCase()) { + case "add": + s.sendMessage(Lang.LOOTCRATES.f("&7Right click on the chest you want to turn in to a Loot Crate. Make sure the chest has display name &e&lLoot Crate&7!")); + user.setBooleanToStorage(BooleanStorageType.ADDING_LOOTCRATE, true); + return true; + case "remove": + s.sendMessage(Lang.LOOTCRATES.f("&7Right click on the chest you would like to remove as a Loot Crate.")); + user.setBooleanToStorage(BooleanStorageType.REMOVING_LOOTCRATE, true); + return true; + case "cooldown": + if (args.length != 2) { + s.sendMessage(Utils.f("&c/lootcrate cooldown <minutes> ")); + return true; + } + try { + Vice.getCrateManager().setCooldown(Integer.parseInt(args[1])); + } catch (NumberFormatException e) { + s.sendMessage(Utils.f("&cThe cooldown must be a number measured in minutes!")); + return true; + } + s.sendMessage(Lang.LOOTCRATES.f("&7The cooldown on Loot Crates was set to &a" + + Vice.getCrateManager().getCooldown() + " minutes&7!")); + return true; + case "check": + s.sendMessage(Lang.LOOTCRATES + .f("&7Right click on the Loot Crate of which you would like to check the cooldown;")); + user.setBooleanToStorage(BooleanStorageType.CHECKING_LOOTCRATE, true); + return true; + case "restock": + s.sendMessage(Lang.LOOTCRATES.f("&7Right click the Loot Crate which you want to restock.")); + user.setBooleanToStorage(BooleanStorageType.RESTOCKING_LOOTCRATE, true); + return true; + case "removeitem": { + if (args.length != 2) { + s.sendMessage(Utils.f("&c/lootcrate removeitem <itemName>")); + return true; + } + GameItem item = Vice.getItemManager().getItem(args[1]); + if (item == null) { + s.sendMessage(Lang.LOOTCRATES.f("&7That GameItem does not exist!")); + return true; + } + LootItem lootItem = Vice.getCrateManager().getItem(item); + if (lootItem == null) { + s.sendMessage(Lang.LOOTCRATES.f("&7That GameItem is not added to Loot Crates!")); + return true; + } + Vice.getCrateManager().removeItem(lootItem); + s.sendMessage(Lang.LOOTCRATES.f("&7GameItem &a" + item.getName() + "&7 was removed from LootCrates!")); + return true; + } + case "items": + if (args.length < 3) { + s.sendMessage(Utils.f("&c/lootcrate items <itemName> <chance> [min] [max]")); + return true; + } + GameItem item = Vice.getItemManager().getItem(args[1]); + if (item == null) { + s.sendMessage(Lang.LOOTCRATES.f("&7That GameItem does not exist!")); + return true; + } + + double chance; + int min; + int max; + try { + chance = Double.parseDouble(args[2]); + min = args.length > 3 ? Integer.parseInt(args[3]) : 1; + max = args.length > 4 ? Integer.parseInt(args[4]) : min; + } catch (NumberFormatException e) { + s.sendMessage(Lang.LOOTCRATES.f("&7The chance must be a double, min and max must be integers!")); + return true; + } + if (min > max) { + s.sendMessage(Lang.LOOTCRATES.f("&7The maximum must be greater than or equal to the minimum!")); + return true; + } + LootItem lootItem = Vice.getCrateManager().getItem(item); + if (lootItem == null) + Vice.getCrateManager().addItem(new LootItem(item.getName(), chance, min, max, false, Area.DropType.DEFAULT)); + else { + lootItem.setChance(chance); + lootItem.setMin(min); + lootItem.setMax(max); + } + s.sendMessage(Lang.LOOTCRATES + .f("&7You added GameItem &a" + item.getName() + "&7 to LootCrates with a chance of &a" + chance + + "&7, a min of &a" + min + "&7 and a max of &a" + max + "&7!")); + return true; + case "list": + List<LootCrate> crates = Vice.getCrateManager().getCrates(); + int page = 1; + if (args.length > 1) { + try { + page = Integer.parseInt(args[1]); + } catch (NumberFormatException e) { + s.sendMessage(Lang.LOOTCRATES.f("&cThe page must be a number!")); + return true; + } + } + if (page < 1) { + s.sendMessage(Lang.LOOTCRATES.f("&7The page must be a positive number!")); + return true; + } + int pages = crates.size() / 6 + 1; + s.sendMessage(Utils.f(" &7&m---------------&7[&e&l Loot Crates List &7Page &e" + page + "&7/&e" + pages + + " &7&m]---------------")); + Iterator<LootCrate> it = crates.iterator(); + for (int i = 0; i < page * 6; i++) { + if (!it.hasNext()) + return true; + LootCrate cr = it.next(); + if (i < page * 6 - 6) + continue; + s.sendMessage(Utils.f("&e" + Utils.blockLocationToString(cr.getLocation()))); + } + return true; + case "load": + Vice.getSettings().setLootCratesConfig(Utils.loadConfig("lootcrates")); + Vice.getSettings().setLootConfig(Utils.loadConfig("loot")); + Vice.getCrateManager().loadCrates(); + s.sendMessage(Lang.LOOTCRATES.f("&7Loaded LootCrates!")); + return true; + case "save": + Vice.getCrateManager().saveCrates(); + s.sendMessage(Lang.LOOTCRATES.f("&7Saved LootCrates!")); + return true; + default: + s.sendMessage(Utils.f("&c/lootcrates add")); + s.sendMessage(Utils.f("&c/lootcrates remove")); + s.sendMessage(Utils.f("&c/lootcrates cooldown <minutes> ")); + s.sendMessage(Utils.f("&c/lootcrates check")); + s.sendMessage(Utils.f("&c/lootcrates restock")); + s.sendMessage(Utils.f("&c/lootcrates list [page]")); + s.sendMessage(Utils.f("&c/lootcrates items <itemName> <chance> <min> <max>")); + s.sendMessage(Utils.f("&c/lootcrates removeitem <itemName>")); + s.sendMessage(Utils.f("&c/lootcrates load")); + s.sendMessage(Utils.f("&c/lootcrates save")); + return true; + } + } + +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/lootcrates/LootItem.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/lootcrates/LootItem.java new file mode 100644 index 0000000..6678f47 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/lootcrates/LootItem.java @@ -0,0 +1,84 @@ +package net.grandtheftmc.vice.lootcrates; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.areas.obj.Area; +import net.grandtheftmc.vice.drugs.Drug; +import net.grandtheftmc.vice.drugs.DrugService; +import net.grandtheftmc.vice.drugs.items.DrugItem; +import net.grandtheftmc.vice.items.GameItem; +import org.bukkit.inventory.ItemStack; + +import java.util.Optional; + +public class LootItem { + + private String item; + private double chance; + private int min; + private int max; + private boolean isDrug; + private Area.DropType type; + + public LootItem(String item, double chance, int min, int max, boolean isDrug, Area.DropType type) { + this.item = item; + this.chance = chance; + this.min = min; + this.max = max; + this.isDrug = isDrug; + this.type = type; + } + + public String getItem() { + return this.item; + } + + public void setItem(String item) { + this.item = item; + } + + public GameItem getGameItem() { + if(!isDrug){ + return Vice.getItemManager().getItem(this.item); + } else { + Optional<Drug> drug = ((DrugService) Vice.getDrugManager().getService()).getDrug(item); + if (!drug.isPresent()) { + return null; + } + DrugItem itema = DrugItem.getByDrug(drug.get()); + ItemStack is = itema.getItemStack(); + return new GameItem(item, is, is.getItemMeta().getDisplayName()); + } + } + + public boolean isDrug(){ + return isDrug; + } + + public double getChance() { + return this.chance; + } + + public void setChance(double chance) { + this.chance = chance; + } + + public int getMin() { + return this.min; + } + + public void setMin(int min) { + this.min = min; + } + + public int getMax() { + return this.max; + } + + public void setMax(int max) { + this.max = max; + } + + public Area.DropType getDropType() { + return type; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/BaseMachine.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/BaseMachine.java new file mode 100644 index 0000000..a09bbc2 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/BaseMachine.java @@ -0,0 +1,215 @@ +package net.grandtheftmc.vice.machine; + +import com.google.common.collect.Maps; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.vice.machine.data.MachineData; +import net.grandtheftmc.vice.machine.data.MachineDataType; +import net.grandtheftmc.vice.machine.recipe.misc.MachineRecipeData; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import java.util.HashMap; + +public abstract class BaseMachine { + + private final HashMap<MachineDataType, MachineData> machineData; + + private int[] openSlots; + private int[] outputSlots; + private int[] blockedSlots; + + // Main data + private int uniqueIdentifier = -1; + private final int machineIdentifier; + private Location location = null; + private boolean enabled = false; + + private final String name; + private final Material material; + private final Inventory inventory; + private ItemStack machineItem; + private ItemStack[] contents; + + private MachineRecipeData recipeData = null; + + /** + * Construct a Machine + */ + public BaseMachine(int machineIdentifier, String name, Material material) { + this(machineIdentifier, name, material, 3); + } + + /** + * Construct a Machine + */ + public BaseMachine(int machineIdentifier, String name, Material material, int inventorySize) { + this.machineIdentifier = machineIdentifier; + this.name = name; + this.material = material; + + this.machineData = Maps.newHashMap(); + + this.inventory = Bukkit.createInventory(null, inventorySize * 9, Utils.f("&e" + name)); + } + + public int getUniqueIdentifier() { + return uniqueIdentifier; + } + + public void setUniqueIdentifier(int uniqueIdentifier) { + this.uniqueIdentifier = uniqueIdentifier; + } + + public int getMachineIdentifier() { + return machineIdentifier; + } + + public Location getLocation() { + return location; + } + + public void setLocation(Location location) { + this.location = location; + } + + public String getName() { + return name; + } + + public Material getMaterial() { + return material; + } + + public Inventory getInventory() { + return inventory; + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public ItemStack getMachineItem() { + return machineItem; + } + + public void setMachineItem(ItemStack machineItem) { + this.machineItem = machineItem; + } + + public ItemStack[] getContents() { + this.contents = this.inventory.getContents(); + return contents; + } + + public void setContents(ItemStack[] contents) { + this.contents = contents; + this.inventory.setContents(contents); + } + + public int[] getOpenSlots() { + return openSlots; + } + + public void setOpenSlots(int... openSlots) { + this.openSlots = openSlots; + } + + public void setOutputSlots(int... outputSlots) { + this.outputSlots = outputSlots; + } + + public int[] getOutputSlots() { + return outputSlots; + } + + public boolean isOutputSlot(int slot) { + for (int i : this.outputSlots) + if (i == slot) return true; + return false; + } + + public int[] getBlockedSlots() { + return blockedSlots; + } + + public void setBlockedSlots(int... blockedSlots) { + this.blockedSlots = blockedSlots; + } + + public boolean isBlockedSlot(int slot) { + for (int i : this.blockedSlots) + if (i == slot) return true; + return false; + } + + public void setData(MachineDataType type, MachineData data) { + this.machineData.put(type, data); + } + + public MachineData getData(MachineDataType type) { + return this.machineData.getOrDefault(type, null); + } + + public void updateFuel() { + MachineData data = this.getData(MachineDataType.FUEL); + if (data == null) return; + if(this.inventory.getItem(19)==null) { + Core.error("there is a broken inventory at " + this.location); + return; + } + this.inventory.getItem(19).setDurability((short) data.getTexture()); +// ServerUtil.debug("FUEL: " + this.fuel + " - " + this.getFuelByte()); + } + + public void updateDurability() { + MachineData data = this.getData(MachineDataType.DURABILITY); + if (data == null) return; + + this.inventory.getItem(25).setDurability((short) data.getTexture()); +// ServerUtil.debug("DURABILITY: " + this.durability + " - " + this.getDurabilityByte()); + } + + public void updateProgress() { + MachineData data = this.getData(MachineDataType.PROGRESS); + if (data == null) return; + + if(this.inventory.getItem(11)==null) { + Core.error("there is a broken inventory at " + this.location); + return; + } + + this.inventory.getItem(11).setDurability((short) data.getTexture()); +// ServerUtil.debug("PROGRESS: " + this.progress + " - " + this.getProgressByte()); + } + + public void updateAllItems() { + updateFuel(); + updateDurability(); + updateProgress(); + } + + public MachineRecipeData getRecipeData() { + return recipeData; + } + + public void setRecipeData(MachineRecipeData recipeData) { + this.recipeData = recipeData; + } + + public boolean isRecipeActive() { + return this.recipeData != null; + } + + public String i(String icon, int amount) { + return C.RESET + icon + C.GRAY + "x" + amount + C.RESET; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/MachineCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/MachineCommand.java new file mode 100644 index 0000000..e6ce503 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/MachineCommand.java @@ -0,0 +1,33 @@ +package net.grandtheftmc.vice.machine; + +import net.grandtheftmc.core.commands.CoreCommand; +import net.grandtheftmc.core.commands.RankedCommand; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.vice.machine.repair.MachineRepairMenu; +import org.bukkit.entity.Player; + +public class MachineCommand extends CoreCommand<Player> implements RankedCommand { + + private final MachineManager machineManager; + + public MachineCommand(MachineManager machineManager) { + super("machine", "Admin command to give a machine."); + this.machineManager = machineManager; + } + + @Override + public void execute(Player sender, String[] strings) { + if (strings.length == 0) { + new MachineRepairMenu(this.machineManager).openInventory(sender); + return; + } + + sender.getInventory().addItem(machineManager.getMachineItemById(Integer.parseInt(strings[0]))); + sender.updateInventory(); + } + + @Override + public UserRank requiredRank() { + return UserRank.ADMIN; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/MachineComponent.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/MachineComponent.java new file mode 100644 index 0000000..27773ba --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/MachineComponent.java @@ -0,0 +1,595 @@ +package net.grandtheftmc.vice.machine; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.Component; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.dao.MachineDAO; +import net.grandtheftmc.vice.items.GameItem; +import net.grandtheftmc.vice.machine.data.MachineData; +import net.grandtheftmc.vice.machine.data.MachineDataType; +import net.grandtheftmc.vice.machine.event.MachineFuelEvent; +import net.grandtheftmc.vice.machine.event.MachineItemTransferEvent; +import net.grandtheftmc.vice.machine.event.MachinePlaceEvent; +import net.grandtheftmc.vice.machine.event.MachineRecipeCompleteEvent; +import net.grandtheftmc.vice.machine.recipe.MachineRecipeManager; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeOutput; +import net.grandtheftmc.vice.utils.ItemStackUtil; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.BlockState; +import org.bukkit.block.Hopper; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.entity.minecart.HopperMinecart; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryMoveItemEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.world.ChunkLoadEvent; +import org.bukkit.event.world.ChunkUnloadEvent; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.Iterator; +import java.util.Optional; + +public class MachineComponent implements Component<MachineComponent, Vice> { + + private final MachineManager machineManager; + private final MachineRecipeManager recipeManager; + + public MachineComponent(MachineManager machineManager, MachineRecipeManager recipeManager) { + this.machineManager = machineManager; + this.recipeManager = recipeManager; + +// ProtocolLibrary.getProtocolManager().addPacketListener(new MachineChunkPacket()); + } + + @Override + public MachineComponent onDisable(Vice plugin) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + this.machineManager.getMachines().forEach(machine -> MachineDAO.updateMachineData(connection, machine)); + } catch (SQLException e) { + e.printStackTrace(); + } + + return this; + } + + @EventHandler(ignoreCancelled = true) + protected final void onBlockPlace(BlockPlaceEvent event) { + ItemStack itemStack = event.getItemInHand(); + if (itemStack == null) return; + + ServerUtil.debug(itemStack.getType().name()); + if (!this.machineManager.isType(itemStack.getType())) return; + if (!itemStack.hasItemMeta()) return; + Optional<BaseMachine> optional = this.machineManager.constructByItem(itemStack); + if (!optional.isPresent()) return; + MachinePlaceEvent placeEvent = new MachinePlaceEvent(event.getPlayer(), event.getBlockPlaced().getLocation(), optional.get()); + Bukkit.getPluginManager().callEvent(placeEvent); + if (placeEvent.isCancelled()) { + event.setCancelled(true); + } + } + + @EventHandler(ignoreCancelled = true) + protected final void onMachinePlace(MachinePlaceEvent event) { + event.getMachine().setLocation(event.getLocation()); + this.machineManager.addMachine(event.getMachine()); + ServerUtil.debug("Machine added"); + + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + MachineDAO.addMachine(connection, event.getMachine()); + MachineDAO.updateMachineData(connection, event.getMachine()); + ServerUtil.debug("Machine query complete."); + + ServerUtil.runTask(() -> event.getMachine().setEnabled(true)); + + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } + + @EventHandler(ignoreCancelled = true) + protected final void onBlockBreak(BlockBreakEvent event) { + if (!this.machineManager.isType(event.getBlock().getType())) return; + + Optional<BaseMachine> optional = this.machineManager.getMachineByLocation(event.getBlock().getLocation()); + if (!optional.isPresent()) return; + + this.machineManager.removeMachine(optional.get()); + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + MachineDAO.removeMachine(connection, optional.get().getUniqueIdentifier()); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + + if (event.getBlock().getState() instanceof InventoryHolder) { + InventoryHolder holder = (InventoryHolder) event.getBlock().getState(); + holder.getInventory().clear(); + } + event.setDropItems(false); + + ItemStack machineFragment = Vice.getItemManager().getItem("machinefragment").getItem(); + ItemMeta meta = machineFragment.getItemMeta(); + meta.setLore(Arrays.asList( + C.GRAY + C.ITALIC + " " + optional.get().getName(), + "", + C.AQUA + C.BOLD + "INFO", + C.GRAY + " Visit the Machine Mechanic", + C.GRAY + " at spawn to turn these fragments", + C.GRAY + " into a functional machine!" + )); + + machineFragment.setItemMeta(meta); + machineFragment = ItemStackUtil.addTag(machineFragment, "machineid", optional.get().getMachineIdentifier()); + + event.getBlock().getWorld().dropItemNaturally(event.getBlock().getLocation(), machineFragment); + + for (int slot : optional.get().getOpenSlots()) { + ItemStack itemStack = optional.get().getInventory().getItem(slot); + if (itemStack == null || itemStack.getType() == Material.AIR) continue; + event.getBlock().getWorld().dropItemNaturally(event.getBlock().getLocation(), itemStack); + } + + for (int slot : optional.get().getOutputSlots()) { + ItemStack itemStack = optional.get().getInventory().getItem(slot); + if (itemStack == null || itemStack.getType() == Material.AIR) continue; + event.getBlock().getWorld().dropItemNaturally(event.getBlock().getLocation(), itemStack); + } + + for (int slot : optional.get().getData(MachineDataType.FUEL).getSlots()) { + ItemStack itemStack = optional.get().getInventory().getItem(slot); + if (itemStack == null || itemStack.getType() == Material.AIR) continue; + event.getBlock().getWorld().dropItemNaturally(event.getBlock().getLocation(), itemStack);// + } + } + + @EventHandler + public void onExplode(EntityExplodeEvent event) { + Iterator<Block> iter = event.blockList().iterator(); + + while (iter.hasNext()) { + Block b = iter.next(); + Optional<BaseMachine> optional = this.machineManager.getMachineByLocation(b.getLocation()); + if (!optional.isPresent()) continue; + + this.machineManager.removeMachine(optional.get()); + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + MachineDAO.removeMachine(connection, optional.get().getUniqueIdentifier()); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + + if (b.getState() instanceof InventoryHolder) { + InventoryHolder holder = (InventoryHolder) b.getState(); + holder.getInventory().clear(); + } + + ItemStack machineFragment = Vice.getItemManager().getItem("machinefragment").getItem(); + ItemMeta meta = machineFragment.getItemMeta(); + meta.setLore(Arrays.asList( + C.GRAY + C.ITALIC + " " + optional.get().getName(), + "", + C.AQUA + C.BOLD + "INFO", + C.GRAY + " Visit the Machine Mechanic", + C.GRAY + " at spawn to turn these fragments", + C.GRAY + " into a functional machine!" + )); + + machineFragment.setItemMeta(meta); + machineFragment = ItemStackUtil.addTag(machineFragment, "machineid", optional.get().getMachineIdentifier()); + + b.getWorld().dropItemNaturally(b.getLocation(), machineFragment); + + for (int slot : optional.get().getOpenSlots()) { + ItemStack itemStack = optional.get().getInventory().getItem(slot); + if (itemStack == null || itemStack.getType() == Material.AIR) continue; + b.getWorld().dropItemNaturally(b.getLocation(), itemStack); + } + + for (int slot : optional.get().getOutputSlots()) { + ItemStack itemStack = optional.get().getInventory().getItem(slot); + if (itemStack == null || itemStack.getType() == Material.AIR) continue; + b.getWorld().dropItemNaturally(b.getLocation(), itemStack); + } + + for (int slot : optional.get().getData(MachineDataType.FUEL).getSlots()) { + ItemStack itemStack = optional.get().getInventory().getItem(slot); + if (itemStack == null || itemStack.getType() == Material.AIR) continue; + b.getWorld().dropItemNaturally(b.getLocation(), itemStack);// + } + + b.setType(Material.AIR); + iter.remove(); + } + } + + @EventHandler(ignoreCancelled = true) + protected final void onInteract(PlayerInteractEvent event) { + if (event.getHand() != EquipmentSlot.HAND) return; + if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return; + + Player player = event.getPlayer(); + Block block = event.getClickedBlock(); + if (block == null || block.getType() == Material.AIR) return; + + ItemStack hand = event.getPlayer().getInventory().getItemInMainHand(); + if (event.getPlayer().isSneaking() && (hand != null && hand.getType() != Material.AIR)) return; + + + Optional<BaseMachine> optional = this.machineManager.getMachineByLocation(block.getLocation()); + if (!optional.isPresent()) return; + + event.setCancelled(true); + + GameItem gameItem = Vice.getItemManager().getItem(hand); + if(gameItem!=null && gameItem.getName().equalsIgnoreCase("machinefragment") && ChatColor.stripColor(hand.getItemMeta().getLore().get(0)).replaceAll("\\s+","").equals(optional.get().getName().replaceAll("\\s+",""))) { + double percentDiff = optional.get().getData(MachineDataType.DURABILITY).getCurrent() / optional.get().getData(MachineDataType.DURABILITY).getMax() * 100; + if(percentDiff > 80) { + player.sendMessage(Lang.VICE.f("&cThat machine is not at least 20% damaged, you'd be wasting this machine fragment!")); + } + else { + MachineData durability = optional.get().getData(MachineDataType.DURABILITY); + durability.setCurrent(durability.getCurrent() + (int)Math.round(durability.getMax() *.20)); + optional.get().updateDurability(); + player.sendMessage(Lang.VOTE.f("&6You have repaired your machine by 20% &7(&6Current Durability: &b" + Math.round(percentDiff + 20) + "%&7)")); + hand.setAmount(hand.getAmount()-1); + player.updateInventory(); + } + return; + } + + + if (optional.get().isEnabled()) { + event.getPlayer().openInventory(optional.get().getInventory()); + } + } + + @EventHandler(ignoreCancelled = true) + protected final void onInventoryClick(InventoryClickEvent event) { + if (event.getInventory() == null || event.getView().getTopInventory() == null) return; + if (event.getWhoClicked() == null) return; + +// ServerUtil.debug("[>---------------------------<]"); +// ServerUtil.debug("Action: " + event.getAction().name()); +// ServerUtil.debug("Slot: " + event.getSlot()); +// ServerUtil.debug("Raw Slot: " + event.getRawSlot()); +// ServerUtil.debug("Click Type: " + event.getClick().name()); +// ServerUtil.debug("Clicked Title: " + (event.getClickedInventory() == null ? "." : event.getClickedInventory().getTitle())); +// ServerUtil.debug("Clicked Item: " + (event.getCurrentItem() == null ? "." : event.getCurrentItem().getType())); +// ServerUtil.debug("Cursor Item: " + (event.getCursor() == null ? "." : event.getCursor().getType())); +// ServerUtil.debug("Slot Type: " + event.getSlotType().name()); +// ServerUtil.debug("Hotbar Button: " + event.getHotbarButton()); +// ServerUtil.debug("[>---------------------------<]"); +// ServerUtil.debug(" "); + + Inventory top = event.getView().getTopInventory(); + if (top.getType() != InventoryType.CHEST) return; + + if(top.getHolder()!=null) return; //basically if the inventory is created out of thin air. So players can't rename their own chests. + + Optional<BaseMachine> optional = this.machineManager.getStatues().stream().filter(m -> m.getInventory().getName().equals(top.getName())).findFirst(); + if (!optional.isPresent()) return; + + + if (event.isShiftClick()) { + if (event.getRawSlot() >= 27) { + int slot = top.firstEmpty(); + int addSlot = top.first(event.getCurrentItem().getType()); + + if (optional.get().isOutputSlot(slot)) { + event.setCancelled(true); + ((Player) event.getWhoClicked()).updateInventory(); + return; + } + + MachineData data = optional.get().getData(MachineDataType.FUEL); + if (data.isSlot(slot)) { + if (!MachineUtil.isFuelType(event.getCurrentItem().getType())) { + event.setCancelled(true); + ((Player) event.getWhoClicked()).updateInventory(); + } else { + MachineFuelEvent machineFuelEvent = new MachineFuelEvent(optional.get(), data, event.getCursor().getType(), event.getRawSlot()); + Bukkit.getPluginManager().callEvent(machineFuelEvent); + if (machineFuelEvent.isCancelled()) { + event.setCancelled(true); + ((Player) event.getWhoClicked()).updateInventory(); + } + } + } + } + } + + //Check if the clicked slot is blocked. + if (optional.get().isBlockedSlot(event.getRawSlot())) { + event.setCancelled(true); + ((Player) event.getWhoClicked()).updateInventory(); + return; + } + + if (optional.get().isOutputSlot(event.getRawSlot())) { + switch (event.getAction()) { + case PICKUP_ALL: + case PICKUP_SOME: + case PICKUP_HALF: + case PICKUP_ONE: + case MOVE_TO_OTHER_INVENTORY: + break; + + default: + event.setCancelled(true); + ((Player) event.getWhoClicked()).updateInventory(); + break; + } + return; + } + + MachineData data = optional.get().getData(MachineDataType.FUEL); + if (data != null) { + if (data.isSlot(event.getRawSlot())) { + switch (event.getAction()) { + case PICKUP_ALL: + case PICKUP_SOME: + case PICKUP_HALF: + case PICKUP_ONE: + case COLLECT_TO_CURSOR: + case MOVE_TO_OTHER_INVENTORY: + break; + + case PLACE_ALL: + case PLACE_SOME: + case PLACE_ONE: + case SWAP_WITH_CURSOR: + if (event.getCursor() == null || !MachineUtil.isFuelType(event.getCursor().getType())) { + event.setCancelled(true); + ((Player) event.getWhoClicked()).updateInventory(); + return; + } + + MachineFuelEvent machineFuelEvent = new MachineFuelEvent(optional.get(), data, event.getCursor().getType(), event.getRawSlot()); + Bukkit.getPluginManager().callEvent(machineFuelEvent); + if (machineFuelEvent.isCancelled()) { + event.setCancelled(true); + ((Player) event.getWhoClicked()).updateInventory(); + } + break; + + //TODO: Change this to listen on 'default' + case DROP_ALL_CURSOR: + case DROP_ONE_CURSOR: + case DROP_ALL_SLOT: + case DROP_ONE_SLOT: + case HOTBAR_MOVE_AND_READD: + case HOTBAR_SWAP: + case CLONE_STACK: + case UNKNOWN: + event.setCancelled(true); + ((Player) event.getWhoClicked()).updateInventory(); + break; + } + } + } + } + + @EventHandler(ignoreCancelled = true) + protected final void onMachineFuel(MachineFuelEvent event) { +// MachineData data = event.getMachine().getData(MachineDataType.FUEL); +// data.add(20); +// ServerUtil.debug("FUEL ADDED."); + } + + @EventHandler + protected final void onMachineRecipeComplete(MachineRecipeCompleteEvent event) { + BaseMachine m = event.getMachine(); + MachineData fuelData = m.getData(MachineDataType.FUEL); + fuelData.take(event.getRecipeData().getRecipe().getFuelUsage()); + m.updateFuel(); + + MachineData durabilityData = m.getData(MachineDataType.DURABILITY); + durabilityData.take(event.getRecipeData().getRecipe().getDurabilityUsage()); + m.updateDurability(); + + + + for (int i = 0; i < event.getRecipeData().getRecipe().getOutput().length; i++) { + RecipeOutput output = event.getRecipeData().getRecipe().getOutput()[i]; + + ItemStack itemStack = output.getItemStack().clone(); + itemStack.setAmount(output.getAmount()); + + Optional<Entity> minecart = m.getLocation().getWorld().getNearbyEntities(m.getLocation(), 2, 2, 2).stream().filter(e -> e.getType() == EntityType.MINECART_HOPPER).findFirst(); + if(minecart.isPresent()) { + HopperMinecart storage = (HopperMinecart)minecart.get(); + if(storage.getInventory().firstEmpty()==-1) { + MachineUtil.addOutput(m.getInventory(), m.getOutputSlots()[i], itemStack); + continue; + } + storage.getInventory().addItem(itemStack); + if(m.getInventory().getItem(m.getOutputSlots()[i])!=null) { + storage.getInventory().addItem(m.getInventory().getItem(m.getOutputSlots()[i])); + m.getInventory().setItem(m.getOutputSlots()[i], new ItemStack(Material.AIR)); + } + continue; + } + + Block block = m.getLocation().getBlock().getRelative(BlockFace.DOWN); + if (block == null || block.getType() == Material.AIR) { + MachineUtil.addOutput(m.getInventory(), m.getOutputSlots()[i], itemStack); + continue; + } + + if (block.getType() != Material.HOPPER) { + MachineUtil.addOutput(m.getInventory(), m.getOutputSlots()[i], itemStack); + continue; + } + + Hopper hopper = (Hopper) block.getState(); + if (hopper.getInventory().firstEmpty() == -1) { + MachineUtil.addOutput(m.getInventory(), m.getOutputSlots()[i], itemStack); + continue; + } + + hopper.getInventory().addItem(itemStack); + if(m.getInventory().getItem(m.getOutputSlots()[i])!=null) { + hopper.getInventory().addItem(m.getInventory().getItem(m.getOutputSlots()[i])); + m.getInventory().setItem(m.getOutputSlots()[i], new ItemStack(Material.AIR)); + } + } + + MachineData progressData = m.getData(MachineDataType.PROGRESS); + progressData.setCurrent(0); + m.updateProgress(); + +// this.recipeManager.removeRecipeData(event.getRecipeData()); + m.setRecipeData(null); + } + + @EventHandler(ignoreCancelled = true) + protected final void onItemMove(InventoryMoveItemEvent event) { + if (event.getInitiator() == null) return; + if (event.getInitiator().getType() != InventoryType.HOPPER) return; + if (event.getInitiator().getLocation() != null) { + if (!event.getInitiator().getLocation().getChunk().isLoaded()) { + event.setCancelled(true); + return; + } + } + + if (event.getItem() == null) return; + if (event.getItem().getType() == Material.AIR) return; + + // Machine -> Hopper + if (event.getSource() != null && event.getSource().getType() == InventoryType.DROPPER) { + + Optional<BaseMachine> optional = this.machineManager.getMachineByLocation(event.getSource().getLocation()); + if (optional.isPresent()) { +// MachineItemTransferEvent itemTransferEvent = new MachineItemTransferEvent(optional.get(), event.getSource(), event.getDestination(), MachineItemTransferEvent.TransferType.FROM_MACHINE, event.getItem()); +// Bukkit.getPluginManager().callEvent(itemTransferEvent); + event.setCancelled(true); + + event.getSource().clear(); + +// if (itemTransferEvent.isTransferred()) { +// //TODO transfer output to hopper. +// } + } + } + + // Hopper -> Machine + if (event.getDestination() != null && event.getDestination().getType() == InventoryType.DROPPER) { + + Optional<BaseMachine> optional = this.machineManager.getMachineByLocation(event.getDestination().getLocation()); + if (optional.isPresent()) { + MachineItemTransferEvent itemTransferEvent = new MachineItemTransferEvent(optional.get(), event.getSource(), event.getDestination(), MachineItemTransferEvent.TransferType.TO_MACHINE, event.getItem()); + Bukkit.getPluginManager().callEvent(itemTransferEvent); + + if (!itemTransferEvent.isTransferred()) { + event.setCancelled(true); + return; + } + + MachineUtil.removeSimilarItem(event.getDestination(), event.getItem()); + event.getDestination().clear(); + } + } + } + + @EventHandler(ignoreCancelled = true) + protected final void onMachineItemTransfer(MachineItemTransferEvent event) { + if (event.getTransferType() == MachineItemTransferEvent.TransferType.TO_MACHINE) { + boolean bool = MachineUtil.tryAddingItem(event.getMachine(), event.getFrom().getLocation(), event.getItemStack()); + event.setTransferred(bool); + + return; + } + } + + @EventHandler + protected final void onChunkLoad(ChunkLoadEvent event) { + if (!event.getWorld().getName().equals("world")) return; + + for (BlockState state : event.getChunk().getTileEntities()) { + if (state == null || state.getBlock() == null) continue; + if (!this.machineManager.isType(state.getType())) continue; + + Optional<BaseMachine> optional = this.machineManager.getMachineByLocation(state.getBlock().getLocation()); + if (!optional.isPresent()) continue; + + if (!optional.get().isEnabled()) + optional.get().setEnabled(true); + + } + } + + @EventHandler + protected final void onChunkUnload(ChunkUnloadEvent event) { + if (!event.getWorld().getName().equals("world")) return; + + for (BlockState state : event.getChunk().getTileEntities()) { + if (state == null || state.getBlock() == null) continue; + if (!this.machineManager.isType(state.getType())) continue; + + Optional<BaseMachine> optional = this.machineManager.getMachineByLocation(state.getBlock().getLocation()); + if (!optional.isPresent()) continue; + + if (optional.get().isEnabled()) + optional.get().setEnabled(false); + + } + } + +// private class MachineChunkPacket implements PacketListener { +// +// @Override +// public void onPacketSending(PacketEvent packetEvent) { +// System.out.println("onPacketSending " + packetEvent.getPacketType().name()); +// } +// +// @Override +// public void onPacketReceiving(PacketEvent packetEvent) { +// System.out.println("onPacketReceiving " + packetEvent.getPacketType().name()); +// } +// +// @Override +// public ListeningWhitelist getSendingWhitelist() { +//// return ListeningWhitelist.newBuilder().types(PacketType.Play.Server.MAP_CHUNK).build(); +// return ListeningWhitelist.EMPTY_WHITELIST; +// } +// +// @Override +// public ListeningWhitelist getReceivingWhitelist() { +// return ListeningWhitelist.newBuilder().types(PacketType.Play.Server.MAP_CHUNK).build(); +// } +// +// @Override +// public Plugin getPlugin() { +// return Vice.getInstance(); +// } +// } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/MachineManager.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/MachineManager.java new file mode 100644 index 0000000..a86e2fe --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/MachineManager.java @@ -0,0 +1,149 @@ +package net.grandtheftmc.vice.machine; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.util.Component; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.dao.MachineDAO; +import net.grandtheftmc.vice.machine.recipe.MachineRecipeManager; +import net.grandtheftmc.vice.machine.recipe.menu.RecipeMenuManager; +import net.grandtheftmc.vice.machine.type.*; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.java.JavaPlugin; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.*; +import java.util.stream.Collectors; + +public class MachineManager implements Component<MachineComponent, Vice> { + + private final HashSet<BaseMachine> statues; + private final HashMap<Location, BaseMachine> machines; + + private final MachineComponent component; + + public MachineManager(JavaPlugin plugin) { + this.statues = Sets.newHashSet(); + this.machines = Maps.newHashMap(); + + this.statues.addAll(Arrays.asList( + new MachineSmallDryingChamber(), + new MachineMediumDryingChamber(), + new MachineLargeDryingMachine(), + new MachineBeerDistillery(), + new MachineVodkaDistillery(), + new MachineCocaProcessor(), + new MachinePulpCondenser(), + new MachineBasicMethProducer(), + new MachineAdvancedMethProducer(), + new MachineSugarBox() + )); + + new MachineCommand(this); + new RecipeMenuManager(plugin); + MachineRecipeManager recipeManager = new MachineRecipeManager(this); + Bukkit.getPluginManager().registerEvents(this.component = new MachineComponent(this, recipeManager), plugin); + + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + long start = System.currentTimeMillis(); + for (BaseMachine machine : MachineDAO.getMachines(connection)) { + this.machines.put(machine.getLocation(), machine); + machine.setEnabled(false); + } + System.out.println("Machines loaded(" + this.machines.size() + "), took " + (System.currentTimeMillis() - start) + "ms."); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + + Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, new MachineTask(this, recipeManager), 10, 1); + } + + @Override + public MachineComponent onDisable(Vice plugin) { + this.component.onDisable(plugin); + return this.component; + } + + public Optional<BaseMachine> constructByItem(ItemStack itemStack) { + Optional<BaseMachine> optional = this.statues.stream().filter(m -> itemStack.isSimilar(m.getMachineItem())).findFirst(); + if (!optional.isPresent()) return Optional.empty(); + + switch (optional.get().getMachineIdentifier()) { + case 1: return Optional.of(new MachineSmallDryingChamber()); + case 2: return Optional.of(new MachineMediumDryingChamber()); + case 3: return Optional.of(new MachineLargeDryingMachine()); + case 4: return Optional.of(new MachineBeerDistillery()); + case 5: return Optional.of(new MachineVodkaDistillery()); + case 6: return Optional.of(new MachineCocaProcessor()); + case 7: return Optional.of(new MachinePulpCondenser()); + case 8: return Optional.of(new MachineBasicMethProducer()); + case 9: return Optional.of(new MachineAdvancedMethProducer()); + case 10: return Optional.of(new MachineSugarBox()); + } + + return Optional.empty(); + } + + public ItemStack getMachineItemById(int id) { + Optional<BaseMachine> optional = this.statues.stream().filter(m -> m.getMachineIdentifier() == id).findFirst(); + if (!optional.isPresent()) return new ItemStack(Material.STONE); + + return optional.get().getMachineItem().clone(); + } + + public Optional<BaseMachine> getMachineById(int uniqueId) { + return this.getMachines().stream().filter(m -> { +// ServerUtil.debug(m.getUniqueIdentifier() + " -"); +// ServerUtil.debug(uniqueId + " --"); + return m.getUniqueIdentifier() == uniqueId; + }).findFirst(); + } + + public boolean isType(Material material) { + return this.statues.stream().anyMatch(m -> m.getMaterial() == material); + } + + public void removeMachine(BaseMachine machine) { + if(this.machines.containsKey(machine.getLocation())) + this.machines.remove(machine.getLocation()); + } + + public Collection<BaseMachine> getMachines() { + return this.machines.values().stream().filter(BaseMachine::isEnabled).collect(Collectors.toList()); + } + + public Collection<BaseMachine> getAllMachines() { + return this.machines.values(); + } + + public void addMachine(BaseMachine machine) { + this.machines.put(machine.getLocation(), machine); + } + + public Optional<BaseMachine> getMachineByLocation(Location location) { +// return this.machines.stream().filter(m -> m.getLocation() != null && this.isLoc(m.getLocation(), location)).findFirst(); + return this.machines.containsKey(location) ? Optional.of(this.machines.get(location)) : Optional.empty(); + } + +// public Optional<BaseMachine> isMachine(Inventory inventory) { +// return this.machines.stream().filter(m -> m.getInventory().equals(inventory)).findFirst(); +// } + + private boolean isLoc(Location loc1, Location loc2) { + return loc1.getBlockX() == loc2.getBlockX() && loc1.getBlockY() == loc2.getBlockY() && loc1.getBlockZ() == loc2.getBlockZ(); + } + + public HashSet<BaseMachine> getStatues() { + return this.statues; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/MachineTask.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/MachineTask.java new file mode 100644 index 0000000..555dc2c --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/MachineTask.java @@ -0,0 +1,142 @@ +package net.grandtheftmc.vice.machine; + +import de.slikey.effectlib.util.ParticleEffect; +import net.grandtheftmc.core.util.Callback; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.vice.machine.data.MachineData; +import net.grandtheftmc.vice.machine.data.MachineDataType; +import net.grandtheftmc.vice.machine.recipe.MachineRecipeManager; +import net.grandtheftmc.vice.machine.recipe.misc.MachineRecipeData; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +import java.util.Random; + +public final class MachineTask implements Runnable { + + private final MachineManager machineManager; + private final MachineRecipeManager recipeManager; + private final Random random; + + public MachineTask(MachineManager machineManager, MachineRecipeManager recipeManager) { + this.machineManager = machineManager; + this.recipeManager = recipeManager; + this.random = new Random(); + } + + /** + * When an object implementing interface <code>Runnable</code> is used + * to create a thread, starting the thread causes the object's + * <code>run</code> method to be called in that separately executing + * thread. + * <p> + * The general contract of the method <code>run</code> is that it may + * take any action whatsoever. + * + * @see Thread#run() + */ + @Override + public void run() { + for (BaseMachine machine : this.machineManager.getMachines()) { + if (!machine.isEnabled()) continue; + + Location loc = machine.getLocation().clone(); + MachineData data = machine.getData(MachineDataType.DURABILITY); + + if(data !=null) + if(data.getCurrent()==0) { + ParticleEffect.VILLAGER_ANGRY.display(0.3f, 0f, 0.3f, 1, 0, loc.clone().add(0.5, .5, 0.5), 50d);//durability is 0 + continue; + } + + if (!machine.getData(MachineDataType.FUEL).isFull()) { + ServerUtil.runTask(() -> { + if (!refillFuel(machine) && machine.getData(MachineDataType.FUEL).getCurrent() == 0) { + ParticleEffect.REDSTONE.display(255f / 255f, 0f, 0f, 1, 0, loc.clone().add(0.5, 1.1, 0.5), 50d);//no fuel + } + }); + } + + ServerUtil.runTask(() -> { + machine.updateFuel(); + machine.updateDurability(); + }); + + if (machine.getData(MachineDataType.FUEL).isEmpty()) continue; + + if (!machine.isRecipeActive()) { + ServerUtil.runTask(() -> { + if (!this.recipeManager.tryInitRecipe(machine)) { + ParticleEffect.REDSTONE.display(255f / 255f, 102f / 255f, 0f, 1, 0, loc.clone().add(0.5, 1.1, 0.5), 50d);//recipe isnt active + } + }); + continue; + } + else + ParticleEffect.REDSTONE.display(102f/255f,255f/255f,102f/255f, 1,0, loc.clone().add(0.5, 1.1, 0.5), 50d); + + MachineRecipeData recipeData = machine.getRecipeData(); + if (recipeData.next()) { + ServerUtil.runTask(machine::updateProgress); + } + } + } + + public boolean refillFuel(BaseMachine machine) { + for (int i : machine.getData(MachineDataType.FUEL).getSlots()) { + ItemStack item = machine.getInventory().getItem(i); + if (item == null || item.getType() == Material.AIR) return false; + + MachineData data = machine.getData(MachineDataType.FUEL); + if (data == null) return false; + + if(data.getCurrent()+MachineUtil.getFuelByType(item.getType())>data.getMax()) return false; + + if (item.getAmount() <= 1) machine.getInventory().setItem(i, new ItemStack(Material.AIR)); + else item.setAmount(item.getAmount() - 1); + + data.add(MachineUtil.getFuelByType(item.getType()));//TODO: CHANGE TO ACTUAL AMOUNT + } + + return true; + } + + private void doStuff(BaseMachine machine, int i, boolean visual) { + boolean x = this.random.nextBoolean(); + if (!x) return; + + MachineData data; + if (i == 0) { + + //Another random because why not.. lmao + if (this.random.nextBoolean()) return; + + data = machine.getData(MachineDataType.FUEL); + if (data == null) return; + + data.take(1); + machine.updateFuel(); + } + else if (i == 1) { + data = machine.getData(MachineDataType.DURABILITY); + if (data == null) return; + + data.take(2); + machine.updateDurability(); + } + else if (i == 2) { + data = machine.getData(MachineDataType.PROGRESS); + if (data == null) return; + + data.add(1); + machine.updateProgress(); + } + } + + public void canRun(Location location, Callback<Boolean> callback) { + ServerUtil.runTask(() -> { + callback.call(location.getChunk().isLoaded()); + }); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/MachineTesting.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/MachineTesting.java new file mode 100644 index 0000000..4d03fb6 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/MachineTesting.java @@ -0,0 +1,44 @@ +package net.grandtheftmc.vice.machine; + +public class MachineTesting { + + static String[] symbols = {"A", "B", "C", "D", "E"}; + + public static void main(String[] args) { +// int max = 100; +// int current = 95; +// int bars = symbols.length - 1; +// int result = (int) Math.round(getPercentBetweenValues(max, current, bars)); +// System.out.println("" + result); +// +// String str = ""; +// for (int i = 0; i < result; i++) +// str += 'x'; +// +// for (int i = result; i < bars; i++) +// str += 'o'; +// +// System.out.println("" + str); +// System.out.println("" + symbols[result]); + + + //NEW +// long next = System.currentTimeMillis() + ((10 * 1000) / 26); +// int i = 1; +// while (i < 27) { +// if (System.currentTimeMillis() > next) { +// System.out.println(i); +// next = System.currentTimeMillis() + ((10 * 1000) / 26); +// i++; +// } +// } + + + //NEW + System.out.println(getPercentBetweenValues(100, 0.76 * 100, 100)); + } + + public static int getPercentBetweenValues(double goal, double value, int bars) { + return (int) Math.round(value >= goal ? bars : bars - Math.abs((goal - value) / goal * bars)); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/MachineUtil.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/MachineUtil.java new file mode 100644 index 0000000..03fe0a2 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/MachineUtil.java @@ -0,0 +1,145 @@ +package net.grandtheftmc.vice.machine; + +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.vice.machine.data.MachineDataType; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +public class MachineUtil { + +// public static Optional<BaseMachine> getMachineByInventory(MachineManager machineManager, Inventory inventory) { +// if (inventory == null) return Optional.empty(); +// if (!inventory.getTitle().contains("Machine-")) return Optional.empty(); +// +// int id = -1; +// try { +// id = Integer.parseInt(inventory.getTitle().split("Machine-")[1]); +// } catch (NumberFormatException e) {} +// +// if (id == -1) return Optional.empty(); +// +// return machineManager.getMachineById(id); +// } +// +// public static Optional<Block> getBlockByInventory(MachineManager machineManager, Inventory inventory) { +// if (inventory == null) return Optional.empty(); +// return Optional.of(inventory.getLocation().getBlock()); +// } + + public static int getFuelByType(Material material) { + switch (material) { + case LAVA_BUCKET: return 100; + case COAL_BLOCK: return 80; + case COAL: return 8; + case WOOD: return 2; + } + + return 0; + } + + public static boolean isFuelType(Material material) { + return material == Material.LAVA_BUCKET || material == Material.COAL || material == Material.WOOD || material == Material.COAL_BLOCK; + } + + public static boolean tryAddingItem(BaseMachine machine, Location from, ItemStack itemStack) { + if (isFuelType(itemStack.getType())) { + for (int slot : machine.getData(MachineDataType.FUEL).getSlots()) { + ItemStack found = machine.getInventory().getItem(slot); + + //If null or AIR, place the item. + if (found == null || found.getType() == Material.AIR) { + machine.getInventory().setItem(slot, itemStack); + return true; + } + + if (found.getType() != itemStack.getType()) continue; + if (found.getAmount() >= found.getMaxStackSize()) continue; + + found.setAmount(found.getAmount() + itemStack.getAmount()); + return true; + } + } + + if (isFuelType(itemStack.getType())) return false; + + for (int slot : machine.getOpenSlots()) { + ItemStack found = machine.getInventory().getItem(slot); + + //If null or AIR, place the item. + if (found == null || found.getType() == Material.AIR) { + machine.getInventory().setItem(slot, itemStack); + return true; + } + + if (!found.isSimilar(itemStack)) continue; + if (found.getAmount() >= found.getMaxStackSize()) continue; + + found.setAmount(found.getAmount() + itemStack.getAmount()); + return true; + } + + return false; + } + + public static void removeSimilarItem(Inventory inventory, ItemStack itemStack) { + if (inventory == null) return; + + for (int i = 0; i < inventory.getSize(); i++) { + int finalI = i; + + ItemStack item = inventory.getItem(i); + if (item == null || item.getType() == Material.AIR) continue; + if (!item.isSimilar(itemStack)) continue; + + if (item.getAmount() <= 1) { + ServerUtil.runTaskLater(() -> inventory.setItem(finalI, new ItemStack(Material.AIR)), 1L); + + ServerUtil.debug(inventory.getTitle() + " - Item removed."); + } + else { + item.setAmount(item.getAmount() - 1); + ServerUtil.runTaskLater(() -> inventory.setItem(finalI, item), 1L); + + ServerUtil.debug(inventory.getTitle() + " - Amount reduced."); + } + } + } + + /** + * @param inventory the inventory of the machine + * @param slot the output slot of the inventory of the machine + */ + public static boolean isOutputFull(Inventory inventory, int slot) { + if(inventory == null) return true; + + ItemStack found = inventory.getItem(slot); + if(found== null || found.getType()== Material.AIR) + return false; + if(found.getAmount() >= 64) + return true; + return false; + } + + public static void addOutput(Inventory inventory, int slot, ItemStack itemStack) { + if (inventory == null) return; + + ItemStack found = inventory.getItem(slot); + if (found == null || found.getType() == Material.AIR) { + inventory.setItem(slot, itemStack); + return; + } + + if (!found.isSimilar(itemStack)) return; + + if (found.getAmount() + itemStack.getAmount() >= 64) { + found.setAmount(64); + return; + } + + if (found.getAmount() < 64) { + found.setAmount(found.getAmount() + itemStack.getAmount()); + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/data/MachineData.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/data/MachineData.java new file mode 100644 index 0000000..a42e4a4 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/data/MachineData.java @@ -0,0 +1,100 @@ +package net.grandtheftmc.vice.machine.data; + +public class MachineData { + + private final DataFlag flag; + private final double max; + private double current; + + private int[] textures; + private int[] slots; + + public MachineData(DataFlag flag, double max, double current) { + this.flag = flag; + this.max = max; + this.current = current; + } + + public MachineData(DataFlag flag, double max) { + this.flag = flag; + this.max = max; + this.current = max; + } + + public DataFlag getFlag() { + return flag; + } + + public double getMax() { + return max; + } + + public double getCurrent() { + return current; + } + + public void setCurrent(double current) { + this.current = current; + } + + public int[] getTextures() { + return textures; + } + + public void setTextures(int... textures) { + this.textures = textures; + } + + public int[] getSlots() { + return slots; + } + + public void setSlots(int... slots) { + this.slots = slots; + } + + public boolean isSlot(int slot) { + for (int i : this.slots) + if (i == slot) return true; + return false; + } + + public boolean isEmpty() { + return this.current <= 0; + } + + public boolean isFull() { + return this.current >= this.max; + } + + public void take(int amount) { + if (this.current - amount < 0) { + this.current = 0; + return; + } + + this.current -= amount; + } + + public void add(int amount) { + if (this.current + amount >= this.max) { + this.current = this.max; + return; + } + + this.current += amount; + } + + public int getTexture() { + return this.textures[this.getPercentBetweenValues(this.max, this.current, this.textures.length - 1)]; + } + + private int getPercentBetweenValues(double goal, double value, int bars) { + return (int) Math.round(value >= goal ? bars : bars - Math.abs((goal - value) / goal * bars)); + } + + public static enum DataFlag { + UP, DOWN, + ; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/data/MachineDataType.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/data/MachineDataType.java new file mode 100644 index 0000000..9a116a2 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/data/MachineDataType.java @@ -0,0 +1,6 @@ +package net.grandtheftmc.vice.machine.data; + +public enum MachineDataType { + FUEL, DURABILITY, PROGRESS, + ; +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/event/MachineDurabilityEvent.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/event/MachineDurabilityEvent.java new file mode 100644 index 0000000..3921090 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/event/MachineDurabilityEvent.java @@ -0,0 +1,37 @@ +package net.grandtheftmc.vice.machine.event; + +import net.grandtheftmc.core.events.CoreEvent; +import net.grandtheftmc.vice.machine.BaseMachine; +import net.grandtheftmc.vice.machine.data.MachineData; +import org.bukkit.event.Cancellable; + +public final class MachineDurabilityEvent extends CoreEvent implements Cancellable { + + private final BaseMachine machine; + private final MachineData data; + private boolean cancelled; + + public MachineDurabilityEvent(BaseMachine machine, MachineData data) { + super(false); + this.machine = machine; + this.data = data; + } + + public BaseMachine getMachine() { + return machine; + } + + public MachineData getData() { + return data; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean b) { + this.cancelled = b; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/event/MachineFuelEvent.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/event/MachineFuelEvent.java new file mode 100644 index 0000000..024c715 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/event/MachineFuelEvent.java @@ -0,0 +1,51 @@ +package net.grandtheftmc.vice.machine.event; + +import net.grandtheftmc.core.events.CoreEvent; +import net.grandtheftmc.vice.machine.BaseMachine; +import net.grandtheftmc.vice.machine.data.MachineData; +import org.bukkit.Material; +import org.bukkit.event.Cancellable; + +public final class MachineFuelEvent extends CoreEvent implements Cancellable { + + private final BaseMachine machine; + private final MachineData data; + private final Material fuelType; + private final int slot; + + private boolean cancelled; + + public MachineFuelEvent(BaseMachine machine, MachineData data, Material fuelType, int slot) { + super(false); + this.machine = machine; + this.data = data; + this.fuelType = fuelType; + this.slot = slot; + } + + public BaseMachine getMachine() { + return machine; + } + + public MachineData getData() { + return data; + } + + public Material getFuelType() { + return fuelType; + } + + public int getSlot() { + return slot; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean b) { + this.cancelled = b; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/event/MachineItemTransferEvent.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/event/MachineItemTransferEvent.java new file mode 100644 index 0000000..d2bdbf5 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/event/MachineItemTransferEvent.java @@ -0,0 +1,71 @@ +package net.grandtheftmc.vice.machine.event; + +import net.grandtheftmc.core.events.CoreEvent; +import net.grandtheftmc.core.util.Callback; +import net.grandtheftmc.vice.machine.BaseMachine; +import org.bukkit.event.Cancellable; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +public final class MachineItemTransferEvent extends CoreEvent implements Cancellable { + + private final BaseMachine machine; + private final Inventory from, to; + private final TransferType transferType; + private final ItemStack itemStack; + + private boolean cancelled, transferred; + + public MachineItemTransferEvent(BaseMachine machine, Inventory from, Inventory to, TransferType transferType, ItemStack itemStack) { + super(false); + this.machine = machine; + this.from = from; + this.to = to; + this.transferType = transferType; + this.itemStack = itemStack; + } + + public BaseMachine getMachine() { + return machine; + } + + public Inventory getFrom() { + return from; + } + + public Inventory getTo() { + return to; + } + + public TransferType getTransferType() { + return transferType; + } + + public ItemStack getItemStack() { + return itemStack; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + @Override + public void setCancelled(boolean b) { + this.cancelled = b; + } + + public boolean isTransferred() { + return transferred; + } + + public void setTransferred(boolean transferred) { + this.transferred = transferred; + } + + public static enum TransferType { + TO_MACHINE, + FROM_MACHINE, + ; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/event/MachinePlaceEvent.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/event/MachinePlaceEvent.java new file mode 100644 index 0000000..e4ac7f5 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/event/MachinePlaceEvent.java @@ -0,0 +1,45 @@ +package net.grandtheftmc.vice.machine.event; + +import net.grandtheftmc.core.events.CoreEvent; +import net.grandtheftmc.vice.machine.BaseMachine; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; + +public final class MachinePlaceEvent extends CoreEvent implements Cancellable { + + private final Player player; + private final Location location; + private final BaseMachine machine; + + private boolean cancelled; + + public MachinePlaceEvent(Player player, Location location, BaseMachine machine) { + super(false); + this.player = player; + this.location = location; + this.machine = machine; + } + + public Player getPlayer() { + return player; + } + + public Location getLocation() { + return location; + } + + public BaseMachine getMachine() { + return machine; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean b) { + cancelled = b; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/event/MachineRecipeCompleteEvent.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/event/MachineRecipeCompleteEvent.java new file mode 100644 index 0000000..98bdae0 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/event/MachineRecipeCompleteEvent.java @@ -0,0 +1,37 @@ +package net.grandtheftmc.vice.machine.event; + +import net.grandtheftmc.core.events.CoreEvent; +import net.grandtheftmc.vice.machine.BaseMachine; +import net.grandtheftmc.vice.machine.recipe.misc.MachineRecipeData; +import org.bukkit.event.Cancellable; + +public final class MachineRecipeCompleteEvent extends CoreEvent implements Cancellable { + + private final BaseMachine machine; + private final MachineRecipeData recipeData; + private boolean cancelled; + + public MachineRecipeCompleteEvent(BaseMachine machine, MachineRecipeData recipeData) { + super(false); + this.machine = machine; + this.recipeData = recipeData; + } + + public BaseMachine getMachine() { + return machine; + } + + public MachineRecipeData getRecipeData() { + return recipeData; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean b) { + this.cancelled = b; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/misc/MachineProgressMultiplier.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/misc/MachineProgressMultiplier.java new file mode 100644 index 0000000..61cb0bc --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/misc/MachineProgressMultiplier.java @@ -0,0 +1,12 @@ +package net.grandtheftmc.vice.machine.misc; + +public interface MachineProgressMultiplier { + + /** + * This multiplier will speed up the brewing/ cooking + * progress by the given amount. + * + * @return + */ + double getMultiplier(); +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/MachineRecipe.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/MachineRecipe.java new file mode 100644 index 0000000..a450b2a --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/MachineRecipe.java @@ -0,0 +1,84 @@ +package net.grandtheftmc.vice.machine.recipe; + +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeInput; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeOutput; + +public abstract class MachineRecipe { + + /** Unique Identifier of the Recipe */ + private final int identifier; + + /** Array of input items, size depends on the machine type */ + private final RecipeInput[] input; + + /** Output of the complete Recipe */ + private final RecipeOutput[] output; + + /** Amount of Fuel this Recipe should consume */ + private final int fuelUsage; + + /** Amount of durability this Recipe should consume */ + private final int durabilityUsage; + + /** Time to cook / brew in seconds */ + private final long time; + + /** Recipe string tutorial */ + protected String recipeText; + + /** + * Construct a new Machine Recipe. + * + * @param identifier - Unique Identifier of the Recipe. + * @param input - Array of input items, size depends on the machine type. + * @param output - Output of the complete Recipe. + * @param fuelUsage - Amount of Fuel this Recipe should consume. + * @param durabilityUsage - Amount of durability this Recipe should consume. + * @param time - Time to cook / brew in seconds. + */ + public MachineRecipe(int identifier, RecipeInput[] input, RecipeOutput[] output, int fuelUsage, int durabilityUsage, int time) { + this.identifier = identifier; + this.input = input; + this.output = output; + this.fuelUsage = fuelUsage; + this.durabilityUsage = durabilityUsage; + this.time = time; + } + + public int getIdentifier() { + return this.identifier; + } + + public RecipeInput[] getInput() { + return this.input; + } + + public RecipeOutput[] getOutput() { + return this.output; + } + + public int getFuelUsage() { + return this.fuelUsage; + } + + public int getDurabilityUsage() { + return this.durabilityUsage; + } + + public long getTime() { + return this.time; + } + + public String getRecipeText() { + return this.recipeText; + } + + public void setRecipeText(String recipeText) { + this.recipeText = recipeText; + } + + public String _(String icon, int amount) { + return C.RESET + icon + C.GRAY + "x" + amount + C.RESET; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/MachineRecipeManager.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/MachineRecipeManager.java new file mode 100644 index 0000000..57c2e8b --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/MachineRecipeManager.java @@ -0,0 +1,120 @@ +package net.grandtheftmc.vice.machine.recipe; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import net.grandtheftmc.vice.machine.BaseMachine; +import net.grandtheftmc.vice.machine.MachineManager; +import net.grandtheftmc.vice.machine.MachineUtil; +import net.grandtheftmc.vice.machine.recipe.misc.MachineRecipeData; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeInput; +import net.grandtheftmc.vice.machine.recipe.type.*; +import org.bukkit.Material; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +public final class MachineRecipeManager { + + private final MachineManager machineManager; + private final HashMap<Integer, List<MachineRecipe>> recipes; + private final List<MachineRecipeData> recipeData; + + /** + case 1: return Optional.of(new MachineSmallDryingChamber()); + case 2: return Optional.of(new MachineMediumDryingChamber()); + case 3: return Optional.of(new MachineLargeDryingMachine()); + case 4: return Optional.of(new MachineBeerDistillery()); + case 5: return Optional.of(new MachineVodkaDistillery()); + case 6: return Optional.of(new MachineCocaProcessor()); + case 7: return Optional.of(new MachinePulpCondenser()); + case 8: return Optional.of(new MachineBasicMethProducer()); + case 9: return Optional.of(new MachineAdvancedMethProducer()); + case 10: return Optional.of(new MachineSugarBox()); + */ + + public MachineRecipeManager(MachineManager machineManager) { + this.machineManager = machineManager; + this.recipes = Maps.newHashMap(); + this.recipeData = Lists.newArrayList(); + + this.recipes.put(1, Arrays.asList(new RecipeHumulusLupulusFruit(), new RecipeWeed(), new RecipeDriedMushroomRed(), new RecipeDriedMushroomBrown(), new RecipeAcid())); + this.recipes.put(2, Arrays.asList(new RecipeHumulusLupulusFruit(), new RecipeWeed(), new RecipeDriedMushroomRed(), new RecipeDriedMushroomBrown(), new RecipeAcid())); + this.recipes.put(3, Arrays.asList(new RecipeHumulusLupulusFruit(), new RecipeWeed(), new RecipeDriedMushroomRed(), new RecipeDriedMushroomBrown(), new RecipeAcid())); + this.recipes.put(4, Arrays.asList(new RecipeBeer(), new RecipeCraftBeer())); + this.recipes.put(5, Arrays.asList(new RecipeVodka(), new RecipeDistilledVodka())); + this.recipes.put(6, Arrays.asList(new RecipeCrack(), new RecipeCocaine())); + this.recipes.put(7, Arrays.asList(new RecipeConcentratedMagicMushroom())); + this.recipes.put(8, Arrays.asList(new RecipeWhiteMeth())); + this.recipes.put(9, Arrays.asList(new RecipePureMeth())); + this.recipes.put(10, Arrays.asList(new RecipeLSD())); + } + + public boolean tryInitRecipe(BaseMachine machine) { + if (machine.isRecipeActive()) return true; + + Inventory inv = machine.getInventory(); + if (inv == null) return false; + if (!this.recipes.containsKey(machine.getMachineIdentifier())) return false; + + for(int i = 0; i < machine.getOutputSlots().length; i++) + if(MachineUtil.isOutputFull(machine.getInventory(), machine.getOutputSlots()[i])) + return false; + + for (MachineRecipe recipe : this.recipes.get(machine.getMachineIdentifier())) { + if (!this.hasAllRecipeItems(machine, recipe)) continue; + + this.removeRecipeItems(machine, recipe); + machine.setRecipeData(new MachineRecipeData(machine, recipe)); + return true; + } + + return false; + } + + private boolean hasAllRecipeItems(BaseMachine machine, MachineRecipe recipe) { + for (RecipeInput input : recipe.getInput()) { + if (!hasRecipeItem(machine, input)) + return false; + } + + return true; + } + + private boolean hasRecipeItem(BaseMachine machine, RecipeInput input) { + Inventory inv = machine.getInventory(); + if (inv == null) return false; + + for (int i : machine.getOpenSlots()) { + ItemStack item = inv.getItem(i); + if (item == null || item.getType() == Material.AIR) continue; + if (!item.isSimilar(input.getItemStack())) continue; + if (item.getAmount() < input.getAmount()) continue; + return true; + } + + return false; + } + + private void removeRecipeItems(BaseMachine machine, MachineRecipe recipe) { + Inventory inv = machine.getInventory(); + if (inv == null) return; + + for (RecipeInput input : recipe.getInput()) { + for (int i : machine.getOpenSlots()) { + ItemStack item = inv.getItem(i); + if (item == null || item.getType() == Material.AIR) continue; + if (!item.isSimilar(input.getItemStack())) continue; + if (item.getAmount() < input.getAmount()) { + inv.setItem(i, new ItemStack(Material.AIR)); + continue; + } + + if (item.getAmount() - input.getAmount() < 1) inv.setItem(i, new ItemStack(Material.AIR)); + else item.setAmount(item.getAmount() - input.getAmount()); + } + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/command/MachineRecipeCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/command/MachineRecipeCommand.java new file mode 100644 index 0000000..fac7cd1 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/command/MachineRecipeCommand.java @@ -0,0 +1,20 @@ +package net.grandtheftmc.vice.machine.recipe.command; + +import net.grandtheftmc.core.commands.CoreCommand; +import net.grandtheftmc.vice.machine.recipe.menu.RecipeMenuManager; +import org.bukkit.entity.Player; + +public final class MachineRecipeCommand extends CoreCommand<Player> { + + private final RecipeMenuManager recipeMenuManager; + + public MachineRecipeCommand(RecipeMenuManager recipeMenuManager) { + super("recipe", "Display visual recipes for Machines & Drugs"); + this.recipeMenuManager = recipeMenuManager; + } + + @Override + public void execute(Player sender, String[] strings) { + this.recipeMenuManager.getRecipeMenuPortal().openInventory(sender); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/RecipeMenu.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/RecipeMenu.java new file mode 100644 index 0000000..827de07 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/RecipeMenu.java @@ -0,0 +1,71 @@ +package net.grandtheftmc.vice.machine.recipe.menu; + +import net.grandtheftmc.core.inventory.CoreMenu; +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import net.grandtheftmc.core.inventory.button.MenuItem; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.vice.machine.recipe.MachineRecipe; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeInput; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeOutput; +import org.bukkit.inventory.ItemStack; + +public abstract class RecipeMenu extends CoreMenu { + + public final short progress = 65; + private final MachineRecipe recipe; + + private int[] openSlots, outputSlots, blockedSlots; + + public RecipeMenu(int rows, String title, MachineRecipe recipe, CoreMenuFlag... menuFlags) { + super(rows, title, menuFlags); + this.recipe = recipe; + } + + public int[] getOpenSlots() { + return openSlots; + } + + public void setOpenSlots(int... openSlots) { + this.openSlots = openSlots; + } + + public void setOutputSlots(int... outputSlots) { + this.outputSlots = outputSlots; + } + + public int[] getOutputSlots() { + return outputSlots; + } + + public void setBlockedSlots(int... blockedSlots) { + this.blockedSlots = blockedSlots; + } + + public int[] getBlockedSlots() { + return blockedSlots; + } + + protected String i(String icon, int amount) { + return C.RESET + icon + C.GRAY + "x" + amount + C.RESET; + } + + public MachineRecipe getRecipe() { + return recipe; + } + + public void initRecipeItems() { + for (int i = 0; i < this.openSlots.length; i++) { + RecipeInput input = this.recipe.getInput()[i]; + ItemStack item = input.getItemStack().clone(); + item.setAmount(input.getAmount()); + super.addItem(new MenuItem(this.openSlots[i], item, false)); + } + + for (int i = 0; i < this.outputSlots.length; i++) { + RecipeOutput output = this.recipe.getOutput()[i]; + ItemStack item = output.getItemStack().clone(); + item.setAmount(output.getAmount()); + super.addItem(new MenuItem(this.outputSlots[i], output.getItemStack().clone(), false)); + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/RecipeMenuManager.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/RecipeMenuManager.java new file mode 100644 index 0000000..16fe27f --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/RecipeMenuManager.java @@ -0,0 +1,52 @@ +package net.grandtheftmc.vice.machine.recipe.menu; + +import com.google.common.collect.Sets; +import net.grandtheftmc.core.util.Component; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.machine.recipe.command.MachineRecipeCommand; +import net.grandtheftmc.vice.machine.recipe.menu.type.*; +import org.bukkit.event.EventHandler; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.plugin.java.JavaPlugin; + +import java.util.Set; + +public class RecipeMenuManager implements Component<RecipeMenuManager, Vice> { + + private final Set<RecipeMenu> recipeMenus; + private final RecipeMenuPortal recipeMenuPortal; + + public RecipeMenuManager(JavaPlugin plugin) { + this.recipeMenus = Sets.newHashSet( + new RecipeMenuAcid(), + new RecipeMenuBeer(), + new RecipeMenuCocaine(), + new RecipeMenuConcentratedMagicMushroom(), + new RecipeMenuCrack(), + new RecipeMenuCraftBeer(), + new RecipeMenuDistilledVodka(), + new RecipeMenuDriedMushroom(), + new RecipeMenuHumulusLapulusFruit(), + new RecipeMenuLSD(), + new RecipeMenuPureMeth(), + new RecipeMenuVodka(), + new RecipeMenuWeed(), + new RecipeMenuWhiteMeth() + ); + + this.recipeMenuPortal = new RecipeMenuPortal(this.recipeMenus); + + new MachineRecipeCommand(this); + } + + public RecipeMenuPortal getRecipeMenuPortal() { + return recipeMenuPortal; + } + + @EventHandler + protected final void onInventoryClick(InventoryClickEvent event) { + if (event.getInventory().getTitle().toLowerCase().contains("recipe :")) { + event.setCancelled(true); + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/RecipeMenuPortal.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/RecipeMenuPortal.java new file mode 100644 index 0000000..00676dc --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/RecipeMenuPortal.java @@ -0,0 +1,34 @@ +package net.grandtheftmc.vice.machine.recipe.menu; + +import net.grandtheftmc.core.inventory.CoreMenu; +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import net.grandtheftmc.core.inventory.button.ClickableItem; +import net.grandtheftmc.core.inventory.button.MenuItem; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.factory.ItemFactory; +import org.bukkit.Material; + +import java.util.Set; + +public final class RecipeMenuPortal extends CoreMenu { + + public RecipeMenuPortal(Set<RecipeMenu> recipeMenus) { + super(4, "Choose a Drug Recipe", CoreMenuFlag.RESET_CURSOR_ON_OPEN, CoreMenuFlag.CLOSE_ON_NULL_CLICK); + + //# # # # # # # # # + //# o o o o o o o # + //# o o o o o o o # + //# # # # # # # # # + + int[] slots = new int[] {10,11,12,13,14,15,16, 19,20,21,22,23,24,25}, empty = new int[] {0,1,2,3,4,5,6,7,8,9,17,18,26,27,28,29,30,31,32,33,34,35}; + int x = 0; + for (RecipeMenu menu : recipeMenus) { + super.addItem(new ClickableItem(slots[x], menu.getRecipe().getOutput()[0].getItemStack().clone(), (player, clickType) -> menu.openInventory(player))); + x++; + } + + for (int i : empty) { + super.addItem(new MenuItem(i, new ItemFactory(Material.STAINED_GLASS_PANE, (byte) 8).setName(C.RED).build(), false)); + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuAcid.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuAcid.java new file mode 100644 index 0000000..26ca263 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuAcid.java @@ -0,0 +1,182 @@ +package net.grandtheftmc.vice.machine.recipe.menu.type; + +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import net.grandtheftmc.core.inventory.button.MenuItem; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.vice.machine.recipe.menu.RecipeMenu; +import net.grandtheftmc.vice.machine.recipe.type.RecipeAcid; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; + +public final class RecipeMenuAcid extends RecipeMenu { + + public RecipeMenuAcid() { + super(3, "Recipe : Drying Chamber", new RecipeAcid(), CoreMenuFlag.RESET_CURSOR_ON_OPEN, CoreMenuFlag.CLOSE_ON_NULL_CLICK); + + super.setBlockedSlots(0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26); + super.setOpenSlots(4); + super.setOutputSlots(22); + + super.initRecipeItems(); + + String[] description = { + C.DARK_GRAY + C.ITALIC + " " + super.getTitle(), + "", + "", + C.YELLOW + C.BOLD + "MACHINE RECIPES", + C.GRAY + " Note, recipes consume fuel and durability.", + C.GRAY + " Some more than others.", + "", + " " + i("需", 1) + " 霚 " + i("霂", 6), + "", + " " + i("霢", 1) + " 霚 " + i("霆", 1), + "", + " " + i("霟", 1) + " 霚 " + i("霋", 1), + "", + " " + i("霞", 1) + " 霚 " + i("霋", 1), + "", + " " + i("霁", 1) + " 霚 " + i("霎", 1), + "" + }; + + for (int i : super.getBlockedSlots()) { + super.addItem(new MenuItem(i, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + //Machine Frame + super.addItem(new MenuItem(0, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 79) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + this.initFuelItems(); + this.initDurabilityItems(); + + //Progress Item. + super.addItem(new MenuItem(11, + new ItemFactory(Material.STONE_SWORD) + .setDurability(super.progress) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setEnchantment(Enchantment.DURABILITY, 1) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + private void initFuelItems() { + String[] lore = { + C.GRAY + " Adding burnable items will replenish", + C.GRAY + " your machine fuel counter.", + "", + // fire - oak_plank - 2 + C.RESET + " 霚 " + C.WHITE + "[霡] +" + C.YELLOW + "2" + C.WHITE + " Fuel", + // fire - coal - 8 + C.RESET + " 霚 " + C.WHITE + "[霖] +" + C.GOLD + "8" + C.WHITE + " Fuel", + // fire - coal_block - 160 + C.RESET + " 霚 " + C.WHITE + "[霗] +" + C.RED + "80" + C.WHITE + " Fuel", + // fire - lava - 100 + C.RESET + " 霚 " + C.WHITE + "[霙] +" + C.RED + "100" + C.WHITE + " Fuel", + "" + }; + + //Fuel Item. + super.addItem(new MenuItem(19, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(10, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(1, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + private void initDurabilityItems() { + String[] lore = { + C.GRAY + " Once the durability is gone, you will", + C.GRAY + " need to fix your machine to repair it.", + "" + }; + + //Fuel Item. + super.addItem(new MenuItem(25, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(16, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(7, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuBeer.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuBeer.java new file mode 100644 index 0000000..b64b0bd --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuBeer.java @@ -0,0 +1,176 @@ +package net.grandtheftmc.vice.machine.recipe.menu.type; + +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import net.grandtheftmc.core.inventory.button.MenuItem; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.vice.machine.recipe.menu.RecipeMenu; +import net.grandtheftmc.vice.machine.recipe.type.RecipeBeer; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; + +public final class RecipeMenuBeer extends RecipeMenu { + + public RecipeMenuBeer() { + super(3, "Recipe : Beer Distillery", new RecipeBeer(), CoreMenuFlag.RESET_CURSOR_ON_OPEN, CoreMenuFlag.CLOSE_ON_NULL_CLICK); + + super.setBlockedSlots(0, 1, 2, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26); + super.setOpenSlots(3, 5); + super.setOutputSlots(22); + + super.initRecipeItems(); + + String[] description = { + C.DARK_GRAY + C.ITALIC + " " + super.getTitle(), + "", + "", + C.YELLOW + C.BOLD + "MACHINE RECIPES", + C.GRAY + " Note, recipes consume fuel and durability.", + C.GRAY + " Some more than others.", + "", + " " + i("霕", 5) + i("霃", 1) + " 霚 " + i("霈", 1), + "", + " " + i("霂", 6) + " " + i("霔", 1) + " 霚 " + i("霃", 1), + "" + }; + + for (int i : super.getBlockedSlots()) { + super.addItem(new MenuItem(i, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + //Machine Frame + super.addItem(new MenuItem(0, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 80) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + this.initFuelItems(); + this.initDurabilityItems(); + + //Progress Item. + super.addItem(new MenuItem(11, + new ItemFactory(Material.STONE_SWORD) + .setDurability(super.progress) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setEnchantment(Enchantment.DURABILITY, 1) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + private void initFuelItems() { + String[] lore = { + C.GRAY + " Adding burnable items will replenish", + C.GRAY + " your machine fuel counter.", + "", + // fire - oak_plank - 2 + C.RESET + " 霚 " + C.WHITE + "[霡] +" + C.YELLOW + "2" + C.WHITE + " Fuel", + // fire - coal - 8 + C.RESET + " 霚 " + C.WHITE + "[霖] +" + C.GOLD + "8" + C.WHITE + " Fuel", + // fire - coal_block - 160 + C.RESET + " 霚 " + C.WHITE + "[霗] +" + C.RED + "80" + C.WHITE + " Fuel", + // fire - lava - 100 + C.RESET + " 霚 " + C.WHITE + "[霙] +" + C.RED + "100" + C.WHITE + " Fuel", + "" + }; + + //Fuel Item. + super.addItem(new MenuItem(19, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(10, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(1, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + private void initDurabilityItems() { + String[] lore = { + C.GRAY + " Once the durability is gone, you will", + C.GRAY + " need to fix your machine to repair it.", + "" + }; + + //Fuel Item. + super.addItem(new MenuItem(25, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(16, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(7, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuCocaine.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuCocaine.java new file mode 100644 index 0000000..19bbee9 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuCocaine.java @@ -0,0 +1,176 @@ +package net.grandtheftmc.vice.machine.recipe.menu.type; + +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import net.grandtheftmc.core.inventory.button.MenuItem; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.vice.machine.recipe.menu.RecipeMenu; +import net.grandtheftmc.vice.machine.recipe.type.RecipeCocaine; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; + +public final class RecipeMenuCocaine extends RecipeMenu { + + public RecipeMenuCocaine() { + super(3, "Recipe : Coca Processor", new RecipeCocaine(), CoreMenuFlag.RESET_CURSOR_ON_OPEN, CoreMenuFlag.CLOSE_ON_NULL_CLICK); + + super.setBlockedSlots(0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26); + super.setOpenSlots(4); + super.setOutputSlots(22); + + super.initRecipeItems(); + + String[] description = { + C.DARK_GRAY + C.ITALIC + " " + super.getTitle(), + "", + "", + C.YELLOW + C.BOLD + "MACHINE RECIPES", + C.GRAY + " Note, recipes consume fuel and durability.", + C.GRAY + " Some more than others.", + "", + " " + i("霅", 3) + " 霚 " + i("霓", 1), + "", + " " + i("霓", 1) + " 霚 " + i("霍", 1), + "" + }; + + for (int i : super.getBlockedSlots()) { + super.addItem(new MenuItem(i, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + //Machine Frame + super.addItem(new MenuItem(0, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 79) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + this.initFuelItems(); + this.initDurabilityItems(); + + //Progress Item. + super.addItem(new MenuItem(11, + new ItemFactory(Material.STONE_SWORD) + .setDurability(super.progress) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setEnchantment(Enchantment.DURABILITY, 1) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + private void initFuelItems() { + String[] lore = { + C.GRAY + " Adding burnable items will replenish", + C.GRAY + " your machine fuel counter.", + "", + // fire - oak_plank - 2 + C.RESET + " 霚 " + C.WHITE + "[霡] +" + C.YELLOW + "2" + C.WHITE + " Fuel", + // fire - coal - 8 + C.RESET + " 霚 " + C.WHITE + "[霖] +" + C.GOLD + "8" + C.WHITE + " Fuel", + // fire - coal_block - 160 + C.RESET + " 霚 " + C.WHITE + "[霗] +" + C.RED + "80" + C.WHITE + " Fuel", + // fire - lava - 100 + C.RESET + " 霚 " + C.WHITE + "[霙] +" + C.RED + "100" + C.WHITE + " Fuel", + "" + }; + + //Fuel Item. + super.addItem(new MenuItem(19, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(10, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(1, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + private void initDurabilityItems() { + String[] lore = { + C.GRAY + " Once the durability is gone, you will", + C.GRAY + " need to fix your machine to repair it.", + "" + }; + + //Fuel Item. + super.addItem(new MenuItem(25, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(16, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(7, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuConcentratedMagicMushroom.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuConcentratedMagicMushroom.java new file mode 100644 index 0000000..02938cb --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuConcentratedMagicMushroom.java @@ -0,0 +1,174 @@ +package net.grandtheftmc.vice.machine.recipe.menu.type; + +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import net.grandtheftmc.core.inventory.button.MenuItem; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.vice.machine.recipe.menu.RecipeMenu; +import net.grandtheftmc.vice.machine.recipe.type.RecipeConcentratedMagicMushroom; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; + +public final class RecipeMenuConcentratedMagicMushroom extends RecipeMenu { + + public RecipeMenuConcentratedMagicMushroom() { + super(3, "Recipe : Pulp Condenser", new RecipeConcentratedMagicMushroom(), CoreMenuFlag.RESET_CURSOR_ON_OPEN, CoreMenuFlag.CLOSE_ON_NULL_CLICK); + + super.setBlockedSlots(0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26); + super.setOpenSlots(4); + super.setOutputSlots(22); + + super.initRecipeItems(); + + String[] description = { + C.DARK_GRAY + C.ITALIC + " " + super.getTitle(), + "", + "", + C.YELLOW + C.BOLD + "MACHINE RECIPES", + C.GRAY + " Note, recipes consume fuel and durability.", + C.GRAY + " Some more than others.", + "", + " " + i("霋", 1) + " 霚 " + i("霌", 1), + "" + }; + + for (int i : super.getBlockedSlots()) { + super.addItem(new MenuItem(i, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + //Machine Frame + super.addItem(new MenuItem(0, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 79) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + this.initFuelItems(); + this.initDurabilityItems(); + + //Progress Item. + super.addItem(new MenuItem(11, + new ItemFactory(Material.STONE_SWORD) + .setDurability(super.progress) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setEnchantment(Enchantment.DURABILITY, 1) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + private void initFuelItems() { + String[] lore = { + C.GRAY + " Adding burnable items will replenish", + C.GRAY + " your machine fuel counter.", + "", + // fire - oak_plank - 2 + C.RESET + " 霚 " + C.WHITE + "[霡] +" + C.YELLOW + "2" + C.WHITE + " Fuel", + // fire - coal - 8 + C.RESET + " 霚 " + C.WHITE + "[霖] +" + C.GOLD + "8" + C.WHITE + " Fuel", + // fire - coal_block - 160 + C.RESET + " 霚 " + C.WHITE + "[霗] +" + C.RED + "80" + C.WHITE + " Fuel", + // fire - lava - 100 + C.RESET + " 霚 " + C.WHITE + "[霙] +" + C.RED + "100" + C.WHITE + " Fuel", + "" + }; + + //Fuel Item. + super.addItem(new MenuItem(19, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(10, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(1, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + private void initDurabilityItems() { + String[] lore = { + C.GRAY + " Once the durability is gone, you will", + C.GRAY + " need to fix your machine to repair it.", + "" + }; + + //Fuel Item. + super.addItem(new MenuItem(25, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(16, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(7, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuCrack.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuCrack.java new file mode 100644 index 0000000..9c95c78 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuCrack.java @@ -0,0 +1,176 @@ +package net.grandtheftmc.vice.machine.recipe.menu.type; + +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import net.grandtheftmc.core.inventory.button.MenuItem; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.vice.machine.recipe.menu.RecipeMenu; +import net.grandtheftmc.vice.machine.recipe.type.RecipeCrack; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; + +public final class RecipeMenuCrack extends RecipeMenu { + + public RecipeMenuCrack() { + super(3, "Recipe : Coca Processor", new RecipeCrack(), CoreMenuFlag.RESET_CURSOR_ON_OPEN, CoreMenuFlag.CLOSE_ON_NULL_CLICK); + + super.setBlockedSlots(0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26); + super.setOpenSlots(4); + super.setOutputSlots(22); + + super.initRecipeItems(); + + String[] description = { + C.DARK_GRAY + C.ITALIC + " " + super.getTitle(), + "", + "", + C.YELLOW + C.BOLD + "MACHINE RECIPES", + C.GRAY + " Note, recipes consume fuel and durability.", + C.GRAY + " Some more than others.", + "", + " " + i("霅", 3) + " 霚 " + i("霓", 1), + "", + " " + i("霓", 1) + " 霚 " + i("霍", 1), + "" + }; + + for (int i : super.getBlockedSlots()) { + super.addItem(new MenuItem(i, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + //Machine Frame + super.addItem(new MenuItem(0, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 79) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + this.initFuelItems(); + this.initDurabilityItems(); + + //Progress Item. + super.addItem(new MenuItem(11, + new ItemFactory(Material.STONE_SWORD) + .setDurability(super.progress) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setEnchantment(Enchantment.DURABILITY, 1) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + private void initFuelItems() { + String[] lore = { + C.GRAY + " Adding burnable items will replenish", + C.GRAY + " your machine fuel counter.", + "", + // fire - oak_plank - 2 + C.RESET + " 霚 " + C.WHITE + "[霡] +" + C.YELLOW + "2" + C.WHITE + " Fuel", + // fire - coal - 8 + C.RESET + " 霚 " + C.WHITE + "[霖] +" + C.GOLD + "8" + C.WHITE + " Fuel", + // fire - coal_block - 160 + C.RESET + " 霚 " + C.WHITE + "[霗] +" + C.RED + "80" + C.WHITE + " Fuel", + // fire - lava - 100 + C.RESET + " 霚 " + C.WHITE + "[霙] +" + C.RED + "100" + C.WHITE + " Fuel", + "" + }; + + //Fuel Item. + super.addItem(new MenuItem(19, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(10, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(1, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + private void initDurabilityItems() { + String[] lore = { + C.GRAY + " Once the durability is gone, you will", + C.GRAY + " need to fix your machine to repair it.", + "" + }; + + //Fuel Item. + super.addItem(new MenuItem(25, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(16, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(7, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuCraftBeer.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuCraftBeer.java new file mode 100644 index 0000000..a8ed0ed --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuCraftBeer.java @@ -0,0 +1,176 @@ +package net.grandtheftmc.vice.machine.recipe.menu.type; + +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import net.grandtheftmc.core.inventory.button.MenuItem; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.vice.machine.recipe.menu.RecipeMenu; +import net.grandtheftmc.vice.machine.recipe.type.RecipeCraftBeer; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; + +public final class RecipeMenuCraftBeer extends RecipeMenu { + + public RecipeMenuCraftBeer() { + super(3, "Recipe : Beer Distillery", new RecipeCraftBeer(), CoreMenuFlag.RESET_CURSOR_ON_OPEN, CoreMenuFlag.CLOSE_ON_NULL_CLICK); + + super.setBlockedSlots(0, 1, 2, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26); + super.setOpenSlots(3, 5); + super.setOutputSlots(22); + + super.initRecipeItems(); + + String[] description = { + C.DARK_GRAY + C.ITALIC + " " + super.getTitle(), + "", + "", + C.YELLOW + C.BOLD + "MACHINE RECIPES", + C.GRAY + " Note, recipes consume fuel and durability.", + C.GRAY + " Some more than others.", + "", + " " + i("霕", 5) + i("霃", 1) + " 霚 " + i("霈", 1), + "", + " " + i("霂", 6) + " " + i("霔", 1) + " 霚 " + i("霃", 1), + "" + }; + + for (int i : super.getBlockedSlots()) { + super.addItem(new MenuItem(i, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + //Machine Frame + super.addItem(new MenuItem(0, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 80) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + this.initFuelItems(); + this.initDurabilityItems(); + + //Progress Item. + super.addItem(new MenuItem(11, + new ItemFactory(Material.STONE_SWORD) + .setDurability(super.progress) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setEnchantment(Enchantment.DURABILITY, 1) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + private void initFuelItems() { + String[] lore = { + C.GRAY + " Adding burnable items will replenish", + C.GRAY + " your machine fuel counter.", + "", + // fire - oak_plank - 2 + C.RESET + " 霚 " + C.WHITE + "[霡] +" + C.YELLOW + "2" + C.WHITE + " Fuel", + // fire - coal - 8 + C.RESET + " 霚 " + C.WHITE + "[霖] +" + C.GOLD + "8" + C.WHITE + " Fuel", + // fire - coal_block - 160 + C.RESET + " 霚 " + C.WHITE + "[霗] +" + C.RED + "80" + C.WHITE + " Fuel", + // fire - lava - 100 + C.RESET + " 霚 " + C.WHITE + "[霙] +" + C.RED + "100" + C.WHITE + " Fuel", + "" + }; + + //Fuel Item. + super.addItem(new MenuItem(19, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(10, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(1, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + private void initDurabilityItems() { + String[] lore = { + C.GRAY + " Once the durability is gone, you will", + C.GRAY + " need to fix your machine to repair it.", + "" + }; + + //Fuel Item. + super.addItem(new MenuItem(25, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(16, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(7, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuDistilledVodka.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuDistilledVodka.java new file mode 100644 index 0000000..eb4a647 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuDistilledVodka.java @@ -0,0 +1,176 @@ +package net.grandtheftmc.vice.machine.recipe.menu.type; + +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import net.grandtheftmc.core.inventory.button.MenuItem; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.vice.machine.recipe.menu.RecipeMenu; +import net.grandtheftmc.vice.machine.recipe.type.RecipeDistilledVodka; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; + +public final class RecipeMenuDistilledVodka extends RecipeMenu { + + public RecipeMenuDistilledVodka() { + super(3, "Recipe : Vodka Distillery", new RecipeDistilledVodka(), CoreMenuFlag.RESET_CURSOR_ON_OPEN, CoreMenuFlag.CLOSE_ON_NULL_CLICK); + + super.setBlockedSlots(0, 1, 2, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26); + super.setOpenSlots(3, 5); + super.setOutputSlots(22); + + super.initRecipeItems(); + + String[] description = { + C.DARK_GRAY + C.ITALIC + " " + super.getTitle(), + "", + "", + C.YELLOW + C.BOLD + "MACHINE RECIPES", + C.GRAY + " Note, recipes consume fuel and durability.", + C.GRAY + " Some more than others.", + "", + " " + i("霜", 6) + i("霔", 1) + " 霚 " + i("霉", 1), + "", + " " + i("霛", 3) + i("霉", 1) + " 霚 " + i("霝", 1), + "" + }; + + for (int i : super.getBlockedSlots()) { + super.addItem(new MenuItem(i, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + //Machine Frame + super.addItem(new MenuItem(0, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 80) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + this.initFuelItems(); + this.initDurabilityItems(); + + //Progress Item. + super.addItem(new MenuItem(11, + new ItemFactory(Material.STONE_SWORD) + .setDurability(super.progress) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setEnchantment(Enchantment.DURABILITY, 1) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + public void initFuelItems() { + String[] lore = { + C.GRAY + " Adding burnable items will replenish", + C.GRAY + " your machine fuel counter.", + "", + // fire - oak_plank - 2 + C.RESET + " 霚 " + C.WHITE + "[霡] +" + C.YELLOW + "2" + C.WHITE + " Fuel", + // fire - coal - 8 + C.RESET + " 霚 " + C.WHITE + "[霖] +" + C.GOLD + "8" + C.WHITE + " Fuel", + // fire - coal_block - 160 + C.RESET + " 霚 " + C.WHITE + "[霗] +" + C.RED + "80" + C.WHITE + " Fuel", + // fire - lava - 100 + C.RESET + " 霚 " + C.WHITE + "[霙] +" + C.RED + "100" + C.WHITE + " Fuel", + "" + }; + + //Fuel Item. + super.addItem(new MenuItem(19, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(10, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(1, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + public void initDurabilityItems() { + String[] lore = { + C.GRAY + " Once the durability is gone, you will", + C.GRAY + " need to fix your machine to repair it.", + "" + }; + + //Fuel Item. + super.addItem(new MenuItem(25, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(16, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(7, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuDriedMushroom.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuDriedMushroom.java new file mode 100644 index 0000000..cd120be --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuDriedMushroom.java @@ -0,0 +1,182 @@ +package net.grandtheftmc.vice.machine.recipe.menu.type; + +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import net.grandtheftmc.core.inventory.button.MenuItem; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.vice.machine.recipe.menu.RecipeMenu; +import net.grandtheftmc.vice.machine.recipe.type.RecipeDriedMushroomBrown; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; + +public final class RecipeMenuDriedMushroom extends RecipeMenu { + + public RecipeMenuDriedMushroom() { + super(3, "Recipe : Drying Chamber", new RecipeDriedMushroomBrown(), CoreMenuFlag.RESET_CURSOR_ON_OPEN, CoreMenuFlag.CLOSE_ON_NULL_CLICK); + + super.setBlockedSlots(0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26); + super.setOpenSlots(4); + super.setOutputSlots(22); + + super.initRecipeItems(); + + String[] description = { + C.DARK_GRAY + C.ITALIC + " " + super.getTitle(), + "", + "", + C.YELLOW + C.BOLD + "MACHINE RECIPES", + C.GRAY + " Note, recipes consume fuel and durability.", + C.GRAY + " Some more than others.", + "", + " " + i("需", 1) + " 霚 " + i("霂", 6), + "", + " " + i("霢", 1) + " 霚 " + i("霆", 1), + "", + " " + i("霟", 1) + " 霚 " + i("霋", 1), + "", + " " + i("霞", 1) + " 霚 " + i("霋", 1), + "", + " " + i("霁", 1) + " 霚 " + i("霎", 1), + "" + }; + + for (int i : super.getBlockedSlots()) { + super.addItem(new MenuItem(i, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + //Machine Frame + super.addItem(new MenuItem(0, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 79) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + this.initFuelItems(); + this.initDurabilityItems(); + + //Progress Item. + super.addItem(new MenuItem(11, + new ItemFactory(Material.STONE_SWORD) + .setDurability(super.progress) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setEnchantment(Enchantment.DURABILITY, 1) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + private void initFuelItems() { + String[] lore = { + C.GRAY + " Adding burnable items will replenish", + C.GRAY + " your machine fuel counter.", + "", + // fire - oak_plank - 2 + C.RESET + " 霚 " + C.WHITE + "[霡] +" + C.YELLOW + "2" + C.WHITE + " Fuel", + // fire - coal - 8 + C.RESET + " 霚 " + C.WHITE + "[霖] +" + C.GOLD + "8" + C.WHITE + " Fuel", + // fire - coal_block - 160 + C.RESET + " 霚 " + C.WHITE + "[霗] +" + C.RED + "80" + C.WHITE + " Fuel", + // fire - lava - 100 + C.RESET + " 霚 " + C.WHITE + "[霙] +" + C.RED + "100" + C.WHITE + " Fuel", + "" + }; + + //Fuel Item. + super.addItem(new MenuItem(19, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(10, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(1, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + private void initDurabilityItems() { + String[] lore = { + C.GRAY + " Once the durability is gone, you will", + C.GRAY + " need to fix your machine to repair it.", + "" + }; + + //Fuel Item. + super.addItem(new MenuItem(25, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(16, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(7, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuHumulusLapulusFruit.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuHumulusLapulusFruit.java new file mode 100644 index 0000000..ba72d28 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuHumulusLapulusFruit.java @@ -0,0 +1,182 @@ +package net.grandtheftmc.vice.machine.recipe.menu.type; + +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import net.grandtheftmc.core.inventory.button.MenuItem; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.vice.machine.recipe.menu.RecipeMenu; +import net.grandtheftmc.vice.machine.recipe.type.RecipeHumulusLupulusFruit; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; + +public final class RecipeMenuHumulusLapulusFruit extends RecipeMenu { + + public RecipeMenuHumulusLapulusFruit() { + super(3, "Recipe : Drying Chamber", new RecipeHumulusLupulusFruit(), CoreMenuFlag.RESET_CURSOR_ON_OPEN, CoreMenuFlag.CLOSE_ON_NULL_CLICK); + + super.setBlockedSlots(0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26); + super.setOpenSlots(4); + super.setOutputSlots(22); + + super.initRecipeItems(); + + String[] description = { + C.DARK_GRAY + C.ITALIC + " " + super.getTitle(), + "", + "", + C.YELLOW + C.BOLD + "MACHINE RECIPES", + C.GRAY + " Note, recipes consume fuel and durability.", + C.GRAY + " Some more than others.", + "", + " " + i("需", 1) + " 霚 " + i("霂", 6), + "", + " " + i("霢", 1) + " 霚 " + i("霆", 1), + "", + " " + i("霟", 1) + " 霚 " + i("霋", 1), + "", + " " + i("霞", 1) + " 霚 " + i("霋", 1), + "", + " " + i("霁", 1) + " 霚 " + i("霎", 1), + "" + }; + + for (int i : super.getBlockedSlots()) { + super.addItem(new MenuItem(i, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + //Machine Frame + super.addItem(new MenuItem(0, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 79) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + this.initFuelItems(); + this.initDurabilityItems(); + + //Progress Item. + super.addItem(new MenuItem(11, + new ItemFactory(Material.STONE_SWORD) + .setDurability(super.progress) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setEnchantment(Enchantment.DURABILITY, 1) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + private void initFuelItems() { + String[] lore = { + C.GRAY + " Adding burnable items will replenish", + C.GRAY + " your machine fuel counter.", + "", + // fire - oak_plank - 2 + C.RESET + " 霚 " + C.WHITE + "[霡] +" + C.YELLOW + "2" + C.WHITE + " Fuel", + // fire - coal - 8 + C.RESET + " 霚 " + C.WHITE + "[霖] +" + C.GOLD + "8" + C.WHITE + " Fuel", + // fire - coal_block - 160 + C.RESET + " 霚 " + C.WHITE + "[霗] +" + C.RED + "80" + C.WHITE + " Fuel", + // fire - lava - 100 + C.RESET + " 霚 " + C.WHITE + "[霙] +" + C.RED + "100" + C.WHITE + " Fuel", + "" + }; + + //Fuel Item. + super.addItem(new MenuItem(19, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(10, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(1, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + private void initDurabilityItems() { + String[] lore = { + C.GRAY + " Once the durability is gone, you will", + C.GRAY + " need to fix your machine to repair it.", + "" + }; + + //Fuel Item. + super.addItem(new MenuItem(25, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(16, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(7, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuLSD.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuLSD.java new file mode 100644 index 0000000..a2233ef --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuLSD.java @@ -0,0 +1,174 @@ +package net.grandtheftmc.vice.machine.recipe.menu.type; + +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import net.grandtheftmc.core.inventory.button.MenuItem; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.vice.machine.recipe.menu.RecipeMenu; +import net.grandtheftmc.vice.machine.recipe.type.RecipeLSD; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; + +public final class RecipeMenuLSD extends RecipeMenu { + + public RecipeMenuLSD() { + super(3, "Recipe : Sugar Box", new RecipeLSD(), CoreMenuFlag.RESET_CURSOR_ON_OPEN, CoreMenuFlag.CLOSE_ON_NULL_CLICK); + + super.setBlockedSlots(0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26); + super.setOpenSlots(4); + super.setOutputSlots(22); + + super.initRecipeItems(); + + String[] description = { + C.DARK_GRAY + C.ITALIC + " " + super.getTitle(), + "", + "", + C.YELLOW + C.BOLD + "MACHINE RECIPES", + C.GRAY + " Note, recipes consume fuel and durability.", + C.GRAY + " Some more than others.", + "", + " " + i("霎", 1) + " 霚 " + i("霏", 1), + "" + }; + + for (int i : super.getBlockedSlots()) { + super.addItem(new MenuItem(i, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + //Machine Frame + super.addItem(new MenuItem(0, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 79) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + this.initFuelItems(); + this.initDurabilityItems(); + + //Progress Item. + super.addItem(new MenuItem(11, + new ItemFactory(Material.STONE_SWORD) + .setDurability(super.progress) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setEnchantment(Enchantment.DURABILITY, 1) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + private void initFuelItems() { + String[] lore = { + C.GRAY + " Adding burnable items will replenish", + C.GRAY + " your machine fuel counter.", + "", + // fire - oak_plank - 2 + C.RESET + " 霚 " + C.WHITE + "[霡] +" + C.YELLOW + "2" + C.WHITE + " Fuel", + // fire - coal - 8 + C.RESET + " 霚 " + C.WHITE + "[霖] +" + C.GOLD + "8" + C.WHITE + " Fuel", + // fire - coal_block - 160 + C.RESET + " 霚 " + C.WHITE + "[霗] +" + C.RED + "80" + C.WHITE + " Fuel", + // fire - lava - 100 + C.RESET + " 霚 " + C.WHITE + "[霙] +" + C.RED + "100" + C.WHITE + " Fuel", + "" + }; + + //Fuel Item. + super.addItem(new MenuItem(19, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(10, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(1, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + private void initDurabilityItems() { + String[] lore = { + C.GRAY + " Once the durability is gone, you will", + C.GRAY + " need to fix your machine to repair it.", + "" + }; + + //Fuel Item. + super.addItem(new MenuItem(25, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(16, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(7, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuPureMeth.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuPureMeth.java new file mode 100644 index 0000000..26898ef --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuPureMeth.java @@ -0,0 +1,176 @@ +package net.grandtheftmc.vice.machine.recipe.menu.type; + +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import net.grandtheftmc.core.inventory.button.MenuItem; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.vice.machine.recipe.menu.RecipeMenu; +import net.grandtheftmc.vice.machine.recipe.type.RecipePureMeth; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; + +public final class RecipeMenuPureMeth extends RecipeMenu { + + public RecipeMenuPureMeth() { + super(3, "Recipe : Meth Producer", new RecipePureMeth(), CoreMenuFlag.RESET_CURSOR_ON_OPEN, CoreMenuFlag.CLOSE_ON_NULL_CLICK); + + super.setBlockedSlots(0, 1, 2, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26); + super.setOpenSlots(3, 5); + super.setOutputSlots(22); + + super.initRecipeItems(); + + String[] description = { + C.DARK_GRAY + C.ITALIC + " " + super.getTitle(), + "", + "", + C.YELLOW + C.BOLD + "MACHINE RECIPES", + C.GRAY + " Note, recipes consume fuel and durability.", + C.GRAY + " Some more than others.", + "", + " " + i("霑", 1) + i("霠", 64) + " 霚 " + i("霒", 4), + "" + }; + + for (int i : super.getBlockedSlots()) { + super.addItem(new MenuItem(i, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + //Machine Frame + super.addItem(new MenuItem(0, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 80) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + this.initFuelItems(); + this.initDurabilityItems(); + + //Progress Item. + super.addItem(new MenuItem(11, + new ItemFactory(Material.STONE_SWORD) + .setDurability(super.progress) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setEnchantment(Enchantment.DURABILITY, 1) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + private void initFuelItems() { + String[] lore = { + C.GRAY + " Adding burnable items will replenish", + C.GRAY + " your machine fuel counter.", + "", + // fire - oak_plank - 2 + C.RESET + " 霚 " + C.WHITE + "[霡] +" + C.YELLOW + "2" + C.WHITE + " Fuel", + // fire - coal - 8 + C.RESET + " 霚 " + C.WHITE + "[霖] +" + C.GOLD + "8" + C.WHITE + " Fuel", + // fire - coal_block - 160 + C.RESET + " 霚 " + C.WHITE + "[霗] +" + C.RED + "80" + C.WHITE + " Fuel", + // fire - lava - 100 + C.RESET + " 霚 " + C.WHITE + "[霙] +" + C.RED + "100" + C.WHITE + " Fuel", + "", + C.GRAY + " Use the command " + C.WHITE + "/recipe" + C.GRAY + " for", + C.GRAY + " a visual tutorial on drug recipes." + }; + + //Fuel Item. + super.addItem(new MenuItem(19, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(10, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(1, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + private void initDurabilityItems() { + String[] lore = { + C.GRAY + " Once the durability is gone, you will", + C.GRAY + " need to fix your machine to repair it.", + "" + }; + + //Fuel Item. + super.addItem(new MenuItem(25, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(16, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(7, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuVodka.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuVodka.java new file mode 100644 index 0000000..310aab1 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuVodka.java @@ -0,0 +1,176 @@ +package net.grandtheftmc.vice.machine.recipe.menu.type; + +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import net.grandtheftmc.core.inventory.button.MenuItem; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.vice.machine.recipe.menu.RecipeMenu; +import net.grandtheftmc.vice.machine.recipe.type.RecipeVodka; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; + +public final class RecipeMenuVodka extends RecipeMenu { + + public RecipeMenuVodka() { + super(3, "Recipe : Vodka Distillery", new RecipeVodka(), CoreMenuFlag.RESET_CURSOR_ON_OPEN, CoreMenuFlag.CLOSE_ON_NULL_CLICK); + + super.setBlockedSlots(0, 1, 2, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26); + super.setOpenSlots(3, 5); + super.setOutputSlots(22); + + super.initRecipeItems(); + + String[] description = { + C.DARK_GRAY + C.ITALIC + " " + super.getTitle(), + "", + "", + C.YELLOW + C.BOLD + "MACHINE RECIPES", + C.GRAY + " Note, recipes consume fuel and durability.", + C.GRAY + " Some more than others.", + "", + " " + i("霜", 6) + i("霔", 1) + " 霚 " + i("霉", 1), + "", + " " + i("霛", 3) + i("霉", 1) + " 霚 " + i("霝", 1), + "" + }; + + for (int i : super.getBlockedSlots()) { + super.addItem(new MenuItem(i, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + //Machine Frame + super.addItem(new MenuItem(0, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 80) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + this.initFuelItems(); + this.initDurabilityItems(); + + //Progress Item. + super.addItem(new MenuItem(11, + new ItemFactory(Material.STONE_SWORD) + .setDurability(super.progress) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setEnchantment(Enchantment.DURABILITY, 1) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + public void initFuelItems() { + String[] lore = { + C.GRAY + " Adding burnable items will replenish", + C.GRAY + " your machine fuel counter.", + "", + // fire - oak_plank - 2 + C.RESET + " 霚 " + C.WHITE + "[霡] +" + C.YELLOW + "2" + C.WHITE + " Fuel", + // fire - coal - 8 + C.RESET + " 霚 " + C.WHITE + "[霖] +" + C.GOLD + "8" + C.WHITE + " Fuel", + // fire - coal_block - 160 + C.RESET + " 霚 " + C.WHITE + "[霗] +" + C.RED + "80" + C.WHITE + " Fuel", + // fire - lava - 100 + C.RESET + " 霚 " + C.WHITE + "[霙] +" + C.RED + "100" + C.WHITE + " Fuel", + "" + }; + + //Fuel Item. + super.addItem(new MenuItem(19, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(10, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(1, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + public void initDurabilityItems() { + String[] lore = { + C.GRAY + " Once the durability is gone, you will", + C.GRAY + " need to fix your machine to repair it.", + "" + }; + + //Fuel Item. + super.addItem(new MenuItem(25, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(16, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(7, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuWeed.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuWeed.java new file mode 100644 index 0000000..0671e98 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuWeed.java @@ -0,0 +1,182 @@ +package net.grandtheftmc.vice.machine.recipe.menu.type; + +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import net.grandtheftmc.core.inventory.button.MenuItem; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.vice.machine.recipe.menu.RecipeMenu; +import net.grandtheftmc.vice.machine.recipe.type.RecipeWeed; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; + +public final class RecipeMenuWeed extends RecipeMenu { + + public RecipeMenuWeed() { + super(3, "Recipe : Drying Chamber", new RecipeWeed(), CoreMenuFlag.RESET_CURSOR_ON_OPEN, CoreMenuFlag.CLOSE_ON_NULL_CLICK); + + super.setBlockedSlots(0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26); + super.setOpenSlots(4); + super.setOutputSlots(22); + + super.initRecipeItems(); + + String[] description = { + C.DARK_GRAY + C.ITALIC + " " + super.getTitle(), + "", + "", + C.YELLOW + C.BOLD + "MACHINE RECIPES", + C.GRAY + " Note, recipes consume fuel and durability.", + C.GRAY + " Some more than others.", + "", + " " + i("需", 1) + " 霚 " + i("霂", 6), + "", + " " + i("霢", 1) + " 霚 " + i("霆", 1), + "", + " " + i("霟", 1) + " 霚 " + i("霋", 1), + "", + " " + i("霞", 1) + " 霚 " + i("霋", 1), + "", + " " + i("霁", 1) + " 霚 " + i("霎", 1), + "" + }; + + for (int i : super.getBlockedSlots()) { + super.addItem(new MenuItem(i, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + //Machine Frame + super.addItem(new MenuItem(0, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 79) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + this.initFuelItems(); + this.initDurabilityItems(); + + //Progress Item. + super.addItem(new MenuItem(11, + new ItemFactory(Material.STONE_SWORD) + .setDurability(super.progress) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setEnchantment(Enchantment.DURABILITY, 1) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + private void initFuelItems() { + String[] lore = { + C.GRAY + " Adding burnable items will replenish", + C.GRAY + " your machine fuel counter.", + "", + // fire - oak_plank - 2 + C.RESET + " 霚 " + C.WHITE + "[霡] +" + C.YELLOW + "2" + C.WHITE + " Fuel", + // fire - coal - 8 + C.RESET + " 霚 " + C.WHITE + "[霖] +" + C.GOLD + "8" + C.WHITE + " Fuel", + // fire - coal_block - 160 + C.RESET + " 霚 " + C.WHITE + "[霗] +" + C.RED + "80" + C.WHITE + " Fuel", + // fire - lava - 100 + C.RESET + " 霚 " + C.WHITE + "[霙] +" + C.RED + "100" + C.WHITE + " Fuel", + "" + }; + + //Fuel Item. + super.addItem(new MenuItem(19, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(10, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(1, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + private void initDurabilityItems() { + String[] lore = { + C.GRAY + " Once the durability is gone, you will", + C.GRAY + " need to fix your machine to repair it.", + "" + }; + + //Fuel Item. + super.addItem(new MenuItem(25, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(16, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(7, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuWhiteMeth.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuWhiteMeth.java new file mode 100644 index 0000000..1e80b98 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/menu/type/RecipeMenuWhiteMeth.java @@ -0,0 +1,174 @@ +package net.grandtheftmc.vice.machine.recipe.menu.type; + +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import net.grandtheftmc.core.inventory.button.MenuItem; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.vice.machine.recipe.menu.RecipeMenu; +import net.grandtheftmc.vice.machine.recipe.type.RecipeWhiteMeth; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; + +public final class RecipeMenuWhiteMeth extends RecipeMenu { + + public RecipeMenuWhiteMeth() { + super(3, "Recipe : Meth Producer", new RecipeWhiteMeth(), CoreMenuFlag.RESET_CURSOR_ON_OPEN, CoreMenuFlag.CLOSE_ON_NULL_CLICK); + + super.setBlockedSlots(0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26); + super.setOpenSlots(4); + super.setOutputSlots(22); + + super.initRecipeItems(); + + String[] description = { + C.DARK_GRAY + C.ITALIC + " " + super.getTitle(), + "", + "", + C.YELLOW + C.BOLD + "MACHINE RECIPES", + C.GRAY + " Note, recipes consume fuel and durability.", + C.GRAY + " Some more than others.", + "", + " " + i("霠", 5) + " 霚 " + i("霐", 1), + "" + }; + + for (int i : super.getBlockedSlots()) { + super.addItem(new MenuItem(i, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + //Machine Frame + super.addItem(new MenuItem(0, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 79) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + this.initFuelItems(); + this.initDurabilityItems(); + + //Progress Item. + super.addItem(new MenuItem(11, + new ItemFactory(Material.STONE_SWORD) + .setDurability(super.progress) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setEnchantment(Enchantment.DURABILITY, 1) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + private void initFuelItems() { + String[] lore = { + C.GRAY + " Adding burnable items will replenish", + C.GRAY + " your machine fuel counter.", + "", + // fire - oak_plank - 2 + C.RESET + " 霚 " + C.WHITE + "[霡] +" + C.YELLOW + "2" + C.WHITE + " Fuel", + // fire - coal - 8 + C.RESET + " 霚 " + C.WHITE + "[霖] +" + C.GOLD + "8" + C.WHITE + " Fuel", + // fire - coal_block - 160 + C.RESET + " 霚 " + C.WHITE + "[霗] +" + C.RED + "80" + C.WHITE + " Fuel", + // fire - lava - 100 + C.RESET + " 霚 " + C.WHITE + "[霙] +" + C.RED + "100" + C.WHITE + " Fuel", + "" + }; + + //Fuel Item. + super.addItem(new MenuItem(19, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(10, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(1, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } + + private void initDurabilityItems() { + String[] lore = { + C.GRAY + " Once the durability is gone, you will", + C.GRAY + " need to fix your machine to repair it.", + "" + }; + + //Fuel Item. + super.addItem(new MenuItem(25, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(16, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + + //Fuel Dummy Item. + super.addItem(new MenuItem(7, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build(), + false + )); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/misc/MachineRecipeData.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/misc/MachineRecipeData.java new file mode 100644 index 0000000..4c54728 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/misc/MachineRecipeData.java @@ -0,0 +1,63 @@ +package net.grandtheftmc.vice.machine.recipe.misc; + +import net.grandtheftmc.vice.machine.BaseMachine; +import net.grandtheftmc.vice.machine.data.MachineData; +import net.grandtheftmc.vice.machine.data.MachineDataType; +import net.grandtheftmc.vice.machine.event.MachineRecipeCompleteEvent; +import net.grandtheftmc.vice.machine.recipe.MachineRecipe; +import org.bukkit.Bukkit; + +public final class MachineRecipeData { + + private final BaseMachine machine; + private final MachineRecipe recipe; + private final MachineData data; + + private long next = -1; + + public MachineRecipeData(BaseMachine machine, MachineRecipe recipe) { + this.machine = machine; + this.recipe = recipe; + this.data = machine.getData(MachineDataType.PROGRESS); + } + + public MachineRecipe getRecipe() { + return this.recipe; + } + + public boolean next() { +// double progress = this.getProgress(); +// double max = this.getMaxProgress(); +// +// if (progress >= max) { +// this.data.setCurrent(0); +// } +// +// if (progress + amount >= max) { +// this.data.setCurrent(max); +// +// MachineRecipeCompleteEvent event = new MachineRecipeCompleteEvent(this.machine, this); +// Bukkit.getPluginManager().callEvent(event); +// return; +// } +// +// this.data.add(amount); + + if (this.next < 0) { + this.next = System.currentTimeMillis() + ((this.recipe.getTime() * 1000) / (int) this.data.getMax()); + } + + if (System.currentTimeMillis() > this.next) { + this.data.add(1); + this.next = System.currentTimeMillis() + ((this.recipe.getTime() * 1000) / (int) this.data.getMax()); + + if (this.data.getCurrent() == this.data.getMax()) { + MachineRecipeCompleteEvent event = new MachineRecipeCompleteEvent(this.machine, this); + Bukkit.getPluginManager().callEvent(event); + } + return true; + } + + return false; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/misc/RecipeInput.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/misc/RecipeInput.java new file mode 100644 index 0000000..1b67afc --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/misc/RecipeInput.java @@ -0,0 +1,22 @@ +package net.grandtheftmc.vice.machine.recipe.misc; + +import org.bukkit.inventory.ItemStack; + +public final class RecipeInput { + + private final ItemStack itemStack; + private final int amount; + + public RecipeInput(ItemStack itemStack, int amount) { + this.itemStack = itemStack; + this.amount = amount; + } + + public ItemStack getItemStack() { + return itemStack; + } + + public int getAmount() { + return amount; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/misc/RecipeOutput.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/misc/RecipeOutput.java new file mode 100644 index 0000000..c06f2fd --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/misc/RecipeOutput.java @@ -0,0 +1,22 @@ +package net.grandtheftmc.vice.machine.recipe.misc; + +import org.bukkit.inventory.ItemStack; + +public final class RecipeOutput { + + private final ItemStack itemStack; + private final int amount; + + public RecipeOutput(ItemStack itemStack, int amount) { + this.itemStack = itemStack; + this.amount = amount; + } + + public ItemStack getItemStack() { + return itemStack; + } + + public int getAmount() { + return amount; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeAcid.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeAcid.java new file mode 100644 index 0000000..72b0a8e --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeAcid.java @@ -0,0 +1,29 @@ +package net.grandtheftmc.vice.machine.recipe.type; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.machine.recipe.MachineRecipe; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeInput; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeOutput; + +public final class RecipeAcid extends MachineRecipe { + + /** + * Construct a new Machine Recipe. + */ + public RecipeAcid() { + super( + 11, + new RecipeInput[] { + new RecipeInput(Vice.getItemManager().getItem("ergotfungi").getItem(), 1) + }, + new RecipeOutput[] { + new RecipeOutput(Vice.getItemManager().getItem("acid").getItem(), 1) + }, + 2, + 100, + 10 + ); + + super.setRecipeText(_("霁", 1) + " 霚 " + _("霎", 1)); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeBeer.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeBeer.java new file mode 100644 index 0000000..8b144ac --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeBeer.java @@ -0,0 +1,32 @@ +package net.grandtheftmc.vice.machine.recipe.type; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.machine.recipe.MachineRecipe; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeInput; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeOutput; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +public final class RecipeBeer extends MachineRecipe { + + /** + * Construct a new Machine Recipe. + */ + public RecipeBeer() { + super( + 2, + new RecipeInput[] { + new RecipeInput(Vice.getItemManager().getItem("hop").getItem(), 6), + new RecipeInput(new ItemStack(Material.GLASS_BOTTLE), 1) + }, + new RecipeOutput[] { + new RecipeOutput(Vice.getItemManager().getItem("alcohol").getItem(), 1) + }, + 2, + 100, + 15 + ); + + super.setRecipeText(_("霂", 6) + " " + _("霔", 1) + " 霚 " + _("霃", 1)); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeCocaine.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeCocaine.java new file mode 100644 index 0000000..0af557e --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeCocaine.java @@ -0,0 +1,29 @@ +package net.grandtheftmc.vice.machine.recipe.type; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.machine.recipe.MachineRecipe; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeInput; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeOutput; + +public final class RecipeCocaine extends MachineRecipe { + + /** + * Construct a new Machine Recipe. + */ + public RecipeCocaine() { + super( + 12, + new RecipeInput[] { + new RecipeInput(Vice.getItemManager().getItem("crack").getItem(), 1) + }, + new RecipeOutput[] { + new RecipeOutput(Vice.getItemManager().getItem("cocaine").getItem(), 1) + }, + 2, + 100, + 10 + ); + + super.setRecipeText(_("霓", 1) + " 霚 " + _("霍", 1)); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeConcentratedMagicMushroom.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeConcentratedMagicMushroom.java new file mode 100644 index 0000000..2d7d1df --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeConcentratedMagicMushroom.java @@ -0,0 +1,34 @@ +package net.grandtheftmc.vice.machine.recipe.type; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.machine.recipe.MachineRecipe; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeInput; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeOutput; + +public final class RecipeConcentratedMagicMushroom extends MachineRecipe { + + /* + Concentrated Magic Mushroom + Dried Magic Mushroom -> Process -> Concentrated Magic Mushroom + */ + + /** + * Construct a new Machine Recipe. + */ + public RecipeConcentratedMagicMushroom() { + super( + 10, + new RecipeInput[] { + new RecipeInput(Vice.getItemManager().getItem("driedmagicmushroom").getItem(), 1) + }, + new RecipeOutput[] { + new RecipeOutput(Vice.getItemManager().getItem("concentratedmagicmushroom").getItem(), 1) + }, + 2, + 100, + 10 + ); + + super.setRecipeText(_("霋", 1) + " 霚 " + _("霌", 1)); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeCrack.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeCrack.java new file mode 100644 index 0000000..5503efd --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeCrack.java @@ -0,0 +1,37 @@ +package net.grandtheftmc.vice.machine.recipe.type; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.machine.recipe.MachineRecipe; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeInput; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeOutput; + +public final class RecipeCrack extends MachineRecipe { + + /* + Crack + Get Coca Seed + Plant Coca Seed -> Coca Plant Grows + Destroy Melon -> 2 Coca Leaf + Coca Leaf -> Process -> Crack + */ + + /** + * Construct a new Machine Recipe. + */ + public RecipeCrack() { + super( + 9, + new RecipeInput[] { + new RecipeInput(Vice.getItemManager().getItem("cocaleaf").getItem(), 3) + }, + new RecipeOutput[] { + new RecipeOutput(Vice.getItemManager().getItem("crack").getItem(), 1) + }, + 2, + 100, + 10 + ); + + super.setRecipeText(_("霅", 3) + " 霚 " + _("霓", 1)); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeCraftBeer.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeCraftBeer.java new file mode 100644 index 0000000..cd8b775 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeCraftBeer.java @@ -0,0 +1,32 @@ +package net.grandtheftmc.vice.machine.recipe.type; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.machine.recipe.MachineRecipe; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeInput; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeOutput; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +public final class RecipeCraftBeer extends MachineRecipe { + + /** + * Construct a new Machine Recipe. + */ + public RecipeCraftBeer() { + super( + 7, + new RecipeInput[] { + new RecipeInput(new ItemStack(Material.INK_SACK), 5), + new RecipeInput(Vice.getItemManager().getItem("alcohol").getItem(), 1) + }, + new RecipeOutput[] { + new RecipeOutput(Vice.getItemManager().getItem("craftbeer").getItem(), 1) + }, + 2, + 100, + 10 + ); + + super.setRecipeText(_("霕", 5) + _("霃", 1) + " 霚 " + _("霈", 1)); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeDistilledVodka.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeDistilledVodka.java new file mode 100644 index 0000000..a537e50 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeDistilledVodka.java @@ -0,0 +1,32 @@ +package net.grandtheftmc.vice.machine.recipe.type; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.machine.recipe.MachineRecipe; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeInput; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeOutput; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +public final class RecipeDistilledVodka extends MachineRecipe { + + /** + * Construct a new Machine Recipe. + */ + public RecipeDistilledVodka() { + super( + 8, + new RecipeInput[] { + new RecipeInput(new ItemStack(Material.GOLD_NUGGET), 3), + new RecipeInput(Vice.getItemManager().getItem("vodka").getItem(), 1) + }, + new RecipeOutput[] { + new RecipeOutput(Vice.getItemManager().getItem("distilledvodka").getItem(), 1) + }, + 2, + 100, + 10 + ); + + super.setRecipeText(_("霛", 3) + _("霉", 1) + " 霚 " + _("霝", 1)); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeDriedMushroomBrown.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeDriedMushroomBrown.java new file mode 100644 index 0000000..489c47e --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeDriedMushroomBrown.java @@ -0,0 +1,29 @@ +package net.grandtheftmc.vice.machine.recipe.type; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.machine.recipe.MachineRecipe; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeInput; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeOutput; + +public final class RecipeDriedMushroomBrown extends MachineRecipe { + + /** + * Construct a new Machine Recipe. + */ + public RecipeDriedMushroomBrown() { + super( + 5, + new RecipeInput[] { + new RecipeInput(Vice.getItemManager().getItem("magicmushroombrown").getItem(), 1) + }, + new RecipeOutput[] { + new RecipeOutput(Vice.getItemManager().getItem("driedmagicmushroom").getItem(), 1) + }, + 2, + 100, + 10 + ); + + super.setRecipeText(_("霞", 1) + " 霚 " + _("霋", 1)); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeDriedMushroomRed.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeDriedMushroomRed.java new file mode 100644 index 0000000..007bea5 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeDriedMushroomRed.java @@ -0,0 +1,29 @@ +package net.grandtheftmc.vice.machine.recipe.type; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.machine.recipe.MachineRecipe; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeInput; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeOutput; + +public final class RecipeDriedMushroomRed extends MachineRecipe { + + /** + * Construct a new Machine Recipe. + */ + public RecipeDriedMushroomRed() { + super( + 4, + new RecipeInput[] { + new RecipeInput(Vice.getItemManager().getItem("magicmushroomred").getItem(), 1) + }, + new RecipeOutput[] { + new RecipeOutput(Vice.getItemManager().getItem("driedmagicmushroom").getItem(), 1) + }, + 2, + 100, + 10 + ); + + super.setRecipeText(_("霟", 1) + " 霚 " + _("霋", 1)); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeHumulusLupulusFruit.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeHumulusLupulusFruit.java new file mode 100644 index 0000000..443e736 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeHumulusLupulusFruit.java @@ -0,0 +1,29 @@ +package net.grandtheftmc.vice.machine.recipe.type; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.machine.recipe.MachineRecipe; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeInput; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeOutput; + +public final class RecipeHumulusLupulusFruit extends MachineRecipe { + + /** + * Construct a new Machine Recipe. + */ + public RecipeHumulusLupulusFruit() { + super( + 1, + new RecipeInput[] { + new RecipeInput(Vice.getItemManager().getItem("humuluslupulusfruit").getItem(), 1) + }, + new RecipeOutput[] { + new RecipeOutput(Vice.getItemManager().getItem("hop").getItem(), 6) + }, + 2, + 100, + 10 + ); + + super.setRecipeText(_("需", 1) + " 霚 " + _("霂", 6)); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeLSD.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeLSD.java new file mode 100644 index 0000000..0ae495e --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeLSD.java @@ -0,0 +1,29 @@ +package net.grandtheftmc.vice.machine.recipe.type; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.machine.recipe.MachineRecipe; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeInput; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeOutput; + +public final class RecipeLSD extends MachineRecipe { + + /** + * Construct a new Machine Recipe. + */ + public RecipeLSD() { + super( + 14, + new RecipeInput[] { + new RecipeInput(Vice.getItemManager().getItem("acid").getItem(), 1) + }, + new RecipeOutput[] { + new RecipeOutput(Vice.getItemManager().getItem("lsd").getItem(), 1) + }, + 2, + 100, + 10 + ); + + super.setRecipeText(_("霎", 1) + " 霚 " + _("霏", 1)); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipePureMeth.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipePureMeth.java new file mode 100644 index 0000000..e00effb --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipePureMeth.java @@ -0,0 +1,30 @@ +package net.grandtheftmc.vice.machine.recipe.type; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.machine.recipe.MachineRecipe; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeInput; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeOutput; + +public final class RecipePureMeth extends MachineRecipe { + + /** + * Construct a new Machine Recipe. + */ + public RecipePureMeth() { + super( + 15, + new RecipeInput[] { + new RecipeInput(Vice.getItemManager().getItem("methylamine").getItem(), 1), + new RecipeInput(Vice.getItemManager().getItem("ephedrasinica").getItem(), 64) + }, + new RecipeOutput[] { + new RecipeOutput(Vice.getItemManager().getItem("puremeth").getItem(), 4) + }, + 16, + 800, + 2560 + ); + + super.setRecipeText(_("霑", 1) + _("霠", 64) + " 霚 " + _("霒", 4)); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeVodka.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeVodka.java new file mode 100644 index 0000000..6d31a8c --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeVodka.java @@ -0,0 +1,40 @@ +package net.grandtheftmc.vice.machine.recipe.type; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.machine.recipe.MachineRecipe; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeInput; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeOutput; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +public final class RecipeVodka extends MachineRecipe { + + /* + Vodka + - Get potato seeds + - Plant potatoes in tilled earth + - Destroy potato plant to get a potato + - Place potato with glass bottle in Vodka Distillery to get Vodka + */ + + /** + * Construct a new Machine Recipe. + */ + public RecipeVodka() { + super( + 6, + new RecipeInput[] { + new RecipeInput(new ItemStack(Material.POTATO_ITEM), 6), + new RecipeInput(new ItemStack(Material.GLASS_BOTTLE), 1) + }, + new RecipeOutput[] { + new RecipeOutput(Vice.getItemManager().getItem("vodka").getItem(), 1) + }, + 2, + 100, + 10 + ); + + super.setRecipeText(_("霜", 6) + _("霔", 1) + " 霚 " + _("霉", 1)); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeWeed.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeWeed.java new file mode 100644 index 0000000..524904a --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeWeed.java @@ -0,0 +1,29 @@ +package net.grandtheftmc.vice.machine.recipe.type; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.machine.recipe.MachineRecipe; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeInput; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeOutput; + +public final class RecipeWeed extends MachineRecipe { + + /** + * Construct a new Machine Recipe. + */ + public RecipeWeed() { + super( + 3, + new RecipeInput[] { + new RecipeInput(Vice.getItemManager().getItem("marijuanaleaf").getItem(), 1) + }, + new RecipeOutput[] { + new RecipeOutput(Vice.getItemManager().getItem("weed").getItem(), 1) + }, + 2, + 100, + 10 + ); + + super.setRecipeText(_("霢", 1) + " 霚 " + _("霆", 1)); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeWhiteMeth.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeWhiteMeth.java new file mode 100644 index 0000000..c96472c --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/recipe/type/RecipeWhiteMeth.java @@ -0,0 +1,36 @@ +package net.grandtheftmc.vice.machine.recipe.type; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.machine.recipe.MachineRecipe; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeInput; +import net.grandtheftmc.vice.machine.recipe.misc.RecipeOutput; + +public final class RecipeWhiteMeth extends MachineRecipe { + + /* + White Meth + Find Ephredra Sinica Seeds + Plant -> Grow -> Ephredra Sinica + Ephredra Sinica -> Process -> White Meth + */ + + /** + * Construct a new Machine Recipe. + */ + public RecipeWhiteMeth() { + super( + 13, + new RecipeInput[] { + new RecipeInput(Vice.getItemManager().getItem("ephedrasinica").getItem(), 5) + }, + new RecipeOutput[] { + new RecipeOutput(Vice.getItemManager().getItem("whitemeth").getItem(), 1) + }, + 2, + 100, + 10 + ); + + super.setRecipeText(_("霠", 5) + " 霚 " + _("霐", 1)); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/repair/MachineRepairMenu.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/repair/MachineRepairMenu.java new file mode 100644 index 0000000..2411317 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/repair/MachineRepairMenu.java @@ -0,0 +1,211 @@ +package net.grandtheftmc.vice.machine.repair; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.inventory.CoreMenu; +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import net.grandtheftmc.core.inventory.button.ClickableItem; +import net.grandtheftmc.core.inventory.button.MenuItem; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.vice.machine.MachineManager; +import net.grandtheftmc.vice.utils.ItemStackUtil; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; + +public final class MachineRepairMenu extends CoreMenu { + + private static final int[] input = new int[] {10,11,12,13}; + private final MachineManager machineManager; + + public MachineRepairMenu(MachineManager machineManager) { + super(3, "Machine Mechanic", CoreMenuFlag.RESET_CURSOR_ON_OPEN); + this.machineManager = machineManager; + super.setSelfHandle(true); + + //Slot 10 - 13 = Fragment input + + //Slot 15 = Machine output + super.addItem(new MenuItem(15, new ItemStack(Material.BARRIER, 1), false)); + + String[] desc = { + C.GRAY + C.ITALIC + " Place 4 of the same type", + C.GRAY + C.ITALIC + " of fragments to construct", + C.GRAY + C.ITALIC + " a functional Machine!", + }; + + super.addItem(new MenuItem(0, new ItemFactory(Material.STONE_SWORD).setDurability((short) 78) + .setName(C.YELLOW + C.BOLD + "Machine Mechanic").setLore(desc).setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS).build(), false)); + + for (int slot : new int[] {1,2,3,4,5,6,7,8,9,14,16,17,18,19,20,21,22,23,24,25,26}) { + super.addItem(new MenuItem(slot, new ItemFactory(Material.STAINED_GLASS_PANE, (byte) 0) + .setName(C.YELLOW + C.BOLD + "Machine Mechanic").setLore(desc).build(), false)); + } + } + + private void generateMachine(int machineId) { + ItemStack itemStack = this.machineManager.getMachineItemById(machineId); + if (itemStack.getType() == Material.STONE) { + super.addItem(new MenuItem(15, new ItemStack(Material.BARRIER, 1), false)); + return; + } + +// super.addItem(new MenuItem(15, itemStack, true)); + + super.addItem(new ClickableItem(15, itemStack, true, (player, clickType) -> { +// if (player.getInventory().firstEmpty() != -1) { +// player.getInventory().addItem(itemStack); +// redeemed = true; +// player.closeInventory(); +// return; +// } +// +// player.getWorld().dropItemNaturally(player.getLocation(), itemStack); +// player.sendMessage(C.RED + "Machine dropped on the floor, your inventory was full."); +// redeemed = true; +// player.closeInventory(); + + for (int i : input) { + ItemStack item = super.getInventory().getItem(i); + if (item.getAmount() > 1) { + item.setAmount(item.getAmount() - 1); + } + else { + super.getInventory().setItem(i, new ItemStack(Material.AIR)); + } + } + + if (player.getInventory().firstEmpty() != -1) { + player.getInventory().addItem(itemStack); + return; + } + + player.getWorld().dropItemNaturally(player.getLocation(), itemStack); + player.sendMessage(C.RED + "Machine dropped on the floor, your inventory was full."); + })); + } + + @Override + public void selfHandle(InventoryClickEvent event) { +// super.selfHandle(event); + + CoreMenu menu = (CoreMenu)event.getInventory().getHolder(); + Player player = (Player)event.getWhoClicked(); + ItemStack clicked = event.getCurrentItem(); + + if (clicked!=null && clicked.getType() == Material.CHEST) { + event.setCancelled(true); + return; + } + + MenuItem item = menu.getMenuItem(event.getRawSlot()); + if (item != null && event.getRawSlot() == 15 && this.machineManager.isType(item.getItemStack().getType())) { + switch (event.getAction()) { + case PICKUP_ALL: + case PICKUP_SOME: + case PICKUP_HALF: + case PICKUP_ONE: + case MOVE_TO_OTHER_INVENTORY: + case COLLECT_TO_CURSOR: + if (item instanceof ClickableItem) { + event.setCancelled(true); + ((ClickableItem)item).getClickAction().onClick(player, event.getClick()); + } + return; + + default: + event.setCancelled(true); + return; + } + } + + menu.onClick(event); + if (item != null) { + if (!item.isAllowingPickup()) { + event.setCancelled(true); + } + + if (item instanceof ClickableItem) { + ((ClickableItem)item).getClickAction().onClick(player, event.getClick()); + } + } + } + + @Override + public void onInteract(CoreMenu menu) { + check(menu.getInventory()); + } + + private void check(Inventory inventory) { + ServerUtil.runTaskLater(() -> { + int id = -1; + boolean stable = true; + for (int slot : input) { + ItemStack found = inventory.getItem(slot); + if (found == null || found.getType() != Material.PRISMARINE_SHARD) { + stable = false; + break; + } + + if (!ItemStackUtil.hasTag(found, "machineid")) { + stable = false; + break; + } + + if (id == -1) { + id = ItemStackUtil.getIntTag(found, "machineid"); + continue; + } + + int temp = ItemStackUtil.getIntTag(found, "machineid"); + if (id != temp) { + stable = false; + break; + } + } + + if (!stable) id = -1; +// +// int amount = -1; +// for (int slot : input) { +// ItemStack found = inventory.getItem(slot); +// if (amount == -1) { +// amount = found.getAmount(); +// continue; +// } +// +// if (amount != found.getAmount()) { +// stable = false; +// break; +// } +// } +// +// if (!stable) id = -1; + + this.generateMachine(id); + }, 1); + } + + @Override + public void onClose(InventoryCloseEvent event) { + Player player = (Player)event.getPlayer(); + for (int slot : input) { + ItemStack found = event.getInventory().getItem(slot); + if (found == null || found.getType() == Material.AIR) continue; + + if (player.getInventory().firstEmpty() != -1) { + player.getInventory().addItem(found); + continue; + } + + player.getWorld().dropItemNaturally(event.getPlayer().getLocation(), found); + } + player.updateInventory(); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/type/MachineAdvancedMethProducer.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/type/MachineAdvancedMethProducer.java new file mode 100644 index 0000000..e0cd2bf --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/type/MachineAdvancedMethProducer.java @@ -0,0 +1,203 @@ +package net.grandtheftmc.vice.machine.type; + +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.vice.machine.BaseMachine; +import net.grandtheftmc.vice.machine.data.MachineData; +import net.grandtheftmc.vice.machine.data.MachineDataType; +import net.grandtheftmc.vice.machine.misc.MachineProgressMultiplier; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; + +public final class MachineAdvancedMethProducer extends BaseMachine implements MachineProgressMultiplier { + + /** + * Construct a Machine + */ + public MachineAdvancedMethProducer() { + super( + 9, + "Advanced Meth Producer", + Material.DROPPER + ); + + // FUEL + MachineData fuelData = new MachineData(MachineData.DataFlag.UP, 100, 0); + fuelData.setTextures(0, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2); + fuelData.setSlots(20); + super.setData(MachineDataType.FUEL, fuelData); + + // DURABILITY + MachineData durabilityData = new MachineData(MachineData.DataFlag.UP, 2500); + durabilityData.setTextures(0, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27); + super.setData(MachineDataType.DURABILITY, durabilityData); + + // PROGRESS + MachineData progressData = new MachineData(MachineData.DataFlag.DOWN, 20, 0); + progressData.setTextures(0, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52); + super.setData(MachineDataType.PROGRESS, progressData); + + super.setBlockedSlots(0, 1, 2, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26); + super.setOpenSlots(3, 5); + super.setOutputSlots(22); + + super.setMachineItem(new ItemFactory(Material.DROPPER).setName(C.WHITE + C.BOLD + super.getName()).setLore(C.GRAY + "Machine").build()); + + String[] description = { + C.DARK_GRAY + C.ITALIC + " " + super.getName(), + "", + "", + C.YELLOW + C.BOLD + "MACHINE RECIPES", + C.GRAY + " Note, recipes consume fuel and durability.", + C.GRAY + " Some more than others.", + "", + " " + i("霑", 1) + i("霠", 64) + " 霚 " + i("霒", 4), + "", + C.GRAY + " Use the command " + C.WHITE + "/recipe" + C.GRAY + " for", + C.GRAY + " a visual tutorial on drug recipes." + }; + + for (int i : super.getBlockedSlots()) { + super.getInventory().setItem(i, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + //Machine Frame + super.getInventory().setItem(0, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 80) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + this.initFuelItems(fuelData); + this.initDurabilityItems(durabilityData); + + //Progress Item. + super.getInventory().setItem(11, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) progressData.getTexture()) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setEnchantment(Enchantment.DURABILITY, 1) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + private void initFuelItems(MachineData data) { + String[] lore = { + C.GRAY + " Adding burnable items will replenish", + C.GRAY + " your machine fuel counter.", + "", + // fire - oak_plank - 2 + C.RESET + " 霚 " + C.WHITE + "[霡] +" + C.YELLOW + "2" + C.WHITE + " Fuel", + // fire - coal - 8 + C.RESET + " 霚 " + C.WHITE + "[霖] +" + C.GOLD + "8" + C.WHITE + " Fuel", + // fire - coal_block - 160 + C.RESET + " 霚 " + C.WHITE + "[霗] +" + C.RED + "80" + C.WHITE + " Fuel", + // fire - lava - 100 + C.RESET + " 霚 " + C.WHITE + "[霙] +" + C.RED + "100" + C.WHITE + " Fuel", + "", + C.GRAY + " Use the command " + C.WHITE + "/recipe" + C.GRAY + " for", + C.GRAY + " a visual tutorial on drug recipes." + }; + + //Fuel Item. + super.getInventory().setItem(19, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(10, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(1, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + private void initDurabilityItems(MachineData data) { + String[] lore = { + C.GRAY + " Once the durability is gone, you will", + C.GRAY + " need to fix your machine to repair it.", + "" + }; + + //Fuel Item. + super.getInventory().setItem(25, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(16, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(7, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + /** + * This multiplier will speed up the brewing/ cooking + * progress by the given amount. + * + * @return + */ + @Override + public double getMultiplier() { + return 2; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/type/MachineBasicMethProducer.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/type/MachineBasicMethProducer.java new file mode 100644 index 0000000..048bdca --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/type/MachineBasicMethProducer.java @@ -0,0 +1,189 @@ +package net.grandtheftmc.vice.machine.type; + +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.vice.machine.BaseMachine; +import net.grandtheftmc.vice.machine.data.MachineData; +import net.grandtheftmc.vice.machine.data.MachineDataType; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; + +public final class MachineBasicMethProducer extends BaseMachine { + + /** + * Construct a Machine + */ + public MachineBasicMethProducer() { + super( + 8, + "Basic Meth Producer", + Material.DROPPER + ); + + // FUEL + MachineData fuelData = new MachineData(MachineData.DataFlag.UP, 100, 0); + fuelData.setTextures(0, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2); + fuelData.setSlots(20); + super.setData(MachineDataType.FUEL, fuelData); + + // DURABILITY + MachineData durabilityData = new MachineData(MachineData.DataFlag.UP, 37500); + durabilityData.setTextures(0, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27); + super.setData(MachineDataType.DURABILITY, durabilityData); + + // PROGRESS + MachineData progressData = new MachineData(MachineData.DataFlag.DOWN, 20, 0); + progressData.setTextures(0, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52); + super.setData(MachineDataType.PROGRESS, progressData); + + super.setBlockedSlots(0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26); + super.setOpenSlots(4); + super.setOutputSlots(22); + + super.setMachineItem(new ItemFactory(Material.DROPPER).setName(C.WHITE + C.BOLD + super.getName()).setLore(C.GRAY + "Machine").build()); + + String[] description = { + C.DARK_GRAY + C.ITALIC + " " + super.getName(), + "", + "", + C.YELLOW + C.BOLD + "MACHINE RECIPES", + C.GRAY + " Note, recipes consume fuel and durability.", + C.GRAY + " Some more than others.", + "", + " " + i("霠", 5) + " 霚 " + i("霐", 1), + "", + C.GRAY + " Use the command " + C.WHITE + "/recipe" + C.GRAY + " for", + C.GRAY + " a visual tutorial on drug recipes." + }; + + for (int i : super.getBlockedSlots()) { + super.getInventory().setItem(i, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + //Machine Frame + super.getInventory().setItem(0, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 79) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + this.initFuelItems(fuelData); + this.initDurabilityItems(durabilityData); + + //Progress Item. + super.getInventory().setItem(11, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) progressData.getTexture()) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setEnchantment(Enchantment.DURABILITY, 1) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + private void initFuelItems(MachineData data) { + String[] lore = { + C.GRAY + " Adding burnable items will replenish", + C.GRAY + " your machine fuel counter.", + "", + // fire - oak_plank - 2 + C.RESET + " 霚 " + C.WHITE + "[霡] +" + C.YELLOW + "2" + C.WHITE + " Fuel", + // fire - coal - 8 + C.RESET + " 霚 " + C.WHITE + "[霖] +" + C.GOLD + "8" + C.WHITE + " Fuel", + // fire - coal_block - 160 + C.RESET + " 霚 " + C.WHITE + "[霗] +" + C.RED + "80" + C.WHITE + " Fuel", + // fire - lava - 100 + C.RESET + " 霚 " + C.WHITE + "[霙] +" + C.RED + "100" + C.WHITE + " Fuel", + "" + }; + + //Fuel Item. + super.getInventory().setItem(19, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(10, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(1, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + private void initDurabilityItems(MachineData data) { + String[] lore = { + C.GRAY + " Once the durability is gone, you will", + C.GRAY + " need to fix your machine to repair it.", + "" + }; + + //Fuel Item. + super.getInventory().setItem(25, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(16, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(7, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/type/MachineBeerDistillery.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/type/MachineBeerDistillery.java new file mode 100644 index 0000000..e350ea7 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/type/MachineBeerDistillery.java @@ -0,0 +1,191 @@ +package net.grandtheftmc.vice.machine.type; + +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.vice.machine.BaseMachine; +import net.grandtheftmc.vice.machine.data.MachineData; +import net.grandtheftmc.vice.machine.data.MachineDataType; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; + +public final class MachineBeerDistillery extends BaseMachine { + + /** + * Construct a Machine + */ + public MachineBeerDistillery() { + super( + 4, + "Beer Distillery", + Material.DROPPER + ); + + // FUEL + MachineData fuelData = new MachineData(MachineData.DataFlag.UP, 100, 0); + fuelData.setTextures(0, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2); + fuelData.setSlots(20); + super.setData(MachineDataType.FUEL, fuelData); + + // DURABILITY + MachineData durabilityData = new MachineData(MachineData.DataFlag.UP, 50000); + durabilityData.setTextures(0, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27); + super.setData(MachineDataType.DURABILITY, durabilityData); + + // PROGRESS + MachineData progressData = new MachineData(MachineData.DataFlag.DOWN, 20, 0); + progressData.setTextures(0, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52); + super.setData(MachineDataType.PROGRESS, progressData); + + super.setBlockedSlots(0, 1, 2, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26); + super.setOpenSlots(3, 5); + super.setOutputSlots(22); + + super.setMachineItem(new ItemFactory(Material.DROPPER).setName(C.WHITE + C.BOLD + super.getName()).setLore(C.GRAY + "Machine").build()); + + String[] description = { + C.DARK_GRAY + C.ITALIC + " " + super.getName(), + "", + "", + C.YELLOW + C.BOLD + "MACHINE RECIPES", + C.GRAY + " Note, recipes consume fuel and durability.", + C.GRAY + " Some more than others.", + "", + " " + i("霔", 5) + i("霃", 1) + " 霚 " + i("霈", 1), + "", + " " + i("霂", 6) + " " + i("霔", 1) + " 霚 " + i("霃", 1), + "", + C.GRAY + " Use the command " + C.WHITE + "/recipe" + C.GRAY + " for", + C.GRAY + " a visual tutorial on drug recipes." + }; + + for (int i : super.getBlockedSlots()) { + super.getInventory().setItem(i, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + //Machine Frame + super.getInventory().setItem(0, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 80) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + this.initFuelItems(fuelData); + this.initDurabilityItems(durabilityData); + + //Progress Item. + super.getInventory().setItem(11, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) progressData.getTexture()) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setEnchantment(Enchantment.DURABILITY, 1) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + private void initFuelItems(MachineData data) { + String[] lore = { + C.GRAY + " Adding burnable items will replenish", + C.GRAY + " your machine fuel counter.", + "", + // fire - oak_plank - 2 + C.RESET + " 霚 " + C.WHITE + "[霡] +" + C.YELLOW + "2" + C.WHITE + " Fuel", + // fire - coal - 8 + C.RESET + " 霚 " + C.WHITE + "[霖] +" + C.GOLD + "8" + C.WHITE + " Fuel", + // fire - coal_block - 160 + C.RESET + " 霚 " + C.WHITE + "[霗] +" + C.RED + "80" + C.WHITE + " Fuel", + // fire - lava - 100 + C.RESET + " 霚 " + C.WHITE + "[霙] +" + C.RED + "100" + C.WHITE + " Fuel", + "" + }; + + //Fuel Item. + super.getInventory().setItem(19, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(10, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(1, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + private void initDurabilityItems(MachineData data) { + String[] lore = { + C.GRAY + " Once the durability is gone, you will", + C.GRAY + " need to fix your machine to repair it.", + "" + }; + + //Fuel Item. + super.getInventory().setItem(25, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(16, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(7, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/type/MachineCocaProcessor.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/type/MachineCocaProcessor.java new file mode 100644 index 0000000..e7c2c25 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/type/MachineCocaProcessor.java @@ -0,0 +1,191 @@ +package net.grandtheftmc.vice.machine.type; + +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.vice.machine.BaseMachine; +import net.grandtheftmc.vice.machine.data.MachineData; +import net.grandtheftmc.vice.machine.data.MachineDataType; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; + +public final class MachineCocaProcessor extends BaseMachine { + + /** + * Construct a Machine + */ + public MachineCocaProcessor() { + super( + 6, + "Coca Processor", + Material.DROPPER + ); + + // FUEL + MachineData fuelData = new MachineData(MachineData.DataFlag.UP, 100, 0); + fuelData.setTextures(0, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2); + fuelData.setSlots(20); + super.setData(MachineDataType.FUEL, fuelData); + + // DURABILITY + MachineData durabilityData = new MachineData(MachineData.DataFlag.UP, 37500); + durabilityData.setTextures(0, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27); + super.setData(MachineDataType.DURABILITY, durabilityData); + + // PROGRESS + MachineData progressData = new MachineData(MachineData.DataFlag.DOWN, 20, 0); + progressData.setTextures(0, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52); + super.setData(MachineDataType.PROGRESS, progressData); + + super.setBlockedSlots(0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26); + super.setOpenSlots(4); + super.setOutputSlots(22); + + super.setMachineItem(new ItemFactory(Material.DROPPER).setName(C.WHITE + C.BOLD + super.getName()).setLore(C.GRAY + "Machine").build()); + + String[] description = { + C.DARK_GRAY + C.ITALIC + " " + super.getName(), + "", + "", + C.YELLOW + C.BOLD + "MACHINE RECIPES", + C.GRAY + " Note, recipes consume fuel and durability.", + C.GRAY + " Some more than others.", + "", + " " + i("霅", 3) + " 霚 " + i("霓", 1), + "", + " " + i("霓", 1) + " 霚 " + i("霍", 1), + "", + C.GRAY + " Use the command " + C.WHITE + "/recipe" + C.GRAY + " for", + C.GRAY + " a visual tutorial on drug recipes." + }; + + for (int i : super.getBlockedSlots()) { + super.getInventory().setItem(i, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + //Machine Frame + super.getInventory().setItem(0, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 79) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + this.initFuelItems(fuelData); + this.initDurabilityItems(durabilityData); + + //Progress Item. + super.getInventory().setItem(11, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) progressData.getTexture()) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setEnchantment(Enchantment.DURABILITY, 1) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + private void initFuelItems(MachineData data) { + String[] lore = { + C.GRAY + " Adding burnable items will replenish", + C.GRAY + " your machine fuel counter.", + "", + // fire - oak_plank - 2 + C.RESET + " 霚 " + C.WHITE + "[霡] +" + C.YELLOW + "2" + C.WHITE + " Fuel", + // fire - coal - 8 + C.RESET + " 霚 " + C.WHITE + "[霖] +" + C.GOLD + "8" + C.WHITE + " Fuel", + // fire - coal_block - 160 + C.RESET + " 霚 " + C.WHITE + "[霗] +" + C.RED + "80" + C.WHITE + " Fuel", + // fire - lava - 100 + C.RESET + " 霚 " + C.WHITE + "[霙] +" + C.RED + "100" + C.WHITE + " Fuel", + "" + }; + + //Fuel Item. + super.getInventory().setItem(19, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(10, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(1, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + private void initDurabilityItems(MachineData data) { + String[] lore = { + C.GRAY + " Once the durability is gone, you will", + C.GRAY + " need to fix your machine to repair it.", + "" + }; + + //Fuel Item. + super.getInventory().setItem(25, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(16, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(7, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/type/MachineLargeDryingMachine.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/type/MachineLargeDryingMachine.java new file mode 100644 index 0000000..f8b93a0 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/type/MachineLargeDryingMachine.java @@ -0,0 +1,209 @@ +package net.grandtheftmc.vice.machine.type; + +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.vice.machine.BaseMachine; +import net.grandtheftmc.vice.machine.data.MachineData; +import net.grandtheftmc.vice.machine.data.MachineDataType; +import net.grandtheftmc.vice.machine.misc.MachineProgressMultiplier; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; + +public final class MachineLargeDryingMachine extends BaseMachine implements MachineProgressMultiplier { + + /** + * Construct a Machine + */ + public MachineLargeDryingMachine() { + super( + 3, + "Large Drying Chamber", + Material.DROPPER + ); + + // FUEL + MachineData fuelData = new MachineData(MachineData.DataFlag.UP, 100, 0); + fuelData.setTextures(0, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2); + fuelData.setSlots(20); + super.setData(MachineDataType.FUEL, fuelData); + + // DURABILITY + MachineData durabilityData = new MachineData(MachineData.DataFlag.UP, 72000 * this.getMultiplier()); + durabilityData.setTextures(0, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27); + super.setData(MachineDataType.DURABILITY, durabilityData); + + // PROGRESS + MachineData progressData = new MachineData(MachineData.DataFlag.DOWN, 20, 0); + progressData.setTextures(0, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52); + super.setData(MachineDataType.PROGRESS, progressData); + + super.setBlockedSlots(0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26); + super.setOpenSlots(4); + super.setOutputSlots(22); + + super.setMachineItem(new ItemFactory(Material.DROPPER).setName(C.WHITE + C.BOLD + super.getName()).setLore(C.GRAY + "Machine").build()); + + String[] description = { + C.DARK_GRAY + C.ITALIC + " " + super.getName(), + "", + "", + C.YELLOW + C.BOLD + "MACHINE RECIPES", + C.GRAY + " Note, recipes consume fuel and durability.", + C.GRAY + " Some more than others.", + "", + " " + i("需", 1) + " 霚 " + i("霂", 6), + "", + " " + i("霢", 1) + " 霚 " + i("霆", 1), + "", + " " + i("霟", 1) + " 霚 " + i("霋", 1), + "", + " " + i("霞", 1) + " 霚 " + i("霋", 1), + "", + " " + i("霁", 1) + " 霚 " + i("霎", 1), + "", + C.GRAY + " Use the command " + C.WHITE + "/recipe" + C.GRAY + " for", + C.GRAY + " a visual tutorial on drug recipes." + }; + + for (int i : super.getBlockedSlots()) { + super.getInventory().setItem(i, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + //Machine Frame + super.getInventory().setItem(0, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 79) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + this.initFuelItems(fuelData); + this.initDurabilityItems(durabilityData); + + //Progress Item. + super.getInventory().setItem(11, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) progressData.getTexture()) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setEnchantment(Enchantment.DURABILITY, 1) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + private void initFuelItems(MachineData data) { + String[] lore = { + C.GRAY + " Adding burnable items will replenish", + C.GRAY + " your machine fuel counter.", + "", + // fire - oak_plank - 2 + C.RESET + " 霚 " + C.WHITE + "[霡] +" + C.YELLOW + "2" + C.WHITE + " Fuel", + // fire - coal - 8 + C.RESET + " 霚 " + C.WHITE + "[霖] +" + C.GOLD + "8" + C.WHITE + " Fuel", + // fire - coal_block - 160 + C.RESET + " 霚 " + C.WHITE + "[霗] +" + C.RED + "80" + C.WHITE + " Fuel", + // fire - lava - 100 + C.RESET + " 霚 " + C.WHITE + "[霙] +" + C.RED + "100" + C.WHITE + " Fuel", + "" + }; + + //Fuel Item. + super.getInventory().setItem(19, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(10, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(1, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + private void initDurabilityItems(MachineData data) { + String[] lore = { + C.GRAY + " Once the durability is gone, you will", + C.GRAY + " need to fix your machine to repair it.", + "" + }; + + //Fuel Item. + super.getInventory().setItem(25, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(16, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(7, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + /** + * This multiplier will speed up the brewing/ cooking + * progress by the given amount. + * + * @return + */ + @Override + public double getMultiplier() { + return 2; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/type/MachineMediumDryingChamber.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/type/MachineMediumDryingChamber.java new file mode 100644 index 0000000..e26c68d --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/type/MachineMediumDryingChamber.java @@ -0,0 +1,209 @@ +package net.grandtheftmc.vice.machine.type; + +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.vice.machine.BaseMachine; +import net.grandtheftmc.vice.machine.data.MachineData; +import net.grandtheftmc.vice.machine.data.MachineDataType; +import net.grandtheftmc.vice.machine.misc.MachineProgressMultiplier; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; + +public final class MachineMediumDryingChamber extends BaseMachine implements MachineProgressMultiplier { + + /** + * Construct a Machine + */ + public MachineMediumDryingChamber() { + super( + 2, + "Medium Drying Chamber", + Material.DROPPER + ); + + // FUEL + MachineData fuelData = new MachineData(MachineData.DataFlag.UP, 100, 0); + fuelData.setTextures(0, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2); + fuelData.setSlots(20); + super.setData(MachineDataType.FUEL, fuelData); + + // DURABILITY + MachineData durabilityData = new MachineData(MachineData.DataFlag.UP, 72000 * this.getMultiplier()); + durabilityData.setTextures(0, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27); + super.setData(MachineDataType.DURABILITY, durabilityData); + + // PROGRESS + MachineData progressData = new MachineData(MachineData.DataFlag.DOWN, 20, 0); + progressData.setTextures(0, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52); + super.setData(MachineDataType.PROGRESS, progressData); + + super.setBlockedSlots(0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26); + super.setOpenSlots(4); + super.setOutputSlots(22); + + super.setMachineItem(new ItemFactory(Material.DROPPER).setName(C.WHITE + C.BOLD + super.getName()).setLore(C.GRAY + "Machine").build()); + + String[] description = { + C.DARK_GRAY + C.ITALIC + " " + super.getName(), + "", + "", + C.YELLOW + C.BOLD + "MACHINE RECIPES", + C.GRAY + " Note, recipes consume fuel and durability.", + C.GRAY + " Some more than others.", + "", + " " + i("需", 1) + " 霚 " + i("霂", 6), + "", + " " + i("霢", 1) + " 霚 " + i("霆", 1), + "", + " " + i("霟", 1) + " 霚 " + i("霋", 1), + "", + " " + i("霞", 1) + " 霚 " + i("霋", 1), + "", + " " + i("霁", 1) + " 霚 " + i("霎", 1), + "", + C.GRAY + " Use the command " + C.WHITE + "/recipe" + C.GRAY + " for", + C.GRAY + " a visual tutorial on drug recipes." + }; + + for (int i : super.getBlockedSlots()) { + super.getInventory().setItem(i, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + //Machine Frame + super.getInventory().setItem(0, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 79) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + this.initFuelItems(fuelData); + this.initDurabilityItems(durabilityData); + + //Progress Item. + super.getInventory().setItem(11, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) progressData.getTexture()) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setEnchantment(Enchantment.DURABILITY, 1) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + private void initFuelItems(MachineData data) { + String[] lore = { + C.GRAY + " Adding burnable items will replenish", + C.GRAY + " your machine fuel counter.", + "", + // fire - oak_plank - 2 + C.RESET + " 霚 " + C.WHITE + "[霡] +" + C.YELLOW + "2" + C.WHITE + " Fuel", + // fire - coal - 8 + C.RESET + " 霚 " + C.WHITE + "[霖] +" + C.GOLD + "8" + C.WHITE + " Fuel", + // fire - coal_block - 160 + C.RESET + " 霚 " + C.WHITE + "[霗] +" + C.RED + "80" + C.WHITE + " Fuel", + // fire - lava - 100 + C.RESET + " 霚 " + C.WHITE + "[霙] +" + C.RED + "100" + C.WHITE + " Fuel", + "" + }; + + //Fuel Item. + super.getInventory().setItem(19, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(10, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(1, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + private void initDurabilityItems(MachineData data) { + String[] lore = { + C.GRAY + " Once the durability is gone, you will", + C.GRAY + " need to fix your machine to repair it.", + "" + }; + + //Fuel Item. + super.getInventory().setItem(25, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(16, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(7, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + /** + * This multiplier will speed up the brewing/ cooking + * progress by the given amount. + * + * @return + */ + @Override + public double getMultiplier() { + return 1.5; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/type/MachinePulpCondenser.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/type/MachinePulpCondenser.java new file mode 100644 index 0000000..4e1808b --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/type/MachinePulpCondenser.java @@ -0,0 +1,189 @@ +package net.grandtheftmc.vice.machine.type; + +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.vice.machine.BaseMachine; +import net.grandtheftmc.vice.machine.data.MachineData; +import net.grandtheftmc.vice.machine.data.MachineDataType; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; + +public final class MachinePulpCondenser extends BaseMachine { + + /** + * Construct a Machine + */ + public MachinePulpCondenser() { + super( + 7, + "Pulp Condenser", + Material.DROPPER + ); + + // FUEL + MachineData fuelData = new MachineData(MachineData.DataFlag.UP, 100, 0); + fuelData.setTextures(0, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2); + fuelData.setSlots(20); + super.setData(MachineDataType.FUEL, fuelData); + + // DURABILITY + MachineData durabilityData = new MachineData(MachineData.DataFlag.UP, 37500); + durabilityData.setTextures(0, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27); + super.setData(MachineDataType.DURABILITY, durabilityData); + + // PROGRESS + MachineData progressData = new MachineData(MachineData.DataFlag.DOWN, 20, 0); + progressData.setTextures(0, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52); + super.setData(MachineDataType.PROGRESS, progressData); + + super.setBlockedSlots(0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26); + super.setOpenSlots(4); + super.setOutputSlots(22); + + super.setMachineItem(new ItemFactory(Material.DROPPER).setName(C.WHITE + C.BOLD + super.getName()).setLore(C.GRAY + "Machine").build()); + + String[] description = { + C.DARK_GRAY + C.ITALIC + " " + super.getName(), + "", + "", + C.YELLOW + C.BOLD + "MACHINE RECIPES", + C.GRAY + " Note, recipes consume fuel and durability.", + C.GRAY + " Some more than others.", + "", + " " + i("霋", 1) + " 霚 " + i("霌", 1), + "", + C.GRAY + " Use the command " + C.WHITE + "/recipe" + C.GRAY + " for", + C.GRAY + " a visual tutorial on drug recipes." + }; + + for (int i : super.getBlockedSlots()) { + super.getInventory().setItem(i, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + //Machine Frame + super.getInventory().setItem(0, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 79) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + this.initFuelItems(fuelData); + this.initDurabilityItems(durabilityData); + + //Progress Item. + super.getInventory().setItem(11, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) progressData.getTexture()) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setEnchantment(Enchantment.DURABILITY, 1) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + private void initFuelItems(MachineData data) { + String[] lore = { + C.GRAY + " Adding burnable items will replenish", + C.GRAY + " your machine fuel counter.", + "", + // fire - oak_plank - 2 + C.RESET + " 霚 " + C.WHITE + "[霡] +" + C.YELLOW + "2" + C.WHITE + " Fuel", + // fire - coal - 8 + C.RESET + " 霚 " + C.WHITE + "[霖] +" + C.GOLD + "8" + C.WHITE + " Fuel", + // fire - coal_block - 160 + C.RESET + " 霚 " + C.WHITE + "[霗] +" + C.RED + "80" + C.WHITE + " Fuel", + // fire - lava - 100 + C.RESET + " 霚 " + C.WHITE + "[霙] +" + C.RED + "100" + C.WHITE + " Fuel", + "" + }; + + //Fuel Item. + super.getInventory().setItem(19, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(10, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(1, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + private void initDurabilityItems(MachineData data) { + String[] lore = { + C.GRAY + " Once the durability is gone, you will", + C.GRAY + " need to fix your machine to repair it.", + "" + }; + + //Fuel Item. + super.getInventory().setItem(25, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(16, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(7, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/type/MachineSmallDryingChamber.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/type/MachineSmallDryingChamber.java new file mode 100644 index 0000000..957b315 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/type/MachineSmallDryingChamber.java @@ -0,0 +1,197 @@ +package net.grandtheftmc.vice.machine.type; + +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.vice.machine.BaseMachine; +import net.grandtheftmc.vice.machine.data.MachineData; +import net.grandtheftmc.vice.machine.data.MachineDataType; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; + +public final class MachineSmallDryingChamber extends BaseMachine { + + /** + * Construct a Machine + */ + public MachineSmallDryingChamber() { + super( + 1, + "Small Drying Chamber", + Material.DROPPER + ); + + // FUEL + MachineData fuelData = new MachineData(MachineData.DataFlag.UP, 100, 0); + fuelData.setTextures(0, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2); + fuelData.setSlots(20); + super.setData(MachineDataType.FUEL, fuelData); + + // DURABILITY + MachineData durabilityData = new MachineData(MachineData.DataFlag.UP, 72000); + durabilityData.setTextures(0, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27); + super.setData(MachineDataType.DURABILITY, durabilityData); + + // PROGRESS + MachineData progressData = new MachineData(MachineData.DataFlag.DOWN, 21, 0); + progressData.setTextures(0, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52); + super.setData(MachineDataType.PROGRESS, progressData); + + super.setBlockedSlots(0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26); + super.setOpenSlots(4); + super.setOutputSlots(22); + + super.setMachineItem(new ItemFactory(Material.DROPPER).setName(C.WHITE + C.BOLD + super.getName()).setLore(C.GRAY + "Machine").build()); + + String[] description = { + C.DARK_GRAY + C.ITALIC + " " + super.getName(), + "", + "", + C.YELLOW + C.BOLD + "MACHINE RECIPES", + C.GRAY + " Note, recipes consume fuel and durability.", + C.GRAY + " Some more than others.", + "", + " " + i("需", 1) + " 霚 " + i("霂", 6), + "", + " " + i("霢", 1) + " 霚 " + i("霆", 1), + "", + " " + i("霟", 1) + " 霚 " + i("霋", 1), + "", + " " + i("霞", 1) + " 霚 " + i("霋", 1), + "", + " " + i("霁", 1) + " 霚 " + i("霎", 1), + "", + C.GRAY + " Use the command " + C.WHITE + "/recipe" + C.GRAY + " for", + C.GRAY + " a visual tutorial on drug recipes." + }; + + for (int i : super.getBlockedSlots()) { + super.getInventory().setItem(i, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + //Machine Frame + super.getInventory().setItem(0, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 79) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + this.initFuelItems(fuelData); + this.initDurabilityItems(durabilityData); + + //Progress Item. + super.getInventory().setItem(11, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) progressData.getTexture()) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setEnchantment(Enchantment.DURABILITY, 1) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + private void initFuelItems(MachineData data) { + String[] lore = { + C.GRAY + " Adding burnable items will replenish", + C.GRAY + " your machine fuel counter.", + "", + // fire - oak_plank - 2 + C.RESET + " 霚 " + C.WHITE + "[霡] +" + C.YELLOW + "2" + C.WHITE + " Fuel", + // fire - coal - 8 + C.RESET + " 霚 " + C.WHITE + "[霖] +" + C.GOLD + "8" + C.WHITE + " Fuel", + // fire - coal_block - 160 + C.RESET + " 霚 " + C.WHITE + "[霗] +" + C.RED + "80" + C.WHITE + " Fuel", + // fire - lava - 100 + C.RESET + " 霚 " + C.WHITE + "[霙] +" + C.RED + "100" + C.WHITE + " Fuel", + "" + }; + + //Fuel Item. + super.getInventory().setItem(19, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(10, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(1, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + private void initDurabilityItems(MachineData data) { + String[] lore = { + C.GRAY + " Once the durability is gone, you will", + C.GRAY + " need to fix your machine to repair it.", + "" + }; + + //Fuel Item. + super.getInventory().setItem(25, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(16, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(7, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/type/MachineSugarBox.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/type/MachineSugarBox.java new file mode 100644 index 0000000..9596152 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/type/MachineSugarBox.java @@ -0,0 +1,201 @@ +package net.grandtheftmc.vice.machine.type; + +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.vice.machine.BaseMachine; +import net.grandtheftmc.vice.machine.data.MachineData; +import net.grandtheftmc.vice.machine.data.MachineDataType; +import net.grandtheftmc.vice.machine.misc.MachineProgressMultiplier; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; + +public final class MachineSugarBox extends BaseMachine implements MachineProgressMultiplier { + + /** + * Construct a Machine + */ + public MachineSugarBox() { + super( + 10, + "Sugar Box", + Material.DROPPER + ); + + // FUEL + MachineData fuelData = new MachineData(MachineData.DataFlag.UP, 100, 0); + fuelData.setTextures(0, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2); + fuelData.setSlots(20); + super.setData(MachineDataType.FUEL, fuelData); + + // DURABILITY + MachineData durabilityData = new MachineData(MachineData.DataFlag.UP, 37500); + durabilityData.setTextures(0, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27); + super.setData(MachineDataType.DURABILITY, durabilityData); + + // PROGRESS + MachineData progressData = new MachineData(MachineData.DataFlag.DOWN, 20, 0); + progressData.setTextures(0, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52); + super.setData(MachineDataType.PROGRESS, progressData); + + super.setBlockedSlots(0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26); + super.setOpenSlots(4); + super.setOutputSlots(22); + + super.setMachineItem(new ItemFactory(Material.DROPPER).setName(C.WHITE + C.BOLD + super.getName()).setLore(C.GRAY + "Machine").build()); + + String[] description = { + C.DARK_GRAY + C.ITALIC + " " + super.getName(), + "", + "", + C.YELLOW + C.BOLD + "MACHINE RECIPES", + C.GRAY + " Note, recipes consume fuel and durability.", + C.GRAY + " Some more than others.", + "", + " " + i("霎", 1) + " 霚 " + i("霏", 1), + "", + C.GRAY + " Use the command " + C.WHITE + "/recipe" + C.GRAY + " for", + C.GRAY + " a visual tutorial on drug recipes." + }; + + for (int i : super.getBlockedSlots()) { + super.getInventory().setItem(i, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + //Machine Frame + super.getInventory().setItem(0, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 79) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + this.initFuelItems(fuelData); + this.initDurabilityItems(durabilityData); + + //Progress Item. + super.getInventory().setItem(11, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) progressData.getTexture()) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setEnchantment(Enchantment.DURABILITY, 1) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + private void initFuelItems(MachineData data) { + String[] lore = { + C.GRAY + " Adding burnable items will replenish", + C.GRAY + " your machine fuel counter.", + "", + // fire - oak_plank - 2 + C.RESET + " 霚 " + C.WHITE + "[霡] +" + C.YELLOW + "2" + C.WHITE + " Fuel", + // fire - coal - 8 + C.RESET + " 霚 " + C.WHITE + "[霖] +" + C.GOLD + "8" + C.WHITE + " Fuel", + // fire - coal_block - 160 + C.RESET + " 霚 " + C.WHITE + "[霗] +" + C.RED + "80" + C.WHITE + " Fuel", + // fire - lava - 100 + C.RESET + " 霚 " + C.WHITE + "[霙] +" + C.RED + "100" + C.WHITE + " Fuel", + "" + }; + + //Fuel Item. + super.getInventory().setItem(19, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(10, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(1, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + private void initDurabilityItems(MachineData data) { + String[] lore = { + C.GRAY + " Once the durability is gone, you will", + C.GRAY + " need to fix your machine to repair it.", + "" + }; + + //Fuel Item. + super.getInventory().setItem(25, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(16, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(7, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + /** + * This multiplier will speed up the brewing/ cooking + * progress by the given amount. + * + * @return + */ + @Override + public double getMultiplier() { + return 2; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/type/MachineVodkaDistillery.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/type/MachineVodkaDistillery.java new file mode 100644 index 0000000..d97dfd9 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/machine/type/MachineVodkaDistillery.java @@ -0,0 +1,191 @@ +package net.grandtheftmc.vice.machine.type; + +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.vice.machine.BaseMachine; +import net.grandtheftmc.vice.machine.data.MachineData; +import net.grandtheftmc.vice.machine.data.MachineDataType; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; + +public final class MachineVodkaDistillery extends BaseMachine { + + /** + * Construct a Machine + */ + public MachineVodkaDistillery() { + super( + 5, + "Vodka Distillery", + Material.DROPPER + ); + + // FUEL + MachineData fuelData = new MachineData(MachineData.DataFlag.UP, 100, 0); + fuelData.setTextures(0, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2); + fuelData.setSlots(20); + super.setData(MachineDataType.FUEL, fuelData); + + // DURABILITY + MachineData durabilityData = new MachineData(MachineData.DataFlag.UP, 50000); + durabilityData.setTextures(0, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27); + super.setData(MachineDataType.DURABILITY, durabilityData); + + // PROGRESS + MachineData progressData = new MachineData(MachineData.DataFlag.DOWN, 20, 0); + progressData.setTextures(0, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52); + super.setData(MachineDataType.PROGRESS, progressData); + + super.setBlockedSlots(0, 1, 2, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26); + super.setOpenSlots(3, 5); + super.setOutputSlots(22); + + super.setMachineItem(new ItemFactory(Material.DROPPER).setName(C.WHITE + C.BOLD + super.getName()).setLore(C.GRAY + "Machine").build()); + + String[] description = { + C.DARK_GRAY + C.ITALIC + " " + super.getName(), + "", + "", + C.YELLOW + C.BOLD + "MACHINE RECIPES", + C.GRAY + " Note, recipes consume fuel and durability.", + C.GRAY + " Some more than others.", + "", + " " + i("霜", 6) + i("霔", 1) + " 霚 " + i("霉", 1), + "", + " " + i("霛", 3) + i("霉", 1) + " 霚 " + i("霝", 1), + "", + C.GRAY + " Use the command " + C.WHITE + "/recipe" + C.GRAY + " for", + C.GRAY + " a visual tutorial on drug recipes." + }; + + for (int i : super.getBlockedSlots()) { + super.getInventory().setItem(i, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + //Machine Frame + super.getInventory().setItem(0, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 80) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + this.initFuelItems(fuelData); + this.initDurabilityItems(durabilityData); + + //Progress Item. + super.getInventory().setItem(11, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) progressData.getTexture()) + .setName(C.GREEN + C.BOLD + "MACHINE TUTORIAL") + .setLore(description) + .setEnchantment(Enchantment.DURABILITY, 1) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + public void initFuelItems(MachineData data) { + String[] lore = { + C.GRAY + " Adding burnable items will replenish", + C.GRAY + " your machine fuel counter.", + "", + // fire - oak_plank - 2 + C.RESET + " 霚 " + C.WHITE + "[霡] +" + C.YELLOW + "2" + C.WHITE + " Fuel", + // fire - coal - 8 + C.RESET + " 霚 " + C.WHITE + "[霖] +" + C.GOLD + "8" + C.WHITE + " Fuel", + // fire - coal_block - 160 + C.RESET + " 霚 " + C.WHITE + "[霗] +" + C.RED + "80" + C.WHITE + " Fuel", + // fire - lava - 100 + C.RESET + " 霚 " + C.WHITE + "[霙] +" + C.RED + "100" + C.WHITE + " Fuel", + "" + }; + + //Fuel Item. + super.getInventory().setItem(19, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(10, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(1, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.GOLD + C.BOLD + "MACHINE FUEL") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } + + public void initDurabilityItems(MachineData data) { + String[] lore = { + C.GRAY + " Once the durability is gone, you will", + C.GRAY + " need to fix your machine to repair it.", + "" + }; + + //Fuel Item. + super.getInventory().setItem(25, + new ItemFactory(Material.STONE_SWORD) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(16, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + + //Fuel Dummy Item. + super.getInventory().setItem(7, + new ItemFactory(Material.STAINED_GLASS_PANE) + .setDurability((short) 0) + .setName(C.AQUA + C.BOLD + "MACHINE DURABILITY") + .setLore(lore) + .setUnbreakable(true) + .addFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE, ItemFlag.HIDE_ENCHANTS) + .build() + ); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/pickers/PickerCommand.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/pickers/PickerCommand.java new file mode 100644 index 0000000..b8b0852 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/pickers/PickerCommand.java @@ -0,0 +1,110 @@ +package net.grandtheftmc.vice.pickers; + +import com.j0ach1mmall3.jlib.inventory.JLibItem; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import org.bukkit.Color; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public class PickerCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender s, Command c, String lbl, String[] args) { + if (!s.hasPermission("picker.use")) { + s.sendMessage(Lang.NOPERM.toString()); + return true; + } + if (!(s instanceof Player)) { + s.sendMessage(Utils.f(Lang.GTM + "&cYou are not a player!")); + return true; + } + Player player = (Player) s; + if (args.length == 0) { + s.sendMessage(Utils.f("&c/picker mechanic")); + s.sendMessage(Utils.f("&c/picker cabdriver")); + s.sendMessage(Utils.f("&c/picker warden")); + s.sendMessage(Utils.f("&c/picker copsalary")); + return true; + } + switch (args[0].toLowerCase()) { + case "mechanic": { + ArmorStand armorStand = (ArmorStand) player.getWorld().spawnEntity(player.getLocation(), + EntityType.ARMOR_STAND); + armorStand.setHelmet(new JLibItem.Builder().withType(Material.LEATHER_HELMET).withColor(Color.fromRGB(165, 42, 42)).build().getItemStack()); + armorStand.setChestplate(Vice.getItemManager().getItem("shirt").getItem()); + armorStand.setLeggings(Vice.getItemManager().getItem("pants").getItem()); + armorStand.setBoots(Vice.getItemManager().getItem("nikes").getItem()); + armorStand.setItemInHand(new ItemStack(Material.WORKBENCH)); + armorStand.setCustomName(Utils.f("&4&lMechanic")); + armorStand.setCustomNameVisible(true); + armorStand.setAI(false); + armorStand.setCollidable(false); + armorStand.setCanPickupItems(true); + armorStand.setGravity(false); + armorStand.setRemoveWhenFarAway(false); + armorStand.setBasePlate(false); + armorStand.setArms(true); + s.sendMessage(Lang.VEHICLES.f("&7You created a Mechanic!")); + return true; + } + case "cabdriver": { + ArmorStand armorStand = (ArmorStand) player.getWorld().spawnEntity(player.getLocation(), + EntityType.ARMOR_STAND); + armorStand.setHelmet(new JLibItem.Builder().withType(Material.LEATHER_HELMET).withColor(Color.YELLOW).build().getItemStack()); + armorStand.setChestplate(Vice.getItemManager().getItem("shirt").getItem()); + armorStand.setLeggings(Vice.getItemManager().getItem("pants").getItem()); + armorStand.setBoots(Vice.getItemManager().getItem("nikes").getItem()); + armorStand.setItemInHand(new ItemStack(Material.WATCH)); + armorStand.setCustomName(Utils.f("&e&lCab Driver")); + armorStand.setCustomNameVisible(true); + armorStand.setAI(false); + armorStand.setCollidable(false); + armorStand.setCanPickupItems(true); + armorStand.setGravity(false); + armorStand.setRemoveWhenFarAway(false); + armorStand.setBasePlate(false); + armorStand.setArms(true); + s.sendMessage(Lang.VEHICLES.f("&7You created a Cab Driver!")); + return true; + } + case "warden": + ArmorStand armorStand = (ArmorStand) player.getWorld().spawnEntity(player.getLocation(), + EntityType.ARMOR_STAND); + armorStand.setHelmet(new JLibItem.Builder().withType(Material.LEATHER_HELMET).withColor(Color.BLACK).build().getItemStack()); + armorStand.setChestplate(Vice.getItemManager().getItem("kevlarvest").getItem()); + armorStand.setLeggings(Vice.getItemManager().getItem("pants").getItem()); + armorStand.setBoots(Vice.getItemManager().getItem("nikes").getItem()); + armorStand.setItemInHand(Vice.getItemManager().getItem("nightstick").getItem()); + armorStand.setCustomName(Utils.f("&c&lWarden")); + armorStand.setCustomNameVisible(true); + armorStand.setAI(false); + armorStand.setCollidable(false); + armorStand.setCanPickupItems(true); + armorStand.setGravity(false); + armorStand.setRemoveWhenFarAway(false); + armorStand.setBasePlate(false); + armorStand.setArms(true); + s.sendMessage(Lang.VEHICLES.f("&7You created a Warden!")); + return true; + case "copsalary": { + Vice.getPickerManager().addCopSalary(player.getLocation()); + s.sendMessage(Lang.COPS.f("&7You added the cop salary picker!")); + return true; + } + default: + s.sendMessage(Utils.f("&c/picker mechanic")); + s.sendMessage(Utils.f("&c/picker cabdriver")); + s.sendMessage(Utils.f("&c/picker warden")); + s.sendMessage(Utils.f("&c/picker copsalary")); + return true; + } + } +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/pickers/PickerManager.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/pickers/PickerManager.java new file mode 100644 index 0000000..c2600b6 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/pickers/PickerManager.java @@ -0,0 +1,43 @@ +package net.grandtheftmc.vice.pickers; + +import net.citizensnpcs.api.CitizensAPI; +import net.citizensnpcs.api.npc.NPC; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import org.bukkit.Location; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.EntityType; +import org.bukkit.event.player.PlayerTeleportEvent; + +public class PickerManager { + + public PickerManager() { + this.load(); + } + + private NPC copSalary; + + private void load() { + YamlConfiguration c = Vice.getSettings().getPickersConfig(); + if (c.get("copSalary") != null) this.addCopSalary(Utils.teleportLocationFromString(c.getString("copSalary"))); + } + + + public void addCopSalary(Location location) { + if (location == null) return; + if (this.copSalary == null) { + this.copSalary = CitizensAPI.getNPCRegistry().createNPC(EntityType.VILLAGER, Utils.f("&3&lCarl")); + this.copSalary.spawn(location); + this.copSalary.setProtected(true); + } + this.copSalary.teleport(location, PlayerTeleportEvent.TeleportCause.PLUGIN); + } + + public void save() { + YamlConfiguration c = Vice.getSettings().getPickersConfig(); + c.set("copSalary", this.copSalary == null ? null : Utils.teleportLocationToString(this.copSalary.getStoredLocation())); + if(this.copSalary!=null) + this.copSalary.destroy(); + Utils.saveConfig(c, "pickers"); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/redstone/PandaRedstoneWire.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/redstone/PandaRedstoneWire.java new file mode 100644 index 0000000..a5bc533 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/redstone/PandaRedstoneWire.java @@ -0,0 +1,334 @@ +package net.grandtheftmc.vice.redstone; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import net.grandtheftmc.vice.utils.ReflectUtil; +import net.minecraft.server.v1_12_R1.*; +import org.apache.commons.lang.ArrayUtils; +import org.bukkit.event.Event; +import org.bukkit.event.block.BlockRedstoneEvent; + +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +/** + * @author md_5 + * @author Teddeh + */ +public class PandaRedstoneWire extends BlockRedstoneWire { + + private List<BlockPosition> turnOff; + private List<BlockPosition> turnOn; + private final Set<BlockPosition> updatedRedstoneWire; + private static final EnumDirection[] facingsHorizontal; + private static final EnumDirection[] facingsVertical; + private static final EnumDirection[] facings; + private static final BaseBlockPosition[] surroundingBlocksOffset; + private boolean g; + + public PandaRedstoneWire() { + this.turnOff = Lists.newArrayList(); + this.turnOn = Lists.newArrayList(); + this.updatedRedstoneWire = Sets.newLinkedHashSet(); + this.g = true; + this.c(0.0f); + this.a(SoundEffectType.d); + this.c("redstoneDust"); + this.p(); + } + + private void e(final World world, final BlockPosition blockposition) { + this.calculateCurrentChanges(world, blockposition); + final Set<BlockPosition> blocksNeedingUpdate = Sets.newLinkedHashSet(); + for (final BlockPosition posi : this.updatedRedstoneWire) { + this.addBlocksNeedingUpdate(world, posi, blocksNeedingUpdate); + } + final Iterator<BlockPosition> it = Lists.newLinkedList(this.updatedRedstoneWire).descendingIterator(); + while (it.hasNext()) { + this.addAllSurroundingBlocks(it.next(), blocksNeedingUpdate); + } + blocksNeedingUpdate.removeAll(this.updatedRedstoneWire); + this.updatedRedstoneWire.clear(); + for (final BlockPosition posi2 : blocksNeedingUpdate) { + world.a(posi2, this, blockposition); + } + } + + private void calculateCurrentChanges(final World world, final BlockPosition blockposition) { + if (world.getType(blockposition).getBlock() == this) { + this.turnOff.add(blockposition); + } + else { + this.checkSurroundingWires(world, blockposition); + } + while (!this.turnOff.isEmpty()) { + final BlockPosition pos = this.turnOff.remove(0); + IBlockData state = world.getType(pos); + final int oldPower = state.get(PandaRedstoneWire.POWER); + this.g = false; + final int blockPower = world.z(pos); + this.g = true; + int wirePower = this.getSurroundingWirePower(world, pos); + --wirePower; + int newPower = Math.max(blockPower, wirePower); + if (oldPower != newPower) { + final BlockRedstoneEvent event = new BlockRedstoneEvent(world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()), oldPower, newPower); + world.getServer().getPluginManager().callEvent(event); + newPower = event.getNewCurrent(); + } + if (newPower < oldPower) { + if (blockPower > 0 && !this.turnOn.contains(pos)) { + this.turnOn.add(pos); + } + state = this.setWireState(world, pos, state, 0); + } + else if (newPower > oldPower) { + state = this.setWireState(world, pos, state, newPower); + } + this.checkSurroundingWires(world, pos); + } + while (!this.turnOn.isEmpty()) { + final BlockPosition pos = this.turnOn.remove(0); + IBlockData state = world.getType(pos); + final int oldPower = state.get(PandaRedstoneWire.POWER); + this.g = false; + final int blockPower = world.z(pos); + this.g = true; + int wirePower = this.getSurroundingWirePower(world, pos); + --wirePower; + int newPower = Math.max(blockPower, wirePower); + if (oldPower != newPower) { + final BlockRedstoneEvent event = new BlockRedstoneEvent(world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()), oldPower, newPower); + world.getServer().getPluginManager().callEvent(event); + newPower = event.getNewCurrent(); + } + if (newPower > oldPower) { + state = this.setWireState(world, pos, state, newPower); + } + else if (newPower < oldPower) {} + this.checkSurroundingWires(world, pos); + } + this.turnOff.clear(); + this.turnOn.clear(); + } + + private void addWireToList(final World worldIn, final BlockPosition pos, final int otherPower) { + final IBlockData state = worldIn.getType(pos); + if (state.getBlock() == this) { + final int power = state.get(PandaRedstoneWire.POWER); + if (power < otherPower - 1 && !this.turnOn.contains(pos)) { + this.turnOn.add(pos); + } + if (power > otherPower && !this.turnOff.contains(pos)) { + this.turnOff.add(pos); + } + } + } + + private void checkSurroundingWires(final World worldIn, final BlockPosition pos) { + final IBlockData state = worldIn.getType(pos); + int ownPower = 0; + if (state.getBlock() == this) { + ownPower = state.get(PandaRedstoneWire.POWER); + } + for (final EnumDirection facing : PandaRedstoneWire.facingsHorizontal) { + final BlockPosition offsetPos = pos.shift(facing); + if (facing.k().c()) { + this.addWireToList(worldIn, offsetPos, ownPower); + } + } + for (final EnumDirection facingVertical : PandaRedstoneWire.facingsVertical) { + final BlockPosition offsetPos = pos.shift(facingVertical); + final boolean solidBlock = worldIn.getType(offsetPos).k(); + for (final EnumDirection facingHorizontal : PandaRedstoneWire.facingsHorizontal) { + if ((facingVertical == EnumDirection.UP && !solidBlock) || (facingVertical == EnumDirection.DOWN && solidBlock && !worldIn.getType(offsetPos.shift(facingHorizontal)).k())) { + this.addWireToList(worldIn, offsetPos.shift(facingHorizontal), ownPower); + } + } + } + } + + private int getSurroundingWirePower(final World worldIn, final BlockPosition pos) { + int wirePower = 0; + for (final EnumDirection enumfacing : EnumDirection.EnumDirectionLimit.HORIZONTAL) { + final BlockPosition offsetPos = pos.shift(enumfacing); + wirePower = this.getPower(worldIn, offsetPos, wirePower); + if (worldIn.getType(offsetPos).l() && !worldIn.getType(pos.up()).l()) { + wirePower = this.getPower(worldIn, offsetPos.up(), wirePower); + } + else { + if (worldIn.getType(offsetPos).l()) { + continue; + } + wirePower = this.getPower(worldIn, offsetPos.down(), wirePower); + } + } + return wirePower; + } + + private void addBlocksNeedingUpdate(final World worldIn, final BlockPosition pos, final Set<BlockPosition> set) { + final List<EnumDirection> connectedSides = this.getSidesToPower(worldIn, pos); + for (final EnumDirection facing : PandaRedstoneWire.facings) { + final BlockPosition offsetPos = pos.shift(facing); + if ((connectedSides.contains(facing.opposite()) || facing == EnumDirection.DOWN || (facing.k().c() && a(worldIn.getType(offsetPos), facing))) && this.canBlockBePoweredFromSide(worldIn.getType(offsetPos), facing, true)) { + set.add(offsetPos); + } + } + for (final EnumDirection facing : PandaRedstoneWire.facings) { + final BlockPosition offsetPos = pos.shift(facing); + if ((connectedSides.contains(facing.opposite()) || facing == EnumDirection.DOWN) && worldIn.getType(offsetPos).l()) { + for (final EnumDirection facing2 : PandaRedstoneWire.facings) { + if (this.canBlockBePoweredFromSide(worldIn.getType(offsetPos.shift(facing2)), facing2, false)) { + set.add(offsetPos.shift(facing2)); + } + } + } + } + } + + private boolean canBlockBePoweredFromSide(final IBlockData state, final EnumDirection side, final boolean isWire) { + if (state.getBlock() instanceof BlockPiston && state.get(BlockPiston.FACING) == side.opposite()) { + return false; + } + if (state.getBlock() instanceof BlockDiodeAbstract && state.get(BlockDiodeAbstract.FACING) != side.opposite()) { + return isWire && state.getBlock() instanceof BlockRedstoneComparator && (state.get(BlockRedstoneComparator.FACING)).k() != side.k() && side.k().c(); + } + return !(state.getBlock() instanceof BlockRedstoneTorch) || (!isWire && state.get(BlockRedstoneTorch.FACING) == side); + } + + private List<EnumDirection> getSidesToPower(final World worldIn, final BlockPosition pos) { + final List retval = Lists.newArrayList(); + for (final EnumDirection facing : PandaRedstoneWire.facingsHorizontal) { + if (this.b(worldIn, pos, facing)) { + retval.add(facing); + } + } + if (retval.isEmpty()) { + return Lists.newArrayList(PandaRedstoneWire.facingsHorizontal); + } + final boolean northsouth = retval.contains(EnumDirection.NORTH) || retval.contains(EnumDirection.SOUTH); + final boolean eastwest = retval.contains(EnumDirection.EAST) || retval.contains(EnumDirection.WEST); + if (northsouth) { + retval.remove(EnumDirection.EAST); + retval.remove(EnumDirection.WEST); + } + if (eastwest) { + retval.remove(EnumDirection.NORTH); + retval.remove(EnumDirection.SOUTH); + } + return retval; + } + + private void addAllSurroundingBlocks(final BlockPosition pos, final Set<BlockPosition> set) { + for (final BaseBlockPosition vect : PandaRedstoneWire.surroundingBlocksOffset) { + set.add(pos.a(vect)); + } + } + + private IBlockData setWireState(final World worldIn, final BlockPosition pos, IBlockData state, final int power) { + state = state.set(PandaRedstoneWire.POWER, power); + worldIn.setTypeAndData(pos, state, 2); + this.updatedRedstoneWire.add(pos); + return state; + } + + public void onPlace(final World world, final BlockPosition blockposition, final IBlockData iblockdata) { + if (!world.isClientSide) { + this.e(world, blockposition); + for (final EnumDirection enumdirection : EnumDirection.EnumDirectionLimit.VERTICAL) { + world.applyPhysics(blockposition.shift(enumdirection), this, false); + } + for (final EnumDirection enumdirection : EnumDirection.EnumDirectionLimit.HORIZONTAL) { + this.b(world, blockposition.shift(enumdirection)); + } + for (final EnumDirection enumdirection : EnumDirection.EnumDirectionLimit.HORIZONTAL) { + final BlockPosition blockposition2 = blockposition.shift(enumdirection); + if (world.getType(blockposition2).l()) { + this.b(world, blockposition2.up()); + } + else { + this.b(world, blockposition2.down()); + } + } + } + } + + public void remove(final World world, final BlockPosition blockposition, final IBlockData iblockdata) { + super.remove(world, blockposition, iblockdata); + if (!world.isClientSide) { + for (final EnumDirection enumdirection : EnumDirection.values()) { + world.applyPhysics(blockposition.shift(enumdirection), this, false); + } + this.e(world, blockposition); + for (final EnumDirection enumdirection2 : EnumDirection.EnumDirectionLimit.HORIZONTAL) { + this.b(world, blockposition.shift(enumdirection2)); + } + for (final EnumDirection enumdirection2 : EnumDirection.EnumDirectionLimit.HORIZONTAL) { + final BlockPosition blockposition2 = blockposition.shift(enumdirection2); + if (world.getType(blockposition2).l()) { + this.b(world, blockposition2.up()); + } + else { + this.b(world, blockposition2.down()); + } + } + } + } + + public void a(final IBlockData iblockdata, final World world, final BlockPosition blockposition, final Block block, final BlockPosition blockposition1) { + if (!world.isClientSide) { + if (this.canPlace(world, blockposition)) { + this.e(world, blockposition); + } + else { + this.b(world, blockposition, iblockdata, 0); + world.setAir(blockposition); + } + } + } + + public int b(final IBlockData iblockdata, final IBlockAccess iblockaccess, final BlockPosition blockposition, final EnumDirection enumdirection) { + if (!this.g) { + return 0; + } + final int i = iblockdata.get(BlockRedstoneWire.POWER); + if (i == 0) { + return 0; + } + if (enumdirection == EnumDirection.UP) { + return i; + } + if (this.getSidesToPower((World)iblockaccess, blockposition).contains(enumdirection)) { + return i; + } + return 0; + } + + private boolean b(final IBlockAccess iblockaccess, final BlockPosition blockposition, final EnumDirection enumdirection) { + final BlockPosition blockposition2 = blockposition.shift(enumdirection); + final IBlockData iblockdata = iblockaccess.getType(blockposition2); + final boolean flag = iblockdata.l(); + final boolean flag2 = iblockaccess.getType(blockposition.up()).l(); + return (!flag2 && flag && c(iblockaccess, blockposition2.up())) || a(iblockdata, enumdirection) || (iblockdata.getBlock() == Blocks.POWERED_REPEATER && iblockdata.get(BlockDiodeAbstract.FACING) == enumdirection) || (!flag && c(iblockaccess, blockposition2.down())); + } + + static { + facingsHorizontal = new EnumDirection[] { EnumDirection.WEST, EnumDirection.EAST, EnumDirection.NORTH, EnumDirection.SOUTH }; + facingsVertical = new EnumDirection[] { EnumDirection.DOWN, EnumDirection.UP }; + facings = (EnumDirection[]) ArrayUtils.addAll(PandaRedstoneWire.facingsVertical, PandaRedstoneWire.facingsHorizontal); + final Set<BaseBlockPosition> set = Sets.newLinkedHashSet(); + for (final EnumDirection facing : PandaRedstoneWire.facings) { + set.add(ReflectUtil.getOfT(facing, BaseBlockPosition.class)); + } + for (final EnumDirection facing2 : PandaRedstoneWire.facings) { + final BaseBlockPosition v1 = ReflectUtil.getOfT(facing2, BaseBlockPosition.class); + for (final EnumDirection facing3 : PandaRedstoneWire.facings) { + final BaseBlockPosition v2 = ReflectUtil.getOfT(facing3, BaseBlockPosition.class); + set.add(new BlockPosition(v1.getX() + v2.getX(), v1.getY() + v2.getY(), v1.getZ() + v2.getZ())); + } + } + set.remove(BlockPosition.ZERO); + surroundingBlocksOffset = set.toArray(new BaseBlockPosition[set.size()]); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/redstone/RedstoneManager.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/redstone/RedstoneManager.java new file mode 100644 index 0000000..84e2455 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/redstone/RedstoneManager.java @@ -0,0 +1,32 @@ +package net.grandtheftmc.vice.redstone; + +import net.grandtheftmc.vice.utils.ReflectUtil; +import net.minecraft.server.v1_12_R1.Block; +import net.minecraft.server.v1_12_R1.Blocks; +import net.minecraft.server.v1_12_R1.IBlockData; +import net.minecraft.server.v1_12_R1.MinecraftKey; + +/** + * @author md_5 + * @author Teddeh + */ +public class RedstoneManager { + + public RedstoneManager() { + add(55, "redstone_wire", (Block)new PandaRedstoneWire()); + ReflectUtil.setStatic("REDSTONE_WIRE", Blocks.class, get("redstone_wire")); + System.out.println("Redstone Manager has been initialised."); + } + + private static Block get(final String s) { + return Block.REGISTRY.get(new MinecraftKey(s)); + } + + private static void add(final int i, final String s, final Block block) { + Block.REGISTRY.a(i, new MinecraftKey(s), block); + for (final IBlockData iblockdata : block.s().a()) { + final int k = Block.REGISTRY.a(block) << 4 | block.toLegacyData(iblockdata); + Block.REGISTRY_ID.a(iblockdata, k); + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/season/Season.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/season/Season.java new file mode 100644 index 0000000..419e3f0 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/season/Season.java @@ -0,0 +1,39 @@ +package net.grandtheftmc.vice.season; + +import java.sql.Timestamp; + +public class Season { + + private final int number; + private final Timestamp start, expire; + private final SeasonData seasonData; + private final boolean current; + + public Season(int number, Timestamp start, Timestamp expire, SeasonData seasonData, boolean current) { + this.number = number; + this.start = start; + this.expire = expire; + this.seasonData = seasonData; + this.current = current; + } + + public int getNumber() { + return number; + } + + public Timestamp getStart() { + return start; + } + + public Timestamp getExpire() { + return expire; + } + + public SeasonData getSeasonData() { + return seasonData; + } + + public boolean isCurrent() { + return current; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/season/SeasonDAO.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/season/SeasonDAO.java new file mode 100644 index 0000000..be500fd --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/season/SeasonDAO.java @@ -0,0 +1,47 @@ +package net.grandtheftmc.vice.season; + +import com.google.common.collect.Lists; +import net.grandtheftmc.core.Core; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +public class SeasonDAO { + +//CREATE TABLE IF NOT EXISTS season ( +//season_num INT NOT NULL, +//server_key VARCHAR(8) NOT NULL, +//start_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP(), +//expire_time TIMESTAMP NOT NULL, +//data BLOB DEFAULT NULL, +//PRIMARY KEY (id, server_key) +//); + + public static List<Season> getSeasons(Connection connection) { + List<Season> list = Lists.newArrayList(); + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM season WHERE server_key=?;")) { + statement.setString(1, Core.getSettings().getType().name()); + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + int id = result.getInt("season_num"); + String data = result.getString("data"); + Season season = new Season( + id, + result.getTimestamp("start_time"), + result.getTimestamp("expire_time"), + data == null || data.equals("NULL") ? null : new SeasonData(data), + SeasonManager.SEASON == id + ); + list.add(season); + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + + return list; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/season/SeasonData.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/season/SeasonData.java new file mode 100644 index 0000000..b971c96 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/season/SeasonData.java @@ -0,0 +1,14 @@ +package net.grandtheftmc.vice.season; + +public class SeasonData { + + private final String rawData; + + public SeasonData(String rawData) { + this.rawData = rawData; + } + + public String getRawData() { + return rawData; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/season/SeasonListener.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/season/SeasonListener.java new file mode 100644 index 0000000..09c0dff --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/season/SeasonListener.java @@ -0,0 +1,92 @@ +package net.grandtheftmc.vice.season; + +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.vice.hologram.Hologram; +import net.grandtheftmc.vice.hologram.HologramManager; +import net.grandtheftmc.vice.hologram.TypeWriter; +import net.grandtheftmc.vice.hologram.event.HologramReceiveEvent; +import net.grandtheftmc.vice.hologram.exception.HologramDuplicateException; +import net.grandtheftmc.vice.hologram.exception.HologramDuplicateNodeException; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitTask; + +public class SeasonListener implements Listener { + + private final SeasonManager seasonManager; + protected Hologram hologram; + BukkitTask task; + + private final TypeWriter typeWriter; + private int progress = 1; + + SeasonListener(SeasonManager seasonManager, JavaPlugin plugin, HologramManager hologramManager) { + this.seasonManager = seasonManager; + this.typeWriter = new TypeWriter("&d&lVice&f&lMC Season &d&l2", 15); + + ServerUtil.runTaskLater(() -> { + Location origin = new Location(Bukkit.getWorld("spawn"), 137.5, 82, 235.5); + try { + this.hologram = hologramManager.create(2, origin); + this.hologram.addNode(1); + this.hologram.addNode(2); + this.hologram.addNode(3); + this.hologram.addNode(4); + + this.task = Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, () -> { + this.hologram.refresh(1); + + if (progress % 10 == 0) { + this.hologram.refresh(4); + this.progress = 0; + } + + progress++; + }, 20L, 3L); + } + catch (HologramDuplicateException | HologramDuplicateNodeException e) { + e.printStackTrace(); + } + }, 20*5); + + Bukkit.getPluginManager().registerEvents(this, plugin); + } + + @EventHandler + protected final void onPlayerJoin(PlayerJoinEvent event) { + if (this.hologram == null) return; + ServerUtil.runTaskLaterAsync(() -> this.hologram.spawn(event.getPlayer()), 20L); + } + + @EventHandler + protected final void onHologramReceive(HologramReceiveEvent event) { + int id = event.getHologram().getId(); + int nodeId = event.getNode().getId(); + + if(id != 2) return; + + if (nodeId == 1) { + event.setText(this.typeWriter.next()); + } + + else if (nodeId == 2) { + event.setText(" "); + event.setDisplay(false); + } + + else if (nodeId == 3) { + event.setText("&c&lSeason ends in"); + } + + else if (nodeId == 4) { + long difference = (seasonManager.getCurrentSeason().getExpire().getTime() - System.currentTimeMillis()) / 1000; + event.setText(Utils.timeInSecondsToText(difference, C.DARK_RED + C.BOLD, C.RED, C.WHITE)); + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/season/SeasonManager.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/season/SeasonManager.java new file mode 100644 index 0000000..16370eb --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/season/SeasonManager.java @@ -0,0 +1,64 @@ +package net.grandtheftmc.vice.season; + +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.Component; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.hologram.HologramManager; +import org.bukkit.Bukkit; +import org.bukkit.plugin.java.JavaPlugin; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.List; + +public class SeasonManager implements Component <SeasonManager, Vice> { + + static final int SEASON = 2; + + private List<Season> seasons; + private Season current; + + private final SeasonListener seasonListener; + + public SeasonManager(JavaPlugin plugin, HologramManager hologramManager) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + this.seasons = SeasonDAO.getSeasons(connection); + } catch (SQLException e) { + e.printStackTrace(); + } + + this.current = getCurrentSeason(); + + if (this.current != null) { + Bukkit.getConsoleSender().sendMessage(C.AQUA + "Vice s" + this.current.getNumber()); + } + + this.seasonListener = new SeasonListener(this, plugin, hologramManager); + } + + @Override + public SeasonManager onDisable(Vice plugin) { + if (seasonListener != null) { + if (seasonListener.task != null) + this.seasonListener.task.cancel(); + + if (seasonListener.hologram != null) + this.seasonListener.hologram.destroy(); + } + + return this; + } + + public List<Season> getSeasons() { + return seasons; + } + + public Season getCurrentSeason() { + return this.current == null ? seasons.stream().filter(Season::isCurrent).findFirst().orElse(null) : this.current; + } + + public boolean hasEnded() { + return this.getCurrentSeason().getExpire().getTime() >= System.currentTimeMillis(); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/tasks/GlassesTask.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/tasks/GlassesTask.java new file mode 100644 index 0000000..49c8b5d --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/tasks/GlassesTask.java @@ -0,0 +1,36 @@ +package net.grandtheftmc.vice.tasks; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +public class GlassesTask extends BukkitRunnable { + private Long ct; + + @Override + public void run() { + this.ct = System.currentTimeMillis(); + Bukkit.getOnlinePlayers().forEach(player -> checkGlasses(player)); + } + + public void checkGlasses(Player player) { + if(player.getInventory().getHelmet() == null) return; + if(player.getInventory().getHelmet().getType() != Material.CHAINMAIL_HELMET) return; + player.getNearbyEntities(30, 30, 30).forEach(entity -> { + if(entity.getType() != EntityType.PLAYER) return; + Player target = (Player)entity; + new BukkitRunnable() { + @Override + public void run() { + ViceUtils.sendGlow(player, target, 12); + } + }.runTaskAsynchronously(Vice.getInstance()); + }); + player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 20, 20); + } +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/tasks/Lottery.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/tasks/Lottery.java new file mode 100644 index 0000000..5d66085 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/tasks/Lottery.java @@ -0,0 +1,285 @@ +package net.grandtheftmc.vice.tasks; + +import com.gmail.filoghost.holographicdisplays.api.Hologram; +import com.gmail.filoghost.holographicdisplays.api.HologramsAPI; +import com.gmail.filoghost.holographicdisplays.api.line.TextLine; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.users.ViceUser; +import net.grandtheftmc.vice.utils.WeightedRandomCollection; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +/** + * Created by Liam on 11/01/2017. + */ +public class Lottery { + + private LocalDateTime end; + private Location hologramLocation; + private Hologram hologram; + private final List<TextLine> textLines = new ArrayList<>(); + private final List<LotteryPlayer> lotteryPlayers = new ArrayList<>(); + private List<LotteryPlayer> winners = new ArrayList<>(3); + + public Lottery() { + //this.loadConfig(); + // this.startScheduler(); + } + + public void loadConfig() { + YamlConfiguration c = Vice.getSettings().getLotteryConfig(); + this.hologramLocation = Utils.teleportLocationFromString(c.getString("hologramLocation")); + this.end = c.get("end") == null ? LocalDateTime.now(ZoneId.of("UTC")).plusDays(7) + : LocalDateTime.of(c.getInt("end.year"), c.getInt("end.month"), c.getInt("end.day"), c.getInt("end.hour"), c.getInt("end.minute")); + this.winners.clear(); + if (c.get("winners") != null) + for (String s : c.getConfigurationSection("winners").getKeys(false)) { + try { + UUID uuid = UUID.fromString(c.getString("winners." + s + ".uuid")); + String name = c.getString("winners." + s + ".name"); + double amnt = c.getDouble("winners." + s + ".amount"); + boolean paid = c.getBoolean("winners." + s + ".paid"); + LotteryPlayer player = new LotteryPlayer(uuid, name); + player.setAmount(amnt); + player.setPaid(paid); + this.winners.add(player); + } catch (Exception e) { + Core.log("Error while loading lottery winner " + s); + e.printStackTrace(); + } + } + this.lotteryPlayers.clear(); + if (c.get("players") != null) + for (String s : c.getConfigurationSection("players").getKeys(false)) + try { + UUID uuid = UUID.fromString(s); + LotteryPlayer player = new LotteryPlayer(uuid, c.getString("players." + uuid + ".name")); + player.setTickets(c.getInt("players." + uuid + ".tickets")); + this.lotteryPlayers.add(player); + } catch (Exception e) { + Core.log("Error while loading lottery player " + s); + e.printStackTrace(); + } + } + + public void saveConfig() { + YamlConfiguration c = Vice.getSettings().getLotteryConfig(); + for (String s : c.getKeys(false)) + c.set(s, null); + c.set("hologramLocation", Utils.teleportLocationToString(this.hologramLocation)); + c.set("end.year", this.end.getYear()); + c.set("end.month", this.end.getMonthValue()); + c.set("end.day", this.end.getDayOfMonth()); + c.set("end.hour", this.end.getHour()); + c.set("end.minute", this.end.getMinute()); + for (int i = 0; i < 3; i++) { + LotteryPlayer player = this.getWinner(i); + if (player == null) continue; + c.set("winners." + i + ".uuid", player.getUUID().toString()); + c.set("winners." + i + ".name", player.getName()); + c.set("winners." + i + ".amount", player.getAmount()); + c.set("winners." + i + ".paid", player.isPaid()); + } + for (LotteryPlayer player : this.lotteryPlayers) { + c.set("players." + player.getUUID() + ".name", player.getName()); + c.set("players." + player.getUUID() + ".tickets", player.getTickets()); + } + Utils.saveConfig(c, "lottery"); + } + + private void startScheduler() { + new BukkitRunnable() { + @Override + public void run() { + if (Lottery.this.end != null && Lottery.this.end.isBefore(LocalDateTime.now(ZoneId.of("UTC")))) + Lottery.this.end(); + Lottery.this.updateHologram(); + } + }.runTaskTimer(Vice.getInstance(), 20, 20); + + } + + public static void test() { + WeightedRandomCollection<String> collection = new WeightedRandomCollection<>(); + collection.add(50, "Top Guy"); + collection.add(5, "Medium Guy"); + collection.add(3, "Mediocre Guy"); + collection.add(2, "Peasant1"); + collection.add(2, "Peasant2"); + collection.add(2, "Peasant3"); + collection.add(2, "Peasant4"); + collection.add(2, "Peasant5"); + collection.add(1, "Slave1"); + collection.add(1, "Slave2"); + collection.add(1, "Slave3"); + collection.add(1, "Slave4"); + collection.add(1, "Slave5"); + List<String> names = new ArrayList<>(); + Bukkit.broadcastMessage("--- " + collection.values().size()); + for (int i = 0; i < 13; i++) + if (!names.contains(collection.next())) + names.add(collection.last()); + + names.forEach(Bukkit::broadcastMessage); + } + + + public void end() { + this.end = LocalDateTime.now(ZoneId.of("UTC")).plusDays(7); + WeightedRandomCollection<LotteryPlayer> players = new WeightedRandomCollection<>(); + for (LotteryPlayer player : this.lotteryPlayers) { + players.add(player.getTickets(), player); + } + this.winners = players.getUniqueElements(3); + double value = this.getPotValue(); + LotteryPlayer winner1 = this.getWinner(0); + LotteryPlayer winner2 = this.getWinner(1); + LotteryPlayer winner3 = this.getWinner(2); + if (winner1 != null) winner1.addAmount(0.7 * value); + if (winner2 != null) winner2.addAmount(0.2 * value); + if (winner3 != null) winner3.addAmount(0.1 * value); + ViceUtils.log("lottery", winner1.getName() + " has won the lottery prize of " + 0.7 * value + "(70% of the pot)"); + ViceUtils.log("lottery", winner2.getName() + " has won the lottery prize of " + 0.2 * value + "(20% of the pot)"); + ViceUtils.log("lottery", winner3.getName() + " has won the lottery prize of " + 0.1 * value + "(10% of the pot)"); + this.lotteryPlayers.clear(); + for (Player p : Bukkit.getOnlinePlayers()) + p.sendMessage(new String[]{"", Utils.f(ViceUtils.HEADER), "", + Utils.fc("&e&lLottery Results"), "", + Utils.fc("&7For a total pot of &a&l" + Utils.formatMoney(value)), + Utils.fc("&a#&l1&7: &r" + winner1 + " &a&l" + Utils.formatMoney(0.7 * value) + "&7 (&a70%&7 of the pot)"), + Utils.fc("&a#&l2&7: &r" + winner2 + " &a&l" + Utils.formatMoney(0.2 * value) + "&7 (&a20%&7 of the pot)"), + Utils.fc("&a#&l3&7: &r" + winner3 + " &a&l" + Utils.formatMoney(0.1 * value) + "&7 (&a10%&7 of the pot)"), + "", Utils.fc("&e&lCongratulations to the winners!"), + "", Utils.f(ViceUtils.FOOTER), ""}); + + for (int i = 0; i < 3 && i < this.winners.size(); i++) { + LotteryPlayer winner = this.winners.get(i); + if (winner != null && !winner.isPaid()) { + Player player = Bukkit.getPlayer(winner.getUUID()); + if (player == null) continue; + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + user.addMoney(winner.getAmount()); + winner.setPaid(true); + player.sendMessage(Lang.LOTTERY.f("&7You've won the lottery, coming in " + (i == 0 ? "1st" : i == 1 ? "2nd" : i == 2 ? "3rd" : "error") + "! &a" + Utils.formatMoney(winner.getAmount()) + "&7 was added to your balance.")); + ViceUtils.updateBoard(player, user); + } + } + + } + + + public void updateHologram() { + if (this.hologramLocation == null) return; + LotteryPlayer winner1 = this.winners.isEmpty() ? null : this.winners.get(0); + LotteryPlayer winner2 = this.winners.size() > 1 ? this.winners.get(1) : null; + LotteryPlayer winner3 = this.winners.size() > 2 ? this.winners.get(2) : null; + if (this.hologram == null) { + this.hologram = HologramsAPI.createHologram(Vice.getInstance(), this.hologramLocation.clone().add(0.5, 4, 0.5)); + this.textLines.add(this.hologram.appendTextLine(Utils.f("&e&lLottery"))); + this.textLines.add(this.hologram.appendTextLine(Utils.f("&7&oGo big or go home!"))); + this.textLines.add(this.hologram.appendTextLine("")); + this.textLines.add(this.hologram.appendTextLine(Utils.f("&7Pot value:"))); + this.textLines.add(this.hologram.appendTextLine(Utils.f("&a&l" + Utils.formatMoney(this.getPotValue())))); + this.textLines.add(this.hologram.appendTextLine("")); + this.textLines.add(this.hologram.appendTextLine(Utils.f("&7Time until jackpot:"))); + this.textLines.add(this.hologram.appendTextLine(Utils.f("&a&l" + this.timeToEnd()))); + this.textLines.add(this.hologram.appendTextLine("")); + this.textLines.add(this.hologram.appendTextLine(Utils.f("&7Last week's winners:"))); + this.textLines.add(this.hologram.appendTextLine(Utils.f(winner1 == null ? "" : ("&a#&l1&7: &r" + winner1 + " &a" + Utils.formatMoney(winner1.getAmount()) + "&7 (&a70%&7 of the pot)")))); + this.textLines.add(this.hologram.appendTextLine(Utils.f(winner2 == null ? "" : ("&a#&l2&7: &r" + winner2 + " &a" + Utils.formatMoney(winner2.getAmount()) + "&7 (&a20%&7 of the pot)")))); + this.textLines.add(this.hologram.appendTextLine(Utils.f(winner3 == null ? "" : ("&a#&l3&7: &r" + winner3 + " &a" + Utils.formatMoney(winner3.getAmount()) + "&7 (&a10%&7 of the pot)")))); + } else { + this.textLines.get(4).setText(Utils.f("&a&l" + Utils.formatMoney(this.getPotValue()))); + this.textLines.get(7).setText(Utils.f("&a&l" + this.timeToEnd())); + this.textLines.get(10).setText(Utils.f("&a#&l1&7: &r" + (winner1 == null ? "" : (winner1 + " &a" + Utils.formatMoney(winner1.getAmount()) + "&7 (&a70%&7 of the pot)")))); + this.textLines.get(11).setText(Utils.f("&a#&l2&7: &r" + (winner2 == null ? "" : (winner2 + " &a" + Utils.formatMoney(winner2.getAmount()) + "&7 (&a20%&7 of the pot)")))); + this.textLines.get(12).setText(Utils.f("&a#&l2&7: &r" + (winner3 == null ? "" : (winner3 + " &a" + Utils.formatMoney(winner3.getAmount()) + "&7 (&a10%&7 of the pot)")))); + + } + } + + public String timeToEnd() { + if (this.end == null) this.end = LocalDateTime.now(ZoneId.of("UTC")).plusDays(1); + return Utils.timeInSecondsToText(ChronoUnit.SECONDS.between(LocalDateTime.now(ZoneId.of("UTC")), this.end)); + } + + public List<LotteryPlayer> getTickets() { + return this.lotteryPlayers; + } + + public LotteryPlayer getLotteryPlayer(UUID uuid) { + return this.lotteryPlayers.stream().filter(player -> Objects.equals(player.getUUID(), uuid)).findFirst().orElse(null); + } + + public LotteryPlayer getWinner(UUID uuid) { + return this.winners.stream().filter(player -> Objects.equals(player.getUUID(), uuid)).findFirst().orElse(null); + } + + + public LotteryPlayer getWinner(int i) { + return this.winners.size() > i ? this.winners.get(i) : null; + } + + public double getPotValue() { + return 500 * this.lotteryPlayers.stream().mapToInt(LotteryPlayer::getTickets).sum(); + } + + public void joinCheck(Player player, User user, ViceUser viceUser) { + for (int i = 0; i < 3 && i < this.winners.size(); i++) { + LotteryPlayer winner = this.winners.get(i); + if (winner != null && !winner.isPaid() && Objects.equals(winner.getUUID(), player.getUniqueId())) { + viceUser.addMoney(winner.getAmount()); + winner.setPaid(true); + player.sendMessage(Lang.LOTTERY.f("&7You've won the lottery, coming in " + (i == 0 ? "1st" : i == 1 ? "2nd" : i == 2 ? "3rd" : "error") + "! &a$&l" + Utils.formatMoney(winner.getAmount()) + "&7 was added to your balance.")); + } + } + if (user.isSpecial()) { + LotteryPlayer p = this.getLotteryPlayer(player.getUniqueId()); + if (p != null) return; + p = new LotteryPlayer(player.getUniqueId(), player.getName()); + this.lotteryPlayers.add(p); + p.addTickets(ViceUtils.getFreeLotteryTickets(user.getUserRank())); + player.sendMessage(Lang.LOTTERY.f("&7Thank you for financially supporting GTM! You have been given &a&l" + p.getTickets() + "&7 free lottery tickets for this week's draw.")); + } + } + + public List<LotteryPlayer> getLastWinners() { + return this.winners; + } + + public void addLotteryPlayer(LotteryPlayer p) { + this.lotteryPlayers.add(p); + } + + public void setHologramLocation(Location hologramLocation) { + this.hologramLocation = hologramLocation; + } + + public Location getHologramLocation() { + return this.hologramLocation; + } + + public void setEnd(LocalDateTime end) { + this.end = end; + } + + public LocalDateTime getEnd() { + return this.end; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/tasks/LotteryPlayer.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/tasks/LotteryPlayer.java new file mode 100644 index 0000000..15fa203 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/tasks/LotteryPlayer.java @@ -0,0 +1,64 @@ +package net.grandtheftmc.vice.tasks; + +import java.util.UUID; + +public class LotteryPlayer { + private final UUID uuid; + private final String name; + private int tickets; + + private double amount; + private boolean paid; + + public LotteryPlayer(UUID uuid, String name) { + this.uuid = uuid; + this.name = name; + } + + public UUID getUUID() { + return this.uuid; + } + + public String getName() { + return this.name; + } + + public int getTickets() { + return this.tickets; + } + + public void setTickets(int tickets) { + this.tickets = tickets; + } + + public void addTickets(int tickets) { + this.tickets += tickets; + } + + public void setAmount(double amount) { + this.amount = amount; + } + + public void addAmount(double amount) { + this.amount += amount; + } + + public double getAmount() { + return this.amount; + } + + public void setPaid(boolean b) { + this.paid = b; + } + + public boolean isPaid() { + return this.paid; + } + + @Override + public String toString() { + return this.name; + } + + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/tasks/PlayerTask.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/tasks/PlayerTask.java new file mode 100644 index 0000000..aada320 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/tasks/PlayerTask.java @@ -0,0 +1,123 @@ +package net.grandtheftmc.vice.tasks; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.ViceUser; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ThreadLocalRandom; + +public class PlayerTask extends BukkitRunnable { + public static List<Block> fireBlocks = new ArrayList<>(); + private Long ct; + + @Override + public void run() { + this.ct = System.currentTimeMillis(); + if (!fireBlocks.isEmpty()) checkFire(); + for (Player player : Bukkit.getOnlinePlayers()) { + ViceUser viceUser = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + this.checkCombatTagExpiration(player, viceUser); + this.checkTpaRequestExpiration(player, viceUser); + this.checkJailRelease(player, viceUser); + this.checkDualWield(player); +// this.checkElytra(player); + viceUser.checkBackupExpiration(player); + } + } + + + private void checkFire() { + Block block = fireBlocks.get(ThreadLocalRandom.current().nextInt(fireBlocks.size())); + if (block.getChunk().isLoaded()) block.setType(Material.AIR); + fireBlocks.remove(block); + } + +// private void checkElytra(Player player) { +// if (player.isGliding()) { +// if (player.getInventory().contains(Material.COAL)) { +// if (player.isSneaking()) { +// ItemStack fuel = player.getInventory().getItem(player.getInventory().first(Material.COAL)); +// if (fuel.getAmount() <= 1 || fuel.getAmount() - 5 < 1) { +// player.getInventory().remove(fuel); +// } else { +// fuel.setAmount(fuel.getAmount() - 5); +// } +// player.getWorld().playSound(player.getLocation(), Sound.ENTITY_ITEM_PICKUP, 1.0F, 1.0F); +// player.getInventory().getChestplate().setDurability((short) 0); +// } +// } else { +// player.sendMessage(Lang.VEHICLES.f("&7Elytra requires (jetpack) fuel to fly!")); +// player.setGliding(false); +// if (player.getInventory().firstEmpty() == -1) { +// player.getWorld().dropItem(player.getLocation(), player.getInventory().getChestplate()); +// } else { +// player.getInventory().addItem(player.getInventory().getChestplate()); +// } +// player.getInventory().setChestplate(null); +// player.setFallDistance(-50); +// } +// } +// } + + private void checkDualWield(Player player) { + if (player.getInventory().getItemInOffHand() != null && player.getInventory().firstEmpty() != -1) { + if (player.getInventory().getItemInOffHand().getType() == Material.SHIELD) return; + player.getInventory().addItem(player.getInventory().getItemInOffHand()); + } + player.getInventory().setItemInOffHand(null); + } + + private void checkJailRelease(Player player, ViceUser viceUser) { + int timer = viceUser.getJailTimer(); + if (!viceUser.isArrested() || timer < 0) + return; + if (timer == 600 || timer == 300 || timer == 180 || timer == 120 || timer == 60 || timer == 30 + || timer == 15 || timer == 10 || (timer <= 5 && timer > 0)) { + player.sendMessage( + Lang.JAIL.f("&7You will be released in &a" + Utils.timeInSecondsToText(timer) + "&7!")); + if (timer == 1) { + player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 50, 0)); + player.playSound(player.getLocation(), Sound.BLOCK_LAVA_EXTINGUISH, 0.5F, 1); + } else + player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 4.0F / timer, 2); + } + if (timer == 0) { + viceUser.resetJail(); + player.teleport(Vice.getWorldManager().getWarpManager().getSpawn().getLocation()); + player.sendMessage(Lang.JAIL.f("&7You were released from jail!")); + player.removePotionEffect(PotionEffectType.SLOW); + player.getActivePotionEffects().clear(); + return; + } + viceUser.setJailTimer(timer - 1); + } + + + private void checkCombatTagExpiration(Player player, ViceUser user) { + if (user.isInCombat() || user.getLastTag() == -1) + return; + user.setLastTag(-1); +// Core.getUserManager().getLoadedUser(player.getUniqueId()).showPet(player); + player.sendMessage(Utils.f(Lang.COMBATTAG + "&7You are no longer in combat. You may log out safely.")); + } + + + private void checkTpaRequestExpiration(Player player, ViceUser viceUser) { + if (viceUser.getLastTpaRequest() > 0 && viceUser.getLastTpaRequest() + 60000 < this.ct) { + viceUser.unsetTpaRequests(); + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/tasks/TaskManager.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/tasks/TaskManager.java new file mode 100644 index 0000000..b16f3a5 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/tasks/TaskManager.java @@ -0,0 +1,24 @@ +package net.grandtheftmc.vice.tasks; + +import net.grandtheftmc.vice.Vice; + +public class TaskManager { + private PlayerTask playerTask; + private GlassesTask glassesTask; + + public TaskManager() { + this.startTasks(); + } + + private void startTasks() { + this.playerTask = new PlayerTask(); + this.playerTask.runTaskTimer(Vice.getInstance(), 20, 20); + this.glassesTask = new GlassesTask(); + this.glassesTask.runTaskTimer(Vice.getInstance(), 100, 100); + } + + public PlayerTask getPlayerTask() { + return this.playerTask; + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/AntiAfkTimer.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/AntiAfkTimer.java new file mode 100644 index 0000000..970a6b6 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/AntiAfkTimer.java @@ -0,0 +1,38 @@ +package net.grandtheftmc.vice.users; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import java.util.HashMap; +import java.util.UUID; + +/** + * Created by Timothy Lampen on 3/6/2018. + */ +public class AntiAfkTimer implements Runnable { + + private final HashMap<UUID, Vector> directions = new HashMap<>(); + + + @Override + public void run() { + purgeData(); + for(Player player : Bukkit.getOnlinePlayers()) { + if(this.directions.containsKey(player.getUniqueId())){ + if(this.directions.get(player.getUniqueId()).equals(player.getLocation().getDirection())) { + player.kickPlayer(Lang.VICE.f("&cYou were kicked for being afk!")); + continue; + } + } + this.directions.put(player.getUniqueId(), player.getLocation().getDirection()); + } + } + + + private void purgeData(){ + directions.entrySet().removeIf(entry -> Bukkit.getPlayer(entry.getKey()) == null); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/CheatCode.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/CheatCode.java new file mode 100644 index 0000000..ca0fe7b --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/CheatCode.java @@ -0,0 +1,211 @@ +package net.grandtheftmc.vice.users; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.State; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import java.util.*; + +/** + * Created by Timothy Lampen on 8/21/2017. + */ +public enum CheatCode { + + KATANA(UserRank.ADMIN, Utils.createItem(Material.DIAMOND_SWORD, 421, "KATANA" , "&7Chop off heads with this masterful weapon!", "&7Delay: &e&l3 days."), true, false, "katana_cc", null), + JELLYLEGS(UserRank.ADMIN, Utils.createItem(Material.DIAMOND_BOOTS, "JELLYLEGS", "&7Recieve no more fall damage."), true, true, null, null), + SILKSPAWNERS(UserRank.SUPREME, Utils.createItem(Material.DIAMOND_PICKAXE, "SILKSPAWNERS", "&7Recieve the ability to silk touch spawners."), true, true, null, "&7To unlock this cheatcode, purchase the &c&lSUPREME&7 rank or the &2&lSILKSPAWNERS&7 cheatcode at &a&lstore.grandtheftmc.net&7!"), + NIGHTVIS(UserRank.SUPREME, Utils.createItem(Material.CHAINMAIL_HELMET, "NIGHTVIS", "&7Be able to toggle permanent night vision."), false, true, null, "&7To unlock this cheatcode, purchase the &c&lSUPREME&7 rank or the &2&lNIGHTVIS&7 cheatcode at &a&lstore.grandtheftmc.net&7!"), + NOFUEL(UserRank.ADMIN, Utils.createItem(Material.DIAMOND_SWORD, 1001, "NOFUEL", "&7Don't use any jetpack fuel in non-enemy territory while enemies aren't around."), true, true, null, null), + SNEAKY(UserRank.ADMIN, Utils.createItem(Material.GLASS_BOTTLE, "SNEAKY", "&7Gain invisibility for 5 seconds when you go to spawn ", "&7and exit the safezone to more easily sell your drugs"), true, true, null, null), + FEED(UserRank.SPONSOR, Utils.createItem(Material.COOKED_BEEF, "FEED", "&7Have access to the feed command."), true, false, null, null), + FUCKME(UserRank.ADMIN, Utils.createItem(Material.DIAMOND_SWORD, 401, "FUCKME", "&7Gives a dildo so you can go fuck yourself.", "&7Delay: &e&l7 days."), true, false, "fuckme_cc", null), + SANIC(UserRank.ADMIN, Utils.createItem(Material.LEATHER_BOOTS, "SANIC", "&7Gives speed II for 5 minutes.", "&7Delay: &e&l1 hour."), true, false, "sanic_cc", null), + YOUCANTSEEME(UserRank.ADMIN, Utils.createItem(Material.GLASS, "YOUCANTSEEME", "&7Gain invisibility for 3 minutes.", "&7Delay: &e&l1 hour."), true, false, "youcantseeme_cc", null), + WINGSUIT(UserRank.ADMIN, Utils.createItem(Material.ELYTRA, "WINGSUIT", "&7Recieve a single wingsuit", "&7Delay: &e&l3 days."), true, false, "wingsuit_cc", null), + FIXHAND(UserRank.VIP, Utils.createItem(Material.STICK, "FIXHAND", "&7Gain access to the /fix hand command."), true, false, null, null), + FIXALL(UserRank.SUPREME, Utils.createItem(Material.CHEST, "FIXALL", "&7Have the ability to do /fix all."), true, false, null, null), + STACK(UserRank.ADMIN, Utils.createItem(Material.GOLD_INGOT, "STACK", "&7Be able to do the /stack command."), true, false, null, null), + VILLAGERJOB(UserRank.ADMIN, Utils.createItem(Material.MONSTER_EGG,120, "Villager Job", "&7Shift right clicking a villager will give you the ability to change their profession.", "&7Delay: &e1 hour."), true, false, null, null), + QUICKSELL(UserRank.ELITE, Utils.createItem(Material.DISPENSER, "QUICK SELL", "&7Have the ability to sell items", "&7without having to travel back", "&7to spawn!"), true, false, null, "&7To unlock this cheatcode, purchase the &c&lELITE&7 rank or the &2&lQUICKSELL&7 cheatcode at &a&lstore.grandtheftmc.net&7!"), + ; + + private final ItemStack displayItem; + private final boolean toggleable, defaultToggle; + private final UserRank rank; + private String cooldownID, lockedLore; + + CheatCode(UserRank rank, ItemStack displayItem, boolean defaultToggle, boolean toggleable, String cooldownID, String lockedLore) { + ItemMeta im = displayItem.getItemMeta(); + im.setUnbreakable(true); + im.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE); + displayItem.setItemMeta(im); + this.defaultToggle = defaultToggle; + this.lockedLore = Utils.f(lockedLore==null ? "&7You can purchase this cheatcode at &a&lstore.grandtheftmc.net&7!" : lockedLore); + this.displayItem = displayItem; + this.toggleable = toggleable; + this.rank = rank; + this.cooldownID = cooldownID; + } + + public UserRank getMinmumRank() { + return rank; + } + + public State getDefaultState(){ + return this.defaultToggle ? State.ON : State.OFF; + } + + public String getLockedLore() { + return this.lockedLore; + } + + public boolean isToggleable() { + return toggleable; + } + + public ItemStack getDisplayItem(User user, State state) { + ItemStack is = displayItem.clone(); + ItemMeta im = is.getItemMeta(); + + if(state==State.LOCKED) { + ArrayList<String> lore = new ArrayList<>(im.getLore()); + lore.add(" "); + lore.add(Utils.f("&4&lLOCKED")); + if(this.rank.isHigherThan(UserRank.DEFAULT) && !this.rank.isHigherThan(UserRank.YOUTUBER)) { + lore.add(Utils.f("&4&lUnlocked with rank: " + rank.getColoredNameBold())); + } + im.setDisplayName(Utils.f(getStateColor(state) + im.getDisplayName())); + im.setLore(lore); + is.setItemMeta(im); + return is; + } + + if(user!=null && this.cooldownID!=null) { + boolean stillOnCooldown = user.isOnCooldown(this.cooldownID); + state = stillOnCooldown ? State.OFF : State.ON; + List<String> lore = new ArrayList<>(im.getLore()); + if(stillOnCooldown) + lore.set(1, Utils.f("&7Delay: &e&l" + Utils.timeInSecondsToText(user.getCooldownTimeLeft(this.cooldownID), C.RED, C.RED, C.GRAY) + "&7.")); + } + im.setDisplayName(Utils.f(getStateColor(state) + im.getDisplayName())); + is.setItemMeta(im); + return is; + } + + public static String seralizeCheatCodes(HashMap<CheatCode, CheatCodeState> codes) { + StringBuilder sb = new StringBuilder(); + codes.forEach((codea, statea) -> sb.append(codea.toString() + "#" + statea.getState() + "#" + statea.isPurchased() + "-")); + sb.deleteCharAt(sb.length()-1); + return sb.toString(); + } + + public void activate(User coreUser, ViceUser user, Player player, CheatCodeState cState) { + if(user.isArrested()) { + player.sendMessage(Lang.CHEAT_CODES.f("&7You cannot use this cheat code while you are arrested!")); + return; + } + if (cState.getState() == State.LOCKED) { + player.sendMessage(Lang.CHEAT_CODES.f("&7You haven't unlocked this cheat code yet!")); + return; + } + if(!this.isToggleable()){//the non-toggleables + if(coreUser.isOnCooldown(this.cooldownID)) { +// player.sendMessage(Lang.CHEAT_CODES.f("&7You must wait &a" + coreUser.getFormattedCooldown(this.cooldownID, true) + " &7before using this cheatcode again!")); + player.sendMessage(Lang.CHEAT_CODES.f("&7You must wait &a" + Utils.timeInSecondsToText(coreUser.getCooldownTimeLeft(this.cooldownID), C.RED, C.RED, C.GRAY) + " &7before using this cheatcode again!")); + return; + } + switch (this) { + case KATANA: + if(Utils.giveItems(player, Vice.getItemManager().getItem("katana").getItem())) { + player.sendMessage(Utils.f(Lang.CHEAT_CODES + "&cYour inventory was full so some items were dropped on the ground!")); + } + coreUser.addCooldown(this.cooldownID, 60*60*24*3, true, true); + player.sendMessage(Lang.CHEAT_CODES.f("&7You have used your katana cheat code!")); + break; + case FUCKME: + if(Utils.giveItems(player, Vice.getItemManager().getItem("dildo").getItem())) { + player.sendMessage(Utils.f(Lang.CHEAT_CODES + "&cYour inventory was full so some items were dropped on the ground!")); + } + coreUser.addCooldown(this.cooldownID, 60*60*24*7, true, true); + player.sendMessage(Lang.CHEAT_CODES.f("&7You have used your fuck me cheat code!")); + break; + case WINGSUIT: + if(Utils.giveItems(player, Vice.getItemManager().getItem("wingsuit").getItem())) { + player.sendMessage(Utils.f(Lang.CHEAT_CODES + "&cYour inventory was full so some items were dropped on the ground!")); + } + coreUser.addCooldown(this.cooldownID, 60*60*24*3, true, true); + player.sendMessage(Lang.CHEAT_CODES.f("&7You have used your wingsuit cheat code!")); + break; + case SANIC: + coreUser.addCooldown(this.cooldownID, 60*60, false, true); + player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 20*60*5, 1)); + player.sendMessage(Lang.CHEAT_CODES.f("&7You have used your sanic cheat code!")); + break; + case YOUCANTSEEME: + coreUser.addCooldown(this.cooldownID, 60*60, false, true); + player.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, 20*60*3, 0)); + player.sendMessage(Lang.CHEAT_CODES.f("&7You have used your you can't see me cheat code!")); + break; + case STACK: + player.chat("/stack"); + break; + case FIXALL: + player.chat("/fix all"); + break; + case FIXHAND: + player.chat("/fix hand"); + break; + case FEED: + player.chat("/feed"); + break; + case QUICKSELL: + player.chat("/qsell"); + break; + } + } + else { + player.sendMessage(Lang.CHEAT_CODES.f("&7You turrned " + (cState.getState() ==State.OFF ? "&a&lon &7" : "&c&loff &7") + (this.toString().toLowerCase().replace("_", " ")))); + switch (this) {//only the toggleable ones that need effects NOW + case NIGHTVIS: + if (cState.getState() == State.OFF) + player.addPotionEffect(new PotionEffect(PotionEffectType.NIGHT_VISION, Integer.MAX_VALUE, 0)); + else if (cState.getState() == State.ON && player.hasPotionEffect(PotionEffectType.NIGHT_VISION)) + player.removePotionEffect(PotionEffectType.NIGHT_VISION); + break; + case JELLYLEGS: + break; + } + } + user.setCheatCodeState(this, new CheatCodeState(cState.getState()==State.ON && this.isToggleable() ? State.OFF : State.ON, cState.isPurchased())); + } + + private String getStateColor(State state){ + switch (state) { + case ON: + return "&a&l"; + case OFF: + return "&c&l"; + case LOCKED: + return "&4&l"; + } + return null; + } + + public static Optional<CheatCode> getCheatCodeFromItemStack(ItemStack stack){ + if(stack==null) + return Optional.empty(); + return Arrays.stream(CheatCode.values()).filter(code -> code.getDisplayItem(null, State.ON).getType()==stack.getType() && code.getDisplayItem(null, State.ON).getDurability()==stack.getDurability()).findFirst(); + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/CheatCodeState.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/CheatCodeState.java new file mode 100644 index 0000000..64d7048 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/CheatCodeState.java @@ -0,0 +1,25 @@ +package net.grandtheftmc.vice.users; + + +import net.grandtheftmc.core.util.State; +/** + * Created by Timothy Lampen on 2017-08-26. + */ +public class CheatCodeState { + + private final State state; + private final boolean purchased; + + public CheatCodeState(State state, boolean purchased) { + this.state = state; + this.purchased = purchased; + } + + public State getState() { + return state; + } + + public boolean isPurchased() { + return purchased; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/CopRank.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/CopRank.java new file mode 100644 index 0000000..6dd9219 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/CopRank.java @@ -0,0 +1,107 @@ +package net.grandtheftmc.vice.users; + +import net.grandtheftmc.core.util.Utils; +import org.bukkit.Material; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +public enum CopRank { + + COP("&b", 10000, Material.CHEST,"essentials.sethome.multiple","essentials.sethome.multiple.2"), + NARC("&b", 25000, Material.STICK,"essentials.sethome.multiple.3"), + LIEUTENANT("&b", 50000, Material.IRON_BARDING,"essentials.sethome.multiple.5"), + CAPTAIN("&b", 100000, Material.SHIELD,"essentials.sethome.multiple.10"), + WARDEN("&3", 250000, Material.BLAZE_ROD,"essentials.sethome.multiple.unlimited"); + + private final String color; + private final int salary; + private final List<String> perms; + private final Material material; + + + CopRank(String color, int salary, Material material, String... perms) { + this.color = color; + this.salary = salary; + this.perms = Arrays.asList(perms); + this.material = material; + } + + public List<String> getAllPerms() { + List<String> permissions = new ArrayList<>(); + for (CopRank c : CopRank.values()) { + permissions.addAll(c.perms); + if (c == this) + return permissions; + } + return permissions; + } + + private List<String> getPerms() { + return this.perms; + } + + public String getName() { + return this.toString(); + } + + public String getColor() { + return this.color; + } + + public String getColoredName() { + return Utils.f(this.color + this.getName() + "&r"); + } + + public String getColoredNameBold() { + return Utils.f(this.color + "&l" + this.getName() + "&r"); + } + + public CopRank getNext() { + String rankName = this.getName(); + if ("GODFATHER".equalsIgnoreCase(rankName)) + return null; + int go = 0; + + CopRank rank = null; + for (CopRank r : CopRank.values()) + if (go == 0) { + if (Objects.equals(r.getName(), rankName)) { + go = 1; + } + } else if (go == 1) { + rank = r; + break; + } + return rank; + } + + public static CopRank fromString(String string) { + return Arrays.stream(CopRank.values()).filter(uc -> uc.getName().equalsIgnoreCase(string)).findFirst().orElse(CopRank.COP); + } + + public Material getMaterial() { + return this.material; + } + + public static CopRank getRankOrNull(String name) { + if (name == null) + return null; + return Arrays.stream(CopRank.values()).filter(r -> r.getName().equalsIgnoreCase(name)).findFirst().orElse(null); + } + + public boolean isHigherThan(CopRank rank) { + for (CopRank r : CopRank.values()) + if (r == this) + return false; + else if (r == rank) + return true; + return false; + } + + public double getSalary() { + return this.salary; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/LockedWeapon.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/LockedWeapon.java new file mode 100644 index 0000000..94a1355 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/LockedWeapon.java @@ -0,0 +1,52 @@ +package net.grandtheftmc.vice.users; + +import net.grandtheftmc.core.users.UserRank; + +import java.util.Arrays; + +public enum LockedWeapon { + + // TODO assign to ranks + MARKSMANPISTOL(ViceRank.FALCON, UserRank.VIP), + HEAVYSHOTGUN(ViceRank.THUG, UserRank.VIP), + CHAINSAW(ViceRank.DEALER, UserRank.PREMIUM), + GUSENBERGSWEEPER(ViceRank.DEALER, UserRank.PREMIUM), + RPG(ViceRank.GROWER, UserRank.PREMIUM), + HEAVYSNIPER(ViceRank.SMUGGLER, UserRank.ELITE), + SPECIALCARBINE(ViceRank.SMUGGLER, UserRank.ELITE), + GRENADELAUNCHER(ViceRank.CHEMIST, UserRank.SPONSOR), + COMBATMG(ViceRank.DRUGLORD, UserRank.SPONSOR), + HOMINGLAUNCHER(ViceRank.KINGPIN, UserRank.SUPREME), + MINIGUN(ViceRank.KINGPIN, UserRank.SUPREME), + GOLDMINIGUN(ViceRank.KINGPIN, UserRank.SUPREME); + + private final ViceRank rank; + private final UserRank userRank; + + LockedWeapon(ViceRank rank, UserRank userRank) { + this.rank = rank; + this.userRank = userRank; + } + + public static boolean canUseWeapon(String identifier, ViceRank rank, UserRank userRank) { + LockedWeapon w = getWeapon(identifier); + return w == null || w.canUseWeapon(rank, userRank); + } + + public ViceRank getViceRank() { + return this.rank; + } + + public UserRank getUserRank() { + return this.userRank; + } + + public boolean canUseWeapon(ViceRank rank, UserRank userRank) { + if(rank == null || userRank == null) return false; + return this.rank == rank || rank.isHigherThan(this.rank) || this.userRank == userRank || userRank.isHigherThan(this.userRank); + } + + public static LockedWeapon getWeapon(String identifier) { + return Arrays.stream(LockedWeapon.values()).filter(w -> w.toString().equalsIgnoreCase(identifier)).findFirst().orElse(null); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/PersonalVehicle.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/PersonalVehicle.java new file mode 100644 index 0000000..2ded2bb --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/PersonalVehicle.java @@ -0,0 +1,355 @@ +package net.grandtheftmc.vice.users; + +import com.j0ach1mmall3.jlib.methods.Random; +import com.j0ach1mmall3.wastedvehicles.api.VehicleProperties; +import com.j0ach1mmall3.wastedvehicles.api.vehicles.WastedVehicle; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.events.TPEvent; +import net.grandtheftmc.vice.items.GameItem; +import net.grandtheftmc.vice.users.storage.BooleanStorageType; +import org.bukkit.*; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; + +/** + * Created by Liam on 24/09/2016. + */ +public class PersonalVehicle { + + private String vehicle; + private double health = -1; + private UUID entityUUID; + private boolean stolen; + + public PersonalVehicle(String vehicle) { + this.vehicle = vehicle; + } + + public String getVehicle() { + return this.vehicle; + } + + public void setVehicle(String vehicle) { + this.vehicle = vehicle; + } + + public String getDisplayName() { + VehicleProperties p = this.getVehicleProperties(); + return p == null ? "Error" : p.getItem().getItemMeta().getDisplayName(); + } + + public VehicleProperties getVehicleProperties() { + Optional<VehicleProperties> opt = Vice.getWastedVehicles().getVehicle(this.vehicle); + return opt.orElse(null); + } + + public String getFormattedHealth() { + if (this.isDestroyed()) return "&c&lDestroyed"; + return Vice.getWastedVehicles().formatHealth(this.getHealth(), this.getVehicleProperties().getMaxHealth()); + } + + public double getHealth() { + return this.health < 0 ? this.getVehicleProperties().getMaxHealth() : this.health; + } + + public boolean isStolen() { + if (this.getEntity() == null) this.stolen = false; + return this.stolen; + } + + public double getPrice() { + GameItem item = Vice.getItemManager().getItemFromVehicle(this.vehicle); + return item == null ? -1 : item.getSellPrice() * 2; + } + + public double getSellPrice() { + return this.getPrice() / 2 - this.getRepairPrice(); + } + + public double getRepairPrice() { + if(!this.isDestroyed()) return 0; + return this.getPrice() / 5; + } + + public void setStolen(boolean b) { + this.stolen = b; + } + + public void setHealth(double health) { + this.health = health; + } + + public UUID getEntityUUID() { + return this.entityUUID; + } + + public void setEntityUUID(UUID entityUUID) { + this.entityUUID = entityUUID; + } + + public ArmorStand getEntity() { + if (this.entityUUID == null) return null; + for (World world : Bukkit.getWorlds()) + for (ArmorStand e : world.getEntitiesByClass(ArmorStand.class)) + if (Objects.equals(e.getUniqueId(), this.entityUUID)) { + this.health = e.getHealth(); + return e; + } + this.entityUUID = null; + return null; + } + + public boolean isDestroyed() { + return this.getHealth() <= 1; + } + + public void updateVehicleInDatabase(Player player, double health) { + VehicleProperties v = this.getVehicleProperties(); + this.health = health; + if (v != null) { + ServerUtil.runTaskAsync(() -> ViceUserDAO.updateVehicles(player.getUniqueId(), v, this.isStolen() ? 0 : this.health)); +// Core.sql.updateAsyncLater("update " + Core.name() + " set `" + v.getIdentifier().toLowerCase() + ":info`='" + (this.isStolen() ? 0 : this.health) + "' where uuid='" + player.getUniqueId() + "';"); + } + } + + public boolean onMap() { + return this.getEntity() != null; + } + + public void call(Player player, User user, ViceUser viceUser) { + this.teleport(player, user, viceUser, false); + } + + public void sendAway(Player player, User user, ViceUser viceUser) { + this.teleport(player, user, viceUser, true); + } + + public void teleport(Player player, User user, ViceUser viceUser, boolean sendAway) { + ViceUtils.giveGameItems(player); + UUID uuid = player.getUniqueId(); + if (viceUser.getVehicleTaskId() != -1) + Bukkit.getScheduler().cancelTask(viceUser.getVehicleTaskId()); + if (viceUser.isInCombat()) { + player.sendMessage(Lang.COMBATTAG.f("&7You can't " + (sendAway ? "send away" : "call") + " your vehicle in combat!")); + return; + } + if (user.isInTutorial()) return; + if (!sendAway && Objects.equals("spawn", player.getWorld().getName())) { + player.sendMessage(Lang.VEHICLES.f("&7You can't call vehicles to spawn!")); + return; + } + if (viceUser.isArrested()) { + player.sendMessage(Lang.JAIL.f("&7You can't " + (sendAway ? "send away" : "call") + " your vehicle in jail!")); + return; + } + if (this.isDestroyed()) { + player.sendMessage(Lang.VEHICLES.f("&7Your " + this.getDisplayName() + "&7 was destroyed, call the mechanic to fix it first!")); + return; + } + if (sendAway && !this.onMap()) { + player.sendMessage(Lang.VEHICLES.f("&7Your vehicle can not be sent away!")); + return; + } + if (this.stolen) { + player.sendMessage(Lang.VEHICLES.f("&7Your " + this.getDisplayName() + "&7 was stolen!")); + return; + } + if (!viceUser.hasMoney(200)) { + player.sendMessage(Lang.VEHICLES.f("&7You can't afford to pay &c$&l200&7 for driver!")); + return; + } + player.sendMessage(Lang.VEHICLES.f("&7A driver is coming to " + (sendAway ? "pick up" : "drop off") + " your " + this.getDisplayName() + "&7!")); + viceUser.setVehicleTimer(ViceUtils.getWarpDelay(user.getUserRank())); + viceUser.setBooleanToStorage(BooleanStorageType.SEND_AWAY, sendAway); + viceUser.setVehicleTaskId(new BukkitRunnable() { + @Override + public void run() { + Player player = Bukkit.getPlayer(uuid); + if (player == null) { + this.cancel(); + return; + } + ViceUser viceUser = Vice.getUserManager().getLoadedUser(uuid); + int timer = viceUser.getVehicleTimer(); + boolean sendAway = viceUser.getBooleanFromStorage(BooleanStorageType.SEND_AWAY); + PersonalVehicle vehicle = viceUser.getPersonalVehicle(); + + if (timer == 15 || timer == 10 || (timer <= 5 && timer > 0)) { + player.sendMessage(Lang.VEHICLES.f("&7Your vehicle is " + (sendAway ? "being picked up" : "arriving") + " in " + timer + " &7second" + + (timer == 1 ? "" : "s") + '!')); + if (timer == 1) + player.playSound(player.getLocation(), Sound.BLOCK_LAVA_EXTINGUISH, 0.5F, 1); + else + player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 4.0F / timer, 2); + } + if (timer == 0) { + if (vehicle == null) { + viceUser.cancelVehicleTeleport(); + player.sendMessage(Lang.VEHICLES.f("&7You have no vehicle to teleport!")); + return; + } + if (viceUser.isInCombat()) { + viceUser.cancelVehicleTeleport(); + player.sendMessage(Lang.COMBATTAG.f("&7You can't " + (sendAway ? "send away" : "call") + " your vehicle in combat!")); + return; + } + if (user.isInTutorial()) return; + if (viceUser.isArrested()) { + viceUser.cancelVehicleTeleport(); + player.sendMessage(Lang.JAIL.f("&7You can't " + (sendAway ? "send away" : "call") + " your vehicle in jail!")); + return; + } + if(Objects.equals("spawn", player.getWorld().getName())) { + viceUser.cancelVehicleTeleport(); + player.sendMessage(Lang.JAIL.f("&7You can't " + (sendAway ? "send away" : "call") + " your vehicle in spawn!")); + return; + } + if (vehicle.isDestroyed()) { + viceUser.cancelVehicleTeleport(); + player.sendMessage(Lang.VEHICLES.f("&7Your " + vehicle.getDisplayName() + "&7 was destroyed, call the mechanic to fix it first!")); + return; + } + if (sendAway && !vehicle.onMap()) { + viceUser.cancelVehicleTeleport(); + player.sendMessage(Lang.VEHICLES.f("&7Your vehicle can not be sent away!")); + return; + } + if (vehicle.stolen) { + viceUser.cancelVehicleTeleport(); + player.sendMessage(Lang.VEHICLES.f("&7Your " + vehicle.getDisplayName() + "&7 was stolen!")); + return; + } + if (!viceUser.hasMoney(200)) { + viceUser.cancelVehicleTeleport(); + player.sendMessage(Lang.VEHICLES.f("&7You can't afford to pay &c$&l200&7 for driver!")); + return; + } + TPEvent e = new TPEvent(player, player, + sendAway ? TPEvent.TPType.VEHICLE_SEND_AWAY : TPEvent.TPType.VEHICLE_CALL).call(); + if (e.isCancelled()) { + viceUser.cancelVehicleTeleport(); + player.sendMessage(Lang.VEHICLES.f(e.getCancelMessage())); + return; + } + PersonalVehicle next = viceUser.getNextVehicle(); + viceUser.cancelVehicleTeleport(); + if (sendAway) { + if (!vehicle.sendAway(player, true)) return; + } else if (!vehicle.teleport(player, true)) return; + viceUser.takeMoney(200); + player.sendMessage(Lang.MONEY_TAKE.f("200")); + ViceUtils.updateBoard(player, Core.getUserManager().getLoadedUser(player.getUniqueId()), viceUser); + if (sendAway && next != null) { + viceUser.setPersonalVehicle(null); + viceUser.setNextVehicle(null); + viceUser.setPersonalVehicle(player, Core.getUserManager().getLoadedUser(uuid), next); + } + MenuManager.updateMenu(player, "vehicles"); + MenuManager.updateMenu(player, "personalvehicle"); + return; + } + viceUser.setVehicleTimer(timer - 1); + } + }.runTaskTimer(Vice.getInstance(), 20, 20).getTaskId()); + } + + private Location getLocationAround(Player player) { + VehicleProperties prop = this.getVehicleProperties(); + for (int i = 0; i < 50; i++) { + Location l = player.getLocation().add(Random.getInt(-7, 7), 0, Random.getInt(-7, 7)); + Material m = l.getBlock().getRelative(BlockFace.DOWN).getType(); + if (m == Material.AIR) + m = l.getBlock().getRelative(BlockFace.DOWN).getRelative(BlockFace.DOWN).getType(); + if (prop.getAllowedBlocks().contains(m.toString())) return l; + } + return null; + } + + private boolean teleport(Player player) { + return this.teleport(player, false); + } + + private boolean teleport(Player player, boolean sendMessage) { + ArmorStand e = this.getEntity(); + if (e == null) { + VehicleProperties v = this.getVehicleProperties(); + if (v == null) { + if (sendMessage) + player.sendMessage(Lang.VEHICLES.f("&7That vehicle does not exist!")); + return false; + } + Location loc = this.getLocationAround(player); + if (loc == null) { + player.sendMessage(Lang.VEHICLES.f("&7Your vehicle can not be placed near you!")); + return false; + } + ArmorStand wv = Vice.getWastedVehicles().spawnVehicle(v, loc, player, (this.health > v.getMaxHealth() || this.health < 0) ? v.getMaxHealth() : this.health); + this.entityUUID = wv.getUniqueId(); + if (sendMessage) + player.sendMessage(Lang.VEHICLES.f("&7The driver dropped off your vehicle!")); + return true; + } + if (this.stolen) { + if (sendMessage) + player.sendMessage(Lang.VEHICLES.f("&7Your " + this.getDisplayName() + "&7 was stolen!")); + return false; + } + Location loc = this.getLocationAround(player); + if (loc == null) { + player.sendMessage(Lang.VEHICLES.f("&7Your vehicle can not be placed near you!")); + return false; + } + e.teleport(loc); + if (sendMessage) + player.sendMessage(Lang.VEHICLES.f("&7The driver dropped off your vehicle!")); + return true; + } + + private boolean sendAway(Player player) { + return this.sendAway(player, false); + } + + private boolean sendAway(Player player, boolean sendMessage) { + ArmorStand e = this.getEntity(); + if (this.isDestroyed()) { + if (sendMessage) + player.sendMessage(Lang.VEHICLES.f("&7Your " + this.getDisplayName() + "&7 is destroyed!")); + return false; + } + if (e == null) { + if (sendMessage) + player.sendMessage(Lang.VEHICLES.f("&7You can't send away your vehicle!")); + return false; + } + if (e.getPassenger() != null) { + if (sendMessage) + player.sendMessage(Lang.VEHICLES.f("&7Your vehicle is not empty!")); + return false; + } + ((WastedVehicle) e.getMetadata("WastedVehicle").get(0).value()).onDismount(e); + ((WastedVehicle) e.getMetadata("WastedVehicle").get(0).value()).getPassengers().forEach(passenger -> { + passenger.eject(); + passenger.remove(); + }); + Vice.getWastedVehicles().getEntityQueue().remove(e); + e.remove(); + this.entityUUID = null; + if (sendMessage) + player.sendMessage(Lang.VEHICLES.f("&7The driver picked up your vehicle!")); + return true; + } + + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/Prestige.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/Prestige.java new file mode 100644 index 0000000..10a4aff --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/Prestige.java @@ -0,0 +1,27 @@ +package net.grandtheftmc.vice.users; + +/** + * Created by Timothy Lampen on 2017-08-11. + */ +public enum Prestige { + I(6000000), + II(7000000), + III(8000000), + IV(9000000), + V(10000000), + VI(11000000), + VII(12000000), + VIII(13000000), + IX(14000000), + X(15000000); + + private double cost; + + Prestige(double cost){ + this.cost = cost; + } + + public double getCost() { + return cost; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/TaxiTarget.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/TaxiTarget.java new file mode 100644 index 0000000..6dbef84 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/TaxiTarget.java @@ -0,0 +1,134 @@ +package net.grandtheftmc.vice.users; + +import net.grandtheftmc.vice.world.warps.Warp; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +import java.util.Objects; +import java.util.UUID; + +public class TaxiTarget { + private TargetType type; + + private UUID targetPlayer; + private UUID targetEntity; + private Location location; + private Warp warp; + + public TaxiTarget() { + this.type = TargetType.NONE; + } + + public TaxiTarget(Player player) { + this.type = TargetType.PLAYER; + this.targetPlayer = player.getUniqueId(); + } + + public TaxiTarget(Entity entity) { + this.type = TargetType.ENTITY; + this.targetEntity = entity.getUniqueId(); + } + + public TaxiTarget(Location position) { + this.type = TargetType.LOCATION; + this.location = position; + } + + public TaxiTarget(Warp warp) { + this.type = TargetType.WARP; + this.warp = warp; + } + + public TargetType getType() { + return this.type; + } + + public void setType(TargetType type) { + this.type = type; + } + + public UUID getTargetPlayerUUID() { + return this.targetPlayer; + } + + public Player getTargetPlayer() { + if (this.targetPlayer == null) + return null; + return Bukkit.getPlayer(this.targetPlayer); + } + + public void setTargetPlayer(UUID targetPlayer) { + this.targetPlayer = targetPlayer; + this.type = TargetType.PLAYER; + } + + public UUID getTargetEntityUUID() { + return this.targetEntity; + } + + public Entity getTargetEntity() { + if (this.targetEntity == null) + return null; + for (World w : Bukkit.getWorlds()) + for (Entity e : w.getEntities()) + if (Objects.equals(e.getUniqueId(), this.targetEntity)) + return e; + this.targetEntity = null; + return null; + } + + public void setTargetEntity(UUID targetEntity) { + this.targetEntity = targetEntity; + this.type = TargetType.ENTITY; + } + + public void setTargetEntity(Entity targetEntity) { + this.targetEntity = targetEntity == null ? null : targetEntity.getUniqueId(); + this.type = TargetType.ENTITY; + } + + public Location getLocation() { + return this.location; + } + + public void setLocation(Location location) { + this.location = location; + } + + public Warp getWarp() { + return this.warp; + } + + public void setWarp(Warp w) { + this.warp = w; + } + + public Location getExactLocation() { + switch (this.type) { + case LOCATION: + return this.location; + case ENTITY: + Entity e = this.getTargetEntity(); + return e == null ? null : e.getLocation(); + case PLAYER: + Player p = this.getTargetPlayer(); + return p == null ? null : p.getLocation(); + case WARP: + return this.warp == null ? null : this.warp.getLocation(); + default: + return null; + } + } + + public enum TargetType { + NONE, + PLAYER, + ENTITY, + LOCATION, + WARP + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/ViceRank.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/ViceRank.java new file mode 100644 index 0000000..6980cb7 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/ViceRank.java @@ -0,0 +1,110 @@ +package net.grandtheftmc.vice.users; + +import net.grandtheftmc.core.util.Utils; +import org.bukkit.Material; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +public enum ViceRank { + + JUNKIE(0, "&7", Material.CHEST), // 1 sethome + FALCON(25000, "&e", Material.FEATHER), // 1 auction item + THUG(100000, "&e", Material.STICK,"essentials.workbench"), // 2 auction items, /workbench + DEALER(250000, "&e", Material.SUGAR), + GROWER(500000, "&e", Material.SEEDS), //2 sethomes, create faction + SMUGGLER(1000000, "&e", Material.CHEST), + CHEMIST(2500000, "&e", Material.BREWING_STAND_ITEM), // 3 auction items + DRUGLORD(5000000, "&e", Material.NETHER_STAR), // 4 auction items + KINGPIN(10000000, "&e", Material.CHORUS_FRUIT_POPPED),// 3 sethomes, + GODFATHER(25000000, "&e", Material.RED_ROSE, "essentials.enderchest"); // 5 auction items + + private final int price; + private final String color; + private final List<String> perms; + private final Material material; + + ViceRank(int price, String color, Material material, String... perms) { + this.price = price; + this.color = color; + this.perms = Arrays.asList(perms); + this.material = material; + } + + public List<String> getAllPerms() { + List<String> permissions = new ArrayList<>(); + for (ViceRank c : ViceRank.values()) { + permissions.addAll(c.perms); + if (c == this) + return permissions; + } + return permissions; + } + + private List<String> getPerms() { + return this.perms; + } + + public int getPrice() { + return this.price; + } + + public String getName() { + return this.toString(); + } + + public String getColor() { + return this.color; + } + + public String getColoredName() { + return Utils.f(this.color + this.getName() + "&r"); + } + + public String getColoredNameBold() { + return Utils.f(this.color + "&l" + this.getName() + "&r"); + } + + public ViceRank getNext() { + String rankName = this.getName(); + if (this == GODFATHER) return null; + int go = 0; + + ViceRank rank = null; + for (ViceRank r : ViceRank.values()) + if (go == 0) { + if (Objects.equals(r.getName(), rankName)) { + go = 1; + } + } else if (go == 1) { + rank = r; + break; + } + return rank; + } + + public static ViceRank fromString(String string) { + return Arrays.stream(ViceRank.values()).filter(uc -> uc.getName().equalsIgnoreCase(string)).findFirst().orElse(ViceRank.JUNKIE); + } + + public Material getMaterial() { + return this.material; + } + + public static ViceRank getRankOrNull(String name) { + if (name == null) + return null; + return Arrays.stream(ViceRank.values()).filter(r -> r.getName().equalsIgnoreCase(name)).findFirst().orElse(null); + } + + public boolean isHigherThan(ViceRank rank) { + for (ViceRank r : ViceRank.values()) + if (r == this) + return false; + else if (r == rank) + return true; + return false; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/ViceUser.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/ViceUser.java new file mode 100644 index 0000000..8218c7a --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/ViceUser.java @@ -0,0 +1,1203 @@ +package net.grandtheftmc.vice.users; + +import com.j0ach1mmall3.jlib.player.JLibPlayer; +import com.j0ach1mmall3.wastedguns.api.events.ranged.AmmoUpdateEvent; +import com.j0ach1mmall3.wastedvehicles.api.VehicleProperties; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.core.util.State; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.guns.weapon.Weapon; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.core.nametags.NametagManager; +import net.grandtheftmc.core.users.Pref; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.items.AmmoType; +import net.grandtheftmc.vice.items.ArmorUpgrade; +import net.grandtheftmc.vice.items.GameItem; +import net.grandtheftmc.vice.items.Kit; +import net.grandtheftmc.vice.users.storage.BooleanStorageType; +import net.grandtheftmc.vice.users.storage.IntStorageType; +import net.grandtheftmc.vice.users.storage.LongStorageType; +import net.grandtheftmc.vice.weapon.skins.WeaponSkinDAO; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.entity.Villager; +import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitRunnable; + +import java.sql.Blob; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; +import java.util.logging.Level; +import java.util.stream.Collectors; + +public class ViceUser { + + protected final UUID uuid; + protected final HashMap<AmmoType, Integer> ammo = new HashMap<>(); + private final HashMap<String, Location> homes = new HashMap<>(); + protected final List<PersonalVehicle> vehicles = new ArrayList<>(); + private final HashMap<BooleanStorageType, Boolean> booleanStorage = new HashMap<>(); + private final HashMap<LongStorageType, Long> longStorage = new HashMap<>(); + private final HashMap<IntStorageType, Integer> intStorage = new HashMap<>(); + protected final HashMap<CheatCode, CheatCodeState> cheatCodes = new HashMap<>(); + + protected ViceRank rank = ViceRank.JUNKIE; + protected CopRank copRank = null; + protected long lastCopSalary = 0l; + protected int kills = 0; + protected int deaths = 0; + protected double money = 0; + protected int killStreak = 0; + protected int bonds = 0; + protected ItemStack[] backpackContents = null; + protected HashMap<String, Long> kitExpiries = new HashMap<>(); + protected Long playtime = 0L; + private Long jointime; + private PersonalVehicle personalVehicle; + private int vehicleTaskId = -1; + private int vehicleTimer; + private PersonalVehicle nextVehicle; + private String actionVehicle; + private int taxiTaskId = -1; + private TaxiTarget taxiTarget; + private int taxiPrice; + private int taxiTimer; + private UUID tpaRequestUUID; + private UUID tpaRequestSentUUID; + private long lastTpaRequest = -1; + private long lastTeleport = -1; + private double bankTransferring = -1; + protected int jailTimer; + protected UUID jailCop; + protected String jailCopName; + private double bribe; + private long lastBackupRequest; + private ArmorUpgrade buyingArmorUpgrade; + private long lastCopSpawn; + private long lastTag = -1; + private long lastJetpackCancel; + private long lastRTP; + private Villager changingJob; + protected Map<Short, List<Short>> unlockedWeaponSkins = new HashMap<>(); + protected Map<Short, Short> equippedWeaponSkins = new HashMap<>(); + + public ViceUser(UUID uuid) { + this.uuid = uuid; + this.load(); + } + + public UUID getUUID() { + return this.uuid; + } + + public void dataCheck(String name, UserRank rank) { +// MySQL sql = Core.sql; +// sql.update("insert into " + Core.name() + "(uuid,name,money) values('" + this.uuid + "','" + name +// + "','5000') on duplicate key update name='" + name + "';"); +// sql.update("update " + Core.name() + " set name='ERROR' where name='" + name + "' and uuid!='" + this.uuid + "';"); + + ViceUserDAO.insertViceUser(this, name); + ViceUserDAO.insertViceUser(this, name); + } + + public boolean updateDataFromDb() { +// MySQL sql = Core.sql; + boolean b = ViceUserDAO.getGeneralViceUser(this); + +// try (ResultSet rs = sql.query("select * from " + Core.name() + " where uuid='" + this.uuid + "' LIMIT 1;")) { +// if (rs.next()) { +// this.rank = ViceRank.fromString(rs.getString("rank")); +// this.copRank = CopRank.getRankOrNull(rs.getString("copRank")); +// this.lastCopSalary = rs.getLong("lastCopSalary"); +// this.kills = rs.getInt("kills"); +// this.deaths = rs.getInt("deaths"); +// this.money = rs.getDouble("money"); +// this.killStreak = rs.getInt("killStreak"); +// this.bonds = rs.getInt("bonds"); +// this.backpackContents = ViceUtils.fromBase64(rs.getString("backpackContents")); +// this.kitExpiries = new HashMap<>(); +// this.jailTimer = rs.getInt("jailTimer"); +// try { +// this.jailCop = rs.getString("jailCop") == null ? null : UUID.fromString(rs.getString("jailCop")); +// } catch (Exception ignored) { +// } +// this.playtime = rs.getLong("playtime"); +// this.jailCopName = rs.getString("jailCopName"); +// String s = rs.getString("kitExpiries"); +// this.kitExpiries = new HashMap<>(); +// if (s != null) +// try { +// String[] expiries = s.split(","); +// for (String e : expiries) { +// String[] a = e.split(":"); +// String kit = a[0]; +// Kit k = Vice.getItemManager().getKit(kit); +// if (kit == null || a.length < 2) +// continue; +// long expiry; +// try { +// expiry = Long.parseLong(a[1]); +// } catch (NumberFormatException ex) { +// continue; +// } +// if (expiry > System.currentTimeMillis()) { +// this.kitExpiries.put(k.getName().toLowerCase(), expiry); +// } +// } +// +// } catch (Exception e) { +// Vice.getInstance().getLogger().log(Level.ALL, "Error while loading kitExpiries for player " + rs.getString("name")); +// e.printStackTrace(); +// } +// for (AmmoType type : AmmoType.getTypes()) +// if (!type.isInInventory()) +// this.ammo.put(type, rs.getInt(type.name().toLowerCase())); +// for (VehicleProperties properties : Vice.getWastedVehicles().getBabies().getVehicleProperties()) { +// if (rs.getBoolean(properties.getIdentifier().toLowerCase())) { +// PersonalVehicle v = new PersonalVehicle(properties.getIdentifier()); +// this.vehicles.add(v); +// String st = rs.getString(properties.getIdentifier().toLowerCase() + ":info"); +// if (st == null) continue; +// String[] a = st.split(":"); +// if (a == null | a.length == 0) continue; +// v.setHealth(Double.parseDouble(a[0])); +// } +// } +// this.loadCheatCodes(rs); +// } else +// b = false; +// rs.close(); +// } catch (SQLException e) { +// e.printStackTrace(); +// b = false; +// } + this.setBooleanToStorage(BooleanStorageType.HAS_UPDATED, b); + return b; + } + + public void save(){ + this.saveHomes(); + // this.saveCheatCodes(); + } + + public HashMap<CheatCode, CheatCodeState> getCheatCodes() { + return cheatCodes; + } + + public void load(){ + this.loadHomes(); + } + +// private void loadCheatCodes(ResultSet rs) throws SQLException { +// +// if(rs.getBlob("cheatcodes")!=null) { +// Blob b = rs.getBlob("cheatcodes"); +// String cheatCodesBlob = new String(b.getBytes(1, (int) b.length())); +// for (String serializedCheatCode : cheatCodesBlob.split("-")) { +// String[] split = serializedCheatCode.split("#"); +// this.cheatCodes.put(CheatCode.valueOf(split[0]), new CheatCodeState(State.valueOf(split[1]), Boolean.valueOf(split[2]))); +// } +// } +// +// User user = Core.getUserManager().getLoadedUser(this.uuid); +// for(CheatCode code : CheatCode.values()) { +// if (user.getUserRank() == code.getMinmumRank() || user.getUserRank().isHigherThan(code.getMinmumRank())) { +// if (!this.cheatCodes.containsKey(code) || this.cheatCodes.get(code).getState() == State.LOCKED) { +// this.cheatCodes.put(code, new CheatCodeState(code.getDefaultState(), false)); +// } +// } +// else { +// if(this.cheatCodes.containsKey(code) && !this.cheatCodes.get(code).isPurchased()) { +// this.cheatCodes.put(code, new CheatCodeState(State.LOCKED, false)); +// } +// } +// } +// for(CheatCode code : CheatCode.values()) +// if(!this.cheatCodes.containsKey(code)) +// this.cheatCodes.put(code, new CheatCodeState(State.LOCKED, false)); +// } + + private void saveHomes(){ + YamlConfiguration config = Vice.getSettings().getHomesConfig(); + config.set(this.uuid.toString(), null); + for(Map.Entry<String, Location> e : this.homes.entrySet()) + config.set(this.uuid + "." + e.getKey(), Utils.blockLocationToString(e.getValue())); + Utils.saveConfig(config, "homes"); + } + + private void loadHomes(){ + YamlConfiguration config = Vice.getSettings().getHomesConfig(); + if(!config.contains(this.uuid.toString())) + return; + for(String id : config.getConfigurationSection(this.uuid.toString()).getKeys(false)){ + this.homes.put(id, Utils.blockLocationFromString(config.getString(this.uuid + "." + id))); + } + } + + private void saveBackpackContents() { +// Bukkit.getScheduler().runTaskAsynchronously(Vice.getInstance(), () -> { +// try (PreparedStatement stmt = Core.sql.prepareStatement("update " + Core.name() + " set backpackContents=? where uuid=?;")) { +// stmt.setString(1, this.backpackContents == null ? null : ViceUtils.toBase64(this.backpackContents)); +// stmt.setString(2, this.uuid.toString()); +// stmt.execute(); +// stmt.close(); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// +// }); + ServerUtil.runTaskAsync(() -> ViceUserDAO.setBackpackContents(this.uuid, this.backpackContents)); + } + + public ViceRank getRank() { + return this.rank; + } + + public CopRank getCopRank() { + return this.copRank; + } + + public boolean isCop() { + return this.copRank != null; + } + + public boolean isRank(ViceRank rank) { + return !(rank == null || this.rank == null) && (this.rank == rank || this.rank.isHigherThan(rank)); + } + + public boolean isCopRank(CopRank copRank) { + return !(copRank == null || this.copRank == null) && (this.copRank == copRank || this.copRank.isHigherThan(copRank)); + } + + public void setRank(ViceRank r, Player player, User u) { + this.rank = r; +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set rank='" + r.getName() + "' where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.setRank(this.uuid, r)); + NametagManager.updateNametag(Bukkit.getPlayer(this.uuid)); + u.setPerms(player); + } + + public void setCopRank(CopRank r, Player player, User u) { + this.copRank = r; +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set copRank='" + (r == null ? null : r.getName()) + "' where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.setCopRank(this, r)); + NametagManager.updateNametag(Bukkit.getPlayer(this.uuid)); + u.setPerms(player); + } + + public long getLastCopSalary() { + return this.lastCopSalary; + } + + public void setLastCopSalary(long lastCopSalary) { + this.lastCopSalary = lastCopSalary; +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set lastCopSalary=" + this.lastCopSalary + " where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.setLastCopSalary(this, lastCopSalary)); + } + + public void rankup(Player player, User u) { + ViceRank nextRank = this.rank.getNext(); + if (nextRank == null) { + player.sendMessage(Utils.f(Lang.RANKUP + "&7You can't rank up any more!")); + return; + } + int price = nextRank.getPrice(); + if (!this.hasMoney(price)) { + player.sendMessage(Utils.f(Lang.RANKUP + "&7You don't have the &c$&l" + price + "&7 required to rank up!")); + return; + } + this.takeMoney(price); + this.setRank(nextRank, player, u); + ViceUtils.updateBoard(player, u, this); + Utils.broadcastExcept(player, Lang.RANKUP + "&7" + u.getColoredName(player) + "&7 ranked up to " + + nextRank.getColoredNameBold() + "&7!"); + player.sendMessage(Lang.MONEY_TAKE.toString() + price); + player.sendMessage(Utils.f(Lang.RANKUP + "&7You ranked up to " + nextRank.getColoredNameBold() + "&7!")); + } + + public int getKills() { + return this.kills; + } + + public void setKills(int i) { + this.kills = i; +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set kills=" + i + " where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.setKills(this, i)); + } + + public void addKills(int i) { + this.kills += i; +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set kills=kills+" + i + " where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.setKills(this, this.kills)); + } + + public int getDeaths() { + return this.deaths; + } + + public void setDeaths(int i) { + this.deaths = i; +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set deaths=" + i + " where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.setDeaths(this, i)); + } + + public void addDeaths(int i) { + this.deaths += i; +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set deaths=deaths+" + i + " where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.setDeaths(this, this.deaths)); + } + + public double getMoney() { + return this.money; + } + + public void setMoney(double i) { + this.money = i; + if(Bukkit.getPlayer(this.uuid)!=null) + ViceUtils.updateBoard(Bukkit.getPlayer(this.uuid), this); +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set money=" + i + " where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.setMoney(this.uuid, i)); + } + + public void addMoney(double i) { + this.money += i; + if(Bukkit.getPlayer(this.uuid)!=null) + ViceUtils.updateBoard(Bukkit.getPlayer(this.uuid), this); +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set money=money+" + i + " where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.setMoney(this.uuid, this.money)); + } + + public void takeMoney(double i) { + this.money -= i; +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set money=money-" + i + " where uuid='" + this.uuid + "';"); + if(Bukkit.getPlayer(this.uuid)!=null) + ViceUtils.updateBoard(Bukkit.getPlayer(this.uuid), this); + ServerUtil.runTaskAsync(() -> ViceUserDAO.setMoney(this.uuid, this.money)); + } + + public boolean hasMoney(double i) { + return this.money >= i; + } + + public Long getPlaytime() {// + return this.playtime; + } + + public void setPlaytime(Long playtime) { + this.playtime = playtime; +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set playtime=" + this.playtime + " where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.setPlaytime(this, playtime)); + } + + public Long getJoinTime() { + return this.jointime; + } + + public void setJointime(Long jointime) { + this.jointime = jointime; + } + + public int getKillStreak() { + return this.killStreak; + } + + public void setKillStreak(int i) { + this.killStreak = i; +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set killStreak=" + i + " where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.setKillStreak(this, i)); + } + + public void addKillStreak(int i) { + this.killStreak += i; +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set killStreak=killStreak+" + i + " where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.setKillStreak(this, this.killStreak)); + } + + public void takeKillStreak(int i) { + this.killStreak -= i; +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set killStreak=killStreak-" + i + " where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.setKillStreak(this, this.killStreak)); + } + + public void giveBonds(int i) { + this.bonds += i; +// Core.sql.update( +// "update " + Core.name() + " set bonds=bonds+" + i + " where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.setBonds(this.uuid, this.bonds)); + } + + public void takeBonds(int i) { + this.bonds -= i; +// Core.sql.update( +// "update " + Core.name() + " set bonds=bonds-" + i + " where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.setBonds(this.uuid, this.bonds)); + } + + public int getBonds() { + return this.bonds; + } + + public void setBonds(int i) { + this.bonds = i; +// Core.sql.update( +// "update " + Core.name() + " set bonds=" + i + " where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.setBonds(this.uuid, this.bonds)); + } + + public boolean hasbonds(int i) { + return this.bonds >= i; + } + + public boolean isInCombat() { + return (this.lastTag + 20000) > System.currentTimeMillis(); + } + + public Long getLastTag() { + return this.lastTag; + } + + public void setLastTag(long i) { + this.lastTag = i; + } + + public boolean isUsingTaxi() { + return this.taxiTarget != null; + } + + public TaxiTarget getTaxiTarget() { + return this.taxiTarget; + } + + public void setTaxiTarget(TaxiTarget t) { + this.taxiTarget = t; + } + + public void unsetTaxiTarget() { + this.taxiTarget = null; + this.taxiTaskId = -1; + this.taxiPrice = 0; + this.taxiTimer = 0; + } + + public int getTaxiPrice() { + return this.taxiPrice; + } + + public void setTaxiPrice(int i) { + this.taxiPrice = i; + } + + public int getTaxiTaskId() { + return this.taxiTaskId; + } + + public void setTaxiTaskId(int i) { + this.taxiTaskId = i; + } + + public int getTaxiTimer() { + return this.taxiTimer; + } + + public void setTaxiTimer(int i) { + this.taxiTimer = i; + } + + public UUID getTpaRequestUUID() { + return this.tpaRequestUUID; + } + + public void setTpaRequestUUID(UUID tpaRequestUUID) { + this.tpaRequestUUID = tpaRequestUUID; + this.lastTpaRequest = tpaRequestUUID == null ? -1 : System.currentTimeMillis(); + } + + public UUID getTpaRequestSentUUID() { + return this.tpaRequestSentUUID; + } + + public void setTpaRequestSentUUID(UUID uuid) { + this.tpaRequestSentUUID = uuid; + } + + public Long getLastTpaRequest() { + return this.lastTpaRequest; + } + + public void setLastTpaRequest(Long lastTpaRequest) { + this.lastTpaRequest = lastTpaRequest; + } + + public boolean hasTpaRequest() { + return !(this.lastTpaRequest > 0 && this.lastTpaRequest + 60000 < System.currentTimeMillis()); + } + + + public void unsetTpaRequests() { + this.lastTpaRequest = -1L; + this.tpaRequestSentUUID = null; + this.tpaRequestUUID = null; + setBooleanToStorage(BooleanStorageType.TPA_HERE, false); + } + + public ItemStack[] getBackpackContents() { + return this.backpackContents; + } + + public void setBackpackContents(ItemStack[] backpackContents) { + this.backpackContents = backpackContents; + this.saveBackpackContents(); + } + + public boolean canUseKit(String name) { + return !(this.kitExpiries.containsKey(name.toLowerCase()) && this.kitExpiries.get(name.toLowerCase()) > System.currentTimeMillis()); + } + + public long getKitExpiry(String name) { + return this.kitExpiries.containsKey(name.toLowerCase()) ? this.kitExpiries.get(name.toLowerCase()) : -1; + } + + public void setKitExpiry(String name, int delay) { // delay is IN SECONDS + this.kitExpiries.put(name.toLowerCase(), System.currentTimeMillis() + (delay * 1000)); + this.updateExpiries(); + } + + public Map<String, Long> getKitExpiries() { + return this.kitExpiries; + } + + public String getKitExpiriesString() { + StringBuilder expiries = new StringBuilder(); + for (Map.Entry<String, Long> entry : this.kitExpiries.entrySet()) { + Long l = entry.getValue(); + if (l > System.currentTimeMillis()) + expiries.append(entry.getKey()).append(':').append(l).append(','); + } + return expiries.toString().endsWith(",") ? expiries.substring(0, expiries.length() - 1) : expiries.toString(); + } + + public void updateExpiries() { +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set kitExpiries='" + this.getKitExpiriesString() + "' where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.updateKitExpiries(this.uuid, this.getKitExpiriesString())); + } + + public long getLastCopSpawn() { + return this.lastCopSpawn; + } + + public void setLastCopSpawn(long lastCopSpawn) { + this.lastCopSpawn = lastCopSpawn; + } + + public double getKDR() { + return Utils.round(this.deaths == 0 ? this.kills : this.kills / (double) this.deaths); + } + + public HashMap<AmmoType, Integer> getAmmo() { + return this.ammo; + } + + public int getAmmoInInventory(Player player, AmmoType type) { + GameItem gameItem = type.getGameItem(); + if (gameItem == null) return 0; + if (gameItem.getItem() == null) return 0; + + if (player == null) return 0; + if (player.getInventory() == null) return 0; + if (player.getInventory().getContents() == null || player.getInventory().getContents().length == 0) return 0; + + return Arrays.stream(player.getInventory().getContents()).filter(item -> item != null && item.isSimilar(gameItem.getItem())).mapToInt(ItemStack::getAmount).sum(); + } + + public int getAmmo(AmmoType type) { + return type.isInInventory() ? this.getAmmoInInventory(Bukkit.getPlayer(this.uuid), type) : this.ammo.getOrDefault(type, 0); + } + + public void setAmmoInInventory(Player player, AmmoType type, int i) { + int ammo = this.getAmmoInInventory(Bukkit.getPlayer(this.uuid), type); + if (ammo > i) + this.removeAmmoFromInventory(player, type, ammo - i); + else if (ammo < i) + this.addAmmoToInventory(player, type, i - ammo); + this.updateAmmo(); + } + + public void setAmmo(AmmoType type, int i) { + if (type.isInInventory()) { + this.setAmmoInInventory(Bukkit.getPlayer(this.uuid), type, i); + return; + } + this.ammo.put(type, i); +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set " + type.name() + '=' + i + " where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.setAmmo(this, type.name(), i)); + this.updateAmmo(); + } + + public void addAmmoToInventory(Player player, AmmoType type, int i) { + GameItem gameItem = type.getGameItem(); + if (gameItem == null) + return; + ItemStack item = gameItem.getItem(); + item.setAmount(i); + Utils.giveItems(player, item); + this.updateAmmo(); + } + + public void addAmmo(AmmoType type, int i) { + if (type.isInInventory()) { + this.addAmmoToInventory(Bukkit.getPlayer(this.uuid), type, i); + return; + } + this.ammo.put(type, this.ammo.get(type) + i); +// Core.sql.updateAsyncLater("update " + Core.name() + " set " + type.name() + '=' + type.name() + '+' + i +// + " where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.setAmmo(this, type.name(), this.ammo.get(type))); + this.updateAmmo(); + } + + public void removeAmmoFromInventory(Player player, AmmoType type, int i) { + GameItem gameItem = type.getGameItem(); + if (gameItem == null) + return; + Utils.takeItems(player, i, gameItem.getItem()); + this.updateAmmo(); + } + + public void removeAmmo(AmmoType type, int i) { + if (type.isInInventory()) { + this.removeAmmoFromInventory(Bukkit.getPlayer(this.uuid), type, i); + return; + } + this.ammo.put(type, this.ammo.get(type) >= i ? this.ammo.get(type) - i : 0); +// Core.sql.updateAsyncLater("update " + Core.name() + " set " + type.name() + '=' + type.name() + '-' + i +// + " where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.setAmmo(this, type.name(), this.ammo.get(type))); + this.updateAmmo(); + } + + public boolean hasAmmoInInventory(Player player, AmmoType type, int i) { + return this.getAmmoInInventory(player, type) >= i; + } + + public boolean hasAmmo(AmmoType type, int i) { + if (type.isInInventory()) + return this.hasAmmoInInventory(Bukkit.getPlayer(this.uuid), type, i); + return this.ammo.get(type) >= i; + } + + public void updateAmmo() { + Bukkit.getPluginManager().callEvent(new AmmoUpdateEvent(Bukkit.getPlayer(this.uuid))); + } + + public void updateAmmoLater() { + new BukkitRunnable() { + @Override + public void run() { + Bukkit.getPluginManager().callEvent(new AmmoUpdateEvent(Bukkit.getPlayer(ViceUser.this.uuid))); + } + }.runTaskLater(Vice.getInstance(), 1); + + } + + public void jail(int jailTimer, Player cop) { + this.jailTimer = jailTimer; + this.jailCop = cop.getUniqueId(); + this.jailCopName = cop.getName(); +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set jailTimer=" + this.jailTimer + ", jailCop='" + this.jailCop + "', jailCopName='" + this.jailCopName + "' where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.setjailed(this, this.jailTimer, this.jailCop, this.jailCopName)); + } + + public boolean isArrested() { + return this.jailTimer >= 0; + } + + public int getJailTimer() { + return this.jailTimer; + } + + public void setJailTimer(int jailTimer) { + this.jailTimer = jailTimer; +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set jailTimer=" + jailTimer + " where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.setJailTimer(this, jailTimer)); + } + + public UUID getJailCop() { + return this.jailCop; + } + + public void resetJail() { + this.jailTimer = -1; + this.jailCop = null; + this.jailCopName = null; + this.bribe = 0; +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set jailTimer=-1, jailCop=NULL, jailCopName=NULL where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.resetJail(this.uuid)); + } + + public String getJailCopName() { + return this.jailCopName; + } + + public double getBribe() { + return this.bribe; + } + + public void setBribe(double bribe) { + this.bribe = bribe; + } + + + public double getBankTransferring() { + return this.bankTransferring; + } + + public boolean isBankTransferring() { + return this.bankTransferring >= 0; + } + + public void setBankTransferring(double bankTransferring) { + this.bankTransferring = bankTransferring; + } + + public void updateTintHealth(Player player, User user) { + if (Utils.returnTrue()) return; + if (!user.getPref(Pref.TINT_HEALTH)) { + new JLibPlayer(player).setWorldborderTint(0); + return; + } + UUID uuid = player.getUniqueId(); + new BukkitRunnable() { + @Override + public void run() { + Player player = Bukkit.getPlayer(uuid); + if (player != null) + new JLibPlayer(player).setWorldborderTint(100 - (int) (player.getHealth() * 100 / player.getMaxHealth())); + } + }.runTaskLater(Vice.getInstance(), 1); + } + + public PersonalVehicle getPersonalVehicle() { + return this.personalVehicle; + } + + public void setPersonalVehicle(PersonalVehicle personalVehicle) { + this.personalVehicle = personalVehicle; + } + + public boolean hasPersonalVehicle() { + return this.personalVehicle != null; + } + + public List<PersonalVehicle> getVehicles() { + return this.vehicles; + } + + public List<VehicleProperties> getVehicleProperties() { + return this.vehicles.stream().filter(v -> v.getVehicleProperties() != null).map(PersonalVehicle::getVehicleProperties).collect(Collectors.toList()); + } + + public boolean hasVehicle(String vehicle) { + return this.vehicles.stream().anyMatch(v -> v.getVehicle().equalsIgnoreCase(vehicle)); + } + + public void giveVehiclePerm(Player player, VehicleProperties vehicle) { +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set `" + vehicle.getIdentifier().toLowerCase() + "`=true where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.setVehiclePerm(this.uuid, vehicle, true)); + if (!this.hasVehicle(vehicle.getIdentifier())) + this.vehicles.add(new PersonalVehicle(vehicle.getIdentifier())); + } + + public void removeVehiclePerm(Player player, VehicleProperties vehicle) { +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set `" + vehicle.getIdentifier().toLowerCase() + "`=false where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.setVehiclePerm(this.uuid, vehicle, false)); + if (this.personalVehicle != null && this.personalVehicle.getVehicle().equalsIgnoreCase(vehicle.getIdentifier())) + this.personalVehicle = null; + new ArrayList<>(this.vehicles).stream().filter(v -> v.getVehicle().equalsIgnoreCase(vehicle.getIdentifier())).forEach(this.vehicles::remove); + } + + public PersonalVehicle getPersonalVehicle(String s) { + if (this.personalVehicle != null && this.personalVehicle.getVehicle().equalsIgnoreCase(s)) + return this.personalVehicle; + return this.vehicles.stream().filter(v -> v.getVehicle().equalsIgnoreCase(s)).findFirst().orElse(null); + } + + public void setPersonalVehicle(Player player, User user, PersonalVehicle vehicle) { + if (this.personalVehicle != null && this.personalVehicle.onMap()) { + this.nextVehicle = vehicle; + this.personalVehicle.teleport(player, user, this, true); + return; + } + if (!this.vehicles.contains(vehicle)) { + player.sendMessage(Lang.VEHICLES.f("&7You do not own that vehicle!")); + return; + } + this.personalVehicle = vehicle; + this.nextVehicle = null; + player.sendMessage(Lang.VEHICLES.f("&7You set " + vehicle.getDisplayName() + "&7 as your personal vehicle!")); + this.personalVehicle.call(player, user, this); + } + + public boolean cancelVehicleTeleport() { + if (this.vehicleTaskId == -1) return false; + Bukkit.getScheduler().cancelTask(this.vehicleTaskId); + this.nextVehicle = null; + this.setBooleanToStorage(BooleanStorageType.SEND_AWAY, false); + this.vehicleTimer = -1; + return true; + } + + public int getVehicleTaskId() { + return this.vehicleTaskId; + } + + public void setVehicleTaskId(int vehicleTaskId) { + this.vehicleTaskId = vehicleTaskId; + } + + public int getVehicleTimer() { + return this.vehicleTimer; + } + + public void setVehicleTimer(int vehicleTimer) { + this.vehicleTimer = vehicleTimer; + } + + public PersonalVehicle getNextVehicle() { + return this.nextVehicle; + } + + public void setNextVehicle(PersonalVehicle nextVehicle) { + this.nextVehicle = nextVehicle; + } + + public String getActionVehicle() { + return this.actionVehicle; + } + + public void setActionVehicle(String actionVehicle) { + this.actionVehicle = actionVehicle; + } + + + public long getLastTeleport() { + return this.lastTeleport; + } + + public void setLastTeleport(long lastTeleport) { + this.lastTeleport = lastTeleport; + } + + public void setLastTeleport() { + this.lastTeleport = System.currentTimeMillis(); + } + + public boolean hasTeleportProtection() { + return this.lastTeleport + 10000 > System.currentTimeMillis(); + } + + public long getTimeUntilTeleportProtectionExpires() { + return this.lastTeleport + 10000 - System.currentTimeMillis(); + } + public long getLastRTP() { + return this.lastRTP; + } + + public void setLastRTP(long lastRTP) { + this.lastRTP = lastRTP; + } + + public void setLastRTP() { + this.lastRTP = System.currentTimeMillis(); + } + + public boolean canRTP() { + return this.lastRTP + 60000 < System.currentTimeMillis(); + } + + public long getTimeUntilRTP() { + return this.lastRTP + 60000 - System.currentTimeMillis(); + } + + public long getLastJetpackCancel() { + return this.lastJetpackCancel; + } + + public void setLastJetpackCancel(long lastJetpackCancel) { + this.lastJetpackCancel = lastJetpackCancel; + } + + public ArmorUpgrade getBuyingArmorUpgrade() { + return this.buyingArmorUpgrade; + } + + public void setBuyingArmorUpgrade(ArmorUpgrade buyingArmorUpgrade) { + this.buyingArmorUpgrade = buyingArmorUpgrade; + } + + public boolean hasRequestedBackup() { + return this.copRank != null && this.lastBackupRequest + 60000 > System.currentTimeMillis(); + } + + public long getTimeUntilBackupRequestExpires() { + return 60000 + this.lastBackupRequest - System.currentTimeMillis(); + } + + public void checkBackupExpiration(Player player) { + if (this.lastBackupRequest > 0) { + if (this.copRank == null) { + this.lastBackupRequest = -1; + return; + } + if (this.lastBackupRequest + 60000 < System.currentTimeMillis()) { + this.lastBackupRequest = -1; + player.spigot().sendMessage(new ComponentBuilder(Lang.COP_MODE.s()).append("Your backup request has expired! Click to extend it: ").color(net.md_5.bungee.api.ChatColor.GRAY). + append(" [ACCEPT] ").color(net.md_5.bungee.api.ChatColor.GREEN).bold(true).event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/backup")).create()); + } + + } + } + + public void setLastBackupRequest(long l) { + this.lastBackupRequest = l; + } + + public Location getHomeLocation(String id){ + id = id.toLowerCase(); + return this.homes.getOrDefault(id, null); + } + + public void setHomeLocation(String id, Location loc){ + id = id.toLowerCase(); + this.homes.put(id, loc); + } + + public boolean removeHomeLocation(String id){ + id = id.toLowerCase(); + if(this.homes.containsKey(id)){ + this.homes.remove(id); + return true; + } + return false; + } + + public HashMap<String, Location> getHomes() { + return homes; + } + + public boolean getBooleanFromStorage(BooleanStorageType type) { + return this.booleanStorage.getOrDefault(type, type.getDefaultValue()); + } + + public CheatCodeState getCheatCodeState(CheatCode code){ + if(this.cheatCodes.containsKey(code)) + return this.cheatCodes.get(code); + this.cheatCodes.put(code, new CheatCodeState(State.LOCKED, false)); + return new CheatCodeState(State.LOCKED, false); + } + + public void setCheatCodeState(CheatCode code, CheatCodeState state){ + this.cheatCodes.put(code, state); +// Core.sql.updateAsyncLater( +// "update " + Core.name() + " set cheatcodes='" + CheatCode.seralizeCheatCodes(this.cheatCodes) + "' where uuid='" + this.uuid + "';"); + ServerUtil.runTaskAsync(() -> ViceUserDAO.setCheatCodeState(this)); + } + + + public void setBooleanToStorage(BooleanStorageType type, boolean value) { + booleanStorage.put(type, value); + } + + public void setChangingJob(Villager changingJob) { + this.changingJob = changingJob; + } + + public Villager getChangingJob() { + return changingJob; + } + + public void checkAchievements() { + // TODO Colt + /* + User user = Core.getUserManager().getLoadedUser(getUUID()); + if (!user.getUnlockedAchievements().contains(Achievement.Hobo)) user.addAchievement(Achievement.Hobo); + if (!user.getUnlockedAchievements().contains(Achievement.CRIMINAL) && + isRank(ViceRank.CRIMINAL)) user.addAchievement(Achievement.CRIMINAL); + if (!user.getUnlockedAchievements().contains(Achievement.HOMIE) && + isRank(ViceRank.HOMIE)) user.addAchievement(Achievement.HOMIE); + if (!user.getUnlockedAchievements().contains(Achievement.THUG) && + isRank(ViceRank.THUG)) user.addAchievement(Achievement.THUG); + if (!user.getUnlockedAchievements().contains(Achievement.GANGSTER) && + isRank(ViceRank.GANGSTER)) user.addAchievement(Achievement.GANGSTER); + if (!user.getUnlockedAchievements().contains(Achievement.MUGGER) && + isRank(ViceRank.MUGGER)) user.addAchievement(Achievement.MUGGER); + if (!user.getUnlockedAchievements().contains(Achievement.HUNTER) && + isRank(ViceRank.HUNTER)) user.addAchievement(Achievement.HUNTER); + if (!user.getUnlockedAchievements().contains(Achievement.DEALER) && + isRank(ViceRank.DEALER)) user.addAchievement(Achievement.DEALER); + if (!user.getUnlockedAchievements().contains(Achievement.PIMP) && + isRank(ViceRank.PIMP)) user.addAchievement(Achievement.PIMP); + if (!user.getUnlockedAchievements().contains(Achievement.MOBSTER) && + isRank(ViceRank.MOBSTER)) user.addAchievement(Achievement.MOBSTER); + if (!user.getUnlockedAchievements().contains(Achievement.GODFATHER) && + isRank(ViceRank.GODFATHER)) user.addAchievement(Achievement.GODFATHER); + if (!user.getUnlockedAchievements().contains(Achievement.Psychopath) && + getKills() >= 10000) user.addAchievement(Achievement.Psychopath); + if (!user.getUnlockedAchievements().contains(Achievement.GTM_God) && + Stats.getInstance().getHoursPlayedRaw(Bukkit.getPlayer(user.getUUID())) > 1000) + user.addAchievement(Achievement.GTM_God); + user.updateNameTag(Bukkit.getPlayer(user.getUUID())); + if (!user.getUnlockedAchievements().contains(Achievement.Witness)) { + Bukkit.getOnlinePlayers().forEach(player -> { + if (player.getUniqueId().toString().equals("0e4a6028-3d9a-4a2e-9797-eb1ddcb0aca9")) { + user.addAchievement(Achievement.Witness); + } + }); + }*/ + } + + public void lockWeaponSkin(Weapon<?> weapon, WeaponSkin skin) { + if (this.unlockedWeaponSkins.get(weapon.getUniqueIdentifier()) != null) { + this.unlockedWeaponSkins.get(weapon.getUniqueIdentifier()).remove((Object) (short) (skin.getIdentifier() - weapon.getWeaponIdentifier())); + + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + WeaponSkinDAO.lockSkin(connection, this.uuid, weapon, skin); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } + } + + public void unlockWeaponSkin(Weapon<?> weapon, WeaponSkin skin) { + if (this.unlockedWeaponSkins.get(weapon.getUniqueIdentifier()) == null) { + this.unlockedWeaponSkins.put(weapon.getUniqueIdentifier(), new ArrayList<Short>()); + } + + if(!this.hasSkinUnlocked(weapon, skin)) { + this.unlockedWeaponSkins.get(weapon.getUniqueIdentifier()).add((short) (skin.getIdentifier() - weapon.getWeaponIdentifier())); + + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + WeaponSkinDAO.unlockSkin(connection, this.uuid, weapon, skin); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } + } + + public void equipWeaponSkin(Weapon<?> weapon, WeaponSkin skin) { + short currentSkin = this.equippedWeaponSkins.containsKey(weapon.getUniqueIdentifier()) ? this.equippedWeaponSkins.get(weapon.getUniqueIdentifier()) : 0; + + ServerUtil.runTaskAsync(() -> { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + if(currentSkin != weapon.getWeaponIdentifier()) { + WeaponSkinDAO.disableSkin(connection, this.uuid, weapon, currentSkin); + } + + if(skin.getIdentifier() != weapon.getWeaponIdentifier()) { + WeaponSkinDAO.enableSkin(connection, this.uuid, weapon, (short) (skin.getIdentifier() - weapon.getWeaponIdentifier())); + } + } catch (SQLException e) { + e.printStackTrace(); + } + }); + + this.equippedWeaponSkins.put(weapon.getUniqueIdentifier(), (short) (skin.getIdentifier() - weapon.getWeaponIdentifier())); + } + + public boolean hasSkinUnlocked(Weapon<?> weapon, WeaponSkin skin) { + if (this.getUnlockedWeaponSkins(weapon) != null) { + for (short skinID : this.getUnlockedWeaponSkins(weapon)) { + if (skinID == (short) (skin.getIdentifier() - weapon.getWeaponIdentifier())) { + return true; + } + } + } + + return false; + } + + public List<Short> getUnlockedWeaponSkins(Weapon<?> weapon) { + return this.unlockedWeaponSkins.get(weapon.getUniqueIdentifier()); + } + + public Map<Short, List<WeaponSkin>> getUnlockedWeaponSkins() { + Map<Short, List<WeaponSkin>> skins = new HashMap<Short, List<WeaponSkin>>(); + + for (short weaponID : this.unlockedWeaponSkins.keySet()) { + Optional<Weapon<?>> weaponOpt = Vice.getWastedGuns().getWeaponManager().getWeaponFromUniqueIdentifier(weaponID); + + if (weaponOpt.isPresent()) { + Weapon<?> weapon = weaponOpt.get(); + List<WeaponSkin> skinSubArray = new ArrayList<WeaponSkin>(); + + for (short skinID : this.unlockedWeaponSkins.get(weaponID)) { + skinSubArray.add(Vice.getWeaponSkinManager().getWeaponSkinFromIdentifier(weapon, skinID)); + } + + skins.put(weaponID, skinSubArray); + } + } + + return skins; + } + + public Map<Short, List<Short>> getRawUnlockedWeaponSkins() { + return this.unlockedWeaponSkins; + } + + public WeaponSkin getEquippedWeaponSkin(Weapon<?> weapon) { + return this.equippedWeaponSkins.containsKey(weapon.getUniqueIdentifier()) ? Vice.getWeaponSkinManager().getWeaponSkinFromIdentifier(weapon, this.equippedWeaponSkins.get(weapon.getUniqueIdentifier())) : weapon.getWeaponSkins()[0]; + } + + public Map<Short, WeaponSkin> getEquippedWeaponSkins() { + Map<Short, WeaponSkin> skins = new HashMap<Short, WeaponSkin>(); + + for (short weaponID : this.equippedWeaponSkins.values()) { + Optional<Weapon<?>> weaponOpt = Vice.getWastedGuns().getWeaponManager().getWeaponFromUniqueIdentifier(weaponID); + + if (weaponOpt.isPresent()) { + skins.put(weaponID, Vice.getWeaponSkinManager().getWeaponSkinFromIdentifier(weaponOpt.get(), this.equippedWeaponSkins.get(weaponID))); + } + } + + return skins; + } +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/ViceUserDAO.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/ViceUserDAO.java new file mode 100644 index 0000000..840e0f5 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/ViceUserDAO.java @@ -0,0 +1,936 @@ +package net.grandtheftmc.vice.users; + +import com.google.common.collect.Lists; +import com.j0ach1mmall3.wastedvehicles.api.VehicleProperties; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.database.BaseDatabase; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.State; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.items.AmmoType; +import net.grandtheftmc.vice.items.Head; +import net.grandtheftmc.vice.items.Kit; +import net.grandtheftmc.vice.weapon.skins.WeaponSkinDAO; + +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import java.sql.*; +import java.util.*; +import java.util.logging.Level; + +public class ViceUserDAO { + + //"select * from " + Core.name() + " where uuid='" + this.uuid + "' LIMIT 1;" + public static boolean getGeneralViceUser(ViceUser user) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + user.unlockedWeaponSkins = WeaponSkinDAO.getUnlockedSkins(connection, user.uuid); + user.equippedWeaponSkins = WeaponSkinDAO.getEquippedSkins(connection, user.uuid); + + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM " + Core.name() + " WHERE `uuid`=? LIMIT 1;")) { + statement.setString(1, user.uuid.toString()); + try (ResultSet result = statement.executeQuery()) { + if(result.next()) { + user.rank = ViceRank.fromString(result.getString("rank")); + user.copRank = CopRank.getRankOrNull(result.getString("copRank")); + user.lastCopSalary = result.getLong("lastCopSalary"); + user.kills = result.getInt("kills"); + user.deaths = result.getInt("deaths"); + user.money = result.getDouble("money"); + user.killStreak = result.getInt("killStreak"); + user.bonds = result.getInt("bonds"); + user.backpackContents = ViceUtils.fromBase64(result.getString("backpackContents")); + user.kitExpiries = new HashMap<>(); + user.jailTimer = result.getInt("jailTimer"); + try { + user.jailCop = result.getString("jailCop") == null ? null : UUID.fromString(result.getString("jailCop")); + } catch (Exception ignored) { + } + user.playtime = result.getLong("playtime"); + user.jailCopName = result.getString("jailCopName"); + String s = result.getString("kitExpiries"); + user.kitExpiries = new HashMap<>(); + if (s != null) + try { + String[] expiries = s.split(","); + for (String e : expiries) { + String[] a = e.split(":"); + String kit = a[0]; + Kit k = Vice.getItemManager().getKit(kit); + if (kit == null || a.length < 2) + continue; + long expiry; + try { + expiry = Long.parseLong(a[1]); + } catch (NumberFormatException ex) { + continue; + } + if (expiry > System.currentTimeMillis()) { + user.kitExpiries.put(k.getName().toLowerCase(), expiry); + } + } + + } catch (Exception e) { + Vice.getInstance().getLogger().log(Level.ALL, "Error while loading kitExpiries for player " + result.getString("name")); + e.printStackTrace(); + } + for (AmmoType type : AmmoType.getTypes()) + if (!type.isInInventory()) + user.ammo.put(type, result.getInt(type.name().toLowerCase())); + for (VehicleProperties properties : Vice.getWastedVehicles().getBabies().getVehicleProperties()) { + if (result.getBoolean(properties.getIdentifier().toLowerCase())) { + PersonalVehicle v = new PersonalVehicle(properties.getIdentifier()); + user.vehicles.add(v); + String st = result.getString(properties.getIdentifier().toLowerCase() + ":info"); + if (st == null) continue; + String[] a = st.split(":"); + if (a == null | a.length == 0) continue; + v.setHealth(Double.parseDouble(a[0])); + } + } + + //Cheat Codes + if(result.getBlob("cheatcodes") != null) { + Blob b = result.getBlob("cheatcodes"); + String cheatCodesBlob = new String(b.getBytes(1, (int) b.length())); + for (String serializedCheatCode : cheatCodesBlob.split("-")) { + String[] split = serializedCheatCode.split("#"); + user.cheatCodes.put(CheatCode.valueOf(split[0]), new CheatCodeState(State.valueOf(split[1]), Boolean.valueOf(split[2]))); + } + } + + User coreUser = Core.getUserManager().getLoadedUser(user.uuid); + for(CheatCode code : CheatCode.values()) { + if (coreUser.getUserRank() == code.getMinmumRank() || coreUser.getUserRank().isHigherThan(code.getMinmumRank())) { + if (!user.cheatCodes.containsKey(code) || user.cheatCodes.get(code).getState() == State.LOCKED) { + user.cheatCodes.put(code, new CheatCodeState(code.getDefaultState(), false)); + } + } + else { + if(user.cheatCodes.containsKey(code) && !user.cheatCodes.get(code).isPurchased()) { + user.cheatCodes.put(code, new CheatCodeState(State.LOCKED, false)); + } + } + } + + for(CheatCode code : CheatCode.values()) + if(!user.cheatCodes.containsKey(code)) + user.cheatCodes.put(code, new CheatCodeState(State.LOCKED, false)); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean insertViceUser(ViceUser user, String name) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO " + Core.name() + "(`uuid`,`name`,`money`) VALUES(?,?,'5000') ON DUPLICATE KEY UPDATE `name`=?;")) { + statement.setString(1, user.uuid.toString()); + statement.setString(2, name); + statement.setString(3, name); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean checkForDuplicate(ViceUser user, String name) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `name`=? WHERE `name`=? AND `uuid`!=?;")) { + statement.setString(1, "ERROR"); + statement.setString(2, name); + statement.setString(3, user.uuid.toString()); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean setCheatCodeState(ViceUser user) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `cheatcodes`=? WHERE `uuid`=?;")) { + statement.setString(1, CheatCode.seralizeCheatCodes(user.cheatCodes)); + statement.setString(2, user.uuid.toString()); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean setBackpackContents(UUID uuid, ItemStack[] backpackContents) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `backpackContents`=? WHERE `uuid`=?;")) { + statement.setString(1, backpackContents == null ? null : ViceUtils.toBase64(backpackContents)); + statement.setString(2, uuid.toString()); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean setBackpackContents(String name, ItemStack[] backpackContents) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `backpackContents`=? WHERE `name`=?;")) { + statement.setString(1, backpackContents == null ? null : ViceUtils.toBase64(backpackContents)); + statement.setString(2, name); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean setRank(UUID uuid, ViceRank rank) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `rank`=? WHERE `uuid`=?;")) { + statement.setString(1, rank.getName()); + statement.setString(2, uuid.toString()); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean setRank(String name, ViceRank rank) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `rank`=? WHERE `name`=?;")) { + statement.setString(1, rank.getName()); + statement.setString(2, name); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean setCopRank(ViceUser user, CopRank rank) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `copRank`=? WHERE `uuid`=?;")) { + statement.setString(1, (rank == null ? null : rank.getName())); + statement.setString(2, user.uuid.toString()); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean setLastCopSalary(ViceUser user, long value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `lastCopSalary`=? WHERE `uuid`=?;")) { + statement.setLong(1, value); + statement.setString(2, user.uuid.toString()); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean setKills(ViceUser user, int value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `kills`=? WHERE `uuid`=?;")) { + statement.setInt(1, value); + statement.setString(2, user.uuid.toString()); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean setDeaths(ViceUser user, int value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `deaths`=? WHERE `uuid`=?;")) { + statement.setInt(1, value); + statement.setString(2, user.uuid.toString()); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean setMoney(UUID uuid, double value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `money`=? WHERE `uuid`=?;")) { + statement.setDouble(1, value); + statement.setString(2, uuid.toString()); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean setMoney(String name, double value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `money`=? WHERE `name`=?;")) { + statement.setDouble(1, value); + statement.setString(2, name); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean addMoney(String name, double value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `money`=money+? WHERE `name`=?;")) { + statement.setDouble(1, value); + statement.setString(2, name); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean takeMoney(String name, double value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `money`=money-? WHERE `name`=?;")) { + statement.setDouble(1, value); + statement.setString(2, name); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean setPlaytime(ViceUser user, long value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `playtime`=? WHERE `uuid`=?;")) { + statement.setLong(1, value); + statement.setString(2, user.uuid.toString()); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean setKillStreak(ViceUser user, int value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `killStreak`=? WHERE `uuid`=?;")) { + statement.setInt(1, value); + statement.setString(2, user.uuid.toString()); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean setBonds(UUID uuid, int value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `bonds`=? WHERE `uuid`=?;")) { + statement.setInt(1, value); + statement.setString(2, uuid.toString()); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean setBonds(String name, int value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `bonds`=? WHERE `name`=?;")) { + statement.setInt(1, value); + statement.setString(2, name); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean addBonds(String name, int value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `bonds`=bonds+? WHERE `name`=?;")) { + statement.setInt(1, value); + statement.setString(2, name); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean takeBonds(String name, int value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `bonds`=bonds-? WHERE `name`=?;")) { + statement.setInt(1, value); + statement.setString(2, name); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean updateKitExpiries(UUID uuid, String value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `kitExpiries`=? WHERE `uuid`=?;")) { + statement.setString(1, value); + statement.setString(2, uuid.toString()); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean updateKitExpiries(String name, String value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `kitExpiries`=? WHERE `name`=?;")) { + statement.setString(1, value); + statement.setString(2, name); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean setAmmo(ViceUser user, String key, int value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET " + key + "=? WHERE `uuid`=?;")) { + statement.setInt(1, value); + statement.setString(2, user.uuid.toString()); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean resetAllAmmo(String name, String set) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET " + set + " WHERE `uuid`=?;")) { + statement.setString(1, name); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean setJailTimer(ViceUser user, int value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `jailTimer`=? WHERE `uuid`=?;")) { + statement.setInt(1, value); + statement.setString(2, user.uuid.toString()); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean resetJail(UUID uuid) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `jailTimer`=-1,`jailCop`=NULL,`jailCopName`=NULL WHERE `uuid`=?;")) { + statement.setString(1, uuid.toString()); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean resetJail(String name) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `jailTimer`=-1,`jailCop`=NULL,`jailCopName`=NULL WHERE `name`=?;")) { + statement.setString(1, name); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean setjailed(ViceUser user, int jailTimer, UUID uuid, String name) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `jailTimer`=?,`jailCop`=?,`jailCopName`=? WHERE `uuid`=?;")) { + statement.setInt(1, jailTimer); + statement.setString(2, uuid.toString()); + statement.setString(3, name); + statement.setString(4, user.uuid.toString()); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean setVehiclePerm(UUID uuid, VehicleProperties vehicle, boolean value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `" + vehicle.getIdentifier().toLowerCase() + "`=? WHERE `uuid`=?;")) { + statement.setBoolean(1, value); + statement.setString(2, uuid.toString()); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean setVehiclePerm(String name, VehicleProperties vehicle, boolean value) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `" + vehicle.getIdentifier().toLowerCase() + "`=? WHERE `name`=?;")) { + statement.setBoolean(1, value); + statement.setString(2, name); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean updateRankByName(String name, ViceRank rank) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `rank`=? WHERE `name`=?;")) { + statement.setString(1, rank.getName()); + statement.setString(2, name); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean resetAllVehicles(String name, String set) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET " + set + " WHERE `name`=?;")) { + statement.setString(1, name); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean updateVehicles(UUID uuid, VehicleProperties v, double d) { + //"UPDATE " + Core.name() + " SET `" + v.getIdentifier().toLowerCase() + ":info`=? WHERE `uuid`=?;" + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE " + Core.name() + " SET `" + v.getIdentifier().toLowerCase() + ":info`=? WHERE `uuid`=?;")) { + statement.setDouble(1, d); + statement.setString(2, uuid.toString()); + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean getCops(HashMap<String, CopRank> onlineCops, HashMap<String, CopRank> offlineCops) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM " + Core.name() + " WHERE `copRank` IS NOT NULL;")) { + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + String name = result.getString("name"); + if(onlineCops.containsKey(name)) + continue; + CopRank rank = CopRank.getRankOrNull(result.getString("copRank")); + offlineCops.put(name, rank); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static int countCops(CopRank rank) { + int amount = 0; + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM " + Core.name() + " WHERE `copRank`=?;")) { + statement.setString(1, rank.getName()); + try (ResultSet result = statement.executeQuery()) { + + while (result.next()) { + amount += 1; + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + return amount; + } + + return amount; + } + + public static Optional<Object[]> getMoneyAndName(String name) { + Object[] objects = new Object[2]; + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT `name`,`money` FROM " + Core.name() + " WHERE `name`=?;")) { + statement.setString(1, name); + try (ResultSet result = statement.executeQuery()) { + if (result.next()) { + objects[0] = result.getString("name"); + objects[1] = result.getDouble("money"); + } + + return Optional.of(objects); + } + } + } catch (SQLException e) { + e.printStackTrace(); + return Optional.empty(); + } + } + + public static Optional<Object[]> getBondAndName(String name) { + Object[] objects = new Object[2]; + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT `name`,`bonds` FROM " + Core.name() + " WHERE `name`=?;")) { + statement.setString(1, name); + try (ResultSet result = statement.executeQuery()) { + if (result.next()) { + objects[0] = result.getString("name"); + objects[1] = result.getDouble("bonds"); + } + + return Optional.of(objects); + } + } + } catch (SQLException e) { + e.printStackTrace(); + return Optional.empty(); + } + } + + public static Optional<Object[][]> getBalanceTop(int limit) { + Object[][] objects = new Object[limit][2]; + + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT `money`,`name` FROM `" + Core.name() + "` ORDER BY cast(`money` as double) DESC LIMIT " + limit + ";")) { + try (ResultSet result = statement.executeQuery()) { + int i = 0; + while (result.next()) { + objects[i][0] = result.getString("name"); + objects[i][1] = result.getDouble("money"); + i++; + } + + return Optional.of(objects); + } + } + } catch (SQLException e) { + e.printStackTrace(); + return Optional.empty(); + } + } + + public static boolean createTable() { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("CREATE TABLE IF NOT EXISTS " + Core.name() + "(" + + "uuid varchar(40) NOT NULL, " + + "name varchar(17) NOT NULL, " + + "rank varchar(255) DEFAULT 'HOBO', " + + "copRank varchar(366) DEFAULT NULL, " + + "kills int(11) default 0, " + + "deaths int(11) default 0, " + + "money double default 0, " + + "killStreak int(11) default 0, " + + "bonds int(11) default 0, " + + "backpackContents longtext, " + + "kitExpiries varchar(255), " + + "houses varchar(255), " + + "gang varchar(255), " + + "gangRank varchar(255) NOT NULL DEFAULT 'member', " + + "jailTimer int(11) DEFAULT -1, " + + "jailCop varchar(255) default NULL, " + + "jailCopName varchar(255) default NULL, " + + "personalVehicle varchar(255), " + + "cheatcodes BLOB, " + + "PRIMARY KEY (uuid)" + + ")")) { + + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean insertHead(UUID sellerUUID, String sellerName, String head, long expiry) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO " + Core.name() + "_heads(sellerUUID, sellerName, head, expiry) values (?,?,?,?);")) { + statement.setString(1, sellerUUID.toString()); + statement.setString(2, sellerName); + statement.setString(3, head); + statement.setLong(4, expiry); + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static boolean deleteHead(UUID sellerUUID, String head, long expiry) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("DELETE FROM " + Core.name() + "_heads WHERE `sellerUUID`=? AND `head`=? AND `expiry`=?;")) { + statement.setString(1, sellerUUID.toString()); + statement.setString(2, head); + statement.setLong(3, expiry); + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public static List<Head> getHeads() { + List<Head> heads = Lists.newArrayList(); + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM " + Core.name() + "_heads;")) { + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + UUID sellerUUID = null; + UUID bidderUUID = null; + try { + sellerUUID = result.getString("sellerUUID") == null ? null : UUID.fromString(result.getString("sellerUUID")); + bidderUUID = result.getString("bidderUUID") == null ? null : UUID.fromString(result.getString("bidderUUID")); + } catch (Exception ignored) { + } + heads.add(new Head( + sellerUUID, + result.getString("sellerName"), + result.getString("head"), + result.getLong("expiry"), + result.getBoolean("done"), + result.getBoolean("paid"), + result.getBoolean("gaveHead"), + bidderUUID, + result.getString("bidderName"), + result.getDouble("bid") + )); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + return heads; + } + + return heads; + } + + public static boolean managePlaytime() { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM " + Core.name() + " LIMIT 1;")) { + try (ResultSet result = statement.executeQuery()) { + ResultSetMetaData metaData = result.getMetaData(); + List<String> columns = new ArrayList<>(); + + for (int i = 1; i <= metaData.getColumnCount(); i++) + columns.add(metaData.getColumnName(i).toLowerCase()); + + if (!columns.contains("playtime")) +// Core.sql.updateAsyncLater("ALTER TABLE " + Core.name() + " ADD COLUMN playtime BIGINT(20) NOT NULL DEFAULT 0;"); + runQuery("ALTER TABLE " + Core.name() + " ADD COLUMN playtime BIGINT(20) NOT NULL DEFAULT 0;"); + + for (AmmoType type : AmmoType.values()) + if (!type.isInInventory() && !columns.contains(type.toString().toLowerCase())) +// Core.sql.update("alter table " + Core.name() + " add column " + type.toString().toLowerCase() + " int(11) default 0;"); + runQuery("ALTER TABLE " + Core.name() + " ADD COLUMN " + type.toString().toLowerCase() + " INT(11) DEFAULT 0;"); + + for (VehicleProperties vehicle : Vice.getWastedVehicles().getBabies().getVehicleProperties()) { + if (!columns.contains(vehicle.getIdentifier().toLowerCase())) +// Core.sql.update("alter table " + Core.name() + " add column " + vehicle.getIdentifier().toLowerCase() + " BOOLEAN not null default 0;"); + runQuery("ALTER TABLE " + Core.name() + " ADD COLUMN " + vehicle.getIdentifier().toLowerCase() + " BOOLEAN NOT NULL DEFAULT 0;"); + + if (!columns.contains(vehicle.getIdentifier().toLowerCase() + ":info")) +// Core.sql.update("alter table " + Core.name() + " add column `" + vehicle.getIdentifier().toLowerCase() + ":info` VARCHAR(255);"); + runQuery("ALTER TABLE " + Core.name() + " ADD COLUMN `" + vehicle.getIdentifier().toLowerCase() + ":info` VARCHAR(255);"); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + private static boolean runQuery(String query) { + try (Connection connection = BaseDatabase.getInstance().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement(query)) { + statement.execute(); + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/ViceUserManager.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/ViceUserManager.java new file mode 100644 index 0000000..f9ed69a --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/ViceUserManager.java @@ -0,0 +1,30 @@ +package net.grandtheftmc.vice.users; + +import java.util.*; + +public class ViceUserManager { + + private final Map<UUID, ViceUser> loadedUsers = new HashMap<>(); + + public Collection<ViceUser> getLoadedUsers() { + return this.loadedUsers.values(); + } + + public boolean unloadUser(UUID uuid) { + if(this.loadedUsers.containsKey(uuid)){ + this.loadedUsers.get(uuid).save(); + this.loadedUsers.remove(uuid); + return true; + } + return false; + } + + public ViceUser getLoadedUser(UUID uuid) { + if (uuid == null) { + return null; + } + + return this.loadedUsers.computeIfAbsent(uuid, k -> new ViceUser(uuid)); + } + +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/npcs/MachineNPC.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/npcs/MachineNPC.java new file mode 100644 index 0000000..c4f9c21 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/npcs/MachineNPC.java @@ -0,0 +1,43 @@ +package net.grandtheftmc.vice.users.npcs; + +import net.citizensnpcs.api.event.NPCLeftClickEvent; +import net.citizensnpcs.api.event.NPCRightClickEvent; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.npc.CoreNPC; +import net.grandtheftmc.core.npc.interfaces.ClickableNPC; +import net.grandtheftmc.vice.machine.MachineManager; +import net.grandtheftmc.vice.machine.repair.MachineRepairMenu; +import org.bukkit.Location; +import org.bukkit.entity.EntityType; + +/** + * Created by Timothy Lampen on 2/12/2018. + */ +public class MachineNPC extends CoreNPC implements ClickableNPC { + + private final MachineManager machineManager; + + public MachineNPC(MachineManager machineManager, Location loc) { + super(loc, EntityType.PLAYER, Utils.f("&6&lHenry Ford"), Utils.f("&7&oTrade your machine shards here!")); + this.machineManager = machineManager; + } + + @Override + protected void generateNewNPC() { + setSkin( + "eyJ0aW1lc3RhbXAiOjE1MTg1MjA2MjU2MTksInByb2ZpbGVJZCI6IjAyMjEyMmM5Yjk5ZjRhNmY4MTNkNzVkNmMwMTk5NWU2IiwicHJvZmlsZU5hbWUiOiJNZWNoYW5pYyIsInNpZ25hdHVyZVJlcXVpcmVkIjp0cnVlLCJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOTVkNzY5ZDEyZWUyN2Y1ZDM4ZGQ2ZjNjMGI0Mjg2NjU2NDU4Njg3NGI3MWFhMjczNTIzZDBhYWM1ZjM3ZSJ9fX0=", + "BFTXOx0chlORiL9UHDrnkQDsU9yFZDriJ18Si52h1vyDnsKwWskAFvp5SnUtQ1gBUebE+vz//CAJWetCdONIKbTU8MDpGS524YI6C6F1lV6bHbvb1MAEX3ezEDpinB7G/gNRQRddBYuuYd0iXqkYbiLrYzGs3O2KTQ+HEz8M2detE6B9JkFwBk797DJ6A7RJyMsJk7NRgTKM2i9cBZhlOklwobQDUH4tQ9zzVsrbKxXBB9rbUKZxIWPMOk9CfPIgZHu14N/rbYfQ9KFRd2BhlSWuFRxXLh3htGZHESsifzbZg0TkKtMpKAOTX7mYbxS8/KUhoQH3Q816CP6EI93B2gvlq7fVNCiyi19ad4A0NkCMBoiv1KBqB4J91CVMoomGalaWxVt+3JJ/IE/No9/mfWhGA5EKs3uHYJD7x6OmsYxbahnV+GyaiXQFJz3x/ObGr5evLBXt5JgQP2DQX/7+2HU7dNh8J6ZwWtEg+Yh33y46Oh6A60ixqpFXN1pwHkXgplS/4HVsliCFbwhTDqBS9sX8pYlj+MEdmPWvYrVk0KsNqEYLawR/8ukTosBRZgWPo2HDHXQ+/IQ7AfKhC/NH0pnTMQrFYTV8p+kqKJCO5Tcu/GefsA7miVAktYFCTGxM8YdZDYFCpf1wC3pJRnHYbjzaHpny839Mh2t7kOHVCCQ=" + ); + setLookClose(true); + } + + @Override + public void onRightClick(NPCRightClickEvent npcRightClickEvent) { + new MachineRepairMenu(this.machineManager).openInventory(npcRightClickEvent.getClicker()); + } + + @Override + public void onLeftClick(NPCLeftClickEvent npcLeftClickEvent) { + new MachineRepairMenu(this.machineManager).openInventory(npcLeftClickEvent.getClicker()); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/npcs/SkinsNPC.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/npcs/SkinsNPC.java new file mode 100644 index 0000000..eddd0bb --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/npcs/SkinsNPC.java @@ -0,0 +1,34 @@ +package net.grandtheftmc.vice.users.npcs; + +import org.bukkit.Location; +import org.bukkit.entity.EntityType; + +import net.citizensnpcs.api.event.NPCLeftClickEvent; +import net.citizensnpcs.api.event.NPCRightClickEvent; +import net.grandtheftmc.core.npc.CoreNPC; +import net.grandtheftmc.core.npc.interfaces.ClickableNPC; +import net.grandtheftmc.vice.weapon.skins.menu.MainMenu; + +public class SkinsNPC extends CoreNPC implements ClickableNPC { + public SkinsNPC(Location location) { + super(location, EntityType.PLAYER, "&9&lMr Skinner", "&7&oManage and view your weapon skins here!"); + } + + @Override + protected void generateNewNPC() { + this.setLookClose(true); + this.setSkin( + "eyJ0aW1lc3RhbXAiOjE1MTg1NjMxNzk3MDEsInByb2ZpbGVJZCI6Ijc2MTJhZWU1YTk5YjQxZWRiYTg3Nzg4MGMyMjZiMzM2IiwicHJvZmlsZU5hbWUiOiJGbG91cmVrIiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS8yNjE0ODNmMGIxNjc2OWQ2NGFlMTI5Yjg5ZDYyY2M3N2M1Mzk0OGRlZTVmYzQ2MmFlNTQ1OTQyZWYwNDdjNzliIn19fQ==", + "svzvIYm7x02JAMpjnW+oKQAM48jpzTNvKtLVSPGuL7DjWjZOuH+fjrw6tqGWKAHZYbR7QaIfNiHKk/uKbF8gGij9jxphAZuD47p53ALODYwbopir2lSdmMl+flPggTS7dWYmPfQsnSa4t13O1yLZMmdtFUTzyJQYZqFeU+Ss7CAiU0Xxvi5SNqlrLlm+utDaQQoobfkHeuHBe1/bFDNrTx7iYGYuPqn3Y5T8YtqgyRVaQsoDyeAmONNJE5R/o8MVOEFKtqE/MqL5ONpAFkkM1iDlajj+C3lhJ/3ORnpA6HTTyAGvLLZJNXBNM2+nl4x7hyEMw6kQJ5JCh3uFGbJamXvpi/pFQS2rBI1OZVzhZbYIE9/dfqxK6MH7A9Z1XlCPYQPFmQzh0unJH8y4OTBxfUsEjaIgB8AG61SjuyJqFo5oeJ2DJ1kO8ua72tLl13ron/fk+AfGeW16LuwxIy1XaUki4UC5MRcE0wj7ou68ME1gR/XmjpQDuaPaJj7yf+epFHc9lDARtb21yqOkYJXAKiN6ec8HU7uhIXW142K+bhzFGTfUZ6jxnL54TQ6qWojwpM/VEM8ewsMaL4Xf3Kh5hPzuXeylca4qPZzhsJ2I9Bf09i1TknDVTnW8qgmz4WZynyBNMdWZ60w25q/afM1DB9QuzUo2Qa+y2z7MSDALMCw="); + } + + @Override + public void onRightClick(NPCRightClickEvent event) { + new MainMenu(event.getClicker()).open(); + } + + @Override + public void onLeftClick(NPCLeftClickEvent npcLeftClickEvent) { + + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/npcs/TaxiNPC.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/npcs/TaxiNPC.java new file mode 100644 index 0000000..15777ba --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/npcs/TaxiNPC.java @@ -0,0 +1,59 @@ +package net.grandtheftmc.vice.users.npcs; + +import net.citizensnpcs.api.event.NPCLeftClickEvent; +import net.citizensnpcs.api.event.NPCRightClickEvent; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.inventory.CoreMenu; +import net.grandtheftmc.core.inventory.button.ClickableItem; +import net.grandtheftmc.core.inventory.button.MenuItem; +import net.grandtheftmc.core.menus.MenuManager; +import net.grandtheftmc.core.npc.CoreNPC; +import net.grandtheftmc.core.npc.interfaces.ClickableNPC; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +/** + * Created by Timothy Lampen on 1/24/2018. + */ +public class TaxiNPC extends CoreNPC implements ClickableNPC { + public TaxiNPC(Location loc) { + super(loc, EntityType.PLAYER, "&e&lGerald Hackney", "&7&oGo to the game world!"); + } + + @Override + protected void generateNewNPC() { + setSkin("eyJ0aW1lc3RhbXAiOjE1MTU5NzAzNjYzNDUsInByb2ZpbGVJZCI6ImFkMWM2Yjk1YTA5ODRmNTE4MWJhOTgyMzY0OTllM2JkIiwicHJvZmlsZU5hbWUiOiJGdXJrYW5iejAwIiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9jYzUzZWQyMzJlYWQyNmU4Y2I0NzJiMGFmOGIyMDQyYjdhZjljZDMyOGRlM2M0YTZlNGQzNjNiNDNiZDlmNDUifX19", "hLKOkCuejv8K7bwWS/SKY6jrxJXNojg4eiv1/TPkKJ/1Hc+njUE99IPLCuexppJASlUEMe2815FfDwS4PTzMzgxBeLPdcB/xJR8BZw4FuvodIXfLubmVkxme245u0hRHfVlPLk31l4dyPFEwRMhbSmHacVroB8pebEov6+164p3fUnctqlM48bf6lNfpsbhY46nvqPVRVtv9ljTL6FwBPDvnZL97zTSsUqjKjLUJMTtuHIaAj26Q9+M9y4rP1VMInDWrgfXpEuwz32xy/2HiHHQrGMrNxU9MmshDX1BTJ4UAxmipmj+pJENRSon3GrIgLE7t/yP0Z1ZCcfHFqZtzLHKPXzt+u4jW5hl9bFUU9d9HSUEV0qt+nD68a1yNiWPE2rB0l549v+AZ5D8bktSpvdLy574/uBLLXbM8JJk8g1iFgyeEpQS8TJuHfnyV62KU6lML5+MTt7/zBXlRh2+Vz89Ti0fbZs1g6NdcJWQisCTtVPMBiws9yoitmSsqKk+8/8WYQX7EYXLGilL7gavoBZhlIyP0P8ltTc4oHfcwoOtoZvPivauUv8lHZu18tZpOE1kq28lNuBdytLTWTuJckDzeRwbB8pHCQKB628nRLt2Xp1N57CNnc9XW/3sWY+rKTRHRNw7BvVqoaCAXP4tNo+c7frELxv+CgWMxRcE2g5E="); + setLookClose(true); + } + + @Override + public void onRightClick(NPCRightClickEvent event) { + Player player = event.getClicker(); + new TaxiMenu().openInventory(player); + } + + @Override + public void onLeftClick(NPCLeftClickEvent event) { + + } + + private class TaxiMenu extends CoreMenu { + + public TaxiMenu() { + super(3, Utils.f("&e&lTaxi")); + + for(int i = 0; i < 27; i++) { + if(i==13) + continue; + addItem(new MenuItem(i, new ItemStack(Material.STAINED_GLASS_PANE, 1, (short)7), false)); + } + + addItem(new ClickableItem(13, Utils.createItem(Material.SAPLING, "&d&lRandom Teleport"), (player, clickType) -> { + player.chat("/rtp"); + }, false)); + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/npcs/TrashCanManager.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/npcs/TrashCanManager.java new file mode 100644 index 0000000..f6a763c --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/npcs/TrashCanManager.java @@ -0,0 +1,244 @@ +package net.grandtheftmc.vice.users.npcs; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.items.GameItem; +import net.grandtheftmc.vice.users.ViceUser; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitRunnable; + +import java.text.DecimalFormat; +import java.util.*; +import java.util.stream.Collectors; + + +/** + * + * + * @apiNote This class is positioned here because it is only used for the drugs menu. + * + */ +public class TrashCanManager implements Listener { + + private final Set<UUID> inTrashcan = new HashSet<>(); + + public void openTrashCan(Player player) { + if (Vice.getUserManager().getLoadedUser(player.getUniqueId()).isArrested()) { + player.sendMessage(Lang.JAIL.f("&7You can't sell items in jail!")); + return; + } + Inventory inv = Bukkit.createInventory(null, 54, Utils.f("&a&lSell Drugs")); + int[] paneSlots = new int[] { 9, 10, 11, 12, 13, 14, 15, 16, 17, 27, 28, 29, 30, 31, 32, 33, 34, 35, 45, 46, 47, + 48, 49, 50, 51, 52 }; + for (int i : paneSlots) + inv.setItem(i, Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a")); + // inv.setItem(52, Utils.createItem(Material.DIAMOND, "&6&lSell Entire Inventory", "&7Total Value: &a$&l" + getTotalInvPrice(player))); + inv.setItem(53, Utils.createItem(Material.PAPER, "&a&lConfirm", "&7Total Reward: &a$&l0")); + inv.setItem(44, Utils.createItem(Material.REDSTONE, "&c&lCancel", "&7Return all items!")); + + this.inTrashcan.add(player.getUniqueId()); + + player.openInventory(inv); + } + + private void m(int i) { + this.m(String.valueOf(i)); + } + + private void m(String s) { + Bukkit.broadcastMessage(s); + } + + @EventHandler + public void onClick(InventoryClickEvent e) { + Player player = (Player) e.getWhoClicked(); + Inventory inv = e.getView().getTopInventory(); + if (inv == null || !this.inTrashcan.contains(player.getUniqueId())) + return; + + ItemStack c = e.getCurrentItem(); + if (c != null) { + switch (c.getType()) { + case PAPER: + e.setCancelled(true); + player.closeInventory(); + return; + case REDSTONE: + e.setCancelled(true); + List<ItemStack> items = itemSlots.stream().mapToInt(i -> i).mapToObj(inv::getItem).filter(Objects::nonNull).collect(Collectors.toList()); + + for (int i : itemSlots) { + inv.setItem(i, null); + inv.setItem(i + 9, Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a")); + } + + player.closeInventory(); + Utils.giveItems(player, items.toArray(new ItemStack[items.size()])); + + if (c.getType() == Material.REDSTONE) + player.sendMessage(Utils.f(Lang.TRASH_CAN + "&7The items have been added back to your inventory.")); + + if (c.getType() == Material.DIAMOND) + player.sendMessage(Utils.f(" &c&lERROR&8&l> &cThis feature is currently disabled, try again soon!")); + + return; + + /* + case DIAMOND://TODO, Fix sell-all, It causes alot of lag! + e.setCancelled(true); +// double price = getTotalInvPrice(player); +// if (price == 0) return; + player.closeInventory(); +// ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); +// user.setSellInvConfirmAmt(price); +// MenuManager.openMenu(player, "sellinvconfirm"); + + //TODO, Remove message after fixing lag. + player.sendMessage(Utils.f(" &c&lERROR&8&l> &cThis feature is currently disabled, try again soon!")); + return; + */ + + default: + break; + } + } + + if (Objects.equals(e.getClickedInventory(), inv) && !itemSlots.contains(e.getSlot())) { + e.setCancelled(true); + player.updateInventory(); + return; + } + new BukkitRunnable() { + @Override + public void run() { + if (!player.isOnline()) + return; + updateTrashCan(inv); + + } + }.runTaskLater(Vice.getInstance(), 1); + } + + private double calculateItem(Inventory inv, int slot, boolean updateInventory) { + ItemStack item = inv.getItem(slot); + + if (item == null) { + if(updateInventory) + inv.setItem(slot + 9, Utils.createItem(Material.STAINED_GLASS_PANE, 7, "&a")); + return 0; + } + GameItem gameItem = Vice.getItemManager().getSellableItem(item); + + if(gameItem==null || gameItem.getType()!= GameItem.ItemType.DRUG) + return 0; + + double price = gameItem.getSellPrice() * item.getAmount(); + DecimalFormat df = new DecimalFormat("#.##"); + if(updateInventory) + inv.setItem(slot + 9, Utils.createItem(Material.STAINED_GLASS_PANE, 13,"&a&lReward: &a$&l" + df.format(price))); + return price; + } + + private double updateTrashCan(Inventory inv) { + List<Integer> itemSlots = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 18, 19, 20, 21, 22, 23, 24, 25, 26, 36, 37, 38, 39, 40, 41, 42, 43); + if(inv.getViewers().size()==0) + return 0; + Player player = (Player) inv.getViewers().get(0); + if(player==null) + return 0; + + //inv.setItem(52, Utils.createItem(Material.DIAMOND, "&6&lSell Entire Inventory", "&7Total Value: &a$&l" + getTotalInvPrice(player))); + DecimalFormat df = new DecimalFormat("#.##"); + double rankMultiplier = ViceUtils.getDrugSellModifier(Core.getUserManager().getLoadedUser(player.getUniqueId()).getUserRank()); + + double totalPrice = itemSlots.stream().mapToDouble(i -> this.calculateItem(inv, i, true)).sum() * rankMultiplier; + + inv.setItem(53, Utils.createItem(Material.PAPER, "&a&lConfirm", "&7Total Reward: &a$&l" + df.format(totalPrice), "&6&lRank Multiplier: &b&l" + rankMultiplier + "x")); + inv.setItem(44, Utils.createItem(Material.REDSTONE, "&c&lCancel", "&7Return all items!")); + return totalPrice; + } + + /*public double getTotalInvPrice(Player player) { + double invPrice = IntStream.range(0, 36).mapToDouble(i -> this.calculateItem(player.getInventory(), i, false)).sum(); + for(int i =9; i<36; i++){ + ItemStack is = player.getInventory().getItem(i); + if(is==null || is.getType()==Material.AIR) + continue; + GameItem item = Vice.getItemManager().getSellableItem(is); + if(item==null || item.getType()== GameItem.ItemType.DRUG) + continue; + invPrice += item.getSellPrice() * is.getAmount() ; + } + return invPrice; + }*/ + + private final List<Integer> itemSlots = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 18, 19, 20, 21, 22, 23, 24, 25, 26, 36, 37, 38, 39, 40, 41, 42, 43); + public Collection<GameItem> getSellableItems(Inventory inv) { + Collection<GameItem> items = new ArrayList<>(); + + for (int slot : itemSlots) { + if (inv.getItem(slot) != null) { + ItemStack itemStack = inv.getItem(slot); + GameItem gameItem = Vice.getItemManager().getSellableItem(itemStack); + if (gameItem == null || gameItem.getType()!= GameItem.ItemType.DRUG ) continue; + gameItem.getItem().setAmount(itemStack.getAmount()); + items.add(gameItem); + } + } + + //I think this causes selling problems. +// itemSlots.stream().forEachOrdered(i -> { +// if (inv.getItem(i) != null) { +// ItemStack itemStack = inv.getItem(i); +// GameItem gameItem = Vice.getItemManager().getSellableItem(itemStack, ViceUtils.isArmor(itemStack.getType())); +// if (gameItem == null || gameItem.getType()== GameItem.ItemType.DRUG) return; +// gameItem.getItem().setAmount(itemStack.getAmount()); +// items.add(gameItem); +// } +// }); + + return items; + } + + @EventHandler + public void onClose(InventoryCloseEvent e) { + Player player = (Player) e.getPlayer(); + Inventory inv = e.getInventory(); + if (!this.inTrashcan.contains(player.getUniqueId())) + return; + double totalPrice = this.updateTrashCan(inv); + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + + + /*for (ItemStack itemStack : inv.getStorageContents()) { + if (itemStack == null) continue; + if (!itemStack.hasItemMeta()) continue; + if (itemStack.getItemMeta().getDisplayName() == null) continue; + Optional<DrugItem> drugItem = ((DrugService) Vice.getDrugManager().getService()).getDrugItem(itemStack.getItemMeta().getDisplayName()); + if (drugItem.isPresent()) { + Optional<DrugDealerItem> drugDealerItem = DrugDealerItem.byDrugItem(drugItem.get()); + if (!drugDealerItem.isPresent()) continue; + drugDealerItem.get().setStockRemaining(drugDealerItem.get().getStockRemaining() + 1); + } + }*/ + + if (totalPrice > 0) { + user.addMoney(totalPrice); + ViceUtils.updateBoard(player, user); + player.sendMessage(Utils.f(Lang.MONEY_ADD.toString() + Math.round(totalPrice))); + } + + this.inTrashcan.remove(player.getUniqueId()); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/npcs/shopnpc/BlocksMenu.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/npcs/shopnpc/BlocksMenu.java new file mode 100644 index 0000000..b89f802 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/npcs/shopnpc/BlocksMenu.java @@ -0,0 +1,199 @@ +package net.grandtheftmc.vice.users.npcs.shopnpc; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.inventory.CoreMenu; +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import net.grandtheftmc.core.inventory.button.ClickableItem; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.items.GameItem; +import net.grandtheftmc.vice.users.ViceUser; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * Created by Timothy Lampen on 1/27/2018. + */ +public class BlocksMenu extends CoreMenu { + private int counter = 0; + private static final int[] ITEM_SPOTS = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + private int[] CATEGORY_SLOTS = new int[]{21,23,30,32}; + + protected BlocksMenu() { + super(6, Utils.f("&c&lBuy Blocks"), CoreMenuFlag.PHONE_LAYOUT); + + for(Category c : Category.values()) { + addItem(getCategoryPlaceholder(c)); + } + + addItem(generateBackwardSelector(new CategoryMenu())); + } + + private enum Category { + COLORFUL, REDSTONE, BASIC, MISC + } + + /** + * @param menu the menu that when this item is clicked, the player will be directed to + * @return a clickable item that does above. + */ + private ClickableItem generateBackwardSelector(CoreMenu menu){ + ItemStack is = new ItemStack(Material.SKULL_ITEM, 1, (short)3); + SkullMeta im = (SkullMeta)is.getItemMeta(); + im.setOwner("MHF_ArrowLeft"); + im.setDisplayName(Utils.f("&c&lBack")); + is.setItemMeta(im); + return new ClickableItem(47, is, ((player, clickType) -> { + menu.openInventory(player); + })); + } + + private ClickableItem getCategoryPlaceholder(Category c){ + String gameItem = "", displayName = ""; + switch (c) { + case MISC: { + gameItem = "rednetherbrick"; + displayName = "&c&lMiscellaneous Blocks"; + break; + } + case REDSTONE: { + gameItem = "redstone"; + displayName = "&c&lRedstone Blocks"; + break; + } + case BASIC: { + gameItem = "dirt"; + displayName = "&c&lBasic Blocks"; + break; + } + case COLORFUL: { + gameItem = "lightbluewool"; + displayName = "&c&lColorful Blocks"; + break; + } + } + ItemStack is = Vice.getItemManager().getItem(gameItem).getItem(); + ItemMeta im = is.getItemMeta(); + im.setLore(Collections.emptyList()); + im.setDisplayName(Utils.f(displayName)); + is.setItemMeta(im); + return new ClickableItem(CATEGORY_SLOTS[counter++], is, + ((player, clickType) -> { + new SubCategoryMenu(c, 1).openInventory(player); + })); + } + + + private class SubCategoryMenu extends CoreMenu{ + private int counter = 0; + private final int page; + private final Category category; + + public SubCategoryMenu(Category category, int page){ + super(6, Utils.f("&c&lBuy Blocks"), CoreMenuFlag.PHONE_LAYOUT); + this.page = page; + this.category = category; + + LinkedList<GameItem> filtered = Vice.getItemManager().getShopItems().stream().filter(gi -> gi.getShopCategory().equals("BLOCKS_" + category.toString())).collect(Collectors.toCollection(LinkedList::new)); + + if(page==1) { + addItem(generateBackwardSelector(new BlocksMenu())); + if(filtered.size()>20) + addItem(generateNextPageSelector()); + } + else if(page*20>=filtered.size()) + addItem(generatePrevPageSelector()); + else { + addItem(generatePrevPageSelector()); + addItem(generateNextPageSelector()); + } + + int beginningIndex = page * 20 - 20; + Set<GameItem> subset; + if (beginningIndex + 20 <= filtered.size()) + subset = filtered.stream().skip(beginningIndex).limit(20).collect(Collectors.toSet()); + else if(beginningIndex <= filtered.size() && filtered.size()-beginningIndex < 20) + subset = filtered.stream().skip(beginningIndex).limit(filtered.size()-beginningIndex).collect(Collectors.toSet()); + else + subset = new HashSet<>(); + + for(GameItem gi : subset) { + if(!gi.canSell()) { + Core.error("[BlocksMenu] " + gi.getName() + " is in category blocks, but has no sell price."); + continue; + } + ServerUtil.debug("loading item " + gi.getName() + " / " + (gi.getItem()==null) + " / " + gi.getSellPrice()); + ItemStack disp = gi.getItem().clone(); + ItemMeta im = disp.getItemMeta(); + + ServerUtil.debug((im==null) + " / " + (disp==null) + " / " + (gi.getSellPrice())); + im. + setLore( + Arrays.asList(Utils.f("&6&lBuy x&b&l1 &6&lBlock &8(&6Left Click&8): &6$&a" + + gi.getSellPrice()), + Utils.f("&6&lBuy x&b&l64 &6&lBlocks &8(&6Right Click&8): &6$&a" + gi.getSellPrice()*64))); + disp.setItemMeta(im); + + addItem(new ClickableItem(ITEM_SPOTS[counter++], disp, ((player, clickType) -> { + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + switch (clickType) { + case LEFT: + case SHIFT_LEFT: + if(!user.hasMoney(gi.getSellPrice())){ + player.sendMessage(Lang.SHOP.f("&cYou do not have enough money for this block!")); + return; + } + user.takeMoney(gi.getSellPrice()); + Utils.giveItems(player, gi.getItem()); + break; + case RIGHT: + case SHIFT_RIGHT: + if(!user.hasMoney(gi.getSellPrice()*64)){ + player.sendMessage(Lang.SHOP.f("&cYou do not have enough money for these blocks!")); + return; + } + user.takeMoney(gi.getSellPrice()*64); + Utils.giveItems(player, gi.getItem(64)); + break; + } + }))); + } + } + + /** + * @return a clickable item that will send player to next page of same category. + */ + private ClickableItem generateNextPageSelector(){ + ItemStack is = new ItemStack(Material.SKULL_ITEM, 1, (short)3); + SkullMeta im = (SkullMeta)is.getItemMeta(); + im.setOwner("MHF_ArrowRight"); + im.setDisplayName(Utils.f("&cTo Page: &a" + (page+1))); + is.setItemMeta(im); + return new ClickableItem(52, is, ((player, clickType) -> { + new SubCategoryMenu(this.category, this.page+1).openInventory(player); + })); + } + + /** + * @return a clickable item that will send player to previous page of same category. + */ + private ClickableItem generatePrevPageSelector(){ + ItemStack is = new ItemStack(Material.SKULL_ITEM, 1, (short)3); + SkullMeta im = (SkullMeta)is.getItemMeta(); + im.setOwner("MHF_ArrowLeft"); + im.setDisplayName(Utils.f("&cTo Page: &a" + (page-1))); + is.setItemMeta(im); + return new ClickableItem(47, is, ((player, clickType) -> { + new SubCategoryMenu(this.category, this.page-1).openInventory(player); + })); + } + } + +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/npcs/shopnpc/CategoryMenu.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/npcs/shopnpc/CategoryMenu.java new file mode 100644 index 0000000..e86fc6d --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/npcs/shopnpc/CategoryMenu.java @@ -0,0 +1,407 @@ +package net.grandtheftmc.vice.users.npcs.shopnpc; + +/** + * Created by Timothy Lampen on 1/27/2018. + */ + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.inventory.CoreMenu; +import net.grandtheftmc.core.inventory.CoreMenuFlag; +import net.grandtheftmc.core.inventory.button.ClickableItem; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.guns.GTMGuns; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.Weapon; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.items.GameItem; +import net.grandtheftmc.vice.machine.BaseMachine; +import net.grandtheftmc.vice.users.ViceUser; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * + * + * @apiNote Main category menu (when you first right click this pops up) + * + */ +public class CategoryMenu extends CoreMenu { + + private static final Set<String> DISABLED = new HashSet<>(Arrays.asList("clausinator")); + private static final HashMap<AmmoType, Integer> AMMO_MULTIPLIERS = new HashMap<>(); + private static final int[] ITEM_SPOTS = new int[]{11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + private int counter = 0; + private int[] CATEGORY_SLOTS = new int[]{21,22,23,30,32}; + + + static { + /** + * The multiples of which the ammo for the certain ammo type is sold as. + */ + AMMO_MULTIPLIERS.put(AmmoType.ASSAULT_RIFLE, 50); + AMMO_MULTIPLIERS.put(AmmoType.GRENADE, 5); + AMMO_MULTIPLIERS.put(AmmoType.ROCKET, 1); + AMMO_MULTIPLIERS.put(AmmoType.LAUNCHER, 1); + AMMO_MULTIPLIERS.put(AmmoType.MINIGUN, 600); + AMMO_MULTIPLIERS.put(AmmoType.PISTOL, 20); + AMMO_MULTIPLIERS.put(AmmoType.SMG, 60); + AMMO_MULTIPLIERS.put(AmmoType.LMG, 40); + AMMO_MULTIPLIERS.put(AmmoType.SHOTGUN, 12); + AMMO_MULTIPLIERS.put(AmmoType.SNIPER, 10); + AMMO_MULTIPLIERS.put(AmmoType.FUEL, 64); + } + + /** + * @apiNote the different categories avaliable. + */ + private enum Category { + SELL_DRUGS, BUY_MACHINES, BUY_SUPPLIES, BUY_GUNS, BUY_BLOCKS + } + + public CategoryMenu() { + super(6, Utils.f("&c&lChoose Category"), CoreMenuFlag.PHONE_LAYOUT); + for(Category c : Category.values()) { + addItem(getCategoryPlaceholder(c)); + } + + } + + /** + * @param menu the menu that when this item is clicked, the player will be directed to + * @return a clickable item that does above. + */ + private ClickableItem generateBackwardSelector(CoreMenu menu){ + ItemStack is = new ItemStack(Material.SKULL_ITEM, 1, (short)3); + SkullMeta im = (SkullMeta)is.getItemMeta(); + im.setOwner("MHF_ArrowLeft"); + im.setDisplayName(Utils.f("&c&lBack")); + is.setItemMeta(im); + return new ClickableItem(46, is, ((player, clickType) -> { + menu.openInventory(player); + })); + } + + /** + * @param c the category that you want to generate a placeholder for. + * @return a clickable item that when clicked, directs the player to the correct category. + */ + private ClickableItem getCategoryPlaceholder(Category c){ + switch (c) { + case SELL_DRUGS: { + ItemStack is = Vice.getItemManager().getItem("heroinsyringe").getItem().clone(); + ItemMeta im = is.getItemMeta(); + im.setLore(Collections.emptyList()); + im.setDisplayName(Utils.f("&a&lSell Drugs")); + is.setItemMeta(im); + return new ClickableItem(CATEGORY_SLOTS[counter++], is, + ((player, clickType) -> { + player.closeInventory(); + Vice.getTrashCanManager().openTrashCan(player); + })); + } + case BUY_MACHINES: { + ItemStack is = new ItemStack(Material.FURNACE); + ItemMeta im = is.getItemMeta(); + im.setDisplayName(Utils.f("&e&lBuy Machines")); + is.setItemMeta(im); + return new ClickableItem(CATEGORY_SLOTS[counter++], is, + ((player, clickType) -> new MachineMenu().openInventory(player))); + } + case BUY_SUPPLIES: + return new ClickableItem(CATEGORY_SLOTS[counter++], Utils.createItem(Material.DIAMOND_PICKAXE, "&b&lBuy Supplies"), + ((player, clickType) -> new SuppliesMenu().openInventory(player))); + case BUY_GUNS: { + ItemStack is = Vice.getItemManager().getItem("smg").getItem(); + ItemMeta im = is.getItemMeta(); + im.setDisplayName(Utils.f("&a&lBuy Guns")); + im.setLore(Collections.emptyList()); + is.setItemMeta(im); + return new ClickableItem(CATEGORY_SLOTS[counter++], + is, + ((player, clickType) -> new GunCategoryMenu().openInventory(player))); + } + case BUY_BLOCKS: + return new ClickableItem(CATEGORY_SLOTS[counter++], + Utils.createItem(Material.SAND, "&c&lBuy Blocks"), + ((player, clickType) -> new BlocksMenu().openInventory(player))); + } + return null; + } + + /** + * + * + * @apiNote Supplies menus + * + */ + private class SuppliesMenu extends CoreMenu { + + private int counter = 0; + private final int page; + + protected SuppliesMenu(){ + this(1); + } + + protected SuppliesMenu(int page) { + super(6, Utils.f("&b&lBuy Supplies"), CoreMenuFlag.PHONE_LAYOUT); + this.page = page; + + + LinkedList<GameItem> filtered = Vice.getItemManager().getShopItems().stream().filter(gi -> gi.getShopCategory().equals("SUPPLIES")).collect(Collectors.toCollection(LinkedList::new)); + + if(page==1) { + addItem(generateNextPageSelector()); + addItem(generateBackwardSelector(new CategoryMenu())); + } + else if(page*20>=filtered.size()) + addItem(generatePrevPageSelector()); + else { + addItem(generatePrevPageSelector()); + addItem(generateNextPageSelector()); + } + + int beginningIndex = page * 20 - 20; + Set<GameItem> subset; + if (beginningIndex + 20 <= filtered.size()) + subset = filtered.stream().skip(beginningIndex).limit(20).collect(Collectors.toSet()); + else if(beginningIndex <= filtered.size() && filtered.size()-beginningIndex < 20) + subset = filtered.stream().skip(beginningIndex).limit(filtered.size()-beginningIndex).collect(Collectors.toSet()); + else + subset = new HashSet<>(); + + for(GameItem gi : subset) { + if(!gi.canSell()) { + Core.error("[SuppliesMenu] " + gi.getName() + " is in category supplies, but has no sell price."); + continue; + } + ItemStack disp = gi.getItem().clone(); + ItemMeta im = disp.getItemMeta(); + im.setLore(Arrays.asList(Utils.f("&6&lBuy x&b&l1 &6&lItem &8(&6Left Click&8): &6$&a" + gi.getSellPrice()), Utils.f("&6&lBuy x&b&l64 &6&lItems &8(&6Right Click&8): &6$&a" + gi.getSellPrice()*64))); + disp.setItemMeta(im); + + addItem(new ClickableItem(ITEM_SPOTS[counter++], disp, ((player, clickType) -> { + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + switch (clickType) { + case LEFT: + case SHIFT_LEFT: + if(!user.hasMoney(gi.getSellPrice())){ + player.sendMessage(Lang.SHOP.f("&cYou do not have enough money for this item!")); + return; + } + user.takeMoney(gi.getSellPrice()); + Utils.giveItems(player, gi.getItem()); + break; + case RIGHT: + case SHIFT_RIGHT: + if(!user.hasMoney(gi.getSellPrice()*64)){ + player.sendMessage(Lang.SHOP.f("&cYou do not have enough money for these items!")); + return; + } + user.takeMoney(gi.getSellPrice()*64); + Utils.giveItems(player, gi.getItem(64)); + break; + } + }))); + } + } + + /** + * @return a clickable item that will send player to next page of same category. + */ + private ClickableItem generateNextPageSelector(){ + ItemStack is = new ItemStack(Material.SKULL_ITEM, 1, (short)3); + SkullMeta im = (SkullMeta)is.getItemMeta(); + im.setOwner("MHF_ArrowRight"); + im.setDisplayName(Utils.f("&cTo Page: &a" + (page+1))); + is.setItemMeta(im); + return new ClickableItem(52, is, ((player, clickType) -> { + new SuppliesMenu(page+1).openInventory(player); + })); + } + + /** + * @return a clickable item that will send player to previous page of same category. + */ + private ClickableItem generatePrevPageSelector(){ + ItemStack is = new ItemStack(Material.SKULL_ITEM, 1, (short)3); + SkullMeta im = (SkullMeta)is.getItemMeta(); + im.setOwner("MHF_ArrowLeft"); + im.setDisplayName(Utils.f("&cTo Page: &a" + (page-1))); + is.setItemMeta(im); + return new ClickableItem(47, is, ((player, clickType) -> { + new SuppliesMenu(page-1).openInventory(player); + })); + } + } + + /** + * + * + * @apiNote Machine buy menu + * + */ + + private class MachineMenu extends CoreMenu { + + private int counter = 0; + + public MachineMenu() { + super(6, Utils.f("&e&lBuy Machines"), CoreMenuFlag.PHONE_LAYOUT); + addItem(generateBackwardSelector(new CategoryMenu())); + + for(BaseMachine machine : Vice.getInstance().getMachineManager().getStatues()) { + GameItem item = Vice.getItemManager().getItem(machine.getName().replace(" ", "")); + ItemStack is = item.getItem(); + ItemMeta im = is.getItemMeta(); + im.setLore(Collections.singletonList(Utils.f("&6&lPrice: &6$&a" + item.getSellPrice()))); + is.setItemMeta(im); + addItem(new ClickableItem(ITEM_SPOTS[counter++], is, ((player, clickType) -> { + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + if(!user.hasMoney(item.getSellPrice())){ + player.sendMessage(Lang.SHOP.f("&cYou do not have enough money for this item!")); + return; + } + user.takeMoney(item.getSellPrice()); + Utils.giveItems(player, item.getItem()); + }))); + } + } + + + } + + /** + * + * + * @apiNote Gun Menus + * + */ + + private class GunCategoryMenu extends CoreMenu { + private final int[] CATEGORY_SLOTS = new int[]{20,21,22,23,24,29,30,31,32,33}; + private int counter = 0; + + protected GunCategoryMenu() { + super(6, Utils.f("&c&lChoose Gun ategory"), CoreMenuFlag.PHONE_LAYOUT); + addItem(getWeaponCategoryPlaceholder(WeaponType.THROWABLE, Utils.f("&7&oRemember: Don't miss!"))); + addItem(getWeaponCategoryPlaceholder(WeaponType.MELEE, Utils.f("&7&oFor when you need to get close and personal."))); + addItem(getWeaponCategoryPlaceholder(WeaponType.PISTOL, Utils.f("&7&oA basic gun; point, shoot, kill."))); + addItem(getWeaponCategoryPlaceholder(WeaponType.LMG, Utils.f("&7&oSlow and steady wins the race... so do a lot of bullets."))); + addItem(getWeaponCategoryPlaceholder(WeaponType.SMG, Utils.f("&7&oFor when you need to get close and personal."))); + addItem(getWeaponCategoryPlaceholder(WeaponType.SHOTGUN, Utils.f("&7&oDamage? Check! Spread? Check!"), Utils.f("&7&oOverall coolness factor? What more could you want!?"))); + addItem(getWeaponCategoryPlaceholder(WeaponType.ASSAULT, Utils.f("&7&oNow we're talking!"))); + addItem(getWeaponCategoryPlaceholder(WeaponType.LAUNCHER, Utils.f("&7&oWhen you're too lazy to throw..."))); + addItem(getWeaponCategoryPlaceholder(WeaponType.SNIPER, Utils.f("&7&oNot all battles are fought at close range."))); + addItem(getWeaponCategoryPlaceholder(WeaponType.SPECIAL, Utils.f("&7&oRespect comes in many forms..."), Utils.f("&7&oespecially that of a giant death machine!"))); + + addItem(generateBackwardSelector(new CategoryMenu())); + + } + + /** + * @param type the type of weapon that you want to generate a placeholder for + * @param lore the flavor lore that you want to add to the placeholder itemstack. + * @return a clickable item that when clicked, will open the specified weapon subcategory to the player. + */ + private ClickableItem getWeaponCategoryPlaceholder(WeaponType type, String... lore){ + ServerUtil.debug("Trying to load weapon category: " + type); + Optional<Weapon<?>> optWeapon = type == WeaponType.SPECIAL ? Vice.getWastedGuns().getWeaponManager().getWeapon("minigun") : Vice.getWastedGuns().getWeaponManager().getRegisteredWeapons().stream().filter(w -> w.getWeaponType()==type && Vice.getItemManager().getItemFromWeapon(w.getCompactName())!=null && Vice.getItemManager().getItemFromWeapon(w.getCompactName()).canSell()).findFirst(); + ItemStack is = optWeapon.get().getBaseItemStack().clone(); + ItemMeta im = is.getItemMeta(); + im.setDisplayName(Utils.f("&a&l" + type.toString())); + im.setLore(Arrays.asList(lore)); + is.setItemMeta(im); + return new ClickableItem(CATEGORY_SLOTS[counter++], is, ((player, clickType) -> { + new GunSubCategoryMenu(type).openInventory(player); + }), false); + } + } + + private class GunSubCategoryMenu extends CoreMenu { + + protected GunSubCategoryMenu(WeaponType type) { + super(6, Utils.f("&9&lPurchase " + type.toString()), CoreMenuFlag.PHONE_LAYOUT); + addItem(generateBackwardSelector(new GunCategoryMenu())); + + int counter = 0; + Set<Weapon<?>> filtered = GTMGuns.getInstance().getWeaponManager().getRegisteredWeapons().stream().filter(w ->{ + if(w==null) + return false; + if(DISABLED.contains(w.getName().toLowerCase())) + return false; + return w.getWeaponType()==type || (type==WeaponType.SPECIAL && (w.getWeaponType()!=WeaponType.MELEE && w.getWeaponType()!=WeaponType.ASSAULT && w.getWeaponType()!=WeaponType.LAUNCHER && w.getWeaponType()!=WeaponType.THROWABLE && w.getWeaponType()!= WeaponType.SMG && w.getWeaponType()!=WeaponType.LMG && w.getWeaponType()!=WeaponType.SHOTGUN && w.getWeaponType()!=WeaponType.PISTOL && w.getWeaponType()!=WeaponType.SNIPER)); + }).collect(Collectors.toSet()); + + for(Weapon<?> w : filtered){ + GameItem item = Vice.getItemManager().getItemFromWeapon(w.getCompactName()); + if(item==null) { + Core.error("[GunSubCategory] Unable to load gameitem from weapon: " + w.getCompactName()); + continue; + } + if(!item.canSell()) { + ServerUtil.debug("[GunSubCategory] Unable to find sell price for weapon: " + w.getCompactName() + " is it suppose to be like that?"); + continue; + } + ItemStack is = item.getItem(); + ItemMeta im = is.getItemMeta(); + im.setDisplayName(Utils.f("&6" + w.getName())); + List<String> lore = new ArrayList<>(); + lore.add(Utils.f("&6&lBuy Weapon &8(&6Left Click&8)&6: $&a" + item.getSellPrice())); + + GameItem ammoItem = null; + if(type!=WeaponType.THROWABLE && type!=WeaponType.MELEE && w.getAmmoType()!= AmmoType.NONE) { + if(type==WeaponType.LMG) + ammoItem = net.grandtheftmc.vice.items.AmmoType.MG.getGameItem();//because of how the naming of the wastedguns / gtmguns is :( + else + ammoItem = net.grandtheftmc.vice.items.AmmoType.getAmmoType(w.getAmmoType().toString()).getGameItem(); + if(ammoItem==null) { + Core.error("[GunSubCategory] Unable to load ammo from string: " + w.getAmmoType() + " for weapon: " + w.getName()); + return; + } + + lore.add(Utils.f("&6&lBuy x&b&l" + AMMO_MULTIPLIERS.get(w.getAmmoType()) + "&6&l Ammo &8(&6Right Click&8)&6: $&a" + (ammoItem.getSellPrice()*AMMO_MULTIPLIERS.get(w.getAmmoType())))); + } + im.setLore(lore); + is.setItemMeta(im); + + final GameItem finalAmmoItem = ammoItem; + addItem(new ClickableItem(ITEM_SPOTS[counter], is, (player, clickType) -> { + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + switch (clickType) { + case LEFT: + case SHIFT_LEFT: + if(!user.hasMoney(item.getSellPrice())){ + player.sendMessage(Lang.SHOP.f("&cYou do not have enough money for this item!")); + return; + } + user.takeMoney(item.getSellPrice()); + Utils.giveItems(player, item.getItem()); + break; + case RIGHT: + case SHIFT_RIGHT: + if(finalAmmoItem ==null) + return; + if(!user.hasMoney(finalAmmoItem.getSellPrice()*AMMO_MULTIPLIERS.get(w.getAmmoType()))){ + player.sendMessage(Lang.SHOP.f("&cYou do not have enough money for this item!")); + return; + } + user.takeMoney(finalAmmoItem.getSellPrice()*AMMO_MULTIPLIERS.get(w.getAmmoType())); + user.addAmmo(net.grandtheftmc.vice.items.AmmoType.getAmmoType(w.getAmmoType().toString()), AMMO_MULTIPLIERS.get(w.getAmmoType())); + player.sendMessage(Lang.AMMO_ADD.f(AMMO_MULTIPLIERS.get(w.getAmmoType()) + "&7 " + w.getAmmoType().toString())); + break; + } + }, false)); + counter++; + } + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/npcs/shopnpc/ShopNPC.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/npcs/shopnpc/ShopNPC.java new file mode 100644 index 0000000..251243c --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/npcs/shopnpc/ShopNPC.java @@ -0,0 +1,40 @@ +package net.grandtheftmc.vice.users.npcs.shopnpc; + +import net.citizensnpcs.api.event.NPCLeftClickEvent; +import net.citizensnpcs.api.event.NPCRightClickEvent; +import net.grandtheftmc.core.npc.CoreNPC; +import net.grandtheftmc.core.npc.interfaces.ClickableNPC; +import org.bukkit.Location; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; + +/** + * Created by Timothy Lampen on 1/24/2018. + */ +public class ShopNPC extends CoreNPC implements ClickableNPC { + + /** + * @apiNote the constructor for the actual npc. + */ + public ShopNPC(Location loc) { + super(loc, EntityType.PLAYER, "&9&lGary McNaggins", "&7&oBuy the best guns and ammo here!"); + } + + @Override + protected void generateNewNPC() { + setLookClose(true); + setSkin("eyJ0aW1lc3RhbXAiOjE1MDc2MTM5NzI2NDUsInByb2ZpbGVJZCI6ImUzYjQ0NWM4NDdmNTQ4ZmI4YzhmYTNmMWY3ZWZiYThlIiwicHJvZmlsZU5hbWUiOiJNaW5pRGlnZ2VyVGVzdCIsInNpZ25hdHVyZVJlcXVpcmVkIjp0cnVlLCJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZGUyYjUwYzI4NDQ1YmQyOWE2OGRmZTIyM2M0YzlmZDYyZTYyOWNkNWU1ZDdjMTc3NzIwNmU4YjRkNjMxIn19fQ==", "gza3eHED3BMmxRjZmDDUQQliH10Q4e8U5uKNv0RaGfOKdPOxMToH2rqSpyNeS+odXQvAq6cDZulKk5LZgcs89kpv+Jkb3sfWdUb6HnJvqkeA+4iTw3n9BxRZpoC0lyBmiJSQPlSwywgjmd9cybGPtgX3+WpbExRDYy90X8ii3iN9dlFlNWFiInNZjBUUjslcqnD8VEkItonJwNbPbXkgvHu0qmiBon6bWmnI81cO0DekrxOGAbQQynNosnGVbV7oGTAtN87G9zM7McNvMXK+1BJqAxdqad3U2Jfnu3PHDZ1pDCJIA+5yQiiTblQPzYx9Fp73E2NpS51239/P5B0bWOa8MWGK2fKCznxRy/lZTd/3Ewojxu9guWann0ALLeYyvXA/FDY1vY6clRF50JyhgBR6Tf58lOF8kkq964gdpYlhtldI1ZWf8jn/inK//b3rNmqu046oKQLuhYjxVNoV4lrzzb+pzjjKx2/iBXqzxnWTjrTLZv6n6jLS9aFghryaLbUXc4IETj+MsZ5Z9WdPCG02V3f3Z+5aFZfMg2zkj1qQxDVhrdJr/87lE23ZupYDV1szocx39JF1gtwbKhTugVKlDV4UQZHokFdcFRtMLSpX7zJwNLiVK/+aMN1YbGQzdwII9CFXN2DtgawzTnQQafEBwNiyp3GAcPTE9VqffFY="); + } + + @Override + public void onRightClick(NPCRightClickEvent event) { + Player player = event.getClicker(); + new CategoryMenu().openInventory(player); + } + + @Override + public void onLeftClick(NPCLeftClickEvent event) { + Player player = event.getClicker(); + new CategoryMenu().openInventory(player); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/storage/BooleanStorageType.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/storage/BooleanStorageType.java new file mode 100644 index 0000000..f6f18ff --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/storage/BooleanStorageType.java @@ -0,0 +1,31 @@ +package net.grandtheftmc.vice.users.storage; + +/** + * Created by Timothy Lampen on 8/3/2017. + */ +public enum BooleanStorageType { + SEND_AWAY(false), + TPA_HERE(false), + BACK_WITHDRAWING(false), + BANK_DEPOSITING(false), + BUYING_LOTTERY_TICKETS(false), + ADDING_LOOTCRATE(false), + REMOVING_LOOTCRATE(false), + CHECKING_LOOTCRATE(false), + RESTOCKING_LOOTCRATE(false), + BRIBING(false), + KICKED(false), + HAS_UPDATED(false), + BACKPACK_OPEN(false), + USED_LOGOUT(false); + + + private final boolean defaultValue; + BooleanStorageType(boolean defaultValue){ + this.defaultValue = defaultValue; + } + + public boolean getDefaultValue(){ + return defaultValue; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/storage/IntStorageType.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/storage/IntStorageType.java new file mode 100644 index 0000000..74f9e1d --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/storage/IntStorageType.java @@ -0,0 +1,17 @@ +package net.grandtheftmc.vice.users.storage; + +/** + * Created by Timothy Lampen on 8/3/2017. + */ +public enum IntStorageType { + KILLS, + DEATHS, + KILL_STREAK, + BONDS, + VEHICLE_TASK_ID, + VEHICLE_TIMER, + TAXI_TASK_ID, + TAXI_PRICE, + TAXI_TIMER, + JAIL_TIMER +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/storage/LongStorageType.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/storage/LongStorageType.java new file mode 100644 index 0000000..577f4d2 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/users/storage/LongStorageType.java @@ -0,0 +1,16 @@ +package net.grandtheftmc.vice.users.storage; + +/** + * Created by Timothy Lampen on 8/3/2017. + */ +public enum LongStorageType { + LAST_COP_SALARY, + PLAY_TIME, + JOIN_TIME, + LAST_TPA_REQUEST, + LAST_TELEPORT, + LAST_BACKUP_REQUEST, + LAST_COP_SPAWN, + LAST_TAG, + LAST_JETPACK_CANCEL +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/CancellationDetector.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/CancellationDetector.java new file mode 100644 index 0000000..506deb5 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/CancellationDetector.java @@ -0,0 +1,217 @@ +package net.grandtheftmc.vice.utils; + +import com.google.common.collect.Lists; +import org.bukkit.event.*; +import org.bukkit.plugin.IllegalPluginAccessException; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.RegisteredListener; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.Iterator; +import java.util.List; + +/** + * Created by Luke Bingham on 09/08/2017. + */ +public class CancellationDetector<TEvent extends Event> { + + public interface CancelListener<TEvent extends Event> { + public void onCancelled(Plugin plugin, TEvent event); + } + + private final Class<TEvent> eventClazz; + private final List<CancelListener<TEvent>> listeners = Lists.newArrayList(); + + // For reverting the detector + private EnumMap<EventPriority, ArrayList<RegisteredListener>> backup; + + public CancellationDetector(Class<TEvent> eventClazz) { + this.eventClazz = eventClazz; +// injectProxy(); + } + + public void addListener(CancelListener<TEvent> listener) { + listeners.add(listener); + } + + public void removeListener(CancelListener<Event> listener) { + listeners.remove(listener); + } + + @SuppressWarnings("unchecked") + private EnumMap<EventPriority, ArrayList<RegisteredListener>> getSlots(HandlerList list) { + try { + return (EnumMap<EventPriority, ArrayList<RegisteredListener>>) getSlotsField(list).get(list); + } catch (Exception e) { + throw new RuntimeException("Unable to retrieve slots.", e); + } + } + + private Field getSlotsField(HandlerList list) { + if (list == null) + throw new IllegalStateException("Detected a NULL handler list."); + + try { + Field slotField = list.getClass().getDeclaredField("handlerslots"); + + // Get our slot map + slotField.setAccessible(true); + return slotField; + } catch (Exception e) { + throw new IllegalStateException("Unable to intercept 'handlerslot' in " + list.getClass(), e); + } + } + + private void injectProxy() { + HandlerList list = getHandlerList(eventClazz); + EnumMap<EventPriority, ArrayList<RegisteredListener>> slots = getSlots(list); + + // Keep a copy of this map + backup = slots.clone(); + + synchronized (list) { + for (EventPriority p : slots.keySet().toArray(new EventPriority[0])) { + final EventPriority priority = p; + final ArrayList<RegisteredListener> proxyList = new ArrayList<RegisteredListener>() { + private static final long serialVersionUID = 7869505892922082581L; + + @Override + public boolean add(RegisteredListener e) { + super.add(injectRegisteredListener(e)); + return backup.get(priority).add(e); + } + + @Override + public boolean remove(Object listener) { + // Remove this listener + for (Iterator<RegisteredListener> it = iterator(); it.hasNext(); ) { + DelegatedRegisteredListener delegated = (DelegatedRegisteredListener) it.next(); + if (delegated.delegate == listener) { + it.remove(); + break; + } + } + return backup.get(priority).remove(listener); + } + }; + slots.put(priority, proxyList); + + for (RegisteredListener listener : backup.get(priority)) { + proxyList.add(listener); + } + } + } + } + + // The core of our magic + private RegisteredListener injectRegisteredListener(final RegisteredListener listener) { + return new DelegatedRegisteredListener(listener) { + @SuppressWarnings("unchecked") + @Override + public void callEvent(Event event) throws EventException { + if (event instanceof Cancellable) { + boolean prior = getCancelState(event); + + listener.callEvent(event); + + // See if this plugin cancelled the event + if (!prior && getCancelState(event)) { + invokeCancelled(getPlugin(), (TEvent) event); + } + } else { + listener.callEvent(event); + } + } + }; + } + + private void invokeCancelled(Plugin plugin, TEvent event) { + for (CancelListener<TEvent> listener : listeners) { + listener.onCancelled(plugin, event); + } + } + + private boolean getCancelState(Event event) { + return ((Cancellable) event).isCancelled(); + } + + public void close() { + if (backup != null) { + try { + HandlerList list = getHandlerList(eventClazz); + getSlotsField(list).set(list, backup); + + Field handlers = list.getClass().getDeclaredField("handlers"); + handlers.setAccessible(true); + handlers.set(list, null); + + } catch (Exception e) { + throw new RuntimeException("Unable to clean up handler list.", e); + } + + backup = null; + } + } + + /** + * Retrieve the handler list associated with the given class. + * + * @param clazz - given event class. + * @return Associated handler list. + */ + private static HandlerList getHandlerList(Class<? extends Event> clazz) { + // Class must have Event as its superclass + while (clazz.getSuperclass() != null && Event.class.isAssignableFrom(clazz.getSuperclass())) { + try { + Method method = clazz.getDeclaredMethod("getHandlerList"); + method.setAccessible(true); + return (HandlerList) method.invoke(null); + } catch (NoSuchMethodException e) { + // Keep on searching + clazz = clazz.getSuperclass().asSubclass(Event.class); + } catch (Exception e) { + throw new IllegalPluginAccessException(e.getMessage()); + } + } + throw new IllegalPluginAccessException("Unable to find handler list for event " + + clazz.getName()); + } + + /** + * Represents a registered listener that delegates to a given listener. + * + * @author Kristian + */ + private static class DelegatedRegisteredListener extends RegisteredListener { + private final RegisteredListener delegate; + + public DelegatedRegisteredListener(RegisteredListener delegate) { + // These values will be ignored however' + super(delegate.getListener(), null, delegate.getPriority(), delegate.getPlugin(), false); + this.delegate = delegate; + } + + public void callEvent(Event event) throws EventException { + delegate.callEvent(event); + } + + public Listener getListener() { + return delegate.getListener(); + } + + public Plugin getPlugin() { + return delegate.getPlugin(); + } + + public EventPriority getPriority() { + return delegate.getPriority(); + } + + public boolean isIgnoringCancelled() { + return delegate.isIgnoringCancelled(); + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/DurabilityUtil.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/DurabilityUtil.java new file mode 100644 index 0000000..5bcf0a3 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/DurabilityUtil.java @@ -0,0 +1,190 @@ +package net.grandtheftmc.vice.utils; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.durability.DurabilityItems; +import net.minecraft.server.v1_12_R1.NBTTagInt; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +/** + * Created by ThatAbstractWolf on 2017-08-03. + */ +public class DurabilityUtil { + + public static ItemStack setDurability(ItemStack item, int durability) { + return NBTUtil.setNBTTag(item, "customDurability", new NBTTagInt(durability)); + } + + public static int getDurability(ItemStack item) { + return (NBTUtil.hasNBTTag(item, "customDurability") ? Integer.parseInt(NBTUtil.getNBTTag(item, "customDurability").toString()) : -1); + } + + public static void setDurabilityOnArmour(Player player, ItemStack item, int amount) { + + if (item == null || item.getType().equals(Material.AIR)) { + return; + } + + if (getDurabilityItem(item).isPresent()) { + + DurabilityItems durabilityItems = getDurabilityItem(item).get(); + + int armourSlot = getArmourSlot(item); + + if (amount > 0) { + + ItemStack newArmour = DurabilityUtil.setDurability(item, amount); + + if (newArmour != null) { + + setDurabilityLore(newArmour, amount, durabilityItems); + + player.getInventory().remove(item); + + switch (armourSlot) { + + case 0: + player.getInventory().setBoots(newArmour); + break; + case 1: + player.getInventory().setLeggings(newArmour); + break; + case 2: + player.getInventory().setChestplate(newArmour); + break; + case 3: + player.getInventory().setHelmet(newArmour); + break; + } + } + } else { + + switch (armourSlot) { + + case 0: + player.getInventory().setBoots(null); + break; + case 1: + player.getInventory().setLeggings(null); + break; + case 2: + player.getInventory().setChestplate(null); + break; + case 3: + player.getInventory().setHelmet(null); + break; + } + } + } + } + + public static void setDurabilityLore(ItemStack item, int amount, DurabilityItems durabilityItems) { + + ItemMeta durabilityMeta = item.getItemMeta(); + + List<String> lore = new ArrayList<>(); + List<String> cachedLore = (item.getItemMeta().getLore() == null ? new ArrayList<>() : item.getItemMeta().getLore()); + + if (durabilityMeta.getLore() != null) { + durabilityMeta.getLore().clear(); + } + + lore.add(ChatColor.translateAlternateColorCodes('&', getDurabilityPercentage(amount, durabilityItems.getMaximumDurability()) + "&f &7[&a" + amount + "&7/&a" + durabilityItems.getMaximumDurability() + "&7]")); + + try { + for (int i = (cachedLore.get(0).contains("-") ? 1 : 0); i < cachedLore.size(); i++) { + lore.add(ChatColor.translateAlternateColorCodes('&', cachedLore.get(i))); + } + } catch (IndexOutOfBoundsException e) { /* Ignored */ } + + durabilityMeta.setLore(lore); + item.setItemMeta(durabilityMeta); + } + + public static void decreaseDurability(Player player, ItemStack item, int amount) { + + if (item == null) { + return; + } + + Optional<DurabilityItems> items = getDurabilityItem(item); + + if (items.isPresent()) { + + if (DurabilityUtil.getDurability(item) == -1) { + setDurabilityOnArmour(player, item, items.get().getMaximumDurability()); + } else { + int newDuration = DurabilityUtil.getDurability(item) - amount; + setDurabilityOnArmour(player, item, newDuration); + } + } + } + + private static int getArmourSlot(ItemStack item) { + + if (item.getType().name().contains("HELMET")) { + return 3; + } else if (item.getType().name().contains("CHESTPLATE")) { + return 2; + } else if (item.getType().name().contains("LEGGINGS")) { + return 1; + } else if (item.getType().name().contains("BOOTS")) { + return 0; + } + + return -1; + } + + public static Optional<DurabilityItems> getDurabilityItem(ItemStack item) { + + for (DurabilityItems items : DurabilityItems.values()) { + + if (item != null && item.getType().equals(DurabilityItems.JETPACK.getMaterial()) && item.getItemMeta() != null && items.getDisplayName() != null && item.getItemMeta().getDisplayName().contains(items.getDisplayName())) { + return Optional.of(DurabilityItems.JETPACK); + } + + if (items.getMaterial().equals(item.getType())) { + return Optional.of(items); + } + } + + return Optional.empty(); + } + + private static String getDurabilityPercentage(int currentDurability, int maxDurability) { + + int length = 18; + String bar = ""; + + for(int x = 1; x < (length + 1); x++) { + if (x * (maxDurability / length) <= currentDurability) + bar += getColour(currentDurability, maxDurability).toString() + ChatColor.STRIKETHROUGH + "-"; + else + bar += ChatColor.GRAY.toString() + ChatColor.STRIKETHROUGH + "-"; + } + + return bar; + } + + private static ChatColor getColour(int currentDurability, int maxDurability) { + + int parts = (maxDurability / 3); + + if (currentDurability < parts) { + return ChatColor.RED; + } else if (currentDurability > parts && currentDurability < (parts * 2)) { + return ChatColor.YELLOW; + } else { + return ChatColor.GREEN; + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/IconUtil.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/IconUtil.java new file mode 100644 index 0000000..78aa374 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/IconUtil.java @@ -0,0 +1,14 @@ +package net.grandtheftmc.vice.utils; + +import net.grandtheftmc.core.util.C; + +public class IconUtil { + + public static String r(char icon, int amount) { + return C.RESET + icon + C.GRAY + "x" + amount + C.RESET; + } + + public static String r(char icon) { + return C.RESET + icon + C.GRAY + "x1" + C.RESET; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/ItemStackUtil.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/ItemStackUtil.java new file mode 100644 index 0000000..3850a9d --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/ItemStackUtil.java @@ -0,0 +1,103 @@ +package net.grandtheftmc.vice.utils; + +import net.grandtheftmc.core.util.ItemStackManager; +import net.minecraft.server.v1_12_R1.NBTBase; +import net.minecraft.server.v1_12_R1.NBTTagCompound; +import net.minecraft.server.v1_12_R1.NBTTagInt; +import org.bukkit.Material; +import org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.List; + +/** + * Created by Luke Bingham on 06/08/2017. + */ +public class ItemStackUtil { + + public static ItemStack makeStackable(org.bukkit.inventory.ItemStack itemStack, int stacksize) { + if(itemStack == null || itemStack.getType() == Material.AIR) return itemStack; + + ItemStackManager.STACKABLES.put(itemStack.getType(), stacksize); + + net.minecraft.server.v1_12_R1.ItemStack stack = org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack.asNMSCopy(itemStack); + stack.getItem().d(stacksize); + itemStack = org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack.asBukkitCopy(stack); + + return itemStack; + } + + public static ItemStack removeStackable(org.bukkit.inventory.ItemStack itemStack) { + if(itemStack == null || itemStack.getType() == Material.AIR) return itemStack; + + net.minecraft.server.v1_12_R1.ItemStack stack = org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack.asNMSCopy(itemStack); + stack.getItem().d(1); + itemStack = org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack.asBukkitCopy(stack); + + return itemStack; + } + + /** + * Creates and returns an ItemStack object with the given Material/Name + * @param material + * @param name + * @return + */ + public static ItemStack createWithName(Material material, String name) { + ItemStack item = new ItemStack(material); + ItemMeta meta = item.getItemMeta(); + + meta.setDisplayName(name); + + item.setItemMeta(meta); + + return item; + } + + /** + * Creates and returns an ItemStack object with the given Material/Name/Lore + * @param material + * @param name + * @param lore + * @return + */ + public static ItemStack createWithNameAndLore(Material material, String name, List<String> lore) { + ItemStack item = new ItemStack(material); + ItemMeta meta = item.getItemMeta(); + + meta.setDisplayName(name); + meta.setLore(lore); + + item.setItemMeta(meta); + + return item; + } + + public static ItemStack addTag(ItemStack itemStack, String key, int value) { + net.minecraft.server.v1_12_R1.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + NBTTagCompound compound = nmsItem.hasTag() ? nmsItem.getTag() : new NBTTagCompound(); + if (compound == null) compound = new NBTTagCompound(); + + compound.set(key, new NBTTagInt(value)); + nmsItem.setTag(compound); + nmsItem.save(compound); + + return CraftItemStack.asBukkitCopy(nmsItem); + } + + public static boolean hasTag(ItemStack itemStack, String key) { + net.minecraft.server.v1_12_R1.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + return nmsItem.hasTag() && nmsItem.getTag() != null && nmsItem.getTag().hasKey(key); + } + + private static boolean hasTag(net.minecraft.server.v1_12_R1.ItemStack nmsItem, String key) { + return nmsItem.hasTag() && nmsItem.getTag() != null && nmsItem.getTag().hasKey(key); + } + + public static int getIntTag(ItemStack itemStack, String key) { + net.minecraft.server.v1_12_R1.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); + NBTTagCompound tag = nmsItem.getTag(); + return Integer.parseInt(tag.get(key).toString()); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/LocationUtil.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/LocationUtil.java new file mode 100644 index 0000000..c2b7f15 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/LocationUtil.java @@ -0,0 +1,204 @@ +package net.grandtheftmc.vice.utils; + +import org.bukkit.*; +import org.bukkit.block.Block; + +import java.util.*; + +/** + * Created by Timothy Lampen on 8/20/2017. + */ +public class LocationUtil { + + public static final Set<Material> HOLLOW_MATERIALS = new HashSet<Material>(); + public static final Vector3D[] VOLUME; + public static final int RADIUS = 3; + + static + { + HOLLOW_MATERIALS.add(Material.AIR); + HOLLOW_MATERIALS.add(Material.SAPLING); + HOLLOW_MATERIALS.add(Material.POWERED_RAIL); + HOLLOW_MATERIALS.add(Material.DETECTOR_RAIL); + HOLLOW_MATERIALS.add(Material.LONG_GRASS); + HOLLOW_MATERIALS.add(Material.DEAD_BUSH); + HOLLOW_MATERIALS.add(Material.YELLOW_FLOWER); + HOLLOW_MATERIALS.add(Material.RED_ROSE); + HOLLOW_MATERIALS.add(Material.BROWN_MUSHROOM); + HOLLOW_MATERIALS.add(Material.RED_MUSHROOM); + HOLLOW_MATERIALS.add(Material.TORCH); + HOLLOW_MATERIALS.add(Material.REDSTONE_WIRE); + HOLLOW_MATERIALS.add(Material.SEEDS); + HOLLOW_MATERIALS.add(Material.SIGN_POST); + HOLLOW_MATERIALS.add(Material.WOODEN_DOOR); + HOLLOW_MATERIALS.add(Material.LADDER); + HOLLOW_MATERIALS.add(Material.RAILS); + HOLLOW_MATERIALS.add(Material.WALL_SIGN); + HOLLOW_MATERIALS.add(Material.LEVER); + HOLLOW_MATERIALS.add(Material.STONE_PLATE); + HOLLOW_MATERIALS.add(Material.IRON_DOOR_BLOCK); + HOLLOW_MATERIALS.add(Material.WOOD_PLATE); + HOLLOW_MATERIALS.add(Material.REDSTONE_TORCH_OFF); + HOLLOW_MATERIALS.add(Material.REDSTONE_TORCH_ON); + HOLLOW_MATERIALS.add(Material.STONE_BUTTON); + HOLLOW_MATERIALS.add(Material.SNOW); + HOLLOW_MATERIALS.add(Material.SUGAR_CANE_BLOCK); + HOLLOW_MATERIALS.add(Material.DIODE_BLOCK_OFF); + HOLLOW_MATERIALS.add(Material.DIODE_BLOCK_ON); + HOLLOW_MATERIALS.add(Material.PUMPKIN_STEM); + HOLLOW_MATERIALS.add(Material.MELON_STEM); + HOLLOW_MATERIALS.add(Material.VINE); + HOLLOW_MATERIALS.add(Material.FENCE_GATE); + HOLLOW_MATERIALS.add(Material.WATER_LILY); + HOLLOW_MATERIALS.add(Material.NETHER_WARTS); + HOLLOW_MATERIALS.add(Material.CARPET); + } + + public static class Vector3D + { + public int x; + public int y; + public int z; + + public Vector3D(int x, int y, int z) + { + this.x = x; + this.y = y; + this.z = z; + } + } + + static + { + List<Vector3D> pos = new ArrayList<Vector3D>(); + for (int x = -RADIUS; x <= RADIUS; x++) + { + for (int y = -RADIUS; y <= RADIUS; y++) + { + for (int z = -RADIUS; z <= RADIUS; z++) + { + pos.add(new Vector3D(x, y, z)); + } + } + } + Collections.sort( + pos, new Comparator<Vector3D>() + { + @Override + public int compare(Vector3D a, Vector3D b) + { + return (a.x * a.x + a.y * a.y + a.z * a.z) - (b.x * b.x + b.y * b.y + b.z * b.z); + } + }); + VOLUME = pos.toArray(new Vector3D[0]); + } + + + public static boolean isBlockAboveAir(final World world, final int x, final int y, final int z) + { + if (y > world.getMaxHeight()) + { + return true; + } + return HOLLOW_MATERIALS.contains(world.getBlockAt(x, y - 1, z).getType()); + } + + public static Location getSafeDestination(final Location loc) + { + final World world = loc.getWorld(); + int x = loc.getBlockX(); + int y = (int)Math.round(loc.getY()); + int z = loc.getBlockZ(); + final int origX = x; + final int origY = y; + final int origZ = z; + while (isBlockAboveAir(world, x, y, z)) + { + y -= 1; + if (y < 0) + { + y = origY; + break; + } + } + if (isBlockUnsafe(world, x, y, z)) + { + x = Math.round(loc.getX()) == origX ? x - 1 : x + 1; + z = Math.round(loc.getZ()) == origZ ? z - 1 : z + 1; + } + int i = 0; + while (isBlockUnsafe(world, x, y, z)) + { + i++; + if (i >= VOLUME.length) + { + x = origX; + y = origY + RADIUS; + z = origZ; + break; + } + x = origX + VOLUME[i].x; + y = origY + VOLUME[i].y; + z = origZ + VOLUME[i].z; + } + while (isBlockUnsafe(world, x, y, z)) + { + y += 1; + if (y >= world.getMaxHeight()) + { + x += 1; + break; + } + } + while (isBlockUnsafe(world, x, y, z)) + { + y -= 1; + if (y <= 1) + { + x += 1; + y = world.getHighestBlockYAt(x, z); + if (x - 48 > loc.getBlockX()) + { + return null; + } + } + } + return new Location(world, x + 0.5, y, z + 0.5, loc.getYaw(), loc.getPitch()); + } + + public static boolean isBlockUnsafe(final World world, final int x, final int y, final int z) + { + + if (isBlockDamaging(world, x, y, z)) + { + return true; + } + return isBlockAboveAir(world, x, y, z); + } + + public static boolean isPlayerNearby(Location loc, double radius) { + return Bukkit.getOnlinePlayers().stream().anyMatch(player -> player.getWorld().equals(loc.getWorld()) && player.getLocation().distance(loc)<=radius); + } + + public static boolean isBlockDamaging(final World world, final int x, final int y, final int z) + { + final Block below = world.getBlockAt(x, y - 1, z); + if (below.getType() == Material.LAVA || below.getType() == Material.STATIONARY_LAVA) + { + return true; + } + if (below.getType() == Material.FIRE) + { + return true; + } + if (below.getType() == Material.BED_BLOCK) + { + return true; + } + if ((!HOLLOW_MATERIALS.contains(world.getBlockAt(x, y, z).getType())) || (!HOLLOW_MATERIALS.contains(world.getBlockAt(x, y + 1, z).getType()))) + { + return true; + } + return false; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/MapUtil.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/MapUtil.java new file mode 100644 index 0000000..c05ce51 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/MapUtil.java @@ -0,0 +1,33 @@ +package net.grandtheftmc.vice.utils; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * Created by Luke Bingham on 26/08/2017. + */ +public class MapUtil { + + public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map, boolean highToLow) { + return map.entrySet() + .stream() + .sorted(highToLow ? Map.Entry.comparingByValue() : Map.Entry.comparingByValue(Collections.reverseOrder())) + .collect(Collectors.toMap( + Map.Entry::getKey, + Map.Entry::getValue, + (e1, e2) -> e1, + LinkedHashMap::new + )); + } + + public static <K, V extends Comparable<? super V>> TreeMap<K, V> sortByValue(HashMap<K, V> map) { + List<Map.Entry<K, V>> list = new LinkedList<>(map.entrySet()); + list.sort(Comparator.comparing(e -> (e.getValue()))); + TreeMap<K, V> result = new TreeMap<>(); + for (Map.Entry<K, V> entry : list) { + result.put(entry.getKey(), entry.getValue()); + } + + return result; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/NBTUtil.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/NBTUtil.java new file mode 100644 index 0000000..a7b8de1 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/NBTUtil.java @@ -0,0 +1,55 @@ +package net.grandtheftmc.vice.utils; + +import net.minecraft.server.v1_12_R1.NBTBase; +import net.minecraft.server.v1_12_R1.NBTTagCompound; +import org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack; +import org.bukkit.inventory.ItemStack; + +/** + * Created by ThatAbstractWolf on 2017-08-02. + */ +public class NBTUtil { + + public static ItemStack setNBTTag(ItemStack itemStack, String key, NBTBase value) { + + net.minecraft.server.v1_12_R1.ItemStack item = CraftItemStack.asNMSCopy(itemStack); + NBTTagCompound compound; + + if (item.getTag() == null) { + compound = new NBTTagCompound(); + } else { + compound = item.getTag(); + } + + compound.set(key, value); + item.setTag(compound); + + return CraftItemStack.asBukkitCopy(item); + } + + public static Object getNBTTag(ItemStack itemStack, String key) { + + net.minecraft.server.v1_12_R1.ItemStack item = CraftItemStack.asNMSCopy(itemStack); + + NBTTagCompound compound = item.getTag(); + + if(compound == null) { + return false; + } + + return compound.get(key); + } + + public static boolean hasNBTTag(ItemStack itemStack, String key) { + + net.minecraft.server.v1_12_R1.ItemStack item = CraftItemStack.asNMSCopy(itemStack); + + NBTTagCompound compound = item.getTag(); + + if(compound == null) { + return false; + } + + return compound.get(key) != null; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/ParticleColor.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/ParticleColor.java new file mode 100644 index 0000000..d675498 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/ParticleColor.java @@ -0,0 +1,206 @@ +package net.grandtheftmc.vice.utils; + + import java.util.Arrays; + import java.util.List; + +/** + * Represents a particle color + */ +@SuppressWarnings("WeakerAccess") +public class ParticleColor { + // Standard Minecraft Chat Colors + public static final ParticleColor BLACK = new ParticleColor(0, 0, 0); // 0x000000 + public static final ParticleColor DARK_BLUE = new ParticleColor(0, 0, 170); // 0x0000AA + public static final ParticleColor DARK_GREEN = new ParticleColor(0, 170, 0); // 0x00AA00 + public static final ParticleColor DARK_AQUA = new ParticleColor(0, 170, 170); // 0x00AAAA + public static final ParticleColor DARK_RED = new ParticleColor(170, 0, 0); // 0xAA0000 + public static final ParticleColor DARK_PURPLE = new ParticleColor(170, 0, 170); // 0xAA00AA + public static final ParticleColor GOLD = new ParticleColor(255, 170, 0); // 0xFFAA00 + public static final ParticleColor GRAY = new ParticleColor(170, 170, 170); // 0xAAAAAA + public static final ParticleColor DARK_GRAY = new ParticleColor(85, 85, 85); // 0x555555 + public static final ParticleColor BLUE = new ParticleColor(85, 85, 255); // 0x5555FF + public static final ParticleColor GREEN = new ParticleColor(85, 255, 85); // 0x55FF55 + public static final ParticleColor AQUA = new ParticleColor(85, 255, 255); // 0x55FFFF + public static final ParticleColor RED = new ParticleColor(255, 85, 85); // 0xFF5555 + public static final ParticleColor LIGHT_PURPLE = new ParticleColor(255, 85, 255); // 0xFF55FF + public static final ParticleColor YELLOW = new ParticleColor(255, 255, 85); // 0xFFFF55 + public static final ParticleColor WHITE = new ParticleColor(255, 255, 255); // 0xFFFFFF + + /** + * List of all pre-named colors + */ + public static final List<String> names = Arrays.asList( + "black", + "dark-blue", + "dark-green", + "dark-aqua", + "dark-red", + "dark-purple", + "gold", + "gray", + "dark-gray", + "blue", + "green", + "aqua", + "red", + "light-purple", + "yellow", + "white" + ); + + private final float red; + private final float green; + private final float blue; + + /** + * Creates a new particle color from RGB values 0 - 255 + * + * @param red Red value + * @param green Green value + * @param blue Blue value + */ + public ParticleColor(int red, int green, int blue) { + // values of 0 are changed to 0.0001 for black + // due to the way the particle packet works + this.red = (red == 0 ? 0.0001F : red) / 255; + this.green = (green == 0 ? 0.0001F : green) / 255; + this.blue = (blue == 0 ? 0.0001F : blue) / 255; + } + + /** + * Get the red value + * <p> + * The values 0.0 - 1.0 represent 0 - 255 + * + * @return Red value + */ + public float getRed() { + return red; + } + + /** + * Get the green value + * <p> + * The values 0.0 - 1.0 represent 0 - 255 + * + * @return Green value + */ + public float getGreen() { + return green; + } + + /** + * Get the blue value + * <p> + * The values 0.0 - 1.0 represent 0 - 255 + * + * @return Blue value + */ + public float getBlue() { + return blue; + } + + /** + * Get the hexadecimal color code for this color + * + * @return Hexadecimal color code + */ + public String getHex() { + return String.format("#%02x%02x%02x", (int) (red * 255), (int) (green * 255), (int) (blue * 255)).toUpperCase(); + } + + /** + * Get color by name or hex code + * <p> + * Invalid colors will default to RED + * + * @param color Color name or hex code + * @return ParticleColor + */ + public static ParticleColor getColor(String color) { + ParticleColor actual = getColorExact(color); + return actual == null ? RED : actual; + } + + /** + * Get color by name or hex code + * <p> + * Invalid colors return NULL + * + * @param color Color name or hex code + * @return ParticleColor + */ + public static ParticleColor getColorExact(String color) { + switch (color.toUpperCase()) { + case "BLACK": + return BLACK; + case "DARK_BLUE": + return DARK_BLUE; + case "DARK_GREEN": + return DARK_GREEN; + case "DARK_AQUA": + return DARK_AQUA; + case "DARK_RED": + return DARK_RED; + case "DARK_PURPLE": + return DARK_PURPLE; + case "GOLD": + return GOLD; + case "GRAY": + return GRAY; + case "DARK_GRAY": + return DARK_GRAY; + case "BLUE": + return BLUE; + case "GREEN": + return GREEN; + case "AQUA": + return AQUA; + case "RED": + return RED; + case "LIGHT_PURPLE": + return LIGHT_PURPLE; + case "YELLOW": + return YELLOW; + case "WHITE": + return WHITE; + } + + if (color.startsWith("#")) { + color = color.substring(1); // remove # sign if present + } + + ParticleColor particleColor = null; + + if (color.length() < 6) { + return null; + } + + try { + particleColor = new ParticleColor( + Integer.valueOf(color.substring(0, 2), 16), + Integer.valueOf(color.substring(2, 4), 16), + Integer.valueOf(color.substring(4, 6), 16) + ); + } catch (Exception ignore) { + } + + return particleColor; + } + + /** + * Get a human readable String representation of this color + * + * @return Human readable String representation of color + */ + @Override + public String toString() { + return "ParticleColor[red:[" + + red + + "], green:[" + + green + + "], blue:[" + + blue + + "]]"; + } +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/ReflectUtil.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/ReflectUtil.java new file mode 100644 index 0000000..81f18c6 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/ReflectUtil.java @@ -0,0 +1,56 @@ +package net.grandtheftmc.vice.utils; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; + +public class ReflectUtil { + + public static <T> T getOfT(final Object obj, final Class<T> type) { + for (final Field field : obj.getClass().getDeclaredFields()) { + if (type.equals(field.getType())) { + return get(obj, field, type); + } + } + return null; + } + + public static <T> T get(final Object obj, final String name, final Class<T> type) { + return get(obj, obj.getClass(), name, type); + } + + public static <T> T get(final Object obj, final Class<?> clazz, final String name, final Class<T> type) { + for (final Field field : clazz.getDeclaredFields()) { + if (name.equals(field.getName())) { + return get(obj, field, type); + } + } + throw new IllegalArgumentException("No field: " + name); + } + + public static void setStatic(final String name, final Class<?> clazz, final Object val) { + try { + final Field field = clazz.getDeclaredField(name); + field.setAccessible(true); + if (Modifier.isFinal(field.getModifiers())) { + final Field modifiersField = Field.class.getDeclaredField("modifiers"); + modifiersField.setAccessible(true); + modifiersField.setInt(field, field.getModifiers() & 0xFFFFFFEF); + } + field.set(null, val); + } + catch (ReflectiveOperationException ex) { + ex.printStackTrace(); + } + } + + public static <T> T get(final Object obj, final Field field, final Class<T> type) { + try { + field.setAccessible(true); + return type.cast(field.get(obj)); + } + catch (ReflectiveOperationException ex) { + ex.printStackTrace(); + return null; + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/ReflectionUtil.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/ReflectionUtil.java new file mode 100644 index 0000000..747c533 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/ReflectionUtil.java @@ -0,0 +1,210 @@ +package net.grandtheftmc.vice.utils; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +public final class ReflectionUtil { + + /* + * The server version string to location NMS & OBC classes + */ + private static String versionString; + + /* + * Cache of NMS classes that we've searched for + */ + private static final Map<String, Class<?>> LOADED_NMS_CLASSES = new HashMap<>(); + + /* + * Cache of OBS classes that we've searched for + */ + private static final Map<String, Class<?>> LOADED_OBC_CLASSES = new HashMap<>(); + + /* + * Cache of methods that we've found in particular classes + */ + private static final Map<Class<?>, Map<String, Method>> LOADED_METHODS; + + static { + LOADED_METHODS = new HashMap<>(); + } + + /* + * Cache of fields that we've found in particular classes + */ + private static final Map<Class<?>, Map<String, Field>> LOADED_FIELDS = new HashMap<>(); + + private ReflectionUtil() { + } + + /** + * Gets the version string for NMS & OBC class paths + * + * @return The version string of OBC and NMS packages + */ + public static String getVersion() { + if (versionString == null) { + String name = Bukkit.getServer().getClass().getPackage().getName(); + versionString = name.substring(name.lastIndexOf('.') + 1) + '.'; + } + + return versionString; + } + + /** + * Get an NMS Class + * + * @param nmsClassName The name of the class + * @return The class + */ + public static Class<?> getNMSClass(String nmsClassName) { + if (LOADED_NMS_CLASSES.containsKey(nmsClassName)) { + return LOADED_NMS_CLASSES.get(nmsClassName); + } + + String clazzName = "net.minecraft.server." + getVersion() + nmsClassName; + Class<?> clazz; + + try { + clazz = Class.forName(clazzName); + } catch (Throwable t) { + t.printStackTrace(); + return LOADED_NMS_CLASSES.put(nmsClassName, null); + } + + LOADED_NMS_CLASSES.put(nmsClassName, clazz); + return clazz; + } + + /** + * Get a class from the org.bukkit.craftbukkit package + * + * @param obcClassName the path to the class + * @return the found class at the specified path + */ + public static synchronized Class<?> getOBCClass(String obcClassName) { + if (LOADED_OBC_CLASSES.containsKey(obcClassName)) { + return LOADED_OBC_CLASSES.get(obcClassName); + } + + String clazzName = "org.bukkit.craftbukkit." + getVersion() + obcClassName; + Class<?> clazz; + + try { + clazz = Class.forName(clazzName); + } catch (Throwable t) { + t.printStackTrace(); + LOADED_OBC_CLASSES.put(obcClassName, null); + return null; + } + + LOADED_OBC_CLASSES.put(obcClassName, clazz); + return clazz; + } + + /** + * Get a Bukkit {@link Player} players NMS playerConnection object + * + * @param player The player + * @return The players connection + */ + public static Object getConnection(Player player) { + Method getHandleMethod = getMethod(player.getClass(), "getHandle"); + + if (getHandleMethod != null) { + try { + Object nmsPlayer = getHandleMethod.invoke(player); + Field playerConField = getField(nmsPlayer.getClass(), "playerConnection"); + return playerConField.get(nmsPlayer); + } catch (Exception e) { + e.printStackTrace(); + } + } + + return null; + } + + /** + * Get a classes constructor + * + * @param clazz The constructor class + * @param params The parameters in the constructor + * @return The constructor object + */ + public static Constructor<?> getConstructor(Class<?> clazz, Class<?>... params) { + try { + return clazz.getConstructor(params); + } catch (NoSuchMethodException e) { + return null; + } + } + + /** + * Get a method from a class that has the specific paramaters + * + * @param clazz The class we are searching + * @param methodName The name of the method + * @param params Any parameters that the method has + * @return The method with appropriate paramaters + */ + public static Method getMethod(Class<?> clazz, String methodName, Class<?>... params) { + if (!LOADED_METHODS.containsKey(clazz)) { + LOADED_METHODS.put(clazz, new HashMap<>()); + } + + Map<String, Method> methods = LOADED_METHODS.get(clazz); + + if (methods.containsKey(methodName)) { + return methods.get(methodName); + } + + try { + Method method = clazz.getMethod(methodName, params); + methods.put(methodName, method); + LOADED_METHODS.put(clazz, methods); + return method; + } catch (Exception e) { + e.printStackTrace(); + methods.put(methodName, null); + LOADED_METHODS.put(clazz, methods); + return null; + } + } + + /** + * Get a field with a particular name from a class + * + * @param clazz The class + * @param fieldName The name of the field + * @return The field object + */ + public static Field getField(Class<?> clazz, String fieldName) { + if (!LOADED_FIELDS.containsKey(clazz)) { + LOADED_FIELDS.put(clazz, new HashMap<>()); + } + + Map<String, Field> fields = LOADED_FIELDS.get(clazz); + + if (fields.containsKey(fieldName)) { + return fields.get(fieldName); + } + + try { + Field field = clazz.getField(fieldName); + fields.put(fieldName, field); + LOADED_FIELDS.put(clazz, fields); + return field; + } catch (Exception e) { + e.printStackTrace(); + fields.put(fieldName, null); + LOADED_FIELDS.put(clazz, fields); + return null; + } + } +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/Stats.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/Stats.java new file mode 100644 index 0000000..5ce1bb0 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/Stats.java @@ -0,0 +1,91 @@ +package net.grandtheftmc.vice.utils; + +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.util.TimeFormatter; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.ViceUser; +import org.bukkit.ChatColor; +import org.bukkit.Statistic; +import org.bukkit.entity.Player; + +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +public class Stats { + private static Stats stats; + + public static Stats getInstance() { + if (stats == null) stats = new Stats(); + return stats; + } + + public List<String> getStats(Player target) { + List<String> stats = new ArrayList<>(); + ViceUser user = Vice.getUserManager().getLoadedUser(target.getUniqueId()); + stats.add(Utils.f(target.getDisplayName())); + stats.add(this.format("Playtime", this.getHoursPlayed(target))); + stats.add(this.format("Money", '$' + this.numberFormat(user.getMoney()))); + // TODO replace Gang with Cartel + /* if (user.getGang() != null) { + stats.add(this.format("Gang", user.getGangName())); + } + if (user.getJobMode() == JobMode.CRIMINAL && user.getWantedLevel() > 0) { + stats.add(this.format("Wanted Level", ChatColor.WHITE + ViceUtils.getWantedLevelStars(user.getWantedLevel()))); + } else if (user.getJobMode() != JobMode.CRIMINAL) { + stats.add(this.format("Job", user.getJobMode().getColoredNameBold())); + }*/ + stats.add(this.format("Kills", this.getKillAmount(target))); + stats.add(this.format("Deaths", this.getDeathAmount(target))); + stats.add(this.format("K/D", this.getKDRatio(target))); + return stats; + } + + public String getKDRatio(Player player) { + int kills = player.getStatistic(Statistic.PLAYER_KILLS); + int deaths = player.getStatistic(Statistic.DEATHS); + if (kills == 0 && deaths == 0) { + return "0.0"; + } + double kd = (double) kills / deaths; + return String.valueOf(kd).substring(0, 3); + } + + public String getDeathAmount(Player player) { + int deaths = player.getStatistic(Statistic.DEATHS); + return this.numberFormat(deaths); + } + + public String getKillAmount(Player player) { + int kills = player.getStatistic(Statistic.PLAYER_KILLS); + return this.numberFormat(kills); + } + + public long getHoursPlayedRaw(Player player) { + if (player == null) return 0; + int ticks = player.getStatistic(Statistic.PLAY_ONE_TICK); + long minutes = ticks / 20 / 60; + TimeFormatter tf = Utils.timeFormatter(TimeUnit.MINUTES, minutes); + return tf.getHours(); + } + + public String getHoursPlayed(Player player) { + int ticks = player.getStatistic(Statistic.PLAY_ONE_TICK); + long minutes = ticks / 20 / 60; + TimeFormatter tf = Utils.timeFormatter(TimeUnit.MINUTES, minutes); + return tf.getDays() + "d " + tf.getHours() + "h " + tf.getMinutes() + "m"; + } + + public String numberFormat(int num) { + return NumberFormat.getInstance().format(num); + } + + public String numberFormat(double num) { + return NumberFormat.getInstance().format(num); + } + + public String format(String key, String value) { + return ChatColor.GRAY + key + ": " + ChatColor.GREEN + value; + } +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/StringUtils.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/StringUtils.java new file mode 100644 index 0000000..2ad642e --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/StringUtils.java @@ -0,0 +1,35 @@ +package net.grandtheftmc.vice.utils; + +import org.bukkit.Material; + +/** + * Created by Timothy Lampen on 7/9/2017. + */ +public class StringUtils { + + public static String getPrettyItemString(Material material) { + return createPrettyEnumString(material.toString()); + } + + private static String createPrettyEnumString(String baseString) { + String[] substrings = baseString.split("_"); + String prettyString = ""; + int size = 1; + + for (String string : substrings) { + prettyString = prettyString.concat(getCapitalized(string)); + + if (size < substrings.length) { + prettyString = prettyString.concat(" "); + } + + size++; + } + + return prettyString; + } + + public static String getCapitalized(String target) { + return target.substring(0, 1).toUpperCase() + target.substring(1).toLowerCase(); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/TextHelper.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/TextHelper.java new file mode 100644 index 0000000..adea153 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/TextHelper.java @@ -0,0 +1,68 @@ +package net.grandtheftmc.vice.utils; + +import net.grandtheftmc.core.util.factory.Factory; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.TextComponent; + +public final class TextHelper extends Factory<TextComponent> { + + public TextHelper() { + this.object = new TextComponent(); + } + + public TextHelper(TextComponent component) { + this.object = component; + } + + public TextHelper(String text) { + this(); + this.object.setText(text); + } + + public TextHelper setText(String text) { + this.object.setText(text); + return this; + } + + public TextHelper setColor(ChatColor color) { + this.object.setColor(color); + return this; + } + + public TextHelper setBold(boolean bold) { + this.object.setBold(bold); + return this; + } + + public TextHelper setItalic(boolean italic) { + this.object.setItalic(italic); + return this; + } + + public TextHelper setHover(HoverEvent event) { + this.object.setHoverEvent(event); + return this; + } + + public TextHelper setClick(ClickEvent event) { + this.object.setClickEvent(event); + return this; + } + + public TextHelper addExtra(TextHelper component) { + this.object.addExtra(component.build().duplicate()); + return this; + } + + @Override + public TextComponent build() { + return this.object; + } + + public BaseComponent[] toBaseComponent() { + return new BaseComponent[] { this.object }; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/TitleBuilder.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/TitleBuilder.java new file mode 100644 index 0000000..06db1dd --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/TitleBuilder.java @@ -0,0 +1,68 @@ +package net.grandtheftmc.vice.utils; + +import net.md_5.bungee.api.ChatColor; +import net.minecraft.server.v1_12_R1.IChatBaseComponent; +import net.minecraft.server.v1_12_R1.PacketPlayOutTitle; +import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer; +import org.bukkit.entity.Player; + +/** + * Created by Timothy Lampen on 2017-04-11. + */ +public class TitleBuilder { + private String bigText = "", smallText = ""; + private int fadeIn = 20, duration = 20, fadeOut = 20; + + public TitleBuilder setTitleText(String bigText) { + this.bigText = bigText; + return this; + } + + public TitleBuilder setSubTitleText(String smallText) { + this.smallText = smallText; + return this; + } + + public TitleBuilder setFadeIn(int fadeIn) { + this.fadeIn = fadeIn; + return this; + } + + public TitleBuilder setDuration(int duration) { + this.duration = duration; + return this; + } + + public TitleBuilder setFadeOut(int fadeOut) { + this.fadeOut = fadeOut; + return this; + } + + public void send(Player player){ + if(!bigText.equals("")) { + + PacketPlayOutTitle title = new PacketPlayOutTitle(PacketPlayOutTitle.EnumTitleAction.TITLE, IChatBaseComponent.ChatSerializer.a(ChatColor.translateAlternateColorCodes( + '&', + "{\"text\": \"" + bigText + "\"}")), + fadeIn, + duration, + fadeOut); + + ((CraftPlayer) player).getHandle().playerConnection.sendPacket(title); + + } + + if(!smallText.equals("")) { + + PacketPlayOutTitle title = new PacketPlayOutTitle( + PacketPlayOutTitle.EnumTitleAction.SUBTITLE, IChatBaseComponent.ChatSerializer.a(ChatColor.translateAlternateColorCodes( + '&', + "{\"text\": \"" + smallText + "\"}")), + fadeIn, + duration, + fadeOut); + + ((CraftPlayer) player).getHandle().playerConnection.sendPacket(title); + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/WeightedRandomCollection.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/WeightedRandomCollection.java new file mode 100644 index 0000000..7902b4d --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/WeightedRandomCollection.java @@ -0,0 +1,91 @@ +package net.grandtheftmc.vice.utils; +/* + * Copyright (C) 2013-Current Carter Gale (Ktar5) <buildfresh@gmail.com> + * + * This file is part of vice. + * + * vice can not be copied and/or distributed without the express + * permission of the aforementioned owner. + */ + +import com.google.common.collect.Lists; + +import java.util.*; +import java.util.concurrent.ThreadLocalRandom; + +/** + * A utility collection created in order to simplify the selection of a random + * element based on its corresponding relative weight + * <p> + * "Relative weight" means that, for example, each "weight" is a lottery ticket thrown + * into the "total weight". We pick a random ticket, and then return that element. Thus, + * the higher the weight, the higher the chance it will be picked. + * + * @param <E> the type of element to be placed into this collection + */ +public class WeightedRandomCollection<E> { + private final NavigableMap<Double, E> map = new TreeMap<>(); + private E last; + private double total; + + /** + * Add an items to the random collection with the + * specified weight + * + * @param weight the weight (relative to the others) + * @param result the items that corresponds to this weight + */ + public WeightedRandomCollection<E> add(double weight, E result) { + if (weight <= 0) throw new NumberFormatException("Weights cannot be less than zero. Idiot."); + this.total += weight; + this.map.put(this.total, result); + this.last = result; + return this; + } + + public E last() { + return this.last; + } + + /** + * Return a set of all the values + * + * @return a set of all the values + */ + public Set<E> values() { + return new HashSet<>(this.map.values()); + } + + /** + * Returns #amount of unique elements chosen randomly for a lottery-type system + * + * @param amount the max amount of unique elements you want returned + * @return a list containing maximum #amount unique elements, unless there are + * less than that many elements in the collection + */ + public List<E> getUniqueElements(int amount) { + if (this.map.size() <= amount) { + return Lists.newArrayList(this.map.values()); + } + List<E> uniqueElements = new ArrayList<>(amount); + while (uniqueElements.size() < amount && uniqueElements.size() < this.map.size()) { + if (!uniqueElements.contains(this.next())) { + uniqueElements.add(this.last()); + } + } + return uniqueElements; + } + + /** + * Select a random items from the list based on the chance + * Uses a ThreadLocalRandom because Random sucks shit + * ThreadLocalRandom is faster + * + * @return a random element from the collection, selected based on its relative weight + */ + public E next() { + double value = ThreadLocalRandom.current().nextDouble() * this.total; + this.last = this.map.ceilingEntry(value).getValue(); + return this.last; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/advancement/AdvancementUtil.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/advancement/AdvancementUtil.java new file mode 100644 index 0000000..158040b --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/advancement/AdvancementUtil.java @@ -0,0 +1,410 @@ +package net.grandtheftmc.vice.utils.advancement; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.chat.ComponentSerializer; +import org.bukkit.Bukkit; +import org.bukkit.NamespacedKey; +import org.bukkit.World; +import org.bukkit.advancement.Advancement; +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Set; + +/** + * @author charliej - the very API + * @author DiscowZombie - adopting for Builder-Pattern + * @author 2008Choco - NamespacedKey support + * @author GiansCode - small but useful changes + * @author Ste3et_C0st - add/take advancement logic + * @author PROgrammer_JARvis - rework and combining + * @author ysl3000 - useful advice and bug-tracking at PullRequests/ JUnit-Tests, full Builder-Pattern support, Lombok + */ + +public class AdvancementUtil { + + private static final Gson gson = new Gson(); + + private NamespacedKey id; + private String parent, icon, background; + private TextComponent title, description; + private FrameType frame; + private boolean announce = true, toast = true, hidden = true; + private int counter = 1; + + private Set<Trigger.TriggerBuilder> triggers; + + private AdvancementUtil(NamespacedKey id, String parent, String icon, String background, TextComponent title, TextComponent description, FrameType frame, boolean announce, boolean toast, boolean hidden, int counter, Set<Trigger.TriggerBuilder> triggers) { + this.id = id; + this.parent = parent; + this.icon = icon; + this.background = background; + this.title = title; + this.description = description; + this.frame = frame; + this.announce = announce; + this.toast = toast; + this.hidden = hidden; + this.counter = counter; + this.triggers = triggers; + } + + + public static AdvancementAPIBuilder builder(NamespacedKey id) { + return new AdvancementAPIBuilder().id(id); + } + + + @Deprecated + public void save(String world) { + this.save(Bukkit.getWorld(world)); + } + + @Deprecated + public void save(World world) { + + + File file = new File(world.getWorldFolder(), "data" + File.separator + "advancements" + + File.separator + id.getNamespace() + File.separator + id.getKey() + ".json"); + + File dir = file.getParentFile(); + + if (dir.mkdirs() || dir.exists()) { + + try (FileWriter writer = new FileWriter(file)) { + writer.write(getJSON()); + Bukkit.getLogger().info("[AdvancementAPI] Created " + id.toString()); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + public String getJSON() { + JsonObject json = new JsonObject(); + + JsonObject icon = new JsonObject(); + icon.addProperty("item", getIcon()); + + JsonObject display = new JsonObject(); + display.add("icon", icon); + display.add("title", getJsonFromComponent(getTitle())); + display.add("description", getJsonFromComponent(getDescription())); + display.addProperty("background", getBackground()); + display.addProperty("frame", getFrame().toString()); + display.addProperty("announce_to_chat", announce); + display.addProperty("show_toast", toast); + display.addProperty("hidden", hidden); + + json.addProperty("parent", getParent()); + + JsonObject criteria = new JsonObject(); + + + //Changed to normal comment as JavaDocs are not displayed here @PROgrm_JARvis + /* + * Define each criteria, for each criteria in list, + * add items, trigger and conditions + */ + + for (Trigger.TriggerBuilder triggerBuilder : getTriggers()) { + Trigger trigger = triggerBuilder.build(); + criteria.add(trigger.name, trigger.toJsonObject()); + } + + json.add("criteria", criteria); + json.add("display", display); + + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + + return gson.toJson(json); + } + + public String getIcon() { + return this.icon; + } + + public static JsonElement getJsonFromComponent(TextComponent textComponent) { + return gson.fromJson(ComponentSerializer.toString(textComponent), JsonElement.class); + + } + + public TextComponent getTitle() { + return this.title; + } + + public TextComponent getDescription() { + return this.description; + } + + public String getBackground() { + return this.background; + } + + public FrameType getFrame() { + return this.frame; + } + + public String getParent() { + return this.parent; + } + + public Set<Trigger.TriggerBuilder> getTriggers() { + return this.triggers; + } + + public AdvancementUtil show(JavaPlugin plugin, Player... players) { + add(); + grant(players); + Bukkit.getScheduler().runTaskLater(plugin, () -> { + revoke(players); + remove(); + }, 20L); + return this; + } + + @SuppressWarnings("deprecation") + public AdvancementUtil add() { + try { + Bukkit.getUnsafe().loadAdvancement(id, getJSON()); + Bukkit.getLogger().info("Successfully registered advancement."); + } catch (IllegalArgumentException e) { + Bukkit.getLogger().info("Error registering advancement. It seems to already exist!"); + } + return this; + } + + public AdvancementUtil grant(Player... players) { + Advancement advancement = getAdvancement(); + for (Player player : players) { + if (!player.getAdvancementProgress(advancement).isDone()) { + Collection<String> remainingCriteria = player.getAdvancementProgress(advancement).getRemainingCriteria(); + Bukkit.getLogger().info(remainingCriteria.toString()); + for (String remainingCriterion : remainingCriteria) + player.getAdvancementProgress(getAdvancement()) + .awardCriteria(remainingCriterion); + } + } + return this; + } + + public AdvancementUtil revoke(Player... players) { + Advancement advancement = getAdvancement(); + for (Player player : players) { + if (player.getAdvancementProgress(advancement).isDone()) { + Collection<String> awardedCriteria = player.getAdvancementProgress(advancement).getAwardedCriteria(); + Bukkit.getLogger().info(awardedCriteria.toString()); + for (String awardedCriterion : awardedCriteria) + player.getAdvancementProgress(getAdvancement()) + .revokeCriteria(awardedCriterion); + } + } + return this; + } + + @SuppressWarnings("deprecation") + public AdvancementUtil remove() { + Bukkit.getUnsafe().removeAdvancement(id); + return this; + } + + public Advancement getAdvancement() { + return Bukkit.getAdvancement(id); + } + + public boolean counterUp(Player player) { + String criteriaString = null; + for (String criteria : getAdvancement().getCriteria()) { + if (player.getAdvancementProgress(getAdvancement()).getDateAwarded(criteria) != null) { + criteriaString = criteria; + } else { + break; + } + } + if (criteriaString == null) return false; + player.getAdvancementProgress(getAdvancement()).awardCriteria(criteriaString); + return true; + } + + public boolean counterDown(Player player) { + String criteriaString = null; + for (String criteria : getAdvancement().getCriteria()) { + if (player.getAdvancementProgress(getAdvancement()).getDateAwarded(criteria) != null) { + criteriaString = criteria; + } else { + break; + } + } + if (criteriaString == null) return false; + player.getAdvancementProgress(getAdvancement()).revokeCriteria(criteriaString); + return true; + } + + public void counterReset(Player player) { + for (String criteria : getAdvancement().getCriteria()) { + if (player.getAdvancementProgress(getAdvancement()).getDateAwarded(criteria) != null) { + player.getAdvancementProgress(getAdvancement()).revokeCriteria(criteria); + } + } + } + + public NamespacedKey getId() { + return this.id; + } + + public boolean isAnnounce() { + return this.announce; + } + + public boolean isToast() { + return this.toast; + } + + public boolean isHidden() { + return this.hidden; + } + + public int getCounter() { + return this.counter; + } + + public static class AdvancementAPIBuilder { + private NamespacedKey id; + private String parent; + private String icon; + private String background; + private TextComponent title; + private TextComponent description; + private FrameType frame; + private boolean announce; + private boolean toast; + private boolean hidden; + private int counter; + private ArrayList<Trigger.TriggerBuilder> triggers; + + AdvancementAPIBuilder() { + } + + public AdvancementAPIBuilder title(String title) { + + this.title = new TextComponent(title); + + return this; + } + + public AdvancementAPIBuilder title(TextComponent title) { + this.title = title; + + return this; + } + + public AdvancementAPIBuilder description(String description) { + this.description = new TextComponent(description); + return this; + } + + public AdvancementAPIBuilder description(TextComponent description) { + this.description = description; + return this; + } + + + public AdvancementAPIBuilder id(NamespacedKey id) { + this.id = id; + return this; + } + + public AdvancementAPIBuilder parent(String parent) { + this.parent = parent; + return this; + } + + public AdvancementAPIBuilder icon(String icon) { + this.icon = icon; + return this; + } + + public AdvancementAPIBuilder background(String background) { + this.background = background; + return this; + } + + public AdvancementAPIBuilder frame(FrameType frame) { + this.frame = frame; + return this; + } + + public AdvancementAPIBuilder announce(boolean announce) { + this.announce = announce; + return this; + } + + public AdvancementAPIBuilder toast(boolean toast) { + this.toast = toast; + return this; + } + + public AdvancementAPIBuilder hidden(boolean hidden) { + this.hidden = hidden; + return this; + } + + public AdvancementAPIBuilder counter(int counter) { + this.counter = counter; + return this; + } + + public AdvancementAPIBuilder trigger(Trigger.TriggerBuilder trigger) { + if (this.triggers == null) + this.triggers = new ArrayList<Trigger.TriggerBuilder>(); + this.triggers.add(trigger); + return this; + } + + public AdvancementAPIBuilder triggers(Collection<? extends Trigger.TriggerBuilder> triggers) { + if (this.triggers == null) + this.triggers = new ArrayList<Trigger.TriggerBuilder>(); + this.triggers.addAll(triggers); + return this; + } + + public AdvancementAPIBuilder clearTriggers() { + if (this.triggers != null) + this.triggers.clear(); + + return this; + } + + public AdvancementUtil build() { + Set<Trigger.TriggerBuilder> triggers; + switch (this.triggers == null ? 0 : this.triggers.size()) { + case 0: + triggers = java.util.Collections.singleton(Trigger.builder(Trigger.TriggerType.IMPOSSIBLE, "default")); + break; + case 1: + triggers = java.util.Collections.singleton(this.triggers.get(0)); + break; + default: + triggers = new java.util.LinkedHashSet<Trigger.TriggerBuilder>(this.triggers.size() < 1073741824 ? 1 + this.triggers.size() + (this.triggers.size() - 3) / 3 : Integer.MAX_VALUE); + triggers.addAll(this.triggers); + triggers = java.util.Collections.unmodifiableSet(triggers); + } + + return new AdvancementUtil(id, parent, icon, background, title, description, frame, announce, toast, hidden, counter, triggers); + } + + public String toString() { + return "AdvancementAPI.AdvancementAPIBuilder(id=" + this.id + ", parent=" + this.parent + ", icon=" + this.icon + ", background=" + this.background + ", title=" + this.title + ", description=" + this.description + ", frame=" + this.frame + ", announce=" + this.announce + ", toast=" + this.toast + ", hidden=" + this.hidden + ", counter=" + this.counter + ", triggers=" + this.triggers + ")"; + } + } + +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/advancement/Condition.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/advancement/Condition.java new file mode 100644 index 0000000..09f1a6a --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/advancement/Condition.java @@ -0,0 +1,61 @@ +package net.grandtheftmc.vice.utils.advancement; + +import com.google.gson.JsonObject; +import org.bukkit.inventory.ItemStack; + +public class Condition { + + protected String name; + protected JsonObject set; + + private Condition(String name, JsonObject set) { + this.name = name; + this.set = set; + } + + public static ConditionBuilder builder(String name, JsonObject itemStack) { + return new Condition.ConditionBuilder().name(name).set(itemStack); + } + + public static ConditionBuilder builder(String name, ItemStack itemStack) { + return Condition.builder(name,convertItemToJSON(itemStack)); + } + + + //BEGIN UTIL + private static JsonObject convertItemToJSON(ItemStack item) { + JsonObject itemJSON = new JsonObject(); + itemJSON.addProperty("item", "minecraft:" + item.getType().name().toLowerCase()); + itemJSON.addProperty("amount", item.getAmount()); + itemJSON.addProperty("data", item.getData().getData()); + return itemJSON; + } + + + + public static class ConditionBuilder { + private String name; + private JsonObject set; + + ConditionBuilder() { + } + + public Condition.ConditionBuilder name(String name) { + this.name = name; + return this; + } + + public Condition.ConditionBuilder set(JsonObject set) { + this.set = set; + return this; + } + + public Condition build() { + return new Condition(name, set); + } + + public String toString() { + return "Condition.ConditionBuilder(name=" + this.name + ", set=" + this.set + ")"; + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/advancement/FrameType.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/advancement/FrameType.java new file mode 100644 index 0000000..238376b --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/advancement/FrameType.java @@ -0,0 +1,33 @@ +package net.grandtheftmc.vice.utils.advancement; + +import org.bukkit.Bukkit; + +public enum FrameType { + TASK("task"), + GOAL("goal"), + CHALLENGE("challenge"); + private String name; + + FrameType(String name) { + this.name = name; + } + + public static FrameType getFromString(String frameType) { + if (frameType.equalsIgnoreCase("random")) return FrameType.RANDOM(); + else try { + return FrameType.valueOf(frameType); + } catch (EnumConstantNotPresentException e) { + Bukkit.getLogger().info("[AdvancementUtil] Unknown FrameType given. Using default (TASK)"); + return FrameType.TASK; + } + } + + public static FrameType RANDOM() { + FrameType[] frameTypes = FrameType.values(); + return frameTypes[(int) (Math.random() * (frameTypes.length - 1))]; + } + + public String toString() { + return name; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/advancement/Trigger.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/advancement/Trigger.java new file mode 100644 index 0000000..d81d8c7 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/advancement/Trigger.java @@ -0,0 +1,135 @@ +package net.grandtheftmc.vice.utils.advancement; + +import com.google.gson.JsonObject; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Set; + +public class Trigger { + + protected TriggerType type; + protected String name; + protected Set<Condition.ConditionBuilder> conditions; + + private Trigger(TriggerType type, String name, Set<Condition.ConditionBuilder> conditions) { + this.type = type; + this.name = name; + this.conditions = conditions; + } + + public static TriggerBuilder builder(TriggerType type, String name) { + return new TriggerBuilder().type(type).name(name); + } + + public JsonObject toJsonObject() { + + JsonObject triggerObj = new JsonObject(); + + final JsonObject advConditions = new JsonObject(); + triggerObj.addProperty("trigger", "minecraft:" + this.type.toString().toLowerCase()); + this.conditions.forEach(conditionBuilder -> { + + Condition condition = conditionBuilder.build(); + advConditions.add(condition.name, condition.set); + }); + if (!this.conditions.isEmpty()) + triggerObj.add("conditions", advConditions); + + + return triggerObj; + + } + + + public static enum TriggerType { + ARBITRARY_PLAYER_TICK, + BRED_ANIMALS, + BREWED_POTION, + CHANGED_DIMENSION, + CONSTRUCT_BEACON, + CONSUME_ITEM, + CURED_ZOMBIE_VILLAGER, + ENCHANTED_ITEM, + ENTER_BLOCK, + ENTITY_HURT_PLAYER, + ENTITY_KILLED_PLAYER, + IMPOSSIBLE, + INVENTORY_CHANGED, + ITEM_DURABILITY_CHANGED, + LEVITATION, + LOCATION, + PLACED_BLOCK, + PLAYER_HURT_ENTITY, + PLAYER_KILLED_ENTITY, + RECIPE_UNLOCKED, + SLEPT_IN_BED, + SUMMONED_ENTITY, + TAME_ANIMAL, + TICK, + USED_ENDER_EYE, + VILLAGER_TRADE + } + + public static class TriggerBuilder { + private TriggerType type; + private String name; + private ArrayList<Condition.ConditionBuilder> conditions; + + TriggerBuilder() { + } + + public Trigger.TriggerBuilder type(TriggerType type) { + this.type = type; + return this; + } + + public Trigger.TriggerBuilder name(String name) { + this.name = name; + return this; + } + + public Trigger.TriggerBuilder condition(Condition.ConditionBuilder condition) { + if (this.conditions == null) + this.conditions = new ArrayList<Condition.ConditionBuilder>(); + this.conditions.add(condition); + return this; + } + + public Trigger.TriggerBuilder conditions(Collection<? extends Condition.ConditionBuilder> conditions) { + if (this.conditions == null) + this.conditions = new ArrayList<Condition.ConditionBuilder>(); + this.conditions.addAll(conditions); + return this; + } + + public Trigger.TriggerBuilder clearConditions() { + if (this.conditions != null) + this.conditions.clear(); + + return this; + } + + public Trigger build() { + Set<Condition.ConditionBuilder> conditions; + switch (this.conditions == null ? 0 : this.conditions.size()) { + case 0: + conditions = java.util.Collections.emptySet(); + break; + case 1: + conditions = java.util.Collections.singleton(this.conditions.get(0)); + break; + default: + conditions = new java.util.LinkedHashSet<Condition.ConditionBuilder>(this.conditions.size() < 1073741824 ? 1 + this.conditions.size() + (this.conditions.size() - 3) / 3 : Integer.MAX_VALUE); + conditions.addAll(this.conditions); + conditions = java.util.Collections.unmodifiableSet(conditions); + } + + return new Trigger(type, name, conditions); + } + + public String toString() { + return "Trigger.TriggerBuilder(type=" + this.type + ", name=" + this.name + ", conditions=" + this.conditions + ")"; + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/recipe/ShapedRegister.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/recipe/ShapedRegister.java new file mode 100644 index 0000000..48cdba2 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/recipe/ShapedRegister.java @@ -0,0 +1,198 @@ +package net.grandtheftmc.vice.utils.recipe; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.ShapedRecipe; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; + +public class ShapedRegister { + + private ItemStack output; + private String[] rows; + private Map<Character, ItemStack> ingredients = new HashMap<>(); + + private final NamespacedKey key; + + /** + * Create a shaped recipe to craft the specified ItemStack. The + * constructor merely determines the result and type; to set the actual + * recipe, you'll need to call the appropriate methods. + * + * @param result The item you want the recipe to create. + * @see ShapedRecipe#shape(String...) + * @see ShapedRecipe#setIngredient(char, Material) + * @see ShapedRecipe#setIngredient(char, ItemStack) + */ + public ShapedRegister(NamespacedKey key, ItemStack result) { + this.key = key; + output = new ItemStack(result); + } + + public NamespacedKey getKey() { + return key; + } + + /** + * Set the shape of this recipe to the specified rows. Each character + * represents a different ingredient; exactly what each character + * represents is set separately. The first row supplied corresponds with + * the upper most part of the recipe on the workbench e.g. if all three + * rows are supplies the first string represents the top row on the + * workbench. + * + * @param shape The rows of the recipe (up to 3 rows). + * @return The changed recipe, so you can chain calls. + */ + public ShapedRegister shape(String... shape) { + Validate.notNull(shape, "Must provide a shape"); + Validate.isTrue(shape.length > 0 && shape.length < 4, "Crafting recipes should be 1, 2, 3 rows, not ", shape.length); + + for (String row : shape) { + Validate.notNull(row, "Shape cannot have null rows"); + Validate.isTrue(row.length() > 0 && row.length() < 4, "Crafting rows should be 1, 2, or 3 characters, not ", row.length()); + Map<Character, ItemStack> newIng = new HashMap<>(); + + for (char c : row.toCharArray()) + newIng.put(c, ingredients.get(c)); + + ingredients = newIng; + } + + rows = shape; + + return this; + } + + /** + * Sets the Material that a character in the recipe shape refers to. + * + * @param key The character that represents the ingredient in the shape. + * @param ingredient The ingredient. + * @return The changed recipe, so you can chain calls. + */ + public ShapedRegister setIngredient(char key, Material mat) { + return setIngredient(key, new ItemStack(mat, 1)); + } + + /** + * Sets the ItemStack that a character in the recipe shape refers to. + * + * @param key The character that represents the ingredient in the shape. + * @param ingredient The ingredient. + * @return The changed recipe, so you can chain calls. + */ + public ShapedRegister setIngredient(char key, ItemStack item) { + Validate.isTrue(ingredients.containsKey(key), "Symbol does not appear in the shape:", key); + ingredients.put(key, item); + return this; + } + + public ItemStack getOutput() { + return output.clone(); + } + + /** + * Registers the Recipe in the server. + */ + public void register() { + ShapedRecipe sr = new ShapedRecipe(key, output); + sr.shape(rows); + try { + Field f = sr.getClass().getDeclaredField("ingredients"); + f.setAccessible(true); + f.set(sr, ingredients); + Bukkit.addRecipe(sr); + } catch (Exception e) { + e.printStackTrace(); + } + } + +// public static void registerShapedRecipe(ItemStack result, Object... data) { +// String s = ""; +// int index = 0; +// int height = 0; +// int width = 0; +// if (data[index] instanceof String[]) { +// String[] strings = (String[]) data[index++]; +// +// for (String shapedRecipes : strings) { +// ++width; +// height = shapedRecipes.length(); +// s = s + shapedRecipes; +// } +// } else { +// while (data[index] instanceof String) { +// String str = (String) data[index++]; +// ++width; +// height = str.length(); +// s = s + str; +// } +// } +// +// HashMap<Character, net.minecraft.server.v1_12_R1.ItemStack> charMap; +// for (charMap = Maps.newHashMap(); index < data.length; index += 2) { +// Character c = (Character) data[index]; +// net.minecraft.server.v1_12_R1.ItemStack stack = null; +// if (data[index + 1] instanceof ItemStack) +// stack = CraftItemStack.asNMSCopy((ItemStack) data[index + 1]); +// else if (data[index + 1] instanceof net.minecraft.server.v1_12_R1.Item) +// stack = new net.minecraft.server.v1_12_R1.ItemStack((net.minecraft.server.v1_12_R1.Item) data[index + 1]); +// else if (data[index + 1] instanceof net.minecraft.server.v1_12_R1.Block) +// stack = new net.minecraft.server.v1_12_R1.ItemStack((net.minecraft.server.v1_12_R1.Block) data[index + 1], 1, Short.MAX_VALUE); +// else if (data[index + 1] instanceof net.minecraft.server.v1_12_R1.ItemStack) +// stack = (net.minecraft.server.v1_12_R1.ItemStack) data[index + 1]; +// +// +// charMap.put(c, stack); +// } +// +// net.minecraft.server.v1_12_R1.ItemStack[] ingredients = new net.minecraft.server.v1_12_R1.ItemStack[height * width]; +// +// for (int j = 0; j < height * width; ++j) { +// char c = s.charAt(j); +// if (charMap.containsKey(c)) +// ingredients[j] = charMap.get(c).cloneItemStack(); +// else +// ingredients[j] = null; +// } +// +// net.minecraft.server.v1_12_R1.ShapedRecipes recipe = new net.minecraft.server.v1_12_R1.ShapedRecipes("test", height, width, ingredients, CraftItemStack.asNMSCopy(result)) { +// @Override public boolean a(net.minecraft.server.v1_12_R1.InventoryCrafting inventory, net.minecraft.server.v1_12_R1.World world) { +// for (int i = 0; i < ingredients.length; i++) { +// net.minecraft.server.v1_12_R1.ItemStack ingredient = ingredients[i]; +// net.minecraft.server.v1_12_R1.ItemStack found = inventory.getItem(i); +// if (ingredient == null) { +// if (found == null) +// continue; +// else +// return false; +// } +// +// if (found == null) +// return false; +// +// if (ingredient.getItem() != found.getItem() || ingredient.getData() != found.getData()) +// return false; +// +// if (ingredient.hasTag()) { +// if (!found.hasTag()) +// return false; +// +// if (!ingredient.getTag().equals(found.getTag())) +// return false; +// } +// } +// +// return true; +// } +// }; +// +// CraftingManager.a(new MinecraftKey(ItemManager.NAMESPACED_KEY.getKey()), recipe); +// } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/recipe/ShapelessRegister.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/recipe/ShapelessRegister.java new file mode 100644 index 0000000..6fc3556 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/utils/recipe/ShapelessRegister.java @@ -0,0 +1,156 @@ +package net.grandtheftmc.vice.utils.recipe; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.ShapelessRecipe; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class ShapelessRegister { + + private final NamespacedKey key; + private final ItemStack output; + private final List<ItemStack> ingredients = new ArrayList<>(); + + /** + * Create a shapeless recipe to craft the specified ItemStack. The + * constructor merely determines the result and type; to set the actual + * recipe, you'll need to call the appropriate methods. + * + * @param result The item you want the recipe to create. + * @see ShapelessRecipe#addIngredient(Material) + * @see ShapelessRecipe#addIngredient(int, Material) + * @see ShapelessRecipe#addIngredient(ItemStack) + * @see ShapelessRecipe#addIngredient(int, ItemStack) + */ + public ShapelessRegister(NamespacedKey key, ItemStack result) { + this.key = key; + output = new ItemStack(result); + } + + public ItemStack getOutput() { + return output.clone(); + } + + /** + * Adds the specified ingredient. + * + * @param ingredient The ingredient to add. + * @return The changed recipe, so you can chain calls. + */ + public ShapelessRegister addIngredient(Material mat) { + return addIngredient(1, mat); + } + + /** + * Adds multiples of the specified ingredient. + * + * @param count How many to add (can't be more than 9!) + * @param ingredient The ingredient to add. + * @return The changed recipe, so you can chain calls. + */ + public ShapelessRegister addIngredient(int count, Material mat) { + return addIngredient(count, new ItemStack(mat, 1)); + } + + /** + * Adds the specified ingredient. + * + * @param ingredient The ingredient to add. + * @return The changed recipe, so you can chain calls. + */ + public ShapelessRegister addIngredient(ItemStack item) { + return addIngredient(1, item); + } + + /** + * Adds multiples of the specified ingredient. + * + * @param count How many to add (can't be more than 9!) + * @param ingredient The ingredient to add. + * @return The changed recipe, so you can chain calls. + */ + public ShapelessRegister addIngredient(int count, ItemStack item) { + Validate.isTrue(ingredients.size() + count <= 9, "Shapeless recipes cannot have more than 9 ingredients"); + + while (count-- > 0) + ingredients.add(item); + + return this; + } + + /** + * Removes an ingredient from the list. If the ingredient occurs multiple + * times, only one instance of it is removed. + * + * @param ingredient The ingredient to remove + * @return The changed recipe. + */ + public ShapelessRegister removeIngredient(Material mat) { + return removeIngredient(1, mat); + } + + /** + * Removes multiple instances of an ingredient from the list. If there are + * less instances then specified, all will be removed. + * + * @param count The number of copies to remove. + * @param ingredient The ingredient to remove. + * @return The changed recipe. + */ + public ShapelessRegister removeIngredient(int count, Material mat) { + return removeIngredient(count, new ItemStack(mat, 1)); + } + + /** + * Removes an ingredient from the list. If the ingredient occurs multiple + * times, only one instance of it is removed. + * + * @param ingredient The ingredient to remove + * @return The changed recipe. + */ + public ShapelessRegister removeIngredient(ItemStack item) { + return removeIngredient(1, item); + } + + /** + * Removes multiple instances of an ingredient from the list. If there are + * less instances then specified, all will be removed. + * + * @param count The number of copies to remove. + * @param ingredient The ingredient to remove. + * @return The changed recipe. + */ + public ShapelessRegister removeIngredient(int count, ItemStack item) { + Iterator<ItemStack> iterator = ingredients.iterator(); + while (count > 0 && iterator.hasNext()) { + ItemStack stack = iterator.next(); + if (stack.isSimilar(item)) { + iterator.remove(); + count--; + } + } + return this; + } + + /** + * Registers the Recipe in the server. + */ + public void register() { + ShapelessRecipe sr = new ShapelessRecipe(key, output); + try { + Field f = sr.getClass().getDeclaredField("ingredients"); + f.setAccessible(true); + f.set(sr, ingredients); + Bukkit.addRecipe(sr); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/README.MD b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/README.MD new file mode 100644 index 0000000..c1e78cb --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/README.MD @@ -0,0 +1,61 @@ +# Weapons: + +### --Ranged: +<p><b>Pistols:</b><br> +Pistol 1<br> +StunGun 11<br> +CombatPistol 21<br> +HeavyPistol 31<br> +MarksmanPistol 41<br><br> + +<b>SMG:</b><br> +MicroSMG 51<br> +SMG 61<br> +AssaultSMG 71<br> +CombatPDW 81<br> +GusenbergSweeper 91<br><br> + +<b>Shotgun:</b><br> +SawedoffShotgun 101<br> +PumpShotgun 111<br> +Musket 121<br> +AssaultShotgun 131<br> +HeavyShotgun 141<br><br> + +<b>Assault:</b><br> +AssaultRifle 151<br> +CarbineRifle 161<br> +BullpupRifle 171<br> +AdvancedRifle 181<br> +SpecialCarbine 191<br><br> + +<b>LMG:</b><br> +MG 201<br> +CombatMG 211<br><br> + +<b>Sniper:</b><br> +SniperRifle 221<br> +HeavySniper 231<br><br> + +<b>Special:</b><br> +Minigun 241<br><br> + +<b>Launcher:</b><br> +RPG 251<br> +HomingLauncher 261<br> +GrenadeLauncher 271<br></p><br><br> + + +### --Melee: +<p>BaseballBat 281<br> +Chainsaw 291<br> +Knife 301<br> +NightStick 311<br> +Rake 321<br></p><br><br> + +### --Throwable: +<p>Grenade 331<br> +MolotovCocktail 341<br> +ProximityMine 351<br> +StickyBomb 361<br> +TearGas 371<br></p> diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/WeaponRegistry.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/WeaponRegistry.java new file mode 100644 index 0000000..bc88923 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/WeaponRegistry.java @@ -0,0 +1,96 @@ +package net.grandtheftmc.vice.weapon; + +import net.grandtheftmc.guns.WeaponManager; +import net.grandtheftmc.vice.weapon.explosive.*; +import net.grandtheftmc.vice.weapon.melee.*; +import net.grandtheftmc.vice.weapon.ranged.assault.*; +import net.grandtheftmc.vice.weapon.ranged.launcher.GrenadeLauncher; +import net.grandtheftmc.vice.weapon.ranged.launcher.HomingLauncher; +import net.grandtheftmc.vice.weapon.ranged.launcher.RPG; +import net.grandtheftmc.vice.weapon.ranged.launcher.NetLauncher; +import net.grandtheftmc.vice.weapon.ranged.lmg.CombatMG; +import net.grandtheftmc.vice.weapon.ranged.lmg.MG; +import net.grandtheftmc.vice.weapon.ranged.pistol.*; +import net.grandtheftmc.vice.weapon.ranged.shotgun.*; +import net.grandtheftmc.vice.weapon.ranged.smg.*; +import net.grandtheftmc.vice.weapon.ranged.sniper.HeavySniper; +import net.grandtheftmc.vice.weapon.ranged.sniper.SniperRifle; +import net.grandtheftmc.vice.weapon.ranged.special.Flamethrower; +import net.grandtheftmc.vice.weapon.ranged.special.GoldMinigun; +import net.grandtheftmc.vice.weapon.ranged.special.Minigun; + +import java.util.Arrays; + +/** + * Created by Luke Bingham on 25/07/2017. + */ +public class WeaponRegistry { + + public WeaponRegistry(WeaponManager weaponManager) { + weaponManager.registerWeapons(Arrays.asList( + + //PISTOL + new Pistol(), + new StunGun(), + new CombatPistol(), + new MarksmanPistol(), + new HeavyPistol(), + + //SMG + new SMG(), + new MicroSMG(), + new CombatPDW(), + new GusenbergSweeper(), + new AssaultSMG(), + + //SHOTGUN + new SawedoffShotgun(), + new PumpShotgun(), + new Musket(), + new AssaultShotgun(), + new HeavyShotgun(), + + //ASSAULT RIFLE + new AssaultRifle(), + new CarbineRifle(), + new BullpupRifle(), + new AdvancedRifle(), + new SpecialCarbine(), + + //LMG + new MG(), + new CombatMG(), + + //SNIPER + new SniperRifle(), + new HeavySniper(), + + //SPECIAL + new Minigun(), + new GoldMinigun(), + new NetLauncher(), + new Flamethrower(), + + //LAUNCHER + new RPG(), + new HomingLauncher(), + new GrenadeLauncher(), + + //MELEE + new Knife(), + new BaseballBat(), + new Rake(), + new NightStick(), + new Chainsaw(), + new Katana(), + new Dildo(), + + //THROWABLE + new Grenade(), + new MolotovCocktail(), + new ProximityMine(), + new StickyBomb(), + new TearGas() + )); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/airstrike/Airstrike.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/airstrike/Airstrike.java new file mode 100644 index 0000000..4411e4f --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/airstrike/Airstrike.java @@ -0,0 +1,34 @@ +package net.grandtheftmc.vice.weapon.airstrike; + +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AirstrikeWeapon; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponType; + +/** + * Created by Luke Bingham on 18/07/2017. + */ +public class Airstrike extends AirstrikeWeapon { + + /** + * Construct a new Weapon. + */ + public Airstrike() { + super( + (short) 51, + "Airstrke", //Name + WeaponType.DROPPABLE, //Weapon Type + AmmoType.NONE, //AmmoType + new ItemFactory(Material.WOOD_BUTTON).build(), //ItemStack + new Sound[] { + Sound.ENTITY_SKELETON_SHOOT, + Sound.ENTITY_BAT_TAKEOFF, + Sound.ENTITY_BAT_TAKEOFF, + Sound.ENTITY_GENERIC_EXPLODE + } + ); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/airstrike/Nuke.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/airstrike/Nuke.java new file mode 100644 index 0000000..73a516c --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/airstrike/Nuke.java @@ -0,0 +1,33 @@ +package net.grandtheftmc.vice.weapon.airstrike; + +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AirstrikeWeapon; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponType; + +/** + * Created by Luke Bingham on 18/07/2017. + */ +public class Nuke extends AirstrikeWeapon { + + /** + * Construct a new Weapon. + */ + public Nuke() { + super( + (short) 52, + "Nuke", //Name + WeaponType.DROPPABLE, //Weapon Type + AmmoType.NONE, //AmmoType + new ItemFactory(Material.WOOD_BUTTON).build(), //ItemStack + new Sound[] { + Sound.ENTITY_SKELETON_SHOOT, + Sound.ENTITY_BAT_TAKEOFF, + Sound.ENTITY_BAT_TAKEOFF, + } + ); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/explosive/Grenade.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/explosive/Grenade.java new file mode 100644 index 0000000..e8ee512 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/explosive/Grenade.java @@ -0,0 +1,46 @@ +package net.grandtheftmc.vice.weapon.explosive; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.ThrowableWeapon; +import net.grandtheftmc.guns.weapon.WeaponType; + +/** + * Created by Luke Bingham on 18/07/2017. + */ +public class Grenade extends ThrowableWeapon { + + /** + * Construct a new Weapon. + */ + public Grenade() { + super( + (short) 34, + "Grenade", //Name + WeaponType.THROWABLE, //Weapon Type + AmmoType.EXPLOSIVE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 331).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_SKELETON_SHOOT, + Sound.ENTITY_BAT_TAKEOFF, + Sound.ENTITY_BAT_TAKEOFF, + Sound.ENTITY_GENERIC_EXPLODE + } + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.FIREWORK_CHARGE).setName(getName()).build()); + setDescription("How to clear a room", "in 3..2..1."); + + this.particles = Effect.EXPLOSION_HUGE; + this.delay = 55; + this.damage = 3; + this.explosionSize = 5.0; + this.explosionDelay = 60; + this.explosionStrength = 2.0; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/explosive/MolotovCocktail.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/explosive/MolotovCocktail.java new file mode 100644 index 0000000..692d3bb --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/explosive/MolotovCocktail.java @@ -0,0 +1,48 @@ +package net.grandtheftmc.vice.weapon.explosive; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.ThrowableWeapon; +import net.grandtheftmc.guns.weapon.WeaponType; + +/** + * Created by Luke Bingham on 18/07/2017. + */ +public class MolotovCocktail extends ThrowableWeapon { + + /** + * Construct a new Weapon. + */ + public MolotovCocktail() { + super( + (short) 36, + "Molotov Cocktail", //Name + WeaponType.THROWABLE, //Weapon Type + AmmoType.EXPLOSIVE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 351).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_SKELETON_SHOOT, + Sound.ENTITY_BAT_TAKEOFF, + Sound.ENTITY_BAT_TAKEOFF, + Sound.ENTITY_GENERIC_EXPLODE + } + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.MAGMA_CREAM).setName(getName()).build()); + setDescription("Nothing says angst quite", "as much as a bottle of", "liquid fire."); + + this.particles = Effect.FLAME; + this.delay = 55; + this.flammable = true; + this.duration = 140; + this.damage = 1.0; + this.explosionSize = 5.0; + this.explosionDelay = 20; + this.explosionStrength = 0.3; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/explosive/ProximityMine.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/explosive/ProximityMine.java new file mode 100644 index 0000000..94bc632 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/explosive/ProximityMine.java @@ -0,0 +1,48 @@ +package net.grandtheftmc.vice.weapon.explosive; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.ThrowableWeapon; +import net.grandtheftmc.guns.weapon.WeaponType; + +/** + * Created by Luke Bingham on 18/07/2017. + */ +public class ProximityMine extends ThrowableWeapon { + + /** + * Construct a new Weapon. + */ + public ProximityMine() { + super( + (short) 38, + "Proximity Mine", //Name + WeaponType.THROWABLE, //Weapon Type + AmmoType.EXPLOSIVE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 371).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_SKELETON_SHOOT, + Sound.ENTITY_BAT_TAKEOFF, + Sound.ENTITY_BAT_TAKEOFF, + Sound.ENTITY_GENERIC_EXPLODE + } + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.GLOWSTONE_DUST).setName(getName()).build()); + setDescription("Enjoy your spawn camping..."); + + this.particles = Effect.EXPLOSION_HUGE; + this.delay = 40; + this.proximity = true; +// this.duration = 100; + this.damage = 3.0; + this.explosionSize = 3.0; + this.explosionDelay = 0; + this.explosionStrength = 3.0; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/explosive/StickyBomb.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/explosive/StickyBomb.java new file mode 100644 index 0000000..504ee56 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/explosive/StickyBomb.java @@ -0,0 +1,49 @@ +package net.grandtheftmc.vice.weapon.explosive; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.ThrowableWeapon; +import net.grandtheftmc.guns.weapon.WeaponType; + +/** + * Created by Luke Bingham on 18/07/2017. + */ +public class StickyBomb extends ThrowableWeapon { + + /** + * Construct a new Weapon. + */ + public StickyBomb() { + super( + (short) 37, + "Sticky Bomb", //Name + WeaponType.THROWABLE, //Weapon Type + AmmoType.EXPLOSIVE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 361).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_SKELETON_SHOOT, + Sound.ENTITY_BAT_TAKEOFF, + Sound.ENTITY_BAT_TAKEOFF, + Sound.ENTITY_GENERIC_EXPLODE + } + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.FIREBALL).setName(getName()).build()); + setDescription("It's like the explosion", "is hugging you!"); + + this.particles = Effect.EXPLOSION_HUGE; + this.delay = 40; + this.sticky = true; +// this.duration = 100; + this.damage = 3; + this.explosionSize = 3.0; + this.explosionDelay = 0; + this.tntFuseDelay = 80; + this.explosionStrength = 0.9; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/explosive/TearGas.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/explosive/TearGas.java new file mode 100644 index 0000000..4cb60d0 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/explosive/TearGas.java @@ -0,0 +1,48 @@ +package net.grandtheftmc.vice.weapon.explosive; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.ThrowableWeapon; +import net.grandtheftmc.guns.weapon.WeaponType; + +/** + * Created by Luke Bingham on 18/07/2017. + */ +public class TearGas extends ThrowableWeapon { + + /** + * Construct a new Weapon. + */ + public TearGas() { + super( + (short) 35, + "Tear Gas", //Name + WeaponType.THROWABLE, //Weapon Type + AmmoType.EXPLOSIVE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 341).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_SKELETON_SHOOT, + Sound.ENTITY_BAT_TAKEOFF, + Sound.ENTITY_BAT_TAKEOFF, + Sound.BLOCK_LAVA_EXTINGUISH + } + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.GHAST_TEAR).setName(getName()).build()); + setDescription("This will make them", "cry more than your ex."); + + this.particles = Effect.CLOUD; + this.delay = 55; + this.teargas = true; + this.duration = 140; + this.damage = 1.0; + this.explosionSize = 5.0; + this.explosionDelay = 20; + this.explosionStrength = 0.0; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/melee/BaseballBat.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/melee/BaseballBat.java new file mode 100644 index 0000000..d38f14c --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/melee/BaseballBat.java @@ -0,0 +1,57 @@ +package net.grandtheftmc.vice.weapon.melee; + +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.MeleeWeapon; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; + +/** + * Created by Luke Bingham on 18/07/2017. + */ +public class BaseballBat extends MeleeWeapon { + + /** + * Construct a new Weapon. + */ + public BaseballBat() { + super( + (short) 4, + "Baseball Bat", //Name + WeaponType.MELEE, //Weapon Type + AmmoType.MELEE, //AmmoType + + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 31).build(), //ItemStack + new Sound[] { //Sounds + Sound.ENTITY_PLAYER_ATTACK_STRONG, + Sound.ITEM_ARMOR_EQUIP_GENERIC, + Sound.ITEM_ARMOR_EQUIP_GENERIC + } + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.IRON_BARDING).setName(getName()).build()); + setDescription("Are you a cave man?"); + + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.delay = 7; + this.meleeDamage = 7.0; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/melee/Chainsaw.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/melee/Chainsaw.java new file mode 100644 index 0000000..4f47071 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/melee/Chainsaw.java @@ -0,0 +1,84 @@ +package net.grandtheftmc.vice.weapon.melee; + +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.MeleeWeapon; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.attribute.RankedWeapon; + +/** + * Created by Luke Bingham on 18/07/2017. + */ +public class Chainsaw extends MeleeWeapon implements RankedWeapon { + + /** + * Construct a new Weapon. + */ + public Chainsaw() { + super( + (short) 5, + "Chainsaw", //Name + WeaponType.MELEE, //Weapon Type + AmmoType.ENERGY, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 41).build(), //ItemStack + new Sound[] { //Sounds + Sound.ENTITY_WOLF_GROWL, + Sound.ITEM_ARMOR_EQUIP_GENERIC, + Sound.ITEM_ARMOR_EQUIP_GENERIC + } + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.DIAMOND_BARDING).setName(getName()).build()); + setDescription("A chainsaw?", "You absolute monster!"); + + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.delay = 5; + this.meleeDamage = 7.0; + this.range = 1.5; + } + + /*@Override + public void onRightClick(Player player) { + ServerUtil.debug("20"); + MathUtil.getNearbyEntities(player, this.range).forEach(e -> { + ServerUtil.debug("21"); + if (player.hasLineOfSight(e)) { + ServerUtil.debug("they have line of sight.2"); + Vector toEntity = e.getLocation().toVector().subtract(player.getLocation().toVector()); + double dot = toEntity.normalize().dot(player.getLocation().getDirection()); + ServerUtil.debug(dot + " / dot2"); + if (dot <= 1 && dot >= 0) { + ServerUtil.debug("yup.2"); + e.setNoDamageTicks(0); + e.damage(getMeleeDamage(), player); + } + } + }); + Sounds.broadcastSound(getSounds()[0], player.getEyeLocation()); + }//todo: moved to the meleeweapon class, don't know why this isn't working.*/ + + @Override + public UserRank requiredRank() { + return UserRank.PREMIUM; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/melee/Dildo.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/melee/Dildo.java new file mode 100644 index 0000000..22bc9cc --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/melee/Dildo.java @@ -0,0 +1,57 @@ +package net.grandtheftmc.vice.weapon.melee; + +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.MeleeWeapon; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; + +/** + * Created by Luke Bingham on 03/08/2017. + */ +public class Dildo extends MeleeWeapon { + + /** + * Construct a new Weapon. + */ + public Dildo() { + super( + (short) 41, + "Dildo", //Name + WeaponType.MELEE, //Weapon Type + AmmoType.MELEE, //AmmoType + + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 401).build(), //ItemStack + new Sound[] { //Sounds + Sound.ENTITY_PLAYER_ATTACK_STRONG, + Sound.ITEM_ARMOR_EQUIP_GENERIC, + Sound.ITEM_ARMOR_EQUIP_GENERIC + } + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.SAPLING, (byte) 1).setName(getName()).build()); + setDescription("Certified 'me time'."); + + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.delay = 7; + this.meleeDamage = 8.0; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/melee/Katana.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/melee/Katana.java new file mode 100644 index 0000000..5ea6aea --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/melee/Katana.java @@ -0,0 +1,57 @@ +package net.grandtheftmc.vice.weapon.melee; + +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.MeleeWeapon; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; + +/** + * Created by Luke Bingham on 03/08/2017. + */ +public class Katana extends MeleeWeapon { + + /** + * Construct a new Weapon. + */ + public Katana() { + super( + (short) 43, + "Katana", //Name + WeaponType.MELEE, //Weapon Type + AmmoType.MELEE, //AmmoType + + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 421).build(), //ItemStack + new Sound[] { //Sounds + Sound.ENTITY_PLAYER_ATTACK_STRONG, + Sound.ITEM_ARMOR_EQUIP_GENERIC, + Sound.ITEM_ARMOR_EQUIP_GENERIC + } + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.FLINT_AND_STEEL).setDurability((short) 56).setName(getName()).build()); + setDescription("An cold-iron forged,", "ancient Japanese samurai sword"); + + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.delay = 12; + this.meleeDamage = 11.0; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/melee/Knife.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/melee/Knife.java new file mode 100644 index 0000000..212c065 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/melee/Knife.java @@ -0,0 +1,56 @@ +package net.grandtheftmc.vice.weapon.melee; + +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.MeleeWeapon; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; + +/** + * Created by Luke Bingham on 18/07/2017. + */ +public class Knife extends MeleeWeapon { + + /** + * Construct a new Weapon. + */ + public Knife() { + super( + (short) 3, + "Knife", //Name + WeaponType.MELEE, //Weapon Type + AmmoType.MELEE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 21).build(), //ItemStack + new Sound[] { //Sounds + Sound.ENTITY_SKELETON_SHOOT, + Sound.ITEM_ARMOR_EQUIP_GENERIC, + Sound.ITEM_ARMOR_EQUIP_GENERIC + } + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.GOLD_BARDING).setName(getName()).build()); + setDescription("Don't bring a knife", "to a gun fight."); + + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.delay = 7; + this.meleeDamage = 8.0; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/melee/NightStick.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/melee/NightStick.java new file mode 100644 index 0000000..73b644a --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/melee/NightStick.java @@ -0,0 +1,56 @@ +package net.grandtheftmc.vice.weapon.melee; + +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.MeleeWeapon; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; + +/** + * Created by Luke Bingham on 18/07/2017. + */ +public class NightStick extends MeleeWeapon { + + /** + * Construct a new Weapon. + */ + public NightStick() { + super( + (short) 2, + "Night Stick", //Name + WeaponType.MELEE, //Weapon Type + AmmoType.MELEE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 11).build(), //ItemStack + new Sound[] { //Sounds + Sound.ENTITY_PLAYER_ATTACK_WEAK, + Sound.ITEM_ARMOR_EQUIP_GENERIC, + Sound.ITEM_ARMOR_EQUIP_GENERIC + } + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.BLAZE_ROD).setName(getName()).build()); + setDescription("Enjoy trying to beat", "armed criminals to death."); + + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.delay = 5; + this.meleeDamage = 7.0; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/melee/Rake.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/melee/Rake.java new file mode 100644 index 0000000..bdbf380 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/melee/Rake.java @@ -0,0 +1,56 @@ +package net.grandtheftmc.vice.weapon.melee; + +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.MeleeWeapon; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; + +/** + * Created by Luke Bingham on 18/07/2017. + */ +public class Rake extends MeleeWeapon { + + /** + * Construct a new Weapon. + */ + public Rake() { + super( + (short) 1, + "Rake", //Name + WeaponType.MELEE, //Weapon Type + AmmoType.MELEE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 1).build(), //ItemStack + new Sound[] { //Sounds + Sound.ENTITY_PLAYER_ATTACK_NODAMAGE, + Sound.ITEM_ARMOR_EQUIP_GENERIC, + Sound.ITEM_ARMOR_EQUIP_GENERIC + } + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.STICK).setName(getName()).build()); + setDescription("This...isn't even a", "proper weapon."); + + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.delay = 6; + this.meleeDamage = 5; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/assault/AdvancedRifle.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/assault/AdvancedRifle.java new file mode 100644 index 0000000..370eccf --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/assault/AdvancedRifle.java @@ -0,0 +1,70 @@ +package net.grandtheftmc.vice.weapon.ranged.assault; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.AssultRifleWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class AdvancedRifle extends AssultRifleWeapon { + /** + * Construct a new RangedWeapon. + */ + public AdvancedRifle() { + super( + (short) 24, + "Advanced Rifle", //Name + WeaponType.ASSAULT, //Weapon Type + AmmoType.ASSAULT_RIFLE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 231).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_ITEM_BREAK, + Sound.ITEM_ARMOR_EQUIP_IRON, + Sound.ITEM_ARMOR_EQUIP_IRON, + Sound.ENTITY_SKELETON_AMBIENT, + }, + Effect.VOID_FOG //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.STONE_AXE).setName(getName()).build()); + setDescription("Bit egotistical to name", "your gun 'advanced', no?"); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.18; //Weapon + + this.damage = 8.0; //RangedWeapon + this.meleeDamage = 5.0; //RangedWeapon + this.accuracy = 0.02; //RangedWeapon + this.magSize = 30; //RangedWeapon + this.reloadTime = 35; //RangedWeapon + this.range = 45; //RangedWeapon + this.recoil = 0.2; //RangedWeapon + this.zoom = 3; //RangedWeapon + + this.rpm = 500; //AssultRifleWeapon + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/assault/AssaultRifle.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/assault/AssaultRifle.java new file mode 100644 index 0000000..6cbf1d7 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/assault/AssaultRifle.java @@ -0,0 +1,70 @@ +package net.grandtheftmc.vice.weapon.ranged.assault; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.AssultRifleWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class AssaultRifle extends AssultRifleWeapon { + /** + * Construct a new RangedWeapon. + */ + public AssaultRifle() { + super( + (short) 21, + "Assault Rifle", //Name + WeaponType.ASSAULT, //Weapon Type + AmmoType.ASSAULT_RIFLE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 201).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_ITEM_BREAK, + Sound.ITEM_ARMOR_EQUIP_IRON, + Sound.ITEM_ARMOR_EQUIP_IRON, + Sound.ENTITY_SKELETON_AMBIENT, + }, + Effect.VOID_FOG //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.STONE_SWORD).setName(getName()).build()); + setDescription("Great stock weapon for", "medium range gunfights."); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.18; //Weapon + + this.damage = 6.0; //RangedWeapon + this.meleeDamage = 5.0; //RangedWeapon + this.accuracy = 0.022; //RangedWeapon + this.magSize = 30; //RangedWeapon + this.reloadTime = 40; //RangedWeapon + this.range = 45; //RangedWeapon + this.recoil = 0.4; //RangedWeapon + this.zoom = 3; //RangedWeapon + + this.rpm = 380; //AssultRifleWeapon + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/assault/BullpupRifle.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/assault/BullpupRifle.java new file mode 100644 index 0000000..c5d9395 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/assault/BullpupRifle.java @@ -0,0 +1,70 @@ +package net.grandtheftmc.vice.weapon.ranged.assault; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.AssultRifleWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class BullpupRifle extends AssultRifleWeapon { + /** + * Construct a new RangedWeapon. + */ + public BullpupRifle() { + super( + (short) 23, + "Bullpup Rifle", //Name + WeaponType.ASSAULT, //Weapon Type + AmmoType.ASSAULT_RIFLE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 221).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_ITEM_BREAK, + Sound.ITEM_ARMOR_EQUIP_IRON, + Sound.ITEM_ARMOR_EQUIP_IRON, + Sound.ENTITY_SKELETON_AMBIENT, + }, + Effect.VOID_FOG //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.STONE_PICKAXE).setName(getName()).build()); + setDescription("It's a bit like the", "normal AR, but Chinese..", "很好!"); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.18; //Weapon + + this.damage = 7.0; //RangedWeapon + this.meleeDamage = 5.0; //RangedWeapon + this.accuracy = 0.016; //RangedWeapon + this.magSize = 30; //RangedWeapon + this.reloadTime = 40; //RangedWeapon + this.range = 45; //RangedWeapon + this.recoil = 0.3; //RangedWeapon + this.zoom = 2; //RangedWeapon + + this.rpm = 500; //AssultRifleWeapon + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/assault/CarbineRifle.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/assault/CarbineRifle.java new file mode 100644 index 0000000..125fe65 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/assault/CarbineRifle.java @@ -0,0 +1,70 @@ +package net.grandtheftmc.vice.weapon.ranged.assault; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.AssultRifleWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class CarbineRifle extends AssultRifleWeapon { + /** + * Construct a new RangedWeapon. + */ + public CarbineRifle() { + super( + (short) 22, + "Carbine Rifle", //Name + WeaponType.ASSAULT, //Weapon Type + AmmoType.ASSAULT_RIFLE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 211).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_ITEM_BREAK, + Sound.ITEM_ARMOR_EQUIP_IRON, + Sound.ITEM_ARMOR_EQUIP_IRON, + Sound.ENTITY_SKELETON_AMBIENT, + }, + Effect.VOID_FOG //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.STONE_SPADE).setName(getName()).build()); + setDescription("A longer range version", "of your stock AR."); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.18; //Weapon + + this.damage = 7.0; //RangedWeapon + this.meleeDamage = 5.0; //RangedWeapon + this.accuracy = 0.018; //RangedWeapon + this.magSize = 30; //RangedWeapon + this.reloadTime = 40; //RangedWeapon + this.range = 45; //RangedWeapon + this.recoil = 0.4; //RangedWeapon + this.zoom = 2; //RangedWeapon + + this.rpm = 445; //AssultRifleWeapon + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/assault/SpecialCarbine.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/assault/SpecialCarbine.java new file mode 100644 index 0000000..80f1076 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/assault/SpecialCarbine.java @@ -0,0 +1,77 @@ +package net.grandtheftmc.vice.weapon.ranged.assault; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.attribute.RankedWeapon; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.AssultRifleWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class SpecialCarbine extends AssultRifleWeapon implements RankedWeapon { + /** + * Construct a new RangedWeapon. + */ + public SpecialCarbine() { + super( + (short) 25, + "Special Carbine", //Name + WeaponType.ASSAULT, //Weapon Type + AmmoType.ASSAULT_RIFLE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 241).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_ITEM_BREAK, + Sound.ITEM_ARMOR_EQUIP_IRON, + Sound.ITEM_ARMOR_EQUIP_IRON, + Sound.ENTITY_SKELETON_AMBIENT, + }, + Effect.VOID_FOG //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.STONE_HOE).setName(getName()).build()); + setDescription("Super solid gun choice;", "very versatile."); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.18; //Weapon + + this.damage = 9.0; //RangedWeapon + this.meleeDamage = 5.0; //RangedWeapon + this.accuracy = 0.016; //RangedWeapon + this.magSize = 30; //RangedWeapon + this.reloadTime = 35; //RangedWeapon + this.range = 45; //RangedWeapon + this.recoil = 0.2; //RangedWeapon + this.zoom = 2; //RangedWeapon + + this.rpm = 445; //AssultRifleWeapon + } + + @Override + public UserRank requiredRank() { + return UserRank.ELITE; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/launcher/GrenadeLauncher.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/launcher/GrenadeLauncher.java new file mode 100644 index 0000000..416d72e --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/launcher/GrenadeLauncher.java @@ -0,0 +1,81 @@ +package net.grandtheftmc.vice.weapon.ranged.launcher; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.attribute.RankedWeapon; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.LauncherWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class GrenadeLauncher extends LauncherWeapon implements RankedWeapon { + + /** + * Construct a new RangedWeapon. + */ + public GrenadeLauncher() { + super( + (short) 31, + "Grenade Launcher", //Name + WeaponType.LAUNCHER, //Weapon Type + AmmoType.GRENADE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 301).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_CHICKEN_EGG, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.BLOCK_PISTON_CONTRACT, + }, + Effect.FIREWORKS_SPARK //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.SHEARS).setName(getName()).build()); + setDescription("For if your throwing", "game is weak " + (Core.getSettings().isSister() ? "." : "AF.")); + + setSupportedAttachments(Attachment.GRIP); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.12; //Weapon + this.delay = 20; + + this.damage = 350.0; //RangedWeapon + this.meleeDamage = 6.0; //RangedWeapon + this.accuracy = 0.005; //RangedWeapon + this.magSize = 6; //RangedWeapon + this.reloadTime = 50; //RangedWeapon + this.range = 50; //RangedWeapon + this.recoil = 0.5; //RangedWeapon + this.zoom = 1; //RangedWeapon + + this.blowOnHit = false; //LauncherWeapon + this.blowDelay = 5; + } + + @Override + public UserRank requiredRank() { + return UserRank.SPONSOR; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/launcher/HomingLauncher.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/launcher/HomingLauncher.java new file mode 100644 index 0000000..89bbfc9 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/launcher/HomingLauncher.java @@ -0,0 +1,82 @@ +package net.grandtheftmc.vice.weapon.ranged.launcher; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.attribute.RankedWeapon; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.LauncherWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class HomingLauncher extends LauncherWeapon implements RankedWeapon { + + /** + * Construct a new RangedWeapon. + */ + public HomingLauncher() { + super( + (short) 32, + "Homing Launcher", //Name + WeaponType.LAUNCHER, //Weapon Type + AmmoType.ROCKET, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 311).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_FIREWORK_LAUNCH, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.BLOCK_PISTON_CONTRACT, + }, + Effect.FIREWORKS_SPARK //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.SULPHUR).setName(getName()).build()); + setDescription("Imagine a homing pidgeon.", "But it explodes."); + + setSupportedAttachments(Attachment.GRIP); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.12; //Weapon + this.delay = 60; + + this.damage = 350.0; //RangedWeapon + this.meleeDamage = 7.0; //RangedWeapon + this.accuracy = 0.005; //RangedWeapon + this.magSize = 1; //RangedWeapon + this.reloadTime = 60; //RangedWeapon + this.range = 70; //RangedWeapon + this.recoil = 1.0; //RangedWeapon + this.zoom = 1; //RangedWeapon + + this.homingLauncher = true; //LauncherWeapon + this.rocketSpeed = 1.0; //LauncherWeapon + this.explosionSize = 5.0; //LauncherWeapon + this.explosionStrength = 1.7; //LauncherWeapon + } + + @Override + public UserRank requiredRank() { + return UserRank.SUPREME; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/launcher/NetLauncher.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/launcher/NetLauncher.java new file mode 100644 index 0000000..87bb8c0 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/launcher/NetLauncher.java @@ -0,0 +1,73 @@ +package net.grandtheftmc.vice.weapon.ranged.launcher; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.LauncherWeapon; + +/** + * Created by Luke Bingham on 03/08/2017. + */ +public class NetLauncher extends LauncherWeapon { + + /** + * Construct a new RangedWeapon. + */ + public NetLauncher() { + super( + (short) 39, + "Net Launcher", //Name + WeaponType.NETGUN, //TODO Weapon Type + AmmoType.ROCKET, //TODO AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 381).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_SHULKER_SHOOT, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.BLOCK_PISTON_CONTRACT, + }, + Effect.BLAZE_SHOOT //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.SAPLING).setName(getName()).build()); + setDescription("It's like discount,", (Core.getSettings().isSister() ? "weak" : "shitty") + " spiderman."); + + setSupportedAttachments(Attachment.GRIP); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.12; //Weapon + this.delay = 50; + + this.damage = 2.5; //RangedWeapon + this.meleeDamage = 8.0; //RangedWeapon + this.accuracy = 0.005; //RangedWeapon + this.magSize = 4; //RangedWeapon + this.reloadTime = 80; //RangedWeapon + this.range = 35; //RangedWeapon + this.recoil = 1.0; //RangedWeapon + this.zoom = 1; //RangedWeapon + + //this.netgun = true; //Launcher weapon todo: disabled because it was updating the actual class, now it just uses getName().equalsignorecase("net launcher") + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/launcher/RPG.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/launcher/RPG.java new file mode 100644 index 0000000..90401c5 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/launcher/RPG.java @@ -0,0 +1,74 @@ +package net.grandtheftmc.vice.weapon.ranged.launcher; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.LauncherWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class RPG extends LauncherWeapon { + + /** + * Construct a new RangedWeapon. + */ + public RPG() { + super( + (short) 30, + "RPG", //Name + WeaponType.LAUNCHER, //Weapon Type + AmmoType.ROCKET, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 291).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_FIREWORK_LAUNCH, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.BLOCK_PISTON_CONTRACT, + }, + Effect.FIREWORKS_SPARK //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.FEATHER).setName(getName()).build()); + setDescription("Want to take out", "the side of a building?", "Use this."); + + setSupportedAttachments(Attachment.GRIP); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.12; //Weapon + this.delay = 80; + + this.damage = 350.0; //RangedWeapon + this.meleeDamage = 7.0; //RangedWeapon + this.accuracy = 0.045; //RangedWeapon + this.magSize = 1; //RangedWeapon + this.reloadTime = 80; //RangedWeapon + this.range = 70; //RangedWeapon + this.recoil = 1.0; //RangedWeapon + this.zoom = 1; //RangedWeapon + + this.rocketSpeed = 4.0; //LauncherWeapon + this.explosionSize = 5.0; //LauncherWeapon + this.explosionStrength = 1.7; //LauncherWeapon + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/lmg/CombatMG.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/lmg/CombatMG.java new file mode 100644 index 0000000..bd0aa9d --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/lmg/CombatMG.java @@ -0,0 +1,79 @@ +package net.grandtheftmc.vice.weapon.ranged.lmg; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.attribute.RankedWeapon; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.LMGWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class CombatMG extends LMGWeapon implements RankedWeapon { + + /** + * Construct a new RangedWeapon. + */ + public CombatMG() { + super( + (short) 27, + "Combat MG", //Name + WeaponType.LMG, //Weapon Type + AmmoType.LMG, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 261).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.BLOCK_NOTE_SNARE, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ENTITY_SKELETON_STEP, + }, + Effect.VOID_FOG //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.DIAMOND_SPADE).setName(getName()).build()); + setDescription("Cover me,", "I'm going in! (Military style)"); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.14; //Weapon + this.delay = 5; + + this.damage = 9.0; //RangedWeapon + this.meleeDamage = 6.0; //RangedWeapon + this.accuracy = 0.02; //RangedWeapon + this.magSize = 100; //RangedWeapon + this.reloadTime = 50; //RangedWeapon + this.range = 60; //RangedWeapon + this.recoil = 0.1; //RangedWeapon + this.zoom = 5; //RangedWeapon + + this.rpm = 550; //LMGWeapon + } + + @Override + public UserRank requiredRank() { + return UserRank.SPONSOR; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/lmg/MG.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/lmg/MG.java new file mode 100644 index 0000000..47f43ee --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/lmg/MG.java @@ -0,0 +1,72 @@ +package net.grandtheftmc.vice.weapon.ranged.lmg; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.LMGWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class MG extends LMGWeapon { + + /** + * Construct a new RangedWeapon. + */ + public MG() { + super( + (short) 26, + "MG", //Name + WeaponType.LMG, //Weapon Type + AmmoType.LMG, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 251).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.BLOCK_NOTE_SNARE, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ENTITY_SKELETON_STEP, + }, + Effect.VOID_FOG //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.DIAMOND_SWORD).setName(getName()).build()); + setDescription("Cover me,", "I'm going in!"); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.14; //Weapon + this.delay = 5; + + this.damage = 8.0; //RangedWeapon + this.meleeDamage = 6.0; //RangedWeapon + this.accuracy = 0.025; //RangedWeapon + this.magSize = 54; //RangedWeapon + this.reloadTime = 60; //RangedWeapon + this.range = 60; //RangedWeapon + this.recoil = 0.2; //RangedWeapon + this.zoom = 3; //RangedWeapon + + this.rpm = 440; //LMGWeapon + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/pistol/CombatPistol.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/pistol/CombatPistol.java new file mode 100644 index 0000000..2fdfd43 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/pistol/CombatPistol.java @@ -0,0 +1,69 @@ +package net.grandtheftmc.vice.weapon.ranged.pistol; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.PistolWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class CombatPistol extends PistolWeapon { + + /** + * Construct a new RangedWeapon. + */ + public CombatPistol() { + super( + (short) 8, + "Combat Pistol", //Name + WeaponType.PISTOL, //Weapon Type + AmmoType.PISTOL, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 71).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_FIREWORK_BLAST, + Sound.ITEM_ARMOR_EQUIP_LEATHER, + Sound.ITEM_ARMOR_EQUIP_LEATHER, + Sound.BLOCK_NOTE_HAT, + }, + Effect.CRIT //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.WOOD_PICKAXE).setName(getName()).build()); + setDescription("Standard Military grade", "Pistol, Don't bring it", "to a proper gunfight."); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.2; //Weapon + this.delay = 7; //Weapon + + this.damage = 6.0; //RangedWeapon + this.meleeDamage = 3.0; //RangedWeapon + this.accuracy = 0.02; //RangedWeapon + this.magSize = 12; //RangedWeapon + this.reloadTime = 30; //RangedWeapon + this.range = 30; //RangedWeapon + this.zoom = 3; //RangedWeapon + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/pistol/HeavyPistol.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/pistol/HeavyPistol.java new file mode 100644 index 0000000..7ad33ef --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/pistol/HeavyPistol.java @@ -0,0 +1,70 @@ +package net.grandtheftmc.vice.weapon.ranged.pistol; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.PistolWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class HeavyPistol extends PistolWeapon { + + /** + * Construct a new RangedWeapon. + */ + public HeavyPistol() { + super( + (short) 9, + "Heavy Pistol", //Name + WeaponType.PISTOL, //Weapon Type + AmmoType.PISTOL, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 81).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_FIREWORK_BLAST, + Sound.ITEM_ARMOR_EQUIP_LEATHER, + Sound.ITEM_ARMOR_EQUIP_LEATHER, + Sound.BLOCK_NOTE_HAT, + }, + Effect.CRIT //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.WOOD_AXE).setName(getName()).build()); + setDescription("Like the" + (Core.getSettings().isSister() ? "" : " bitch") + " basic", "pistol, but bigger.", "And badder."); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.2; //Weapon + this.delay = 8; //Weapon + + this.damage = 8.0; //RangedWeapon + this.meleeDamage = 4.0; //RangedWeapon + this.accuracy = 0.02; //RangedWeapon + this.magSize = 18; //RangedWeapon + this.reloadTime = 40; //RangedWeapon + this.range = 30; //RangedWeapon + this.zoom = 3; //RangedWeapon + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/pistol/MarksmanPistol.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/pistol/MarksmanPistol.java new file mode 100644 index 0000000..549c1a3 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/pistol/MarksmanPistol.java @@ -0,0 +1,74 @@ +package net.grandtheftmc.vice.weapon.ranged.pistol; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.attribute.RankedWeapon; +import net.grandtheftmc.guns.weapon.ranged.guns.PistolWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class MarksmanPistol extends PistolWeapon implements RankedWeapon { + + /** + * Construct a new RangedWeapon. + */ + public MarksmanPistol() { + super( + (short) 10, + "Marksman Pistol", //Name + WeaponType.PISTOL, //Weapon Type + AmmoType.PISTOL, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 91).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_FIREWORK_BLAST, + Sound.ITEM_ARMOR_EQUIP_LEATHER, + Sound.ITEM_ARMOR_EQUIP_LEATHER, + Sound.BLOCK_NOTE_HAT, + }, + Effect.CRIT //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.WOOD_HOE).setName(getName()).build()); + setDescription("For when you can't afford", "a real sniper rifle."); + + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.2; //Weapon + this.delay = 57; //Weapon + + this.damage = 20.0; //RangedWeapon + this.meleeDamage = 4.0; //RangedWeapon + this.accuracy = 0.035; //RangedWeapon + this.magSize = 1; //RangedWeapon + this.reloadTime = 100; //RangedWeapon + this.range = 10; //RangedWeapon + this.zoom = 4; //RangedWeapon + } + + @Override + public UserRank requiredRank() { + return UserRank.VIP; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/pistol/Pistol.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/pistol/Pistol.java new file mode 100644 index 0000000..fc68c80 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/pistol/Pistol.java @@ -0,0 +1,70 @@ +package net.grandtheftmc.vice.weapon.ranged.pistol; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.PistolWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class Pistol extends PistolWeapon { + + /** + * Construct a new RangedWeapon. + */ + public Pistol() { + super( + (short) 6, + "Pistol", //Name + WeaponType.PISTOL, //Weapon Type + AmmoType.PISTOL, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 51).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_FIREWORK_BLAST, + Sound.ITEM_ARMOR_EQUIP_LEATHER, + Sound.ITEM_ARMOR_EQUIP_LEATHER, + Sound.BLOCK_NOTE_HAT, + }, + Effect.WITHER_BREAK_BLOCK //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.WOOD_SWORD).setName(getName()).build()); + setDescription((Core.getSettings().isSister() ? "." : "Bitch ") + "basic pistol,", "great for scaring the cat"); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.2; //Weapon + this.delay = 7; //Weapon + + this.damage = 5.0; //RangedWeapon + this.meleeDamage = 3.0; //RangedWeapon + this.accuracy = 0.025; //RangedWeapon + this.magSize = 12; //RangedWeapon + this.reloadTime = 40; //RangedWeapon + this.range = 25; //RangedWeapon + this.zoom = 4; //RangedWeapon + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/pistol/StunGun.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/pistol/StunGun.java new file mode 100644 index 0000000..7733329 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/pistol/StunGun.java @@ -0,0 +1,73 @@ +package net.grandtheftmc.vice.weapon.ranged.pistol; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.PistolWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class StunGun extends PistolWeapon { + + /** + * Construct a new RangedWeapon. + */ + public StunGun() { + super( + (short) 7, + "Stun Gun", //Name + WeaponType.PISTOL, //Weapon Type + AmmoType.NONE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 61).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.BLOCK_DISPENSER_DISPENSE, + Sound.ITEM_ARMOR_EQUIP_LEATHER, + Sound.ITEM_ARMOR_EQUIP_LEATHER, + Sound.BLOCK_NOTE_HAT, + }, + Effect.MAGIC_CRIT //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.WOOD_SPADE).setName(getName()).build()); + setDescription("Nothing quite like", "50,000 volts straight", "to the " + (Core.getSettings().isSister() ? "head." : "nipples.")); + + setSupportedAttachments(Attachment.GRIP); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.2; //Weapon + this.delay = 57; //Weapon + + this.damage = 1.0; //RangedWeapon + this.meleeDamage = 3.0; //RangedWeapon + this.accuracy = 0.008; //RangedWeapon + this.magSize = 1; //RangedWeapon + this.reloadTime = 60; //RangedWeapon + this.range = 10; //RangedWeapon + this.zoom = 0; //RangedWeapon + + this.stun = true; //PistolWeapon + this.duration = 80; //PistolWeapon + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/shotgun/AssaultShotgun.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/shotgun/AssaultShotgun.java new file mode 100644 index 0000000..3406216 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/shotgun/AssaultShotgun.java @@ -0,0 +1,72 @@ +package net.grandtheftmc.vice.weapon.ranged.shotgun; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.ShotgunWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class AssaultShotgun extends ShotgunWeapon { + + /** + * Construct a new RangedWeapon. + */ + public AssaultShotgun() { + super( + (short) 19, + "Assault Shotgun", //Name + WeaponType.SHOTGUN, //Weapon Type + AmmoType.SHOTGUN, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 181).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_ZOMBIE_ATTACK_DOOR_WOOD, + Sound.ITEM_ARMOR_EQUIP_CHAIN, + Sound.ITEM_ARMOR_EQUIP_CHAIN, + Sound.ENTITY_IRONGOLEM_ATTACK, + }, + Effect.SMOKE //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.GOLD_AXE).setName(getName()).build()); + setDescription("Aggressive? Yes.", "Overkill? Most definitely."); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.14; //Weapon + this.delay = 5; + + this.damage = 5.75; //RangedWeapon + this.meleeDamage = 5.0; //RangedWeapon + this.accuracy = 0.018; //RangedWeapon + this.magSize = 8; //RangedWeapon + this.reloadTime = 40; //RangedWeapon + this.range = 20; //RangedWeapon + this.recoil = 0.5; //RangedWeapon + this.zoom = 2; //RangedWeapon + + this.shellSize = 3; //AssultRifleWeapon + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/shotgun/HeavyShotgun.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/shotgun/HeavyShotgun.java new file mode 100644 index 0000000..47b8343 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/shotgun/HeavyShotgun.java @@ -0,0 +1,79 @@ +package net.grandtheftmc.vice.weapon.ranged.shotgun; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.attribute.RankedWeapon; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.ShotgunWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class HeavyShotgun extends ShotgunWeapon implements RankedWeapon { + + /** + * Construct a new RangedWeapon. + */ + public HeavyShotgun() { + super( + (short) 20, + "Heavy Shotgun", //Name + WeaponType.SHOTGUN, //Weapon Type + AmmoType.SHOTGUN, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 191).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_ZOMBIE_ATTACK_DOOR_WOOD, + Sound.ITEM_ARMOR_EQUIP_CHAIN, + Sound.ITEM_ARMOR_EQUIP_CHAIN, + Sound.ENTITY_IRONGOLEM_ATTACK, + }, + Effect.SMOKE //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.GOLD_HOE).setName(getName()).build()); + setDescription("Like your normal shotgun,", "but even heftier."); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.12; //Weapon + this.delay = 6; + + this.damage = 6.25; //RangedWeapon + this.meleeDamage = 6.0; //RangedWeapon + this.accuracy = 0.022; //RangedWeapon + this.magSize = 6; //RangedWeapon + this.reloadTime = 40; //RangedWeapon + this.range = 20; //RangedWeapon + this.recoil = 0.6; //RangedWeapon + this.zoom = 3; //RangedWeapon + + this.shellSize = 3; //AssultRifleWeapon + } + + @Override + public UserRank requiredRank() { + return UserRank.VIP; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/shotgun/Musket.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/shotgun/Musket.java new file mode 100644 index 0000000..a7b4b48 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/shotgun/Musket.java @@ -0,0 +1,70 @@ +package net.grandtheftmc.vice.weapon.ranged.shotgun; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.guns.ShotgunWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class Musket extends ShotgunWeapon { + + /** + * Construct a new RangedWeapon. + */ + public Musket() { + super( + (short) 18, + "Musket", //Name + WeaponType.SHOTGUN, //Weapon Type + AmmoType.SHOTGUN, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 171).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_ZOMBIE_ATTACK_DOOR_WOOD, + Sound.ITEM_ARMOR_EQUIP_CHAIN, + Sound.ITEM_ARMOR_EQUIP_CHAIN, + Sound.ENTITY_IRONGOLEM_ATTACK, + }, + Effect.SMOKE //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.GOLD_PICKAXE).setName(getName()).build()); + setDescription("Great if you want to", "roleplay a battle in 1776"); + + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.14; //Weapon + this.delay = 92; + + this.damage = 37.5; //RangedWeapon + this.meleeDamage = 4.0; //RangedWeapon + this.accuracy = 0.025; //RangedWeapon + this.magSize = 1; //RangedWeapon + this.reloadTime = 100; //RangedWeapon + this.range = 25; //RangedWeapon + this.recoil = 1.0; //RangedWeapon + this.zoom = 4; //RangedWeapon + + this.shellSize = 1; //AssultRifleWeapon + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/shotgun/PumpShotgun.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/shotgun/PumpShotgun.java new file mode 100644 index 0000000..291eb07 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/shotgun/PumpShotgun.java @@ -0,0 +1,71 @@ +package net.grandtheftmc.vice.weapon.ranged.shotgun; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.guns.ShotgunWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class PumpShotgun extends ShotgunWeapon { + + /** + * Construct a new RangedWeapon. + */ + public PumpShotgun() { + super( + (short) 17, + "Pump Shotgun", //Name + WeaponType.SHOTGUN, //Weapon Type + AmmoType.SHOTGUN, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 161).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_ZOMBIE_ATTACK_DOOR_WOOD, + Sound.ITEM_ARMOR_EQUIP_CHAIN, + Sound.ITEM_ARMOR_EQUIP_CHAIN, + Sound.ENTITY_IRONGOLEM_ATTACK, + }, + Effect.SMOKE //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.GOLD_SPADE).setName(getName()).build()); + setDescription("Standard, solid shotgun.", "This'll keep you going."); + + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.14; //Weapon + this.delay = 70; + + this.damage = 4.75; //RangedWeapon + this.meleeDamage = 5.0; //RangedWeapon + this.accuracy = 0.05; //RangedWeapon + this.magSize = 8; //RangedWeapon + this.reloadTime = 56; //RangedWeapon + this.range = 20; //RangedWeapon + this.recoil = 0.7; //RangedWeapon + this.zoom = 6; //RangedWeapon + this.reloadShoot = true; + + this.shellSize = 4; //AssultRifleWeapon + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/shotgun/SawedoffShotgun.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/shotgun/SawedoffShotgun.java new file mode 100644 index 0000000..01b3474 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/shotgun/SawedoffShotgun.java @@ -0,0 +1,71 @@ +package net.grandtheftmc.vice.weapon.ranged.shotgun; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.guns.ShotgunWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class SawedoffShotgun extends ShotgunWeapon { + + /** + * Construct a new RangedWeapon. + */ + public SawedoffShotgun() { + super( + (short) 16, + "Sawed-off Shotgun", //Name + WeaponType.SHOTGUN, //Weapon Type + AmmoType.SHOTGUN, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 151).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_ZOMBIE_ATTACK_DOOR_WOOD, + Sound.ITEM_ARMOR_EQUIP_CHAIN, + Sound.ITEM_ARMOR_EQUIP_CHAIN, + Sound.ENTITY_IRONGOLEM_ATTACK, + }, + Effect.SMOKE //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.GOLD_SWORD).setName(getName()).build()); + setDescription("Yehaw, time t'shoot me", "some uppities!"); + + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.16; //Weapon + this.delay = 70; + + this.damage = 3.75; //RangedWeapon + this.meleeDamage = 4.0; //RangedWeapon + this.accuracy = 0.075; //RangedWeapon + this.magSize = 8; //RangedWeapon + this.reloadTime = 56; //RangedWeapon + this.range = 15; //RangedWeapon + this.recoil = 1.0; //RangedWeapon + this.zoom = 6; //RangedWeapon + this.reloadShoot = true; + + this.shellSize = 5; //AssultRifleWeapon + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/smg/AssaultSMG.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/smg/AssaultSMG.java new file mode 100644 index 0000000..10eaaa9 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/smg/AssaultSMG.java @@ -0,0 +1,71 @@ +package net.grandtheftmc.vice.weapon.ranged.smg; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.SMGWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class AssaultSMG extends SMGWeapon { + + /** + * Construct a new RangedWeapon. + */ + public AssaultSMG() { + super( + (short) 13, + "Assault SMG", //Name + WeaponType.SMG, //Weapon Type + AmmoType.SMG, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 121).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_BLAZE_HURT, + Sound.ITEM_ARMOR_EQUIP_GOLD, + Sound.ITEM_ARMOR_EQUIP_GOLD, + Sound.BLOCK_WOODEN_DOOR_OPEN, + }, + Effect.FLYING_GLYPH //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.IRON_PICKAXE).setName(getName()).build()); + setDescription("A solid,", "Military grade weapon.", "Good for mowing down enemies."); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.2; //Weapon + + this.damage = 5.0; //RangedWeapon + this.meleeDamage = 4.0; //RangedWeapon + this.accuracy = 0.025; //RangedWeapon + this.magSize = 30; //RangedWeapon + this.reloadTime = 50; //RangedWeapon + this.range = 35; //RangedWeapon + this.recoil = 0.0; //RangedWeapon + this.zoom = 4; //RangedWeapon + + this.rpm = 460; //AssultRifleWeapon + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/smg/CombatPDW.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/smg/CombatPDW.java new file mode 100644 index 0000000..47c30ff --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/smg/CombatPDW.java @@ -0,0 +1,71 @@ +package net.grandtheftmc.vice.weapon.ranged.smg; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.SMGWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class CombatPDW extends SMGWeapon { + + /** + * Construct a new RangedWeapon. + */ + public CombatPDW() { + super( + (short) 14, + "Combat PDW", //Name + WeaponType.SMG, //Weapon Type + AmmoType.SMG, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 131).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_BLAZE_HURT, + Sound.ITEM_ARMOR_EQUIP_GOLD, + Sound.ITEM_ARMOR_EQUIP_GOLD, + Sound.BLOCK_WOODEN_DOOR_OPEN, + }, + Effect.FLYING_GLYPH //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.IRON_AXE).setName(getName()).build()); + setDescription("It's a defensive weapon.", "With a supressor.", "Thanks, Congress!"); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.2; //Weapon + + this.damage = 6.0; //RangedWeapon + this.meleeDamage = 4.0; //RangedWeapon + this.accuracy = 0.025; //RangedWeapon + this.magSize = 30; //RangedWeapon + this.reloadTime = 40; //RangedWeapon + this.range = 35; //RangedWeapon + this.recoil = 0.0; //RangedWeapon + this.zoom = 4; //RangedWeapon + + this.rpm = 450; //AssultRifleWeapon + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/smg/GusenbergSweeper.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/smg/GusenbergSweeper.java new file mode 100644 index 0000000..e829d49 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/smg/GusenbergSweeper.java @@ -0,0 +1,78 @@ +package net.grandtheftmc.vice.weapon.ranged.smg; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.attribute.RankedWeapon; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.SMGWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class GusenbergSweeper extends SMGWeapon implements RankedWeapon { + + /** + * Construct a new RangedWeapon. + */ + public GusenbergSweeper() { + super( + (short) 15, + "Gusenberg Sweeper", //Name + WeaponType.SMG, //Weapon Type + AmmoType.SMG, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 141).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_BLAZE_HURT, + Sound.ITEM_ARMOR_EQUIP_GOLD, + Sound.ITEM_ARMOR_EQUIP_GOLD, + Sound.BLOCK_WOODEN_DOOR_OPEN, + }, + Effect.FLYING_GLYPH //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.IRON_HOE).setName(getName()).build()); + setDescription("With this gun, you can", "make them an offer they", "can't refuse."); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.2; //Weapon + + this.damage = 6.0; //RangedWeapon + this.meleeDamage = 5.0; //RangedWeapon + this.accuracy = 0.016; //RangedWeapon + this.magSize = 50; //RangedWeapon + this.reloadTime = 40; //RangedWeapon + this.range = 47; //RangedWeapon + this.recoil = 0.0; //RangedWeapon + this.zoom = 2; //RangedWeapon + + this.rpm = 555; //AssultRifleWeapon + } + + @Override + public UserRank requiredRank() { + return UserRank.PREMIUM; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/smg/MicroSMG.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/smg/MicroSMG.java new file mode 100644 index 0000000..07e5c4f --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/smg/MicroSMG.java @@ -0,0 +1,71 @@ +package net.grandtheftmc.vice.weapon.ranged.smg; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.SMGWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class MicroSMG extends SMGWeapon { + + /** + * Construct a new RangedWeapon. + */ + public MicroSMG() { + super( + (short) 11, + "Micro SMG", //Name + WeaponType.SMG, //Weapon Type + AmmoType.SMG, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 101).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_BLAZE_HURT, + Sound.ITEM_ARMOR_EQUIP_GOLD, + Sound.ITEM_ARMOR_EQUIP_GOLD, + Sound.BLOCK_WOODEN_DOOR_OPEN, + }, + Effect.FLYING_GLYPH //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.IRON_SWORD).setName(getName()).build()); + setDescription("It's like a peashooter,", "on steriods."); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.2; //Weapon + + this.damage = 4.0; //RangedWeapon + this.meleeDamage = 4.0; //RangedWeapon + this.accuracy = 0.035; //RangedWeapon + this.magSize = 16; //RangedWeapon + this.reloadTime = 40; //RangedWeapon + this.range = 25; //RangedWeapon + this.recoil = 0.0; //RangedWeapon + this.zoom = 4; //RangedWeapon + + this.rpm = 600; //AssultRifleWeapon + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/smg/SMG.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/smg/SMG.java new file mode 100644 index 0000000..b5aaa55 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/smg/SMG.java @@ -0,0 +1,71 @@ +package net.grandtheftmc.vice.weapon.ranged.smg; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.SMGWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class SMG extends SMGWeapon { + + /** + * Construct a new RangedWeapon. + */ + public SMG() { + super( + (short) 12, + "SMG", //Name + WeaponType.SMG, //Weapon Type + AmmoType.SMG, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 111).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_BLAZE_HURT, + Sound.ITEM_ARMOR_EQUIP_GOLD, + Sound.ITEM_ARMOR_EQUIP_GOLD, + Sound.BLOCK_WOODEN_DOOR_OPEN, + }, + Effect.FLYING_GLYPH //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.IRON_SPADE).setName(getName()).build()); + setDescription("The intro to proper", "gang warfare."); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.EXTENDED_MAGS, Attachment.GRIP, Attachment.SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.2; //Weapon + + this.damage = 4.0; //RangedWeapon + this.meleeDamage = 4.0; //RangedWeapon + this.accuracy = 0.025; //RangedWeapon + this.magSize = 30; //RangedWeapon + this.reloadTime = 50; //RangedWeapon + this.range = 35; //RangedWeapon + this.recoil = 0.0; //RangedWeapon + this.zoom = 4; //RangedWeapon + + this.rpm = 510; //AssultRifleWeapon + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/sniper/HeavySniper.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/sniper/HeavySniper.java new file mode 100644 index 0000000..24c194a --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/sniper/HeavySniper.java @@ -0,0 +1,76 @@ +package net.grandtheftmc.vice.weapon.ranged.sniper; + +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.attribute.RankedWeapon; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.SniperWeapon; +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class HeavySniper extends SniperWeapon implements RankedWeapon { + + /** + * Construct a new RangedWeapon. + */ + public HeavySniper() { + super( + (short) 29, + "Heavy Sniper", //Name + WeaponType.SNIPER, //Weapon Type + AmmoType.SNIPER, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 281).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_IRONGOLEM_HURT, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.BLOCK_PISTON_EXTEND, + }, + Effect.CLOUD //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.DIAMOND_AXE).setName(getName()).build()); + setDescription("When you really like", "killing people without", "getting your hands dirty."); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.GRIP, Attachment.ADVANCED_SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.14; //Weapon + this.delay = 41; + + this.damage = 34.5; //RangedWeapon + this.meleeDamage = 6.0; //RangedWeapon + this.accuracy = 0.01265; //RangedWeapon + this.magSize = 6; //RangedWeapon + this.reloadTime = 80; //RangedWeapon + this.range = 100; //RangedWeapon + this.recoil = 0.3; //RangedWeapon + this.zoom = 9; //RangedWeapon + } + + @Override + public UserRank requiredRank() { + return UserRank.ELITE; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/sniper/SniperRifle.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/sniper/SniperRifle.java new file mode 100644 index 0000000..95b74a1 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/sniper/SniperRifle.java @@ -0,0 +1,69 @@ +package net.grandtheftmc.vice.weapon.ranged.sniper; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.SniperWeapon; +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class SniperRifle extends SniperWeapon { + + /** + * Construct a new RangedWeapon. + */ + public SniperRifle() { + super( + (short) 28, + "Sniper Rifle", //Name + WeaponType.SNIPER, //Weapon Type + AmmoType.SNIPER, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 271).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_IRONGOLEM_HURT, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.BLOCK_PISTON_EXTEND, + }, + Effect.CLOUD //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.DIAMOND_PICKAXE).setName(getName()).build()); + setDescription("When you like killing", "people without getting", "your hands dirty."); + + setSupportedAttachments(Attachment.SUPPRESSOR, Attachment.GRIP, Attachment.ADVANCED_SCOPE); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.14; //Weapon + this.delay = 32; + + this.damage = 23.0; //RangedWeapon + this.meleeDamage = 5.0; //RangedWeapon + this.accuracy = 0.0175; //RangedWeapon + this.magSize = 10; //RangedWeapon + this.reloadTime = 80; //RangedWeapon + this.range = 95; //RangedWeapon + this.recoil = 0.3; //RangedWeapon + this.zoom = 8; //RangedWeapon + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/special/Clausinator.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/special/Clausinator.java new file mode 100644 index 0000000..13f5f42 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/special/Clausinator.java @@ -0,0 +1,51 @@ +package net.grandtheftmc.vice.weapon.ranged.special; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.inventory.ItemStack; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.guns.PistolWeapon; + +/** + * Created by Timothy Lampen on 2017-12-12. + */ +public class Clausinator extends PistolWeapon { + public Clausinator() { + super( + (short) 50, + "Clausinator", //Name + WeaponType.CLAUSINATOR, //Weapon Type + AmmoType.NONE, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 1011).build(), + new Sound[] { //Gun Sounds + Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ITEM_FLINTANDSTEEL_USE, + }, + Effect.FLYING_GLYPH //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setDescription("Snowball fight!"); + + setOldItemStack(new ItemStack(Material.ACACIA_DOOR_ITEM)); + + + + this.walkSpeed = 0.1; //Weapon + this.delay = 40; //Weapon + + this.damage = 0.001; //RangedWeapon + this.meleeDamage = 3.0; //RangedWeapon + this.accuracy = 0.025; //RangedWeapon + this.magSize = 600; //RangedWeapon + this.reloadTime = 40; //RangedWeapon + this.range = 25; //RangedWeapon + this.zoom = 4; //RangedWeapon + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/special/Flamethrower.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/special/Flamethrower.java new file mode 100644 index 0000000..00b4681 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/special/Flamethrower.java @@ -0,0 +1,84 @@ +package net.grandtheftmc.vice.weapon.ranged.special; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.ShotgunWeapon; + +/** + * Created by Luke Bingham on 03/08/2017. + */ +public class Flamethrower extends ShotgunWeapon { + + /** + * Construct a new RangedWeapon. + */ + public Flamethrower() { + super( + (short) 40, + "Flamethrower", //Name + WeaponType.FLAMETHROWER, //TODO Weapon Type + AmmoType.NONE, //TODO AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 391).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ITEM_FIRECHARGE_USE, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.UI_BUTTON_CLICK, + }, + Effect.MOBSPAWNER_FLAMES //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.FLINT_AND_STEEL).setDurability((short) 10).setName(getName()).build()); + setDescription("Is it me, or is it", "getting hot in here?"); + + setSupportedAttachments(Attachment.GRIP); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.2; //Weapon + this.delay = 2; + + this.damage = 6.0; //RangedWeapon + this.meleeDamage = 3.0; //RangedWeapon + this.accuracy = 0.05; //RangedWeapon + this.magSize = 25; //RangedWeapon + this.reloadTime = 100; //RangedWeapon + this.range = 25; //RangedWeapon + this.recoil = 0.001; //RangedWeapon + this.zoom = 3; //RangedWeapon + this.shellSize = 5; + +// this.flamethrower = true; //SpecialWeapon +// this.rpm = 200; //SpecialWeapon + } + + @Override + public int getRpm() { + return 200; + } + + @Override + public boolean isAutomatic() { + return true; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/special/GoldMinigun.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/special/GoldMinigun.java new file mode 100644 index 0000000..3ce070a --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/special/GoldMinigun.java @@ -0,0 +1,80 @@ +package net.grandtheftmc.vice.weapon.ranged.special; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.attribute.RankedWeapon; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.SpecialWeapon; + +/** + * Created by Luke Bingham on 03/08/2017. + */ +public class GoldMinigun extends SpecialWeapon implements RankedWeapon { + + /** + * Construct a new RangedWeapon. + */ + public GoldMinigun() { + super( + (short) 42, + "Gold Minigun", //Name + WeaponType.MINIGUN, //Weapon Type + AmmoType.MINIGUN, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 411).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ITEM_FLINTANDSTEEL_USE, + }, + Effect.FLYING_GLYPH //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.DIAMOND_HOE).setDurability((short) -1/* IDK?.. */).setName(getName()).build());//TODO Unknown at the moment. + setDescription("Is it me, or is it", "getting hot in here?"); + + setSupportedAttachments(Attachment.GRIP); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.1; //Weapon + + this.damage = 5.0; //RangedWeapon + this.meleeDamage = 3.0; //RangedWeapon + this.accuracy = 0.025; //RangedWeapon + this.magSize = 600; //RangedWeapon + this.reloadTime = 100; //RangedWeapon + this.range = 55; //RangedWeapon + this.recoil = 0.05; //RangedWeapon + this.zoom = 3; //RangedWeapon + this.reloadShoot = true; + + this.minigun = true; //SpecialWeapon + this.rpm = 1200; //SpecialWeapon + } + + @Override + public UserRank requiredRank() { + return UserRank.SUPREME; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/special/Handcuffs.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/special/Handcuffs.java new file mode 100644 index 0000000..6b1acfe --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/special/Handcuffs.java @@ -0,0 +1,43 @@ +package net.grandtheftmc.vice.weapon.ranged.special; + +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.inventory.ItemStack; + +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.MeleeWeapon; +import net.grandtheftmc.guns.weapon.WeaponType; + +/** + * Created by Timothy Lampen on 2017-11-22. + */ +public class Handcuffs extends MeleeWeapon { + public Handcuffs() { + super((short) 57, + "Handcuffs", + WeaponType.MELEE, + AmmoType.MELEE, + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 1003).build(), + new Sound[] { + Sound.ENTITY_SKELETON_SHOOT, + Sound.ITEM_ARMOR_EQUIP_GENERIC, + Sound.ITEM_ARMOR_EQUIP_GENERIC + }); + setOldItemStack(new ItemStack(Material.ACACIA_DOOR)); + setDescription("Multipurpose tool", "for work or for kink"); + + + this.delay = 10; + this.meleeDamage = 1.0; + } + +// @Override +// public void onHit(EntityDamageByEntityEvent event){ +// if(event.getDamager() instanceof Player && event.getEntity() instanceof Player){ +// Player player = (Player)event.getDamager(); +// Player victim = (Player)event.getEntity(); +// GTMUtils.arrestPlayer(event, this, player, victim); +// } +// } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/special/Minigun.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/special/Minigun.java new file mode 100644 index 0000000..58dd31e --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/ranged/special/Minigun.java @@ -0,0 +1,80 @@ +package net.grandtheftmc.vice.weapon.ranged.special; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; + +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.core.util.factory.ItemFactory; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.attribute.RankedWeapon; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.SpecialWeapon; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public class Minigun extends SpecialWeapon implements RankedWeapon { + + /** + * Construct a new RangedWeapon. + */ + public Minigun() { + super( + (short) 33, + "Minigun", //Name + WeaponType.MINIGUN, //Weapon Type + AmmoType.MINIGUN, //AmmoType + new ItemFactory(Material.DIAMOND_SWORD).setDurability((short) 321).build(), //ItemStack + new Sound[] { //Gun Sounds + Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ITEM_ARMOR_EQUIP_DIAMOND, + Sound.ITEM_FLINTANDSTEEL_USE, + }, + Effect.FLYING_GLYPH //Particles + ); + + //This is the OLD itemstack, this isn't needed when creating a new weapon. + setOldItemStack(new ItemFactory(Material.DIAMOND_HOE).setName(getName()).build()); + setDescription("Say hello to my", "little friend."); + + setSupportedAttachments(Attachment.GRIP); + setWeaponSkins( + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), "&6&lUrban Camo"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), "&e&lGreen"), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), "&e&lSlate") + /*new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 1), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 2), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 3), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 4), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 5), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 6), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 7), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 8), null), + new WeaponSkin(getWeaponType(), (short) (getWeaponIdentifier() + 9), null)*/ + ); + + this.walkSpeed = 0.1; //Weapon + + this.damage = 5.0; //RangedWeapon + this.meleeDamage = 3.0; //RangedWeapon + this.accuracy = 0.025; //RangedWeapon + this.magSize = 600; //RangedWeapon + this.reloadTime = 100; //RangedWeapon + this.range = 55; //RangedWeapon + this.recoil = 0.05; //RangedWeapon + this.zoom = 3; //RangedWeapon + this.reloadShoot = true; + + this.minigun = true; //SpecialWeapon + this.rpm = 1200; //SpecialWeapon + } + + @Override + public UserRank requiredRank() { + return UserRank.SUPREME; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/skins/WeaponSkinDAO.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/skins/WeaponSkinDAO.java new file mode 100644 index 0000000..b8705b5 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/skins/WeaponSkinDAO.java @@ -0,0 +1,136 @@ +package net.grandtheftmc.vice.weapon.skins; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.guns.weapon.Weapon; +import net.grandtheftmc.guns.weapon.WeaponSkin; + +public class WeaponSkinDAO { + public static boolean lockSkin(Connection connection, UUID uuid, Weapon<?> weapon, WeaponSkin skin) { + String query = "DELETE FROM user_weapon_skin WHERE weapon_id=? AND skin_id=? AND uuid=UNHEX(?);"; + + try (PreparedStatement statement = connection.prepareStatement(query)) { + statement.setShort(1, weapon.getUniqueIdentifier()); + statement.setShort(2, (short) (skin.getIdentifier() - weapon.getWeaponIdentifier())); + statement.setString(3, uuid.toString().replaceAll("-", "")); + statement.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + + return false; + } + + return true; + } + + public static boolean unlockSkin(Connection connection, UUID uuid, Weapon<?> weapon, WeaponSkin skin) { + String query = "INSERT INTO user_weapon_skin (uuid, server_key, weapon_id, skin_id) VALUES (UNHEX(?), ?, ?, ?);"; + + try (PreparedStatement statement = connection.prepareStatement(query)) { + statement.setString(1, uuid.toString().replaceAll("-", "")); + statement.setString(2, Core.name().toUpperCase()); + statement.setShort(3, weapon.getUniqueIdentifier()); + statement.setShort(4, (short) (skin.getIdentifier() - weapon.getWeaponIdentifier())); + statement.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + + return false; + } + + return true; + } + + public static boolean enableSkin(Connection connection, UUID uuid, Weapon<?> weapon, short skinID) { + String query = "UPDATE user_weapon_skin SET enabled=1 WHERE server_key=? AND weapon_id=? AND skin_id=? AND uuid=UNHEX(?);"; + + try (PreparedStatement statement = connection.prepareStatement(query)) { + statement.setString(1, Core.name().toUpperCase()); + statement.setShort(2, weapon.getUniqueIdentifier()); + statement.setShort(3, skinID); + statement.setString(4, uuid.toString().replaceAll("-", "")); + statement.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + + return false; + } + + return true; + } + + public static boolean disableSkin(Connection connection, UUID uuid, Weapon<?> weapon, short skinID) { + String query = "UPDATE user_weapon_skin SET enabled=0 WHERE server_key=? AND weapon_id=? AND skin_id=? AND uuid=UNHEX(?);"; + + try (PreparedStatement statement = connection.prepareStatement(query)) { + statement.setString(1, Core.name().toUpperCase()); + statement.setShort(2, weapon.getUniqueIdentifier()); + statement.setShort(3, skinID); + statement.setString(4, uuid.toString().replaceAll("-", "")); + statement.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + + return false; + } + + return true; + } + + public static Map<Short, List<Short>> getUnlockedSkins(Connection connection, UUID uuid) { + Map<Short, List<Short>> skins = new HashMap<Short, List<Short>>(); + String query = "SELECT * FROM user_weapon_skin WHERE server_key=? AND uuid=UNHEX(?);"; + + try (PreparedStatement statement = connection.prepareStatement(query)) { + statement.setString(1, Core.name().toUpperCase()); + statement.setString(2, uuid.toString().replaceAll("-", "")); + + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + short weaponID = result.getShort("weapon_id"); + + if (skins.containsKey(weaponID)) { + skins.get(weaponID).add(result.getShort("skin_id")); + } else { + skins.put(weaponID, new ArrayList<Short>()); + skins.get(weaponID).add(result.getShort("skin_id")); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + + return skins; + } + + public static Map<Short, Short> getEquippedSkins(Connection connection, UUID uuid) { + Map<Short, Short> skins = new HashMap<Short, Short>(); + String query = "SELECT * FROM user_weapon_skin WHERE server_key=? AND uuid=UNHEX(?) AND enabled=?;"; + + try (PreparedStatement statement = connection.prepareStatement(query)) { + statement.setString(1, Core.name().toUpperCase()); + statement.setString(2, uuid.toString().replaceAll("-", "")); + statement.setShort(3, (short) 1); + + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + skins.put(result.getShort("weapon_id"), result.getShort("skin_id")); + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + + return skins; + } +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/skins/WeaponSkinManager.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/skins/WeaponSkinManager.java new file mode 100644 index 0000000..ac07a5b --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/skins/WeaponSkinManager.java @@ -0,0 +1,195 @@ +package net.grandtheftmc.vice.weapon.skins; + +import java.util.Arrays; +import java.util.Optional; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryMoveItemEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import com.j0ach1mmall3.wastedguns.api.events.WeaponDropEvent; +import com.j0ach1mmall3.wastedguns.api.events.WeaponPickupEvent; + +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.gui.ConfirmationMenu; +import net.grandtheftmc.guns.WeaponManager; +import net.grandtheftmc.guns.weapon.Weapon; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.ViceUser; +import net.minecraft.server.v1_12_R1.NBTTagCompound; + +public class WeaponSkinManager { + public WeaponSkinManager() { + Bukkit.getPluginManager().registerEvents(new SkinListener(), Vice.getInstance()); + } + + public void updateWeaponSkin(Player player, Weapon<?> weapon, WeaponSkin skin) { + ViceUser user = Vice.getUserManager().getLoadedUser(player.getUniqueId()); + user.equipWeaponSkin(weapon, skin); + + for (ItemStack stack : player.getInventory().getContents()) { + Optional<Weapon<?>> weaponOpt = Vice.getWastedGuns().getWeaponManager().getWeapon(stack); + + if (weaponOpt.isPresent()) { + if (weaponOpt.get().getUniqueIdentifier() == weapon.getUniqueIdentifier()) { + stack.setDurability(skin.getIdentifier()); + } + } + } + } + + public WeaponSkin getHeldItemWeaponSkin(ItemStack stack) { + WeaponManager weaponManager = Vice.getWastedGuns().getWeaponManager(); + + if (stack != null) { + Optional<Weapon<?>> weaponOpt = weaponManager.getWeapon(stack); + + if (weaponOpt.isPresent()) { + Weapon<?> weapon = weaponOpt.get(); + + if (weapon.getWeaponSkins() != null) { + for (WeaponSkin skin : weapon.getWeaponSkins()) { + if (stack.getDurability() == skin.getIdentifier()) { + return skin; + } + } + } + } + } + + return null; + } + + public WeaponSkin getWeaponSkinFromIdentifier(Weapon<?> weapon, short identifier) { + for (WeaponSkin skin : weapon.getWeaponSkins()) { + if ((skin.getIdentifier() - weapon.getWeaponIdentifier()) == identifier) { + return skin; + } + } + + return null; + } + + public ItemStack createSkinItem(Weapon<?> weapon, WeaponSkin skin) { + ItemStack stack = new ItemStack(Material.ENCHANTED_BOOK); + ItemMeta meta = stack.getItemMeta(); + + meta.setLore(Arrays.asList(new String[] { + Utils.f("&7Included skin:"), Utils.f("&8- &7" + ChatColor.stripColor(Utils.f(skin.getDisplayName())) + " (" + weapon.getName() + ")"), + })); + + meta.setDisplayName(Utils.f("&9&lWeapon Skin")); + stack.setItemMeta(meta); + + net.minecraft.server.v1_12_R1.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack); + NBTTagCompound compound = nmsStack.getTag(); + compound.setShort("weapon_id", weapon.getUniqueIdentifier()); + compound.setShort("skin_id", (short) (skin.getIdentifier() - weapon.getWeaponIdentifier())); + nmsStack.setTag(compound); + + return CraftItemStack.asBukkitCopy(nmsStack); + } + + private class SkinListener implements Listener { + @EventHandler + public void onWeaponPickup(WeaponPickupEvent event) { + ItemStack stack = event.getItem().getItemStack(); + Optional<Weapon<?>> weaponOpt = Vice.getWastedGuns().getWeaponManager().getWeapon(stack); + + if (weaponOpt.isPresent()) { + stack.setDurability(Vice.getUserManager().getLoadedUser(event.getLivingEntity().getUniqueId()).getEquippedWeaponSkin(weaponOpt.get()).getIdentifier()); + } + } + + @EventHandler + public void onWeaponDrop(WeaponDropEvent event) { + ItemStack stack = event.getItemDrop().getItemStack(); + Optional<Weapon<?>> weaponOpt = Vice.getWastedGuns().getWeaponManager().getWeapon(stack); + + if (weaponOpt.isPresent()) { + stack.setDurability(weaponOpt.get().getWeaponIdentifier()); + } + } + + @EventHandler + public void onItemMove(InventoryMoveItemEvent event) { + InventoryHolder holder = event.getSource().getHolder(); + + if (holder instanceof Player) { + Player player = (Player) holder; + + if (event.getDestination() != player.getInventory()) { + ItemStack stack = event.getItem(); + Optional<Weapon<?>> weaponOpt = Vice.getWastedGuns().getWeaponManager().getWeapon(stack); + + if (weaponOpt.isPresent() && stack.getDurability() != 0) { + stack.setDurability(weaponOpt.get().getWeaponIdentifier()); + } + } else { + ItemStack stack = event.getItem(); + Optional<Weapon<?>> weaponOpt = Vice.getWastedGuns().getWeaponManager().getWeapon(stack); + + if (weaponOpt.isPresent()) { + stack.setDurability(Vice.getUserManager().getLoadedUser(player.getUniqueId()).getEquippedWeaponSkin(weaponOpt.get()).getIdentifier()); + } + } + } + } + + @EventHandler + public void onItemRightClick(PlayerInteractEvent event) { + if (event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_AIR) { + ItemStack item = event.getItem(); + + net.minecraft.server.v1_12_R1.ItemStack nmsStack = CraftItemStack.asNMSCopy(item); + NBTTagCompound compound = nmsStack.getTag(); + + if (compound != null && compound.hasKey("weapon_id") && compound.hasKey("skin_id") && item.getType() == Material.ENCHANTED_BOOK) { + ConfirmationMenu menu = new ConfirmationMenu(Vice.getInstance(), event.getItem()) { + @Override + protected void onConfirm(InventoryClickEvent e, Player p) { + net.minecraft.server.v1_12_R1.ItemStack nmsStack = CraftItemStack.asNMSCopy(event.getItem()); + NBTTagCompound compound = nmsStack.getTag(); + + short weaponID = compound.getShort("weapon_id"); + short skinID = compound.getShort("skin_id"); + + Optional<Weapon<?>> weaponOpt = Vice.getWastedGuns().getWeaponManager().getWeaponFromUniqueIdentifier(weaponID); + if (weaponOpt.isPresent()) { + Weapon<?> weapon = weaponOpt.get(); + WeaponSkin skin = getWeaponSkinFromIdentifier(weapon, skinID); + + ViceUser user = Vice.getUserManager().getLoadedUser(p.getUniqueId()); + + if (!user.hasSkinUnlocked(weapon, skin)) { + user.unlockWeaponSkin(weapon, skin); + + p.getInventory().remove(event.getItem()); + p.sendMessage(Utils.f("&aYou have unlocked a " + skin.getDisplayName() + " Skin &afor &6&l" + weapon.getName() + "&a! Please go to Mr Skinner at spawn to equip it.")); + } else { + p.sendMessage(Utils.f("&cYou already have this skin unlocked!")); + } + + event.setCancelled(true); + } + } + }; + + menu.open(event.getPlayer()); + } + } + } + } +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/skins/menu/MainMenu.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/skins/menu/MainMenu.java new file mode 100644 index 0000000..05ac240 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/skins/menu/MainMenu.java @@ -0,0 +1,164 @@ +package net.grandtheftmc.vice.weapon.skins.menu; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import org.bukkit.ChatColor; +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import net.grandtheftmc.core.inventory.CoreMenu; +import net.grandtheftmc.core.inventory.button.ClickableItem; +import net.grandtheftmc.core.inventory.button.MenuItem; +import net.grandtheftmc.guns.weapon.MeleeWeapon; +import net.grandtheftmc.guns.weapon.Weapon; +import net.grandtheftmc.guns.weapon.ranged.RangedWeapon; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.items.GameItem; +import net.grandtheftmc.vice.users.ViceUser; + +public class MainMenu extends CoreMenu { + private final Player holder; + private final int page; + + public MainMenu(Player holder) { + super(5, "Weapon Skins"); + + this.holder = holder; + this.page = 0; + + this.setup(); + } + + private MainMenu(Player holder, int page) { + super(5, "Weapon Skins"); + + this.holder = holder; + this.page = page; + + this.setup(); + } + + @SuppressWarnings("deprecation") + protected void setup() { + for (int i = 0; i < 45; i++) { + ItemStack stack = new ItemStack(Material.STAINED_GLASS_PANE, 1, (byte) DyeColor.BLACK.getWoolData()); + ItemMeta meta = stack.getItemMeta(); + meta.setDisplayName(""); + stack.setItemMeta(meta); + + this.addItem(new MenuItem(i, stack, false)); + } + + this.createMenuContent(); + } + + private void createMenuContent() { + List<Weapon<?>> weapons = new ArrayList<Weapon<?>>(); + List<Weapon<?>> pageWeapons = null; + + for (GameItem gameItem : Vice.getItemManager().getItems()) { + if (gameItem.getType() == GameItem.ItemType.WEAPON) { + Optional<Weapon<?>> optional = Vice.getWastedGuns().getWeaponManager().getWeapon(gameItem.getWeaponOrVehicleOrDrug()); + + if (optional.isPresent()) { + Weapon<?> weapon = optional.get(); + + if ((weapon instanceof RangedWeapon || weapon instanceof MeleeWeapon) && weapon.getWeaponSkins().length > 1) { + weapons.add(weapon); + } + } + } + } + + try { + pageWeapons = weapons.subList(this.page * 15, (this.page * 15) + 15); + } catch (IndexOutOfBoundsException e) { + pageWeapons = weapons.subList(this.page * 15, weapons.size() - 1); + } + + int index = 11; + for (int i = 0; i < pageWeapons.size(); i++) { + Weapon<?> weapon = weapons.get(i + (this.page * 15)); + + this.addItem(new ClickableItem(index, this.createSkinButton(weapon), (player, action) -> { + new SkinsMenu(player, weapon).open(); + })); + + if (i == 4 || i == 9) { + index += 5; + } else { + index++; + } + } + + this.createNextPageButtons((int) Math.ceil(((double) weapons.size()) / 15.0)); + this.createPreviousPageButtons(); + } + + @SuppressWarnings("deprecation") + private void createNextPageButtons(int numPages) { + for (int i = 0; i < 3; i++) { + if (numPages > 1 && (this.page + 1) < numPages) { + ItemStack stack = new ItemStack(Material.STAINED_GLASS_PANE, 1, (byte) DyeColor.LIME.getWoolData()); + ItemMeta meta = stack.getItemMeta(); + meta.setDisplayName("Next Page"); + stack.setItemMeta(meta); + + this.addItem(new ClickableItem((i * 9) + 17, stack, (player, action) -> { + new MainMenu(this.holder, this.page + 1).open(); + })); + } + } + } + + @SuppressWarnings("deprecation") + private void createPreviousPageButtons() { + for (int i = 0; i < 3; i++) { + if (this.page != 0) { + ItemStack stack = new ItemStack(Material.STAINED_GLASS_PANE, 1, (byte) DyeColor.RED.getWoolData()); + ItemMeta meta = stack.getItemMeta(); + meta.setDisplayName("Next Page"); + stack.setItemMeta(meta); + + this.addItem(new ClickableItem((i * 9) + 9, stack, (player, action) -> { + new MainMenu(this.holder, this.page - 1).open(); + })); + } + } + } + + private ItemStack createSkinButton(Weapon<?> weapon) { + ItemStack stack = weapon.createItemStack(); + ItemMeta meta = stack.getItemMeta(); + meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', "&e&l" + weapon.getName())); + + int unlockedSkins = 0; + ViceUser user = Vice.getUserManager().getLoadedUser(this.holder.getUniqueId()); + + if (user.getUnlockedWeaponSkins(weapon) != null) { + unlockedSkins = user.getUnlockedWeaponSkins(weapon).size(); + } + + meta.setLore(Arrays.asList(new String[] { + ChatColor.translateAlternateColorCodes('&', "&6Unlocked:&r " + (1 + unlockedSkins) + "/4"), " ", ChatColor.translateAlternateColorCodes('&', "&7Click to view the skins for this weapon.") + })); + + stack.setItemMeta(meta); + + return stack; + } + + public void open() { + this.openInventory(this.holder); + } + + protected Player getHolder() { + return this.holder; + } +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/skins/menu/SkinsMenu.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/skins/menu/SkinsMenu.java new file mode 100644 index 0000000..2856a11 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/weapon/skins/menu/SkinsMenu.java @@ -0,0 +1,164 @@ +package net.grandtheftmc.vice.weapon.skins.menu; + +import java.util.Arrays; +import java.util.List; + +import org.bukkit.ChatColor; +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import net.grandtheftmc.core.inventory.CoreMenu; +import net.grandtheftmc.core.inventory.button.ClickableItem; +import net.grandtheftmc.core.inventory.button.MenuItem; +import net.grandtheftmc.guns.weapon.Weapon; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.users.ViceUser; + +public class SkinsMenu extends CoreMenu { + private final Player holder; + private final Weapon<?> weapon; + + public SkinsMenu(Player holder, Weapon<?> weapon) { + super(5, "Weapon Skins"); + + this.holder = holder; + this.weapon = weapon; + + this.setup(); + } + + @SuppressWarnings("deprecation") + protected void setup() { + ViceUser user = Vice.getUserManager().getLoadedUser(this.holder.getUniqueId()); + List<WeaponSkin> unlockedSkins = user.getUnlockedWeaponSkins().get(this.weapon.getUniqueIdentifier()); + + for (int i = 0; i < 45; i++) { + ItemStack stack = new ItemStack(Material.STAINED_GLASS_PANE, 1, (byte) DyeColor.BLACK.getWoolData()); + ItemMeta meta = stack.getItemMeta(); + meta.setDisplayName(""); + stack.setItemMeta(meta); + + this.addItem(new MenuItem(i, stack, false)); + } + + for (int i = 0; i < this.weapon.getWeaponSkins().length; i++) { + WeaponSkin skin = this.weapon.getWeaponSkins()[i]; + + if ((unlockedSkins != null && unlockedSkins.contains(skin)) || (skin.getIdentifier() - this.weapon.getWeaponIdentifier()) == 0) { + WeaponSkin currentSkin = user.getEquippedWeaponSkin(this.weapon); + boolean selected = false; + + if (currentSkin != null) { + if (skin == currentSkin) { + selected = true; + } + } + + if (i >= 0 && i <= 2) { + if (!selected) { + this.addItem(new ClickableItem(i + 12, this.createSkinStack(skin, selected), (player, action) -> { + Vice.getWeaponSkinManager().updateWeaponSkin(this.holder, this.weapon, skin); + + new SkinsMenu(this.holder, this.weapon).open(); + })); + } else { + this.addItem(new MenuItem(i + 12, this.createSkinStack(skin, selected), false)); + } + } else { + if (!selected) { + this.addItem(new ClickableItem(22, this.createSkinStack(skin, selected), (player, action) -> { + Vice.getWeaponSkinManager().updateWeaponSkin(this.holder, this.weapon, skin); + + new SkinsMenu(this.holder, this.weapon).open(); + })); + } else { + this.addItem(new MenuItem(22, this.createSkinStack(skin, selected), false)); + } + } + } else { + if (i >= 0 && i <= 2) { + this.addItem(new MenuItem(i + 12, this.createLockedSkinStack(), false)); + } else { + this.addItem(new MenuItem(22, this.createLockedSkinStack(), false)); + } + } + } + + this.addItem(new ClickableItem(40, this.createBackStack(), (player, action) -> { + new MainMenu(player).open(); + })); + } + + private ItemStack createBackStack() { + ItemStack stack = new ItemStack(Material.REDSTONE, 1); + + ItemMeta meta = stack.getItemMeta(); + meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', "&c&lBack")); + meta.setLore(Arrays.asList(new String[] { + ChatColor.translateAlternateColorCodes('&', "&7Return to the home page!") + })); + + stack.setItemMeta(meta); + + return stack; + } + + private ItemStack createSkinStack(WeaponSkin skin, boolean selected) { + ItemStack stack = this.weapon.createItemStack(skin); + + ItemMeta meta = stack.getItemMeta(); + meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', skin.getDisplayName())); + + if (selected) { + meta.setLore(Arrays.asList(new String[] { + ChatColor.translateAlternateColorCodes('&', "&7This is the currently selected skin"), ChatColor.translateAlternateColorCodes('&', "&7for this weapon.") + })); + } else { + meta.setLore(Arrays.asList(new String[] { + ChatColor.translateAlternateColorCodes('&', "&7Click to change the selected skin.") + })); + } + + if (selected) { + meta.addEnchant(Enchantment.SILK_TOUCH, 1, false); + meta.addItemFlags(ItemFlag.HIDE_ENCHANTS); + } + + stack.setItemMeta(meta); + + return stack; + } + + private ItemStack createLockedSkinStack() { + ItemStack stack = new ItemStack(Material.STRING); + + ItemMeta meta = stack.getItemMeta(); + meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', "&4&l????")); + meta.setLore(Arrays.asList(new String[] { + ChatColor.translateAlternateColorCodes('&', "&7Unknown skin. Find it at the following places:"), ChatColor.translateAlternateColorCodes('&', "&8- &7Skin Crates"), ChatColor.translateAlternateColorCodes('&', "&8- &7Loot Chests"), + ChatColor.translateAlternateColorCodes('&', "&8- &7Crowbar Crates") + })); + + stack.setItemMeta(meta); + + return stack; + } + + public void open() { + this.openInventory(this.holder); + } + + protected Player getHolder() { + return this.holder; + } + + protected Weapon<?> getWeapon() { + return this.weapon; + } +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/ViceSelection.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/ViceSelection.java new file mode 100644 index 0000000..5950827 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/ViceSelection.java @@ -0,0 +1,96 @@ +package net.grandtheftmc.vice.world; + +import org.bukkit.Location; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +/** + * Created by Timothy Lampen on 8/25/2017. + */ +public class ViceSelection { + + private final Location lowCorner, highCorner; + private final List<ZoneFlag> flags; + private final String name; + private final List<UUID> insideSelection = new ArrayList<>(); + + public ViceSelection(String name, List<ZoneFlag> flags, Location corner1, Location corner2, boolean ignoreheight) { + if(corner1.getBlockY()==corner2.getBlockY() || ignoreheight) { + corner1.setY(0); + corner2.setY(255); + this.lowCorner = corner1; + this.highCorner = corner2; + } + else { + this.lowCorner = corner1.getBlockY()<corner2.getBlockY() ? corner1 : corner2; + this.highCorner = corner1.getBlockY()>corner2.getBlockY() ? corner1 : corner2; + } + this.name = name; + this.flags = flags; + } + + public String getName() { + return name; + } + + public List<ZoneFlag> getFlags() { + return flags; + } + + public void addFlag(ZoneFlag flag) { + this.flags.add(flag); + } + + public boolean removeFlag(ZoneFlag flag){ + if(this.flags.contains(flag)) { + this.flags.remove(flag); + return true; + } + return false; + } + + public Location getHighCorner() { + return highCorner; + } + + public Location getLowCorner() { + return lowCorner; + } + + public boolean isInRegion(Location loc){ + if(loc.getY()>=this.lowCorner.getY() && loc.getY()<=this.highCorner.getY()) { + double[] dim = new double[2]; + + dim[0] = this.highCorner.getX(); + dim[1] = this.lowCorner.getX(); + Arrays.sort(dim); + if(loc.getX() > dim[1] || loc.getX() < dim[0]) + return false; + + dim[0] = this.highCorner.getZ(); + dim[1] = this.lowCorner.getZ(); + Arrays.sort(dim); + if(loc.getZ() > dim[1] || loc.getZ() < dim[0]) + return false; + return true; + } + return false; + } + + public List<UUID> getInsideSelection() { + return insideSelection; + } + + public void addPlayerToSelection(UUID uuid) { + if(!this.insideSelection.contains(uuid)) + this.insideSelection.add(uuid); + } + + public void removePlayerFromSelection(UUID uuid) { + if(this.insideSelection.contains(uuid)) + this.insideSelection.remove(uuid); + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/WorldManager.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/WorldManager.java new file mode 100644 index 0000000..1333fbe --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/WorldManager.java @@ -0,0 +1,117 @@ +package net.grandtheftmc.vice.world; + +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.world.obsidianbreaker.ObsidianManager; +import net.grandtheftmc.vice.world.warps.WarpManager; +import org.bukkit.Location; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * Created by Timothy Lampen on 8/25/2017. + */ +public class WorldManager { + + private List<ViceSelection> zones =new ArrayList<>(); + private final ObsidianManager om; + private final WarpManager wm; + + public WorldManager(){ + om = new ObsidianManager(); + wm = new WarpManager(); + } + + public void load() { + wm.loadWarps(); + this.loadZones(); + } + + public void save() { + wm.saveWarps(); + this.saveZones(); + } + + private void saveZones(){ + YamlConfiguration c = Vice.getSettings().getZoneConfig(); + for(String s : c.getConfigurationSection("").getKeys(false)) { + c.set(s, null);//clearing past zones + } + for(ViceSelection zone : this.zones) { + StringBuilder flags = new StringBuilder(); + if(zone.getFlags().size()>0) { + zone.getFlags().forEach(flag -> { + flags.append(flag + ":"); + }); + flags.deleteCharAt(flags.length() - 1); + } + c.set(zone.getName() + ".flags", flags.toString()); + c.set(zone.getName() + ".highcorner", ViceUtils.serializeLocation(zone.getHighCorner())); + c.set(zone.getName() + ".lowcorner", ViceUtils.serializeLocation(zone.getLowCorner())); + } + Utils.saveConfig(c, "zones"); + } + + private void loadZones(){ + YamlConfiguration c = Vice.getSettings().getZoneConfig(); + if(c.getConfigurationSection("")==null) + return; + for(String name : c.getConfigurationSection("").getKeys(false)) { + List<ZoneFlag> flags = new ArrayList<>(); + String seralizedFlags = c.getString(name + ".flags"); + if(seralizedFlags.contains(":")) { + for(String s : seralizedFlags.split(":")) { + flags.add(ZoneFlag.valueOf(s)); + } + } + else { + flags.add(ZoneFlag.valueOf(seralizedFlags)); + } + Location highCorner = ViceUtils.deserializeLocation(c.getString(name + ".highcorner")).get(); + Location lowCorner = ViceUtils.deserializeLocation(c.getString(name + ".lowcorner")).get(); + this.zones.add(new ViceSelection(name, flags, lowCorner, highCorner, false)); + + } + } + + public Optional<ViceSelection> getZone(String name) { + return this.zones.stream().filter(zone -> zone.getName().equalsIgnoreCase(name)).findFirst(); + } + + public List<ViceSelection> getZones(Location loc) { + return this.zones.stream().filter(zone -> zone.isInRegion(loc)).collect(Collectors.toList()); + } + + public ObsidianManager getObsidianManager() { + return om; + } + + + public List<ViceSelection> getZones() { + return zones; + } + + public void addZone(ViceSelection selection) { + this.zones.add(selection); + } + + public boolean removeZone(String name) { + List<ViceSelection> clone = this.zones; + for(ViceSelection z : clone) { + if(z.getName().equalsIgnoreCase(name)) { + this.zones.remove(z); + return true; + } + } + return false; + } + + public WarpManager getWarpManager() { + return wm; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/ZoneFlag.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/ZoneFlag.java new file mode 100644 index 0000000..f33172d --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/ZoneFlag.java @@ -0,0 +1,9 @@ +package net.grandtheftmc.vice.world; + +/** + * Created by Timothy Lampen on 8/25/2017. + */ +public enum ZoneFlag { + COP_TELEPORT_STATION, + COP_CANT_ARREST +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/events/PlayerEnterZoneEvent.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/events/PlayerEnterZoneEvent.java new file mode 100644 index 0000000..b573515 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/events/PlayerEnterZoneEvent.java @@ -0,0 +1,44 @@ +package net.grandtheftmc.vice.world.events; + +import net.grandtheftmc.vice.world.ViceSelection; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; + +/** + * Created by Timothy Lampen on 8/25/2017. + */ +public class PlayerEnterZoneEvent extends PlayerEvent implements Cancellable { + private static final HandlerList HANDLER_LIST = new HandlerList(); + private boolean cancelled; + private final ViceSelection zone; + + public PlayerEnterZoneEvent(Player who, ViceSelection zone) { + super(who); + this.zone = zone; + } + + public ViceSelection getZone() { + return zone; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean b) { + this.cancelled = b; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/events/PlayerLeaveZoneEvent.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/events/PlayerLeaveZoneEvent.java new file mode 100644 index 0000000..87fa874 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/events/PlayerLeaveZoneEvent.java @@ -0,0 +1,44 @@ +package net.grandtheftmc.vice.world.events; + +import net.grandtheftmc.vice.world.ViceSelection; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; + +/** + * Created by Timothy Lampen on 8/25/2017. + */ +public class PlayerLeaveZoneEvent extends PlayerEvent implements Cancellable { + private static final HandlerList HANDLER_LIST = new HandlerList(); + private boolean cancelled; + private final ViceSelection zone; + + public PlayerLeaveZoneEvent(Player who, ViceSelection zone) { + super(who); + this.zone = zone; + } + + public ViceSelection getZone() { + return zone; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean b) { + this.cancelled = b; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/obsidianbreaker/BlockStatus.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/obsidianbreaker/BlockStatus.java new file mode 100644 index 0000000..ebfdeae --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/obsidianbreaker/BlockStatus.java @@ -0,0 +1,90 @@ +package net.grandtheftmc.vice.world.obsidianbreaker; + +/** + * Created by Timothy Lampen on 7/2/2017. + */ +/** + * Stores damage data concerning one block + * + * @author oggehej + */ +public class BlockStatus { + private float damage = 0; + private float maxDamage; + private boolean modified = true; + private final String blockHash; + private final String chunkHash; + + /** + * An object that contains information about the + * damage taken and id it was recently modified. + */ + BlockStatus(String blockHash, String chunkHash, float maxDamage) { + this.blockHash = blockHash; + this.chunkHash = chunkHash; + this.maxDamage = maxDamage; + } + + /** + * Get current damage to block + * + * @return Damage + */ + public float getDamage() { + return damage; + } + + /** + * Set current damage to block + * + * @param damage Damage + */ + public void setDamage(float damage) { + this.damage = damage; + } + + /** + * Check whether the block was recently modified or not + * + * @return Recently modified + */ + public boolean isModified() { + return modified; + } + + /** + * Set whether the block was recently modified or not + * + * @param modified Recently modified + */ + public void setModified(boolean modified) { + this.modified = modified; + } + + /** + * Get the maximum amount of damage the block can take + * + * @return Max damage + */ + float getTotalDurability() { + return this.maxDamage; + } + + /** + * Get the block hash associated with this object + * + * @return Block hash + */ + public String getBlockHash() { + return blockHash; + } + + /** + * Get the chunk hash associated with this object + * + * @return Chunk hash + */ + public String getChunkHash() { + return chunkHash; + } +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/obsidianbreaker/DamageStorage.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/obsidianbreaker/DamageStorage.java new file mode 100644 index 0000000..c31ed4b --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/obsidianbreaker/DamageStorage.java @@ -0,0 +1,124 @@ +package net.grandtheftmc.vice.world.obsidianbreaker; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.vice.Vice; +import org.bukkit.Bukkit; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.block.Block; + +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Created by Timothy Lampen on 7/2/2017. + */ +public class DamageStorage { + + // The HashMaps inside the HashMap represent chunks + private final ConcurrentHashMap<String, ConcurrentHashMap<String, BlockStatus>> damage = new ConcurrentHashMap<String, ConcurrentHashMap<String, BlockStatus>>(); + + /** + * Generate a unique {@code String} for the {@code Block} {@code Location} + * + * @param loc Block location + * @return Unique string + */ + protected String generateBlockHash(Location loc) { + return loc.getWorld().getUID().toString() + ":" + loc.getBlockX() + ":" + loc.getBlockY() + ":" + loc.getBlockZ(); + } + + /** + * Generate a unique {@code String} for the {@code Chunk} {@code Location} + * + * @return Unique string + */ + protected String generateChunkHash(Chunk chunk) { + return chunk.getWorld().getUID().toString() + ":" + chunk.getX() + ":" + chunk.getZ(); + } + + /** + * Generate a {@code Location} from the unique {@code String} + * + * @param blockHash + * @return Location + */ + public Location generateLocation(String blockHash) { + try { + String[] s = blockHash.split(":"); + return new Location(Bukkit.getWorld(UUID.fromString(s[0])), Integer.parseInt(s[1]), Integer.parseInt(s[2]), Integer.parseInt(s[3])); + } catch(Exception e) { + Core.error("Couldn't generate hash from location (hash: " + blockHash + ")"); + return null; + } + } + + + /** + * Get the {@code BlockStatus} object of the block + * + * @param block The block + * @param create Whether we should create the object if it doesn't exist + * @return The {@code BlockStatus}, or null if it doesn't exist and create==false OR invalid block + */ + public BlockStatus getBlockStatus(Block block, boolean create) { + String chunkHash = generateChunkHash(block.getLocation().getChunk()); + Map<String, BlockStatus> chunkMap = null; + + if (damage.containsKey(chunkHash)) + chunkMap = damage.get(chunkHash); + else if (create) { + damage.put(chunkHash, new ConcurrentHashMap<String, BlockStatus>()); + chunkMap = damage.get(chunkHash); + } else + return null; + + String blockHash = generateBlockHash(block.getLocation()); + + if (chunkMap.containsKey(blockHash)) + return chunkMap.get(blockHash); + else if (create) { + chunkMap.put(blockHash, new BlockStatus(blockHash, chunkHash, 10)); + return chunkMap.get(blockHash); + } else { + return null; + } + } + + /** + * Remove the {@code BlockStatus} object from the map + * + * @param blockStatus + */ + public void removeBlockStatus(BlockStatus blockStatus) { + String chunkHash = blockStatus.getChunkHash(); + Map<String, BlockStatus> chunk = damage.get(chunkHash); + if(chunk == null) + return; + + chunk.remove(blockStatus.getBlockHash()); + + if(chunk.isEmpty()) + damage.remove(chunkHash); + } + + /** + * Render cracks in {@code Block} + * + * @param block Block + */ + public void renderCracks(Block block) { + BlockStatus status = getBlockStatus(block, false); + + if(status == null || status.getTotalDurability() <= 0) + return; + + int durability = 10 - (int) Math.ceil((status.getTotalDurability() - status.getDamage()) / status.getTotalDurability() * 10); + Vice.getWorldManager().getObsidianManager().getNMSHandler().sendCrackEffect(block.getLocation(), durability); + } + + public ConcurrentHashMap<String, ConcurrentHashMap<String, BlockStatus>> getBlocks() { + return damage; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/obsidianbreaker/ObsidianManager.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/obsidianbreaker/ObsidianManager.java new file mode 100644 index 0000000..31ae5d0 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/obsidianbreaker/ObsidianManager.java @@ -0,0 +1,171 @@ +package net.grandtheftmc.vice.world.obsidianbreaker; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.world.obsidianbreaker.nms.NMS; +import net.grandtheftmc.vice.world.obsidianbreaker.nms.Reflection; +import net.grandtheftmc.vice.world.obsidianbreaker.tasks.RegenTask; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Timothy Lampen on 7/2/2017. + */ +//note that this code has been borrowed from https://raw.githubusercontent.com/oggehej/ObsidianBreaker +public class ObsidianManager { + private DamageStorage damageStorage; + private NMS nmsHandler; + + + public ObsidianManager(){ + this.damageStorage = new DamageStorage(); + setupNMS(); + new RegenTask().runTaskTimerAsynchronously(Vice.getInstance(), 0,20*60*5);//every minute 2 damage is regenned. + } + + /** + * Check if we even handle the explosion for the specified block + * + * @param block Block to check + * @return Whether we're handling these kind of blocks + */ + private boolean isValidBlock(Block block) { + return block!=null && block.getType()== Material.OBSIDIAN; + } + + public void updateRange(double radius, Entity explosive, int damage){ + for(double x = explosive.getLocation().getBlockX()-radius; x<explosive.getLocation().getBlockX()+radius; x++){ + for(double y = explosive.getLocation().getBlockY()-radius; y<explosive.getLocation().getBlockY()+radius; y++){ + for(double z = explosive.getLocation().getBlockZ()-radius; z<explosive.getLocation().getBlockZ()+radius; z++){ + Block b = explosive.getWorld().getBlockAt(new Location(explosive.getWorld(), x, y, z)); + if(!isValidBlock(b)) + continue; + if(explosionThroughLiquid(explosive.getLocation(), b.getLocation())) + continue; + BlockStatus status = getDamageStorage().getBlockStatus(b, true); + if(status.getDamage()+damage>=status.getTotalDurability()) { + b.breakNaturally(); + getDamageStorage().removeBlockStatus(status); + getNMSHandler().sendCrackEffect(b.getLocation(), -1); + } + else { + status.setDamage(status.getDamage() + damage); + getDamageStorage().renderCracks(b); + } + } + } + } + } + + + private boolean explosionThroughLiquid(Location explosionSource, Location block) { + if(explosionSource.getWorld().getBlockAt(block).getType()== Material.BEDROCK || explosionSource.getBlock().getType()==Material.WATER || explosionSource.getBlock().getType()==Material.STATIONARY_WATER) + return true; + List<Block> list = new ArrayList<Block>(); + int i, dx, dy, dz, l, m, n, x_inc, y_inc, z_inc, err_1, err_2, dx2, dy2, dz2; + int pixelX, pixelY, pixelZ; + + pixelX = explosionSource.getBlockX(); + pixelY = explosionSource.getBlockY(); + pixelZ = explosionSource.getBlockZ(); + dx = block.getBlockX() - explosionSource.getBlockX(); + dy = block.getBlockY() - explosionSource.getBlockY(); + dz = block.getBlockZ() - explosionSource.getBlockZ(); + x_inc = (dx < 0) ? -1 : 1; + l = Math.abs(dx); + y_inc = (dy < 0) ? -1 : 1; + m = Math.abs(dy); + z_inc = (dz < 0) ? -1 : 1; + n = Math.abs(dz); + dx2 = l << 1; + dy2 = m << 1; + dz2 = n << 1; + + if ((l >= m) && (l >= n)) { + err_1 = dy2 - l; + err_2 = dz2 - l; + for (i = 0; i < l; i++) { + list.add(explosionSource.getWorld().getBlockAt(pixelX, pixelY, pixelZ)); + if (err_1 > 0) { + pixelY += y_inc; + err_1 -= dx2; + } + if (err_2 > 0) { + pixelZ += z_inc; + err_2 -= dx2; + } + err_1 += dy2; + err_2 += dz2; + pixelX += x_inc; + } + } else if ((m >= l) && (m >= n)) { + err_1 = dx2 - m; + err_2 = dz2 - m; + for (i = 0; i < m; i++) { + list.add(explosionSource.getWorld().getBlockAt(pixelX, pixelY, pixelZ)); + if (err_1 > 0) { + pixelX += x_inc; + err_1 -= dy2; + } + if (err_2 > 0) { + pixelZ += z_inc; + err_2 -= dy2; + } + err_1 += dx2; + err_2 += dz2; + pixelY += y_inc; + } + } else { + err_1 = dy2 - n; + err_2 = dx2 - n; + for (i = 0; i < n; i++) { + list.add(explosionSource.getWorld().getBlockAt(pixelX, pixelY, pixelZ)); + if (err_1 > 0) { + pixelY += y_inc; + err_1 -= dz2; + } + if (err_2 > 0) { + pixelX += x_inc; + err_2 -= dz2; + } + err_1 += dy2; + err_2 += dx2; + pixelZ += z_inc; + } + } + list.add(explosionSource.getWorld().getBlockAt(pixelX, pixelY, pixelZ)); + + return list.stream().filter(Block::isLiquid).findFirst().isPresent(); + } + + public DamageStorage getDamageStorage() { + return damageStorage; + } + + private void setupNMS() { + String packageName = Bukkit.getServer().getClass().getPackage().getName(); + String version = packageName.substring(packageName.lastIndexOf('.') + 1); + + try { + final Class<?> clazz = Class.forName(getClass().getPackage().getName() + ".nms." + version); + if (NMS.class.isAssignableFrom(clazz)) { + Vice.log("Using NMS version " + version); + this.nmsHandler = (NMS) clazz.getConstructor().newInstance(); + } + } catch (final Exception e) { + Vice.log("Could not find NMS version " + version + ". Falling back to reflections. Are you sure you're using the latest version?\n" + + "If you are using the latest verion and an error appears later on or block cracks don't work, contact the plugin author. " + + "Otherwise everything should function normally."); + this.nmsHandler = new Reflection(); + } + } + + public NMS getNMSHandler() { + return nmsHandler; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/obsidianbreaker/nms/NMS.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/obsidianbreaker/nms/NMS.java new file mode 100644 index 0000000..dde287f --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/obsidianbreaker/nms/NMS.java @@ -0,0 +1,10 @@ +package net.grandtheftmc.vice.world.obsidianbreaker.nms; + +/** + * Created by Timothy Lampen on 7/2/2017. + */ +import org.bukkit.Location; + +public interface NMS { + public void sendCrackEffect(Location location, int damage); +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/obsidianbreaker/nms/Reflection.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/obsidianbreaker/nms/Reflection.java new file mode 100644 index 0000000..9a17221 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/obsidianbreaker/nms/Reflection.java @@ -0,0 +1,33 @@ +package net.grandtheftmc.vice.world.obsidianbreaker.nms; + +import org.bukkit.Bukkit; +import org.bukkit.Location; + +/** + * Created by Timothy Lampen on 7/2/2017. + */ +public class Reflection implements NMS { + private boolean failed = false; + + @Override + public void sendCrackEffect(Location location, int damage) { + if(!failed) { + try { + int x = location.getBlockX(), y = location.getBlockY(), z = location.getBlockZ(); + Object worldHandle = location.getWorld().getClass().getMethod("getHandle").invoke(location.getWorld()); + Object blockPosition = ReflectionUtils.getNMSClass("BlockPosition").getConstructor(Integer.TYPE, Integer.TYPE, Integer.TYPE).newInstance(x, y, z); + int dimension = worldHandle.getClass().getField("dimension").getInt(worldHandle); + Object packet = ReflectionUtils.getNMSClass("PacketPlayOutBlockBreakAnimation") + .getConstructor(Integer.TYPE, ReflectionUtils.getNMSClass("BlockPosition"), Integer.TYPE) + .newInstance(location.hashCode(), blockPosition, damage); + Object serverHandle = Bukkit.getServer().getClass().getMethod("getHandle").invoke(Bukkit.getServer()); + serverHandle.getClass() + .getMethod("sendPacketNearby", ReflectionUtils.getNMSClass("EntityHuman"), Double.TYPE, Double.TYPE, Double.TYPE, Double.TYPE, Integer.TYPE, ReflectionUtils.getNMSClass("Packet")) + .invoke(serverHandle, null, x, y, z, 30, dimension, packet); + } catch(Exception e) { + failed = true; + System.err.println("[ObsidianBreaker] Generic reflection failed. Visible block cracks are disabled. Please contact the plugin author."); + } + } + } +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/obsidianbreaker/nms/ReflectionUtils.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/obsidianbreaker/nms/ReflectionUtils.java new file mode 100644 index 0000000..7acf98d --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/obsidianbreaker/nms/ReflectionUtils.java @@ -0,0 +1,77 @@ +package net.grandtheftmc.vice.world.obsidianbreaker.nms; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import java.util.HashMap; + +/** + * Created by Timothy Lampen on 7/2/2017. + */ +public class ReflectionUtils { + private static HashMap<String, Class<?>> nmsClasses = new HashMap<String, Class<?>>(); + + /** + * Get the current server revision. + * <p>Example: v1_8_R3 + */ + public static String getVersion() { + String name = Bukkit.getServer().getClass().getPackage().getName(); + String version = name.substring(name.lastIndexOf('.') + 1) + "."; + return version; + } + + /** + * Get the NMS class with the specified name + */ + public static Class<?> getNMSClass(String className) { + Class<?> clazz = null; + if(nmsClasses.containsKey(className)) { + clazz = nmsClasses.get(className); + } else { + String fullName = "net.minecraft.server." + getVersion() + className; + try { + clazz = Class.forName(fullName); + } catch (Exception e) { + System.err.println("Could not find NMS class!"); + e.printStackTrace(); + } + nmsClasses.put(className, clazz); + } + return clazz; + } + + /** + * Get the player connection as a generic object + */ + public static Object getConnection(Player player) { + try { + Object nmsPlayer = getPlayerHandle(player); + return nmsPlayer.getClass().getField("playerConnection").get(nmsPlayer); + } catch(Exception e) { + System.err.println("Could not fetch player connection!"); + e.printStackTrace(); + return null; + } + } + + /** + * Get the handle of specified player + */ + public static Object getPlayerHandle(Player player) { + try { + return player.getClass().getMethod("getHandle").invoke(player); + } catch (Exception e) { + System.err.println("Could not get player handle!"); + e.printStackTrace(); + return null; + } + } + + /** + * Clear the NMS class cache + */ + public static void clearCache() { + nmsClasses.clear(); + } +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/obsidianbreaker/tasks/RegenTask.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/obsidianbreaker/tasks/RegenTask.java new file mode 100644 index 0000000..a7919d9 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/obsidianbreaker/tasks/RegenTask.java @@ -0,0 +1,36 @@ +package net.grandtheftmc.vice.world.obsidianbreaker.tasks; + +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.world.obsidianbreaker.BlockStatus; +import org.bukkit.block.Block; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.concurrent.ConcurrentHashMap; + +/** + * Created by Timothy Lampen on 7/3/2017. + */ +public class RegenTask extends BukkitRunnable{ + @Override + public void run() { + try { + for(ConcurrentHashMap<String, BlockStatus> map : Vice.getWorldManager().getObsidianManager().getDamageStorage().getBlocks().values()) { + for(BlockStatus status : map.values()) { + if(status.isModified()) + status.setModified(false); + else { + status.setDamage(status.getDamage() - 2); + Block b = Vice.getWorldManager().getObsidianManager().getDamageStorage().generateLocation(status.getBlockHash()).getBlock(); + if(b==null) + continue; + Vice.getWorldManager().getObsidianManager().getDamageStorage().renderCracks(b); + if(status.getDamage()<=0) + Vice.getWorldManager().getObsidianManager().getDamageStorage().removeBlockStatus(status); + } + } + } + } catch(Exception e) { + Vice.error("Error occured while trying to regen block (tasks "+getTaskId()+")"); + } + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/warps/Warp.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/warps/Warp.java new file mode 100644 index 0000000..e594686 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/warps/Warp.java @@ -0,0 +1,31 @@ +package net.grandtheftmc.vice.world.warps; + +import org.bukkit.Location; + +public class Warp { + + private String name; + private Location location; + + public Warp(String name, Location location) { + this.name = name; + this.location = location; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public Location getLocation() { + return this.location; + } + + public void setLocation(Location location) { + this.location = location; + } + +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/warps/WarpCache.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/warps/WarpCache.java new file mode 100644 index 0000000..0691299 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/warps/WarpCache.java @@ -0,0 +1,44 @@ +package net.grandtheftmc.vice.world.warps; + +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.vice.users.TaxiTarget; +import net.grandtheftmc.vice.users.ViceUser; + +/** + * Created by Luke Bingham. + */ +public class WarpCache { + + private final User user; + private final ViceUser viceUser; + private final TaxiTarget target; + private final int price, delay; + + public WarpCache(User user, ViceUser viceUser, TaxiTarget target, int price, int delay) { + this.user = user; + this.viceUser = viceUser; + this.target = target; + this.price = price; + this.delay = delay; + } + + public User getUser() { + return user; + } + + public ViceUser getViceUser() { + return viceUser; + } + + public TaxiTarget getTarget() { + return target; + } + + public int getPrice() { + return price; + } + + public int getDelay() { + return delay; + } +} diff --git a/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/warps/WarpManager.java b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/warps/WarpManager.java new file mode 100644 index 0000000..0046674 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/java/net/grandtheftmc/vice/world/warps/WarpManager.java @@ -0,0 +1,657 @@ +package net.grandtheftmc.vice.world.warps; + +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.util.State; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.users.Pref; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.vice.Vice; +import net.grandtheftmc.vice.ViceUtils; +import net.grandtheftmc.vice.events.TPEvent; +import net.grandtheftmc.vice.events.TPEvent.TPType; +import net.grandtheftmc.vice.users.ViceRank; +import net.grandtheftmc.vice.users.ViceUser; +import net.grandtheftmc.vice.users.TaxiTarget; +import net.grandtheftmc.vice.users.TaxiTarget.TargetType; +import net.grandtheftmc.vice.users.storage.BooleanStorageType; +import org.bukkit.*; +import org.bukkit.block.BlockFace; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.*; +import java.util.stream.Collectors; + +public class WarpManager { + + private Warp tutorialSpawn; + private Warp spawn; + private Warp jail; + private List<Warp> warps = new ArrayList<>(); + private Map<Location, String> warpPads = new HashMap<>(); + private final HashMap<UUID, WarpCache> warpCache = Maps.newHashMap(); + private final HashSet<UUID> toRemove = Sets.newHashSet(); + + public WarpManager() { + this.loadWarps(); + + new BukkitRunnable() { + @Override public void run() { + if(!warpCache.isEmpty()) { + + // for each player + for (UUID uuid : warpCache.keySet()) { + + try{ + Player player = Bukkit.getPlayer(uuid); + if (player == null || !player.isOnline()) { + toRemove.add(uuid); + continue; + } + + WarpCache cache = warpCache.get(uuid); + if (cache == null) { + toRemove.add(uuid); + continue; + } + + int timer = cache.getViceUser().getTaxiTimer(); + if (cache.getViceUser().isInCombat()) { + player.sendMessage(Utils.f(Lang.COMBATTAG + "&7You can't call a cab while in combat!")); + cache.getViceUser().unsetTaxiTarget(); + toRemove.add(uuid); + continue; + } + + if (timer == 15 || timer == 10 || (timer <= 5 && timer > 0)) { + player.sendMessage(Utils.f(Lang.TAXI + "&eYour taxi is arriving in &a" + timer + " &esecond" + + (timer == 1 ? "" : "s") + '!')); + if (timer == 1) { + player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 50, 0)); + player.playSound(player.getLocation(), Sound.BLOCK_LAVA_EXTINGUISH, 0.5F, 1); + } else + player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 4.0F / timer, 2); + } + + if (timer == 0) { + if (!cache.getUser().isRank(UserRank.ELITE)) { + if (!cache.getViceUser().hasMoney(cache.getViceUser().getTaxiPrice())) { + player.sendMessage(Utils.f(Lang.TAXI + "&eYou can't afford to pay &a$&l" + + cache.getViceUser().getTaxiPrice() + "&e for the ride! Taxi cancelled.")); + toRemove.add(uuid); + continue; + } + } + + TaxiTarget target = cache.getViceUser().getTaxiTarget(); + if (target == null) { + cache.getViceUser().unsetTaxiTarget(); + player.sendMessage(Lang.TAXI.f("&eYour target could not be reached!")); + toRemove.add(uuid); + continue; + } + + Location tpLoc = target.getExactLocation(); + TPEvent e = new TPEvent(player, target.getTargetPlayer(), + target.getType() == TargetType.PLAYER ? TPType.TP_COMPLETE : TPType.WARP).call(); + if (e.isCancelled()) { + cache.getViceUser().unsetTaxiTarget(); + toRemove.add(uuid); + player.sendMessage(Lang.TAXI.f(e.getCancelMessage())); + continue; + } + + if (e.targetLocationIsChanged()) + tpLoc = e.getTargetLocation(); + + // if warping an entity or player + if (target.getType() == TargetType.ENTITY || target.getType() == TargetType.PLAYER){ + + // if they are tping to air + if (tpLoc != null && tpLoc.getBlock().getRelative(BlockFace.DOWN).getType() == Material.AIR){ + tpLoc = tpLoc.getWorld().getHighestBlockAt(tpLoc).getLocation(); + } + } + + if (tpLoc == null) { + cache.getViceUser().unsetTaxiTarget(); + toRemove.add(uuid); + player.sendMessage(Lang.TAXI.f("&eYour destination could not be reached!")); + continue; + } + + player.teleport(tpLoc); + cache.getViceUser().setLastTeleport(); +// if(cache.getViceUser().getCheatCodeState(CheatCode.SNEAKY).getState()== State.ON) { +// player.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, 20*10, 0)); +// } + int price = cache.getViceUser().getTaxiPrice(); + cache.getViceUser().unsetTaxiTarget(); + player.sendMessage(Utils.f(Lang.TAXI + "&eThe taxi dropped you off at your destination" + (target.getWarp() != null ? " (" + target.getWarp().getName() + ")" : "."))); + if (price > 0 && !cache.getUser().isRank(UserRank.ELITE)) { + cache.getViceUser().takeMoney(price); + ViceUtils.updateBoard(player, Core.getUserManager().getLoadedUser(player.getUniqueId()), cache.getViceUser()); + Lang.MONEY_TAKE.f(String.valueOf(price)); + } + + toRemove.add(uuid); + continue; + } + + cache.getViceUser().setTaxiTimer(timer - 1); + } + catch(Exception e){ + // if we get here there's a null pointer somewhere + // stops bug affecting multiple users + e.printStackTrace(); + toRemove.add(uuid); + } + } + } + + if(toRemove.isEmpty()) return; + for(UUID uuid : toRemove) warpCache.remove(uuid); + toRemove.clear(); + } + }.runTaskTimer(Vice.getInstance(), 20L, 20L); + } + + public Warp getTutorialSpawn() { + return this.tutorialSpawn; + } + + public void setTutorialSpawn(Location location) { + this.tutorialSpawn = new Warp("tutorialSpawn", location); + } + + public Warp getSpawn() { + return this.spawn; + } + + public void setSpawn(Location location) { + this.spawn = new Warp("spawn", location); + } + + public Warp getJail() { + return this.jail; + } + + public void setJail(Location location) { + this.jail = new Warp("jail", location); + } + + public List<Warp> getWarps() { + return this.warps; + } + + public Warp getRandomWarp() { + if (this.warps.isEmpty()) + return null; + return this.warps.get(Utils.getRandom().nextInt(this.warps.size())); + } + + public Warp getWarp(String warpName) { + return this.warps.stream().filter(warp -> warp.getName().equalsIgnoreCase(warpName)).findFirst().orElse(null); + } + + public void addWarp(Warp warp) { + this.warps.add(warp); + } + + public void removeWarp(Warp warp) { + this.warps.remove(warp); + } + + public boolean cancelTaxi(Player player, ViceUser viceUser) { +// if (viceUser.getTaxiTaskId() == -1) +// return false; +// Bukkit.getScheduler().cancelTask(viceUser.getTaxiTaskId()); +// viceUser.unsetTaxiTarget(); + + if(player == null || viceUser == null) return false; + if(!warpCache.containsKey(player.getUniqueId())) return false; + + viceUser.unsetTaxiTarget(); + warpCache.remove(player.getUniqueId()); + + return true; + } + + public void warp(Player player, User user, ViceUser viceUser, TaxiTarget target) { + this.warp(player, user, viceUser, target, 0, -1, null); + } + + public void warp(Player player, User user, ViceUser viceUser, TaxiTarget target, int price) { + this.warp(player, user, viceUser, target, price, -1, null); + } + + public void warp(Player player, User user, ViceUser viceUser, TaxiTarget target, int price, int delay) { + this.warp(player, user, viceUser, target, price, delay, null); + } + + public void warp(Player player, User user, ViceUser viceUser, TaxiTarget target, int price, int delay, String msg) { + ViceUtils.giveGameItems(player); + if (delay < 0) + delay = Objects.equals(player.getWorld().getName(), "spawn") && user.isPremium() ? 1 : ViceUtils.getWarpDelay(user.getUserRank()); + UUID uuid = player.getUniqueId(); + if (viceUser.cancelVehicleTeleport()) + player.sendMessage(Lang.VEHICLES.f("&7You cancelled " + (viceUser.getBooleanFromStorage(BooleanStorageType.SEND_AWAY) ? "sending away" : "calling") + " your personal vehicle!")); + if (this.cancelTaxi(player, viceUser)) + player.sendMessage(Utils.f(Lang.TAXI + "&eThe previous taxi was cancelled.")); + if (player.getGameMode() == GameMode.SPECTATOR) { + player.sendMessage(Lang.TAXI.f("&7You can't teleport to players while you're dead!")); + return; + } + if (viceUser.isInCombat()) { + player.sendMessage(Utils.f(Lang.COMBATTAG + "&7You can't call a cab while in combat!")); + return; + } + if (user.isInTutorial()) return; + if (viceUser.isArrested()) { + player.sendMessage(Lang.JAIL.f("&7You can't teleport in jail!")); + return; + } + if (price > 0 && !user.isRank(UserRank.ELITE)) { + if (!viceUser.hasMoney(price)) { + player.sendMessage(Utils.f(Lang.TAXI + "&eYou can't afford to pay &a$&l" + + price + "&e for the ride! Taxi cancelled.")); + return; + } + } + if (target == null || target.getExactLocation() == null) { + player.sendMessage(Utils.f(Lang.TAXI + "&eThat location does not exist!")); + return; + } + player.sendMessage(Lang.TAXI.f( msg == null ? "&eYou called a taxi!" : msg )); + final Location origin = player.getLocation(); + viceUser.setTaxiTimer(delay); + viceUser.setTaxiTarget(target); + viceUser.setTaxiPrice(price); + + this.warpCache.put(uuid, new WarpCache(user, viceUser, target, price, delay)); + +// viceUser.setTaxiTaskId(new BukkitRunnable() { +// @Override +// public void run() { +// Player player = Bukkit.getPlayer(uuid); +// if (player == null) { +// this.cancel(); +// return; +// } +// ViceUser viceUser = Vice.getUserManager().getLoadedUser(uuid); +// int timer = viceUser.getTaxiTimer(); +// if (viceUser.isInCombat()) { +// player.sendMessage(Utils.f(Lang.COMBATTAG + "&7You can't call a cab while in combat!")); +// viceUser.unsetTaxiTarget(); +// this.cancel(); +// return; +// } +// if(player.getWorld().getName().equals(origin.getWorld().getName()) && player.getLocation().distance(origin)>1) { +// player.sendMessage(Utils.f(Lang.WARP + "&7You cannot move while calling a taxi!")); +// viceUser.unsetTaxiTarget(); +// this.cancel(); +// return; +// } +// if (timer == 15 || timer == 10 || (timer <= 5 && timer > 0)) { +// player.sendMessage(Utils.f(Lang.TAXI + "&eYour taxi is arriving in &a" + timer + " &esecond" +// + (timer == 1 ? "" : "s") + '!')); +// if (timer == 1) { +// player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 50, 0)); +// player.playSound(player.getLocation(), Sound.BLOCK_LAVA_EXTINGUISH, 0.5F, 1); +// } else +// player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 4.0F / timer, 2); +// } +// if (timer <= 0) { +// this.cancel(); +// if (!user.isRank(UserRank.ELITE)) { +// if (!viceUser.hasMoney(viceUser.getTaxiPrice())) { +// player.sendMessage(Utils.f(Lang.TAXI + "&eYou can't afford to pay &a$&l" +// + viceUser.getTaxiPrice() + "&e for the ride! Taxi cancelled.")); +// return; +// } +// } +// TaxiTarget target = viceUser.getTaxiTarget(); +// if (target == null) { +// viceUser.unsetTaxiTarget(); +// player.sendMessage(Lang.TAXI.f("&eYour target could not be reached!")); +// return; +// } +// Location tpLoc = target.getExactLocation(); +// TPEvent e = new TPEvent(player, target.getTargetPlayer(), +// target.getType() == TargetType.PLAYER ? TPType.TP_COMPLETE : TPType.WARP).call(); +// if (e.isCancelled()) { +// viceUser.unsetTaxiTarget(); +// player.sendMessage(Lang.TAXI.f(e.getCancelMessage())); +// return; +// } +// if (e.targetLocationIsChanged()) +// tpLoc = e.getTargetLocation(); +// if ((target.getType() == TargetType.ENTITY || target.getType() == TargetType.PLAYER) && tpLoc.getBlock().getRelative(BlockFace.DOWN).getType() == Material.AIR) +// tpLoc = tpLoc.getWorld().getHighestBlockAt(tpLoc).getLocation(); +// if (tpLoc == null) { +// viceUser.unsetTaxiTarget(); +// player.sendMessage(Lang.TAXI.f("&eYour destination could not be reached!")); +// return; +// } +// if(target.getWarp()!=null && target.getWarp().equals(getSpawn())) +// if(player.hasPotionEffect(PotionEffectType.INVISIBILITY)) +// player.removePotionEffect(PotionEffectType.INVISIBILITY); +// player.teleport(tpLoc); +// viceUser.setLastTeleport(); +// int price = viceUser.getTaxiPrice(); +// viceUser.unsetTaxiTarget(); +// player.sendMessage(Utils.f(Lang.TAXI + "&eThe taxi dropped you off at your destination.")); +// if (price > 0 && !user.isRank(UserRank.ELITE)) { +// viceUser.takeMoney(price); +// ViceUtils.updateBoard(player, Core.getUserManager().getLoadedUser(player.getUniqueId()), viceUser); +// Lang.MONEY_TAKE.f(String.valueOf(price)); +// } +// return; +// } +// viceUser.setTaxiTimer(timer - 1); +// } +// }.runTaskTimer(Vice.getInstance(), 20, 20).getTaskId()); + + } + + public void tpa(Player player, User user, ViceUser viceUser, Player target) { + ViceUtils.giveGameItems(player); + if (target == null) { + player.sendMessage(Utils.f(Lang.TAXI + "&eThat player is not online!")); + return; + } + ViceUser targetViceUser = Vice.getUserManager().getLoadedUser(target.getUniqueId()); + if (!user.isSpecial() && !viceUser.isRank(ViceRank.FALCON) && !viceUser.isCop()) { + player.sendMessage(Utils.f(Lang.TAXI + + "&eYou don't have access to teleport to other players! Buy &6&lVIP&e to unlock it!")); + return; + } + if (player.getGameMode() == GameMode.SPECTATOR) { + player.sendMessage(Lang.TAXI.f("&7You can't teleport to players while you're dead!")); + return; + } + if (viceUser.isInCombat()) { + player.sendMessage(Utils.f(Lang.COMBATTAG + "&7You can't call a cab while in combat!")); + return; + } + if (targetViceUser.isInCombat()) { + player.sendMessage(Utils.f(Lang.COMBATTAG + target.getDisplayName() + "&7 is in combat!")); + return; + } + if (user.isInTutorial()) return; + if (viceUser.isArrested()) { + player.sendMessage(Lang.JAIL.f("&7You can't teleport in jail!")); + return; + } + UUID uuid = player.getUniqueId(); + if (viceUser.cancelVehicleTeleport()) + player.sendMessage(Lang.VEHICLES.f("&7You cancelled " + (viceUser.getBooleanFromStorage(BooleanStorageType.SEND_AWAY) ? "sending away" : "calling") + " your personal vehicle!")); + if (this.cancelTaxi(player, viceUser)) + player.sendMessage(Utils.f(Lang.TAXI + "&eThe previous taxi was cancelled.")); + + User targetUser = Core.getUserManager().getLoadedUser(target.getUniqueId()); + if (!targetUser.getPref(Pref.TP_REQUESTS)) { + player.sendMessage(Utils.f(Lang.TAXI + "&eThat player has disabled teleport requests!")); + return; + } + if (targetUser.isInTutorial()) { + player.sendMessage(Lang.TUTORIALS.f("&7That player is in a tutorial!")); + return; + } + TPEvent e = new TPEvent(player, target, TPType.TPA_REQ).call(); + if (e.isCancelled()) { + viceUser.unsetTpaRequests(); + player.sendMessage(Lang.TAXI.f(e.getCancelMessage())); + return; + } + player.sendMessage( + Utils.f(Lang.TAXI + "&eYou requested to teleport to " + targetUser.getColoredName(target) + "&e!")); + target.sendMessage(Utils.f(Lang.TAXI + user.getColoredName(player) + + "&e requested to teleport to you. Use &a\'/tpaccept\'&e to accept.")); + viceUser.setTpaRequestSentUUID(target.getUniqueId()); + viceUser.setBooleanToStorage(BooleanStorageType.TPA_HERE, false); + targetViceUser.setTpaRequestUUID(uuid); + } + + public void tpaHere(Player player, User user, ViceUser viceUser, Player target) { + ViceUtils.giveGameItems(player); + if (target == null) { + player.sendMessage(Utils.f(Lang.TAXI + "&eThat player is not online!")); + return; + } + ViceUser targetViceUser = Vice.getUserManager().getLoadedUser(target.getUniqueId()); + if (!user.getUserRank().isHigherThan(UserRank.PREMIUM) && !viceUser.isCop()) { + player.sendMessage(Utils.f(Lang.TAXI + + "&eYou don't have access to teleport other players to yourself! Buy &b&lELITE&e to unlock it!")); + return; + } + if (player.getGameMode() == GameMode.SPECTATOR) { + player.sendMessage(Lang.TAXI.f("&7You can't teleport players to you while you're dead!")); + return; + } + if (viceUser.isArrested()) { + player.sendMessage(Lang.JAIL.f("&7You can't teleport players to yourself in jail!")); + return; + } + if (viceUser.isInCombat()) { + player.sendMessage(Utils.f(Lang.COMBATTAG + "&7You can't request teleportation while in combat!")); + return; + } + if (targetViceUser.isInCombat()) { + player.sendMessage(Utils.f(Lang.COMBATTAG + target.getDisplayName() + "&7 is in combat!")); + return; + } + if (user.isInTutorial()) return; + if (target.getGameMode() == GameMode.SPECTATOR) { + player.sendMessage(Lang.TAXI.f("&7You can't teleport dead players to you!")); + return; + } + UUID uuid = player.getUniqueId(); + if (viceUser.cancelVehicleTeleport()) + player.sendMessage(Lang.VEHICLES.f("&7You cancelled " + (viceUser.getBooleanFromStorage(BooleanStorageType.SEND_AWAY) ? "sending away" : "calling") + " your personal vehicle!")); + if (this.cancelTaxi(player, viceUser)) + player.sendMessage(Utils.f(Lang.TAXI + "&eThe previous taxi was cancelled.")); + User targetUser = Core.getUserManager().getLoadedUser(target.getUniqueId()); + if (!targetUser.getPref(Pref.TP_REQUESTS)) { + player.sendMessage(Utils.f(Lang.TAXI + "&eThat player has disabled teleport requests!")); + return; + } + if (targetUser.isInTutorial()) { + player.sendMessage(Lang.TUTORIALS.f("&7That player is in a tutorial!")); + return; + } + TPEvent e = new TPEvent(player, target, TPType.TPAHERE_REQ).call(); + if (e.isCancelled()) { + viceUser.unsetTpaRequests(); + player.sendMessage(Lang.TAXI.f(e.getCancelMessage())); + return; + } + player.sendMessage( + Utils.f(Lang.TAXI + "&eYou requested " + targetUser.getColoredName(target) + "&e to teleport to you!")); + target.sendMessage(Utils.f(Lang.TAXI + user.getColoredName(player) + + "&e requested you to teleport to them. Use &a\'/tpaccept\'&e to accept.")); + viceUser.setTpaRequestSentUUID(target.getUniqueId()); + viceUser.setBooleanToStorage(BooleanStorageType.TPA_HERE, true); + targetViceUser.setTpaRequestUUID(uuid); + } + + public void tpDeny(Player player, User user, ViceUser viceUser) { + ViceUtils.giveGameItems(player); + if (!viceUser.hasTpaRequest()) { + player.sendMessage(Utils.f(Lang.TAXI + "&eNobody has requested to teleport to you!")); + return; + } + if (user.isInTutorial()) return; + Player target = Bukkit.getPlayer(viceUser.getTpaRequestUUID()); + if (target == null) { + player.sendMessage(Utils.f(Lang.TAXI + "&eNobody has requested to teleport to you!")); + return; + } + User targetUser = Core.getUserManager().getLoadedUser(target.getUniqueId()); + ViceUser targetViceUser = Vice.getUserManager().getLoadedUser(target.getUniqueId()); + if (!targetUser.isInTutorial()) + target.sendMessage(Lang.TAXI.f("&a" + user.getColoredName(player) + "&e denied your request!")); + player.sendMessage(Lang.TAXI.f("&e You denied &a" + targetUser.getColoredName(target) + "&e's request!")); + targetViceUser.unsetTpaRequests(); + viceUser.unsetTpaRequests(); + } + + public void tpAccept(Player target, User targetUser, ViceUser targetViceUser) { + ViceUtils.giveGameItems(target); + if (!targetViceUser.hasTpaRequest()) { + target.sendMessage(Utils.f(Lang.TAXI + "&eNobody has requested to teleport to you!")); + return; + } + if (target.getGameMode() == GameMode.SPECTATOR) { + target.sendMessage(Lang.VEHICLES.f("&7You can't teleport while you're dead!")); + return; + } + if (targetViceUser.isArrested()) { + target.sendMessage(Lang.JAIL.f("&7You can't teleport in jail!")); + return; + } + if (targetUser.isInTutorial()) return; + UUID uuid = targetViceUser.getTpaRequestUUID(); + Player player = Bukkit.getPlayer(uuid); + if (player == null) { + target.sendMessage(Utils.f(Lang.TAXI + "&eNobody has requested to teleport to you!")); + return; + } + ViceUser viceUser = Vice.getUserManager().getLoadedUser(uuid); + if (viceUser.isInCombat()) { + player.sendMessage(Utils.f(Lang.COMBATTAG + "&7Teleport cancelled due to combat tag!")); + return; + } + if (targetViceUser.isInCombat()) { + player.sendMessage(Utils.f(Lang.COMBATTAG + "&7Teleport cancelled due to combat tag!")); + return; + } + if (player.getGameMode() == GameMode.SPECTATOR) { + target.sendMessage(Lang.VEHICLES.f("&7You can't teleport to a dead player!")); + return; + } + if (viceUser.isArrested()) { + target.sendMessage(Lang.JAIL.f("&7You can't teleport in jail!")); + return; + } + User user = Core.getUserManager().getLoadedUser(uuid); + if (user.isInTutorial()) { + target.sendMessage(Lang.TUTORIALS.f("&7That player is in a tutorial!")); + return; + } + if (viceUser.getBooleanFromStorage(BooleanStorageType.TPA_HERE)) { + int delay = ViceUtils.getWarpDelay(targetUser.getUserRank()); + TPEvent e = new TPEvent(target, player, TPType.TPAHERE_ACCEPT).call(); + if (e.isCancelled()) { + targetViceUser.unsetTpaRequests(); + viceUser.unsetTpaRequests(); + target.sendMessage(Lang.TAXI.f(e.getCancelMessage())); + return; + } + target.sendMessage(Utils.f(Lang.TAXI + "&eYou accepted &a" + user.getColoredName(player) + + "&e's request to teleport to them!")); + player.sendMessage(Utils.f(Lang.TAXI + "&a" + targetUser.getColoredName(target) + "&e accepted your request to teleport to them! Their cab will arrive in &a" + delay + "&e second" + (delay == 1 ? "" : "s"))); + targetViceUser.unsetTpaRequests(); + viceUser.unsetTpaRequests(); + this.warp(target, targetUser, targetViceUser, new TaxiTarget(player), 0, delay); + return; + } + int delay = ViceUtils.getWarpDelay(user.getUserRank()); + TPEvent e = new TPEvent(player, target, TPType.TPA_ACCEPT).call(); + if (e.isCancelled()) { + targetViceUser.unsetTpaRequests(); + viceUser.unsetTpaRequests(); + player.sendMessage(Lang.TAXI.f(e.getCancelMessage())); + return; + } + target.sendMessage(Utils.f(Lang.TAXI + "&eYou accepted &a" + user.getColoredName(player) + + "&e's teleport request. Their cab will arrive in &a" + delay + "&e second" + (delay == 1 ? "" : "s") + + '!')); + player.sendMessage( + Utils.f(Lang.TAXI + "&a" + targetUser.getColoredName(target) + "&e accepted your teleport request!")); + targetViceUser.unsetTpaRequests(); + viceUser.unsetTpaRequests(); + this.warp(player, user, viceUser, new TaxiTarget(target), 0, delay); + } + + + public void backupAccept(Player player, ViceUser viceUser, Player target, ViceUser targetViceUser) { + User targetUser = Core.getUserManager().getLoadedUser(target.getUniqueId()); + ViceUtils.giveGameItems(target); + if (targetUser.isInTutorial()) return; + if (viceUser.isCop()) { + player.sendMessage(Lang.COP_MODE.f("&7You must be in &3&lCOP Mode&7 to request backup!")); + return; + } + if (player.getGameMode() == GameMode.SPECTATOR) { + player.sendMessage(Lang.VEHICLES.f("&7You can't teleport while you're dead!")); + return; + } + if (target.getGameMode() == GameMode.SPECTATOR || !targetViceUser.hasRequestedBackup()) { + player.sendMessage(Lang.COP_MODE.f("&7That player has not requested backup!")); + return; + } + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if (user.isInTutorial()) + return; + + int delay = ViceUtils.getWarpDelay(user.getUserRank()); + TPEvent e = new TPEvent(player, target, TPType.BACKUP).call(); + if (e.isCancelled()) { + player.sendMessage(Lang.COP_MODE.f(e.getCancelMessage())); + return; + } + target.sendMessage(Lang.COP_MODE.f("&7" + user.getColoredName(player) + "&7 has accepted your backup request. They will arrive in &a" + delay + "&e second" + (delay == 1 ? "" : "s") + + '!')); + player.sendMessage( + Utils.f(Lang.COP_MODE.f("&7You are providing backup to " + targetUser.getColoredName(target) + "&7!"))); + this.warp(player, user, viceUser, new TaxiTarget(target), 0, delay); + } + + + public Warp getWarpFromPad(Location blockLocation) { + String name = this.warpPads.get(blockLocation); + if (name == null) + return null; + if ("random".equalsIgnoreCase(name)) + return this.warps.get(Utils.getRandom().nextInt(this.warps.size())); + return this.getWarp(name); + } + + public void loadWarps() { + YamlConfiguration c = Vice.getSettings().getWarpsConfig(); + this.tutorialSpawn = new Warp("spawn", Utils.teleportLocationFromString(c.getString("tutorialSpawn"))); + this.spawn = new Warp("tutorialSpawn", Utils.teleportLocationFromString(c.getString("spawn"))); + this.jail = new Warp("jail", Utils.teleportLocationFromString(c.getString("jail"))); + this.warps = new ArrayList<>(); + if (c.get("warps") != null) + this.warps.addAll(c.getConfigurationSection("warps").getKeys(false).stream().map(s -> new Warp(s, Utils.teleportLocationFromString(c.getString("warps." + s)))).collect(Collectors.toList())); + this.warpPads = new HashMap<>(); + if (c.get("warpPads") != null) + for (String loc : c.getConfigurationSection("warpPads").getKeys(false)) + this.warpPads.put(Utils.blockLocationFromString(loc), c.getString("warpPads." + loc)); + + } + + public void saveWarps() { + YamlConfiguration c = Vice.getSettings().getWarpsConfig(); + c.set("spawn", Utils.teleportLocationToString(this.spawn.getLocation())); + c.set("tutorialSpawn", Utils.teleportLocationToString(this.tutorialSpawn.getLocation())); + c.set("jail", Utils.teleportLocationToString(this.jail.getLocation())); + c.set("warps", null); + for (Warp warp : this.warps) + c.set("warps." + warp.getName(), Utils.teleportLocationToString(warp.getLocation())); + c.set("warpPads", null); + for (Map.Entry<Location, String> locationStringEntry : this.warpPads.entrySet()) + c.set(Utils.blockLocationToString(locationStringEntry.getKey()), this.warpPads.get(locationStringEntry.getKey())); + Utils.saveConfig(c, "warps"); + } + +} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/resources/barrels.yml b/vice-master@f8937e1dbf1/src/main/resources/barrels.yml new file mode 100644 index 0000000..ef3597d --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/resources/barrels.yml @@ -0,0 +1 @@ +barrels: diff --git a/vice-master@f8937e1dbf1/src/main/resources/bounties.yml b/vice-master@f8937e1dbf1/src/main/resources/bounties.yml new file mode 100644 index 0000000..6c37909 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/resources/bounties.yml @@ -0,0 +1,11 @@ +0e4a6028-3d9a-4a2e-9797-eb1ddcb0aca9: + name: Presidentx + placers: + b5d6834b-465b-4593-8b8d-c2cba400015c: + name: Samuri629 + amount: 10000 + anonymous: true + 5c8bb461-a075-4526-b0e1-e3a701c2dc98: + name: 2Legiit4U + amount: 5000 + anonymous: false \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/resources/drugblocks.yml b/vice-master@f8937e1dbf1/src/main/resources/drugblocks.yml new file mode 100644 index 0000000..6a40527 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/resources/drugblocks.yml @@ -0,0 +1 @@ +blocks: diff --git a/vice-master@f8937e1dbf1/src/main/resources/drugdealer.yml b/vice-master@f8937e1dbf1/src/main/resources/drugdealer.yml new file mode 100644 index 0000000..1892498 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/resources/drugdealer.yml @@ -0,0 +1,51 @@ +drugs: + alcohol: + min: 10 + max: 20 + chance: 50 + minprice: 100 + maxprice: 100 + cocaine: + min: 5 + max: 19 + chance: 50 + minprice: 400 + maxprice: 750 + lsd: + min: 13 + max: 54 + chance: 50 + minprice: 250 + maxprice: 500 + mdma: + min: 1 + max: 89 + chance: 50 + minprice: 75 + maxprice: 150 + weed: + min: 43 + max: 910 + chance: 50 + minprice: 75 + maxprice: 150 + heroinRecipe: + min: 10 + max: 23 + chance: 12 + minprice: 250 + maxprice: 500 + meth: + min: 10 + max: 23 + chance: 43 + minprice: 250 + maxprice: 500 + "anabolic steroids": + min: 3 + max: 129 + chance: 100 + minprice: 500 + maxprice: 1000 + +locs: diff --git a/vice-master@f8937e1dbf1/src/main/resources/gtm.yml b/vice-master@f8937e1dbf1/src/main/resources/gtm.yml new file mode 100644 index 0000000..54ca728 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/resources/gtm.yml @@ -0,0 +1 @@ +map: test \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/resources/homes.yml b/vice-master@f8937e1dbf1/src/main/resources/homes.yml new file mode 100644 index 0000000..e69de29 diff --git a/vice-master@f8937e1dbf1/src/main/resources/items.yml b/vice-master@f8937e1dbf1/src/main/resources/items.yml new file mode 100644 index 0000000..e69de29 diff --git a/vice-master@f8937e1dbf1/src/main/resources/kits.yml b/vice-master@f8937e1dbf1/src/main/resources/kits.yml new file mode 100644 index 0000000..116d3e7 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/resources/kits.yml @@ -0,0 +1,13 @@ +hobo: + delay: 300 + items: + - chicken + - beef,pork +kak: + cost: 50 + delay: 300 + items: + - chicken + - beef:40,pork:50 +vip: + delay: 86400 \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/resources/loot.yml b/vice-master@f8937e1dbf1/src/main/resources/loot.yml new file mode 100644 index 0000000..3f468b8 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/resources/loot.yml @@ -0,0 +1,6 @@ +loot: + chicken: + chance: 5 + min: 2 + max: 5 +lootcrates: {} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/resources/lootcrates.yml b/vice-master@f8937e1dbf1/src/main/resources/lootcrates.yml new file mode 100644 index 0000000..5a61cd1 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/resources/lootcrates.yml @@ -0,0 +1,2 @@ +lootcrates: +cooldown: 30 \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/resources/playercache.yml b/vice-master@f8937e1dbf1/src/main/resources/playercache.yml new file mode 100644 index 0000000..e69de29 diff --git a/vice-master@f8937e1dbf1/src/main/resources/plugin.yml b/vice-master@f8937e1dbf1/src/main/resources/plugin.yml new file mode 100644 index 0000000..8ebad53 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/resources/plugin.yml @@ -0,0 +1,75 @@ +name: Vice +version: 1.0 +description: Vice +author: Presidentx +main: net.grandtheftmc.vice.Vice +depend: [Core,ProtocolLib,JLib,WastedGuns,WastedVehicles,EffectLib,Citizens,WorldGuard] +commands: + ammo: + lootcrates: + aliases: ["lc", "lootc", "lcrates", "lootcrate", "lcrate"] + warp: + spawn: + viceadmin: + gameitem: + aliases: [gi, gamei, gitem] + kit: + aliases: [kits] + resetstats: + shop: + vicerank: + rankup: + drugcheck: + aliases: [dc] + drugdealer: + money: + aliases: [bal,balance,eco,economy,cash] + pay: + tpa: + tpahere: + tpaccept: + aliases: [tpyes] + tpdeny: + aliases: [tpdeny] + bonds: + kill: + suicide: + picker: + aliases: [modepicker, armorstandpicker] + feed: + aliases: [eat,food,saturate] + vehicle: + aliases: [wv, vehicles, wastedvehicles, wastedvehicle, wvehicle, wvehicles, wastedv] + backpack: + aliases: [bp, backp, bpack] + bribe: + aliases: [bail] + reset: + tokenshop: + antiaura: + clear: + aliases: [clearinventory, cleari, ci, clearinv] + fix: + aliases: [repair] + teleport: + aliases: [tp, tpo] + spectator: + aliases: [gm3staff, spectatormode] + backup: + lottery: + speed: + chunkunload: + topkillers: + stats: + aliases: [stat] + resourcepack: + aliases: [respack, rp, tex, textures, rpack, resourcep, resp, rep, texturepack, texpack, pack, resource] + drugs: + aliases: [drug] + viceranks: + aliases: [ranks] + stack: + cop: + rtp: + aliases: [randomtp, wild, rteleport, wilderness] + area: \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/resources/rules.yml b/vice-master@f8937e1dbf1/src/main/resources/rules.yml new file mode 100644 index 0000000..7da18e6 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/resources/rules.yml @@ -0,0 +1,5 @@ +rules: + - "" + - "" + - "" + - "" \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/resources/salemenus.yml b/vice-master@f8937e1dbf1/src/main/resources/salemenus.yml new file mode 100644 index 0000000..6da8ca4 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/resources/salemenus.yml @@ -0,0 +1,60 @@ +#sale-menu-name: +# menu-title: +# subcategories: +# subcategoryA: +# category-name: +# display-items: +# subcategories: +# subcategoryAa: +# category-name: +# display-items: +# sale-items: +# -game-items-name +# -game-items-name +# -game-items-name +# subcategoryAb: +# category-name: +# display-items: +# subcategories: +# subcategoryAba: +# category-name: +# display-items: +# sale-items: +# -game-items-name +# -game-items-name +# -game-items-name +# +#All subcategories MUST terminate with a sale-items array. + +weapons: + menu-title: "&a&lWeapons" + subcategories: + smgs: + display-item: 267 + sale-items: + - smg + - microsmg + - assaultsmg + - combatpdw + rifles: + display-item: 272 + sale-items: + - assaultrifle + - carbinerifle + pistols: + display-item: 268 + sale-items: + - pistol + - stungun + - combatpistol + - heavypistol + - marksmanpistol + shotguns: + display-item: 284 + sale-items: + - sawedoffshotgun + - pumpshotgun + - assaultshotgun + - heavyshotgun + + \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/resources/upgradedcontainers.yml b/vice-master@f8937e1dbf1/src/main/resources/upgradedcontainers.yml new file mode 100644 index 0000000..e69de29 diff --git a/vice-master@f8937e1dbf1/src/main/resources/warps.yml b/vice-master@f8937e1dbf1/src/main/resources/warps.yml new file mode 100644 index 0000000..5b73fb1 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/main/resources/warps.yml @@ -0,0 +1,3 @@ +firstSpawn: spawn,0,0,0,0,0 +spawn: spawn,0,50,0,0,0 +warps: {} \ No newline at end of file diff --git a/vice-master@f8937e1dbf1/src/main/resources/zones.yml b/vice-master@f8937e1dbf1/src/main/resources/zones.yml new file mode 100644 index 0000000..e69de29 diff --git a/vice-master@f8937e1dbf1/src/test/prices/TestPrices.java b/vice-master@f8937e1dbf1/src/test/prices/TestPrices.java new file mode 100644 index 0000000..0f41582 --- /dev/null +++ b/vice-master@f8937e1dbf1/src/test/prices/TestPrices.java @@ -0,0 +1,164 @@ +package prices; + +import net.grandtheftmc.vice.pickers.drugdealer.data.PricingData; + +import java.text.DecimalFormat; +import java.util.HashMap; +import java.util.Map; + +/** + * Created by Adam on 18/06/2017. + */ +public class TestPrices { + + public static void main(String[] args) { + calculatePrices(); + } + + private static Map<String, Double> currentPrices; + + static { + //Initialise current prices + currentPrices = new HashMap<>(); + currentPrices.put("cocain", 200.0); + currentPrices.put("weed", 850.0); + currentPrices.put("lsd", 2500.50); + currentPrices.put("mdma", 1367.50); + currentPrices.put("heroin", 1100.0); + } + + protected static Map<String, Double> calculatePrices() { + + Map<String, PricingData> data = new HashMap<>(); + double totalSales = 0; + + //Set current transaction data + data.put("cocain", new PricingData(150, 250, 40000)); + totalSales += 40000; + data.put("weed", new PricingData(700, 900, 45278)); + totalSales += 45278; + data.put("lsd", new PricingData(2000, 3000, 65000)); + totalSales += 65000; + data.put("mdma", new PricingData(1200, 1500, 54214)); + totalSales += 54214; + data.put("heroin", new PricingData(850, 1350, 59004)); + totalSales += 59004; + + double totalRelativeMarketShare = 0; + + for (PricingData pd : data.values()) { + //Compute the market share of each drug + double share = pd.computeMarketShare(totalSales); + + double amntAbove = 0, amntBelow = 0; + double pcentAbove = 0, pcentBelow = 0; + //We want to compute the average percentage of market share above and below this market share + + for (PricingData pd2 : data.values()) { + if (!pd2.equals(pd)) { + //we are comparing a different object + + //Sum the market share percentages above and below this object + if (pd2.getMarketShare() > share) { + amntAbove++; + pcentAbove += pd2.getMarketShare(); + } else if (pd2.getMarketShare() < share) { + amntBelow++; + pcentBelow += pd2.getMarketShare(); + } + } + } + + //compute the averages + double avgPcentAbove = 0, avgPcentBelow = 0; + + if (amntAbove != 0) { + avgPcentAbove = pcentAbove / amntAbove; + } + + if (amntBelow != 0) { + avgPcentBelow = pcentBelow / amntBelow; + } + + //Compute the average change in market share compared to all other drugs + double diffShare = avgPcentBelow - avgPcentAbove; + pd.setRelativeMarketShare(diffShare); + totalRelativeMarketShare += diffShare; + } + + double correctionFactor = 0; + + if (totalRelativeMarketShare != 0) { + //we need to normalise the relative differences to all average 0. + correctionFactor = totalRelativeMarketShare / ((double) data.size()); + + if (totalRelativeMarketShare < 0 && correctionFactor < 0) { + //Make positive + correctionFactor *= -1; + } else if (totalRelativeMarketShare > 0 && correctionFactor > 0) { + correctionFactor *= -1; + } + + } + + //Now scale all results so that no items exceeds +/- 10% of its price + double maxVariant = Double.MIN_VALUE; + + for (PricingData pd : data.values()) { + //if this is negative we add it, if positive adding works also + pd.setRelativeMarketShare(pd.getRelativeMarketShare() + correctionFactor); + + + double rms = Math.abs(pd.getRelativeMarketShare()); + if (rms > maxVariant) { + //set the max variant to equal the largest relative percentage change in market share + maxVariant = rms; + } + } + + + //If there is some +/- variant of more than 10% we must scale all values down + while (maxVariant > 0.1) { + + for (PricingData pd : data.values()) { + //Half everything constantly + pd.setRelativeMarketShare(pd.getRelativeMarketShare() / 2); + } + + maxVariant = Double.MIN_VALUE; + for (PricingData pd : data.values()) { + if (pd.getRelativeMarketShare() > maxVariant) { + maxVariant = pd.getRelativeMarketShare(); + } + } + } + + Map<String, Double> priceData = new HashMap<>(); + + DecimalFormat df = new DecimalFormat("##.##"); + + //Now calculate and set the price data + for (Map.Entry<String, PricingData> e : data.entrySet()) { + PricingData pd = e.getValue(); + double curPrice = currentPrices.get(e.getKey()); + //Increasing or decreasing will still work + double newPrice = curPrice + (curPrice * pd.getRelativeMarketShare()); + + if (newPrice > pd.getMaxCost()) { + newPrice = pd.getMaxCost(); + } else if (newPrice < pd.getMinCost()) { + newPrice = pd.getMinCost(); + } + + priceData.put(e.getKey(), newPrice); + + System.out.println("Drug(" + e.getKey() + "). Market Share= " + df.format(pd.getMarketShare()) + + ". Relative Share= " + df.format(pd.getRelativeMarketShare()) + ". Old->New Price " + + df.format(curPrice) +"-->" + df.format(newPrice)); + } + + //We are done. + return priceData; + } + +} diff --git a/wastedcops-master@4d070d71e37/.gitignore b/wastedcops-master@4d070d71e37/.gitignore new file mode 100644 index 0000000..73ad67c --- /dev/null +++ b/wastedcops-master@4d070d71e37/.gitignore @@ -0,0 +1,6 @@ +# Folders +/.idea/ +/out/ +/target/ + +*.iml \ No newline at end of file diff --git a/wastedcops-master@4d070d71e37/README.MD b/wastedcops-master@4d070d71e37/README.MD new file mode 100644 index 0000000..e7e5a08 --- /dev/null +++ b/wastedcops-master@4d070d71e37/README.MD @@ -0,0 +1,4 @@ +# WastedCops +Link: https://circleci.com/gh/GrandTheftMinecart/WastedCops + +Latest Artifact: https://github.com/GrandTheftMinecart/WastedCops/releases/latest/ \ No newline at end of file diff --git a/wastedcops-master@4d070d71e37/lib/Core.jar b/wastedcops-master@4d070d71e37/lib/Core.jar new file mode 100644 index 0000000..3bce0e0 Binary files /dev/null and b/wastedcops-master@4d070d71e37/lib/Core.jar differ diff --git a/wastedcops-master@4d070d71e37/lib/GTM.jar b/wastedcops-master@4d070d71e37/lib/GTM.jar new file mode 100644 index 0000000..6ce16e9 Binary files /dev/null and b/wastedcops-master@4d070d71e37/lib/GTM.jar differ diff --git a/wastedcops-master@4d070d71e37/lib/Houses.jar b/wastedcops-master@4d070d71e37/lib/Houses.jar new file mode 100644 index 0000000..f49efe2 Binary files /dev/null and b/wastedcops-master@4d070d71e37/lib/Houses.jar differ diff --git a/wastedcops-master@4d070d71e37/lib/WastedGuns.jar b/wastedcops-master@4d070d71e37/lib/WastedGuns.jar new file mode 100644 index 0000000..6d512d6 Binary files /dev/null and b/wastedcops-master@4d070d71e37/lib/WastedGuns.jar differ diff --git a/wastedcops-master@4d070d71e37/pom.xml b/wastedcops-master@4d070d71e37/pom.xml new file mode 100644 index 0000000..da20d8e --- /dev/null +++ b/wastedcops-master@4d070d71e37/pom.xml @@ -0,0 +1,158 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>net.grandtheftmc</groupId> + <artifactId>wastedcops</artifactId> + <version>1.1.0</version> + <name>WastedCops</name> + + <repositories> + <repository> + <id>spigot-repo</id> + <url>https://hub.spigotmc.org/nexus/content/repositories/public/</url> + </repository> + <repository> + <id>jitpack.io</id> + <url>https://jitpack.io</url> + </repository> + <repository> + <id>nexus-release</id> + <url>http://nexus.grandtheftmc.net/content/repositories/releases</url> + </repository> + </repositories> + + <distributionManagement> + <repository> + <id>nexus-release</id> + <name>Internal Releases</name> + <url>http://nexus.grandtheftmc.net/content/repositories/releases</url> + </repository> + <snapshotRepository> + <id>nexus-snapshot</id> + <name>Internal Snapshots</name> + <url>http://nexus.grandtheftmc.net/content/repositories/snapshots</url> + </snapshotRepository> + </distributionManagement> + + <developers> + <developer> + <id>1</id> + <name>Presidentx</name> + <roles> + <role>Owner</role> + <role>Developer</role> + </roles> + </developer> + + <developer> + <id>2</id> + <name>MrTeddeh</name> + <roles> + <role>Senior Developer</role> + </roles> + </developer> + + <developer> + <id>3</id> + <name>Tim</name> + <roles> + <role>Developer</role> + </roles> + </developer> + + <developer> + <id>4</id> + <name>ThatAbstractWolf</name> + <roles> + <role>Developer</role> + </roles> + </developer> + </developers> + + <dependencies> + <dependency> + <groupId>org.spigotmc.1.12</groupId> + <artifactId>spigot</artifactId> + <version>1.12.0</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.github.j0ach1mmall3</groupId> + <artifactId>JLib</artifactId> + <version>LATEST</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>net.grandtheftmc</groupId> + <artifactId>wastedguns</artifactId> + <version>1.0.2</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>net.grandtheftmc</groupId> + <artifactId>core</artifactId> + <version>2.3.10</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>net.grandtheftmc</groupId> + <artifactId>gtm</artifactId> + <version>2.4.0</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>net.grandtheftmc</groupId> + <artifactId>houses</artifactId> + <version>1.0.2</version> + <scope>provided</scope> + </dependency> + </dependencies> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <maven.compiler.source>1.8</maven.compiler.source> + <maven.compiler.target>1.8</maven.compiler.target> + </properties> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-shade-plugin</artifactId> + <configuration> + <finalName>WastedCops</finalName> + </configuration> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>shade</goal> + </goals> + </execution> + </executions> + </plugin> + + <!-- Nexus deploy --> + <plugin> + <groupId>org.sonatype.plugins</groupId> + <artifactId>nexus-staging-maven-plugin</artifactId> + <version>1.6.8</version> + <extensions>true</extensions> + <executions> + <execution> + <id>default-deploy</id> + <phase>deploy</phase> + <goals> + <goal>deploy</goal> + </goals> + </execution> + </executions> + <configuration> + <serverId>nexus</serverId> + <nexusUrl>http://nexus.grandtheftmc.net/</nexusUrl> + <skipStaging>true</skipStaging> + </configuration> + </plugin> + </plugins> + </build> +</project> \ No newline at end of file diff --git a/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/Main.java b/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/Main.java new file mode 100644 index 0000000..5159bb9 --- /dev/null +++ b/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/Main.java @@ -0,0 +1,214 @@ +package com.j0ach1mmall3.wastedcops; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Creature; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Villager; +import org.bukkit.entity.Zombie; +import org.bukkit.metadata.FixedMetadataValue; + +import com.j0ach1mmall3.jlib.commands.Command; +import com.j0ach1mmall3.jlib.methods.Random; +import com.j0ach1mmall3.jlib.plugin.JLibPlugin; +import com.j0ach1mmall3.wastedcops.api.Cop; +import com.j0ach1mmall3.wastedcops.api.CopProperties; +import com.j0ach1mmall3.wastedcops.api.events.CopSpawnEvent; +import com.j0ach1mmall3.wastedcops.commands.WCReloadCommandHandler; +import com.j0ach1mmall3.wastedcops.config.Config; +import com.j0ach1mmall3.wastedcops.listeners.CopListener; +import com.j0ach1mmall3.wastedcops.listeners.EntityListener; + +import net.grandtheftmc.gtm.GTMUtils; +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.users.GTMUserManager; + +public final class Main extends JLibPlugin<Config> { + private final Map<Player, Set<LivingEntity>> cops = new ConcurrentHashMap<>(); + private final Map<Player, Long> noTargetTicks = new ConcurrentHashMap<>(); + + private final List<Material> disallowedBlocks = Arrays.asList(Material.LEAVES, + Material.LEAVES_2, Material.COBBLE_WALL, Material.WOOD_STEP, Material.WOOD); + + public static boolean canSeeTarget(LivingEntity cop, Player target) { + return cop.hasLineOfSight(target); + } + + public static Location faceLocation(LivingEntity entity, Location to) { + if (entity.getWorld() != to.getWorld()) { + return null; + } + Location fromLocation = entity.getLocation(); + + double xDiff = to.getX() - fromLocation.getX(); + double yDiff = to.getY() - fromLocation.getY(); + double zDiff = to.getZ() - fromLocation.getZ(); + + double distanceXZ = Math.sqrt(xDiff * xDiff + zDiff * zDiff); + double distanceY = Math.sqrt(distanceXZ * distanceXZ + yDiff * yDiff); + + double yaw = Math.toDegrees(Math.acos(xDiff / distanceXZ)); + double pitch = Math.toDegrees(Math.acos(yDiff / distanceY)) - 90.0D; + if (zDiff < 0.0D) { + yaw += Math.abs(180.0D - yaw) * 2.0D; + } + Location loc = entity.getLocation(); + loc.setYaw((float) (yaw - 90.0F)); + loc.setPitch((float) (pitch - 90.0F)); + return loc; + } + + @Override + public void onEnable() { + this.reload(); + new EntityListener(this); + new CopListener(this); + new WCReloadCommandHandler(this).registerCommand(new Command("WCReload", "wc.reload", ChatColor.RED + "/wcreload")); + } + + @Override + public void onDisable() { + this.cops.values().forEach(s -> s.forEach(LivingEntity::remove)); + } + + public Map<Player, Set<LivingEntity>> getCops() { + return this.cops; + } + + public Map<Player, Long> getNoTargetTicks() { + return this.noTargetTicks; + } + + public void reload() { + this.config = new Config(this); + } + + public Config getCustomConfig() { + return this.config; + } + + public void setWantedLevel(Player player, int level) { + switch(level) { + case 0: + level = 0; + break; + case 1: + level = 1; + break; + case 2: + level = 2; + break; + case 3: + level = 4; + break; + case 4: + level = 10; + break; + case 5: + level = 25; + break; + default: + level = 0; + break; + } + + GTMUser gtmUser = GTMUserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + if (gtmUser != null){ + gtmUser.setKillCounter(level); + GTMUtils.updateBoard(player, gtmUser); + } + } + + public int getWantedLevel(Player player) { + + int wantedLevel = 0; + int[] wantedLevels = new int[]{0, 1, 2, 4, 10, 25}; + + GTMUser gtmUser = GTMUserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + if (gtmUser != null){ + int killCounter = gtmUser.getKillCounter(); + for (int i = 0; i < wantedLevels.length; i++) + if (killCounter >= wantedLevels[i]) + wantedLevel = i; + } + + return wantedLevel; + } + + public void resetWantedLevel(Player player) { + + GTMUser gtmUser = GTMUserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + if (gtmUser != null){ + gtmUser.setKillCounter(0); + GTMUtils.updateBoard(player, gtmUser); + } + } + + public void addKill(Player player) { + + GTMUser gtmUser = GTMUserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + if (gtmUser != null){ + gtmUser.addKillCounter(1); + GTMUtils.updateBoard(player, gtmUser); + } + } + + public void addMoney(Player player, int amount) { + if(amount > Integer.MAX_VALUE || amount < Integer.MIN_VALUE){ + return; + } + + GTMUser gtmUser = GTMUserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + if (gtmUser != null){ + gtmUser.addMoney(amount); + GTMUtils.updateBoard(player, gtmUser); + } + } + + private Location getLocationInRange(Location location, int minRange, int maxRange) { + return location.add(Random.getInt(minRange, maxRange) * (Random.getBoolean() ? 1 : -1), 0, Random.getInt(minRange, maxRange) * (Random.getBoolean() ? 1 : -1)); + } + + public void spawnCopAtLocation(Location location, CopProperties copProperties, Player target) { + Cop cop = new Cop(this, copProperties); + CopSpawnEvent copSpawnEvent = new CopSpawnEvent(cop, target, location); + Bukkit.getPluginManager().callEvent(copSpawnEvent); + if(copSpawnEvent.isCancelled()) return; + String entityName = copProperties.getEntity(); + LivingEntity livingEntity; + location = copSpawnEvent.getLocation(); + location = location.getWorld().getHighestBlockAt(this.getLocationInRange(location, 0, 4)).getLocation(); + if (Objects.equals(entityName, "husk")) { + livingEntity = (Creature) location.getWorld().spawnEntity(location, EntityType.ZOMBIE); + ((Zombie)livingEntity).setVillagerProfession(Villager.Profession.HUSK); + } else { + livingEntity = (Creature) location.getWorld().spawnEntity(location, EntityType.valueOf(entityName)); + } + livingEntity.setMetadata("Cop", new FixedMetadataValue(this, cop)); + Set<LivingEntity> cops = this.cops.getOrDefault(target, new HashSet<>()); + cops.add(livingEntity); + this.cops.put(target, cops); + cop.onSpawn(livingEntity, copSpawnEvent.getTarget()); + if (this.disallowedBlocks.contains(location.getBlock().getType())) { + livingEntity.setHealth(0); + livingEntity.remove(); + cop.onDestroy(livingEntity); + return; + } + if(location.getBlockY() > 100) { + cop.onDestroy(livingEntity); + } + } +} diff --git a/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/api/Cop.java b/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/api/Cop.java new file mode 100644 index 0000000..8a181d0 --- /dev/null +++ b/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/api/Cop.java @@ -0,0 +1,159 @@ +package com.j0ach1mmall3.wastedcops.api; + +import com.j0ach1mmall3.jlib.integration.Placeholders; +import com.j0ach1mmall3.jlib.methods.ReflectionAPI; +import com.j0ach1mmall3.jlib.nms.pathfinding.WrappedPathfinderGoalSelector; +import com.j0ach1mmall3.wastedcops.Main; +import com.j0ach1mmall3.wastedguns.api.events.WeaponRightClickEvent; +import com.j0ach1mmall3.wastedguns.api.weapons.Weapon; +import com.j0ach1mmall3.wastedguns.api.weapons.ranged.RangedWeapon; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.users.HouseUser; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Material; +import org.bukkit.entity.*; +import org.bukkit.inventory.ItemStack; + +import java.util.Optional; +import java.util.concurrent.ThreadLocalRandom; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 4/06/2016 + */ +public final class Cop { + private static final Class ENTITY_CREATURE_CLASS = ReflectionAPI.getNmsClass("EntityCreature"); + private static final Class ENTITY_INSENTIENT_CLASS = ReflectionAPI.getNmsClass("EntityInsentient"); + private static final Class ENTITY_HUMAN_CLASS = ReflectionAPI.getNmsClass("EntityHuman"); + private static final Class PATHFINDER_GOAL_FLOAT_CLASS = ReflectionAPI.getNmsClass("PathfinderGoalFloat"); + private static final Class PATHFINDER_GOAL_MELEE_ATTACK_CLASS = ReflectionAPI.getNmsClass("PathfinderGoalMeleeAttack"); + private static final Class PATHFINDER_GOAL_MOVE_TOWARDS_RESTRICTION_CLASS = ReflectionAPI.getNmsClass("PathfinderGoalMoveTowardsRestriction"); + private static final Class PATHFINDER_GOAL_RANDOM_STROLL_CLASS = ReflectionAPI.getNmsClass("PathfinderGoalRandomStroll"); + private static final Class PATHFINDER_GOAL_LOOK_AT_PLAYER_CLASS = ReflectionAPI.getNmsClass("PathfinderGoalLookAtPlayer"); + private static final Class PATHFINDER_GOAL_RANDOM_LOOKAROUND_CLASS = ReflectionAPI.getNmsClass("PathfinderGoalRandomLookaround"); + private static final Class PATHFINDER_GOAL_HURT_BY_TARGET_CLASS = ReflectionAPI.getNmsClass("PathfinderGoalHurtByTarget"); + private static final Class PATHFINDER_GOAL_NEAREST_ATTACKABLE_TARGET_CLASS = ReflectionAPI.getNmsClass("PathfinderGoalNearestAttackableTarget"); + + private final Main plugin; + private final CopProperties copProperties; + private Weapon weapon; + private boolean weaponCooldown; + + public Cop(Main plugin, CopProperties copProperties) { + this.plugin = plugin; + this.copProperties = copProperties; + } + + public Main getPlugin() { + return this.plugin; + } + + public CopProperties getCopProperties() { + return this.copProperties; + } + + public Weapon getWeapon() { + return this.weapon; + } + + public void setWeapon(Weapon weapon) { + this.weapon = weapon; + } + + public boolean isWeaponCooldown() { + return this.weaponCooldown; + } + + public void setWeaponCooldown(boolean weaponCooldown) { + this.weaponCooldown = weaponCooldown; + } + + public void onSpawn(LivingEntity livingEntity, Player target) { + if(!this.copProperties.getWeapons().isEmpty()) { + String w = this.copProperties.getWeapons().get(ThreadLocalRandom.current().nextInt(this.copProperties.getWeapons().size())); + Optional<Weapon> weapon = ((com.j0ach1mmall3.wastedguns.Main) Bukkit.getPluginManager().getPlugin("WastedGuns")).getWeapon(w); + if (weapon.isPresent()) this.weapon = weapon.get(); + } + livingEntity.setCustomName(Placeholders.parse(this.copProperties.getName(), target)); + livingEntity.setCustomNameVisible(true); + livingEntity.setMaxHealth(this.copProperties.getHealth()); + livingEntity.setHealth(livingEntity.getMaxHealth()); + livingEntity.setCanPickupItems(false); + livingEntity.setRemoveWhenFarAway(false); + livingEntity.setAI(true); + if(livingEntity.getType() == EntityType.WOLF) { + ((Wolf) livingEntity).setAngry(true); + ((Wolf) livingEntity).setAdult(); + ((Wolf) livingEntity).setSitting(false); + ((Wolf) livingEntity).setTarget(target); + } + if(livingEntity.getType() == EntityType.ZOMBIE || livingEntity.getType() == EntityType.PIG_ZOMBIE) { + ((Zombie) livingEntity).setBaby(false); + ((Zombie) livingEntity).setTarget(target); + } + if (this.weapon != null) livingEntity.getEquipment().setItemInMainHand(this.weapon.getItemStack()); + livingEntity.getEquipment().setHelmet(new ItemStack(Material.STONE_BUTTON)); + + try { + WrappedPathfinderGoalSelector goalSelector = new WrappedPathfinderGoalSelector(WrappedPathfinderGoalSelector.Type.GOAL_SELECTOR, (Creature)livingEntity); + goalSelector.getActive().clear(); + goalSelector.getInactive().clear(); + Object handle = ReflectionAPI.getHandle((Object) livingEntity); + + goalSelector.add(1, PATHFINDER_GOAL_FLOAT_CLASS.getConstructor(ENTITY_INSENTIENT_CLASS).newInstance(handle)); + goalSelector.add(2, PATHFINDER_GOAL_MELEE_ATTACK_CLASS.getConstructor(ENTITY_CREATURE_CLASS, double.class, boolean.class).newInstance(handle, 1.0D, false)); + goalSelector.add(5, PATHFINDER_GOAL_MOVE_TOWARDS_RESTRICTION_CLASS.getConstructor(ENTITY_CREATURE_CLASS, double.class).newInstance(handle, 1.0D)); + goalSelector.add(7, PATHFINDER_GOAL_RANDOM_STROLL_CLASS.getConstructor(ENTITY_CREATURE_CLASS, double.class).newInstance(handle, 1.0D)); + goalSelector.add(8, PATHFINDER_GOAL_LOOK_AT_PLAYER_CLASS.getConstructor(ENTITY_INSENTIENT_CLASS, Class.class, float.class).newInstance(handle, ENTITY_HUMAN_CLASS, 8.0F)); + goalSelector.add(8, PATHFINDER_GOAL_RANDOM_LOOKAROUND_CLASS.getConstructor(ENTITY_INSENTIENT_CLASS).newInstance(handle)); + goalSelector.apply((Creature)livingEntity); + + WrappedPathfinderGoalSelector targetSelector = new WrappedPathfinderGoalSelector(WrappedPathfinderGoalSelector.Type.TARGET_SELECTOR, (Creature)livingEntity); + targetSelector.getActive().clear(); + targetSelector.getInactive().clear(); + targetSelector.add(1, PATHFINDER_GOAL_HURT_BY_TARGET_CLASS.getConstructor(ENTITY_CREATURE_CLASS, boolean.class, Class[].class).newInstance(handle, false, new Class[0])); + targetSelector.add(2, PATHFINDER_GOAL_NEAREST_ATTACKABLE_TARGET_CLASS.getConstructor(ENTITY_CREATURE_CLASS, Class.class, boolean.class).newInstance(handle, ENTITY_HUMAN_CLASS, false)); + targetSelector.apply((Creature)livingEntity); + } catch (Exception e) { + e.printStackTrace(); + } + + ((Creature)livingEntity).setTarget(target); + livingEntity.teleport(Main.faceLocation(livingEntity, target.getEyeLocation())); + } + + public void onDestroy(LivingEntity zombie) { + zombie.setHealth(0); + zombie.remove(); + this.plugin.getCops().values().forEach(s -> s.remove(zombie)); + } + + public boolean onTick(LivingEntity cop, Player player) { + if (cop == null || cop.isDead() || player.getWorld() != cop.getWorld()) { + this.onDestroy(cop); + return false; + } + if (cop.isInsideVehicle()) cop.getVehicle().eject(); + + HouseUser houseUser = Houses.getUserManager().getLoadedUser(player.getUniqueId()); + if (houseUser.isInsideHouse() || houseUser.isInsidePremiumHouse()) { + this.onDestroy(cop); + return false; + } + + if(!Main.canSeeTarget(cop, player)) { + return false; + } + + boolean valid = !player.isDead() && player.isOnline() && player.getGameMode() != GameMode.SPECTATOR && player.getGameMode() != GameMode.CREATIVE && player.getWorld().getName().equals(cop.getWorld().getName()) && this.plugin.getWantedLevel(player) > 0 && cop.hasLineOfSight(player); + double distance = cop.getLocation().distance(player.getLocation()); + if (valid && !this.weaponCooldown && this.weapon instanceof RangedWeapon && distance <= ((RangedWeapon) this.weapon).getRange()) { + WeaponRightClickEvent weaponRightClickEvent = new WeaponRightClickEvent(cop, this.weapon); + Bukkit.getPluginManager().callEvent(weaponRightClickEvent); + this.weaponCooldown = true; + Bukkit.getScheduler().scheduleSyncDelayedTask(this.plugin, () -> this.weaponCooldown = false, 4L); + } + return valid; + } +} diff --git a/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/api/CopProperties.java b/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/api/CopProperties.java new file mode 100644 index 0000000..957a048 --- /dev/null +++ b/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/api/CopProperties.java @@ -0,0 +1,57 @@ +package com.j0ach1mmall3.wastedcops.api; + +import java.util.Collections; +import java.util.List; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 4/06/2016 + */ +public final class CopProperties { + private final String identifier; + private final String entity; + private final double health; + private final int weaponDropChance; + private final String name; + private final int killReward; + private final List<String> weapons; + + public CopProperties(String identifier, String entity, double health, int weaponDropChance, String name, int killReward, List<String> weapons) { + this.identifier = identifier; + this.entity = entity; + this.health = health; + this.weaponDropChance = weaponDropChance; + this.name = name; + this.killReward = killReward; + this.weapons = weapons; + Collections.shuffle(this.weapons); + } + + public String getIdentifier() { + return this.identifier; + } + + public String getEntity() { + return this.entity; + } + + public double getHealth() { + return this.health; + } + + public int getWeaponDropChance() { + return this.weaponDropChance; + } + + public String getName() { + return this.name; + } + + public int getKillReward() { + return this.killReward; + } + + public List<String> getWeapons() { + return this.weapons; + } +} diff --git a/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/api/events/CopDamagePlayerEvent.java b/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/api/events/CopDamagePlayerEvent.java new file mode 100644 index 0000000..9ca95ab --- /dev/null +++ b/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/api/events/CopDamagePlayerEvent.java @@ -0,0 +1,48 @@ +package com.j0ach1mmall3.wastedcops.api.events; + +import com.j0ach1mmall3.wastedcops.api.Cop; +import com.j0ach1mmall3.wastedguns.api.weapons.Weapon; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +public class CopDamagePlayerEvent extends CopEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + private Player victim; + private Weapon weapon; + private double damageDealt; + + public CopDamagePlayerEvent(Cop cop, Player victim, Weapon weapon, double damageDealt) { + super(cop); + this.victim = victim; + this.weapon = weapon; + this.damageDealt = damageDealt; + } + + public Player getVictim() { + return this.victim; + } + + public Weapon getWeapon() { + return this.weapon; + } + + public double getDamageDealt(){ + return this.damageDealt; + } + + public void setDamageDealt(double newDamage) { + if(newDamage > victim.getMaxHealth() || newDamage < 0) + newDamage = victim.getMaxHealth(); + this.damageDealt = newDamage; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } + +} \ No newline at end of file diff --git a/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/api/events/CopEvent.java b/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/api/events/CopEvent.java new file mode 100644 index 0000000..d6b7ab4 --- /dev/null +++ b/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/api/events/CopEvent.java @@ -0,0 +1,28 @@ +package com.j0ach1mmall3.wastedcops.api.events; + +import com.j0ach1mmall3.wastedcops.api.Cop; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; + +public abstract class CopEvent extends Event implements Cancellable { + private final Cop cop; + private boolean cancelled; + + protected CopEvent(Cop cop) { + this.cop = cop; + } + + public Cop getCop() { + return this.cop; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + @Override + public void setCancelled(boolean b) { + this.cancelled = b; + } +} \ No newline at end of file diff --git a/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/api/events/CopKillPlayerEvent.java b/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/api/events/CopKillPlayerEvent.java new file mode 100644 index 0000000..8132ded --- /dev/null +++ b/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/api/events/CopKillPlayerEvent.java @@ -0,0 +1,45 @@ +package com.j0ach1mmall3.wastedcops.api.events; + +import com.j0ach1mmall3.wastedcops.api.Cop; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.ItemStack; + +import java.util.List; + +public class CopKillPlayerEvent extends CopEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + private final Player playerKilled; + private List<ItemStack> drops; + + public CopKillPlayerEvent(Cop cop, Player playerKilled, List<ItemStack> drops) { + super(cop); + this.playerKilled = playerKilled; + this.drops = drops; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } + + public Player getPlayerKilled() { + return this.playerKilled; + } + + public List<ItemStack> getDrops() { + return this.drops; + } + + public void setDrops(List<ItemStack> newDrops) { + if(newDrops == null || newDrops.isEmpty()) return; + this.drops = newDrops; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + +} + + diff --git a/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/api/events/CopSpawnEvent.java b/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/api/events/CopSpawnEvent.java new file mode 100644 index 0000000..252b28d --- /dev/null +++ b/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/api/events/CopSpawnEvent.java @@ -0,0 +1,48 @@ +package com.j0ach1mmall3.wastedcops.api.events; + +import com.j0ach1mmall3.wastedcops.api.Cop; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +public class CopSpawnEvent extends CopEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + private Player target; + private Location location; + + public CopSpawnEvent(Cop cop, Player target, Location location) { + super(cop); + this.target = target; + this.location = location; + } + + public Player getTarget() { + return this.target; + } + + public void setTarget(Player newTarget) { + if(newTarget == null || newTarget.getWorld() != location.getWorld()) return; + this.target = newTarget; + } + + public Location getLocation() { + return new Location(this.location.getWorld(), this.location.getX(), + this.location.getY(), this.location.getZ(), this.location.getYaw(), + this.location.getPitch()); + } + + public void setLocation(Location newLocation) { + if(newLocation == null || newLocation.getWorld() == null) return; + this.location = newLocation; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } + +} diff --git a/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/api/events/PlayerKillCopEvent.java b/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/api/events/PlayerKillCopEvent.java new file mode 100644 index 0000000..3fcda5b --- /dev/null +++ b/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/api/events/PlayerKillCopEvent.java @@ -0,0 +1,53 @@ +package com.j0ach1mmall3.wastedcops.api.events; + +import com.j0ach1mmall3.wastedcops.api.Cop; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.ItemStack; + +import java.util.List; + +/** + * Created by colt on 10/27/16. + */ +public class PlayerKillCopEvent extends CopEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + private LivingEntity copKiled; + private Player player; + private List<ItemStack> drops; + + public PlayerKillCopEvent(Cop cop, LivingEntity copKiled, Player player, List<ItemStack> drops) { + super(cop); + this.copKiled = copKiled; + this.player = player; + this.drops = drops; + } + + public LivingEntity getCopKiled() { + return this.copKiled; + } + + public Player getPlayer() { + return this.player; + } + + public List<ItemStack> getDrops() { + return this.drops; + } + + public void setDrops(List<ItemStack> newDrops) { + if(newDrops == null || newDrops.isEmpty()) return; + this.drops = newDrops; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } + +} diff --git a/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/commands/WCReloadCommandHandler.java b/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/commands/WCReloadCommandHandler.java new file mode 100644 index 0000000..79b5e94 --- /dev/null +++ b/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/commands/WCReloadCommandHandler.java @@ -0,0 +1,23 @@ +package com.j0ach1mmall3.wastedcops.commands; + +import com.j0ach1mmall3.jlib.commands.CommandHandler; +import com.j0ach1mmall3.wastedcops.Main; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 31/08/2016 + */ +public final class WCReloadCommandHandler extends CommandHandler<Main> { + public WCReloadCommandHandler(Main plugin) { + super(plugin); + } + + @Override + protected boolean handleCommand(CommandSender commandSender, String[] strings) { + this.plugin.reload(); + commandSender.sendMessage(ChatColor.GREEN + "Reloaded config!"); + return true; + } +} diff --git a/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/config/Config.java b/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/config/Config.java new file mode 100644 index 0000000..2f44ec4 --- /dev/null +++ b/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/config/Config.java @@ -0,0 +1,51 @@ +package com.j0ach1mmall3.wastedcops.config; + +import com.j0ach1mmall3.jlib.storage.file.yaml.ConfigLoader; +import com.j0ach1mmall3.wastedcops.Main; +import com.j0ach1mmall3.wastedcops.api.CopProperties; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 4/06/2016 + */ +public final class Config extends ConfigLoader<Main> { + private final List<CopProperties> copProperties; + private final Map<Integer, Map<String, int[]>> groups; + + public Config(Main plugin) { + super("config.yml", plugin); + this.copProperties = this.loadCopProperties(); + this.groups = this.loadGroups(); + } + + public List<CopProperties> getCopProperties() { + return this.copProperties; + } + + public Map<Integer, Map<String, int[]>> getGroups() { + return this.groups; + } + + private List<CopProperties> loadCopProperties() { + return this.customConfig.getKeys("Cops").stream().map(s -> new CopProperties( + s, + this.config.getString("Cops." + s + ".Entity").toUpperCase(), + this.config.getDouble("Cops." + s + ".Health"), + this.config.getInt("Cops." + s + ".WeaponDropChance"), + this.config.getString("Cops." + s + ".Name"), + this.config.getInt("Cops." + s + ".KillReward"), + this.config.getStringList("Cops." + s + ".Weapons") + )).collect(Collectors.toList()); + } + + private Map<Integer, Map<String, int[]>> loadGroups() { + return this.customConfig.getKeys("Groups").stream().collect(Collectors.toMap(Integer::valueOf, s -> this.customConfig.getKeys("Groups." + s).stream().collect(Collectors.toMap(s1 -> s1, s2 -> new int[]{ + this.config.getInt("Groups." + s + '.' + s2 + ".Min"), + this.config.getInt("Groups." + s + '.' + s2 + ".Max"), + })))); + } +} \ No newline at end of file diff --git a/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/listeners/CopListener.java b/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/listeners/CopListener.java new file mode 100644 index 0000000..1e049e4 --- /dev/null +++ b/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/listeners/CopListener.java @@ -0,0 +1,63 @@ +package com.j0ach1mmall3.wastedcops.listeners; + +import com.j0ach1mmall3.jlib.methods.Random; +import com.j0ach1mmall3.wastedcops.Main; +import com.j0ach1mmall3.wastedcops.api.Cop; +import com.j0ach1mmall3.wastedcops.api.events.CopSpawnEvent; +import com.j0ach1mmall3.wastedcops.api.events.PlayerKillCopEvent; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +public class CopListener implements Listener { + private final Main plugin; + + public CopListener(Main plugin) { + this.plugin = plugin; + this.plugin.getServer().getPluginManager().registerEvents(this, this.plugin); + } + + @EventHandler + public void onCopSpawnEvent(CopSpawnEvent event) { + if(event.getLocation().getWorld().getName().equalsIgnoreCase("spawn")) { + event.setCancelled(true); + } + } + + @EventHandler + public void onPlayerKillCopEvent(PlayerKillCopEvent event) { + Player killer = event.getPlayer(); + LivingEntity victim = event.getCopKiled(); + Cop cop = event.getCop(); + if (Random.getInt(100) < cop.getCopProperties().getWeaponDropChance()) + victim.getWorld().dropItemNaturally(victim.getLocation(), victim.getEquipment().getItemInMainHand()); + event.getDrops().clear(); + int reward = cop.getCopProperties().getKillReward(); + this.plugin.addMoney(killer, reward); + ArmorStand as = (ArmorStand) victim.getWorld().spawnEntity(victim.getLocation(), EntityType.ARMOR_STAND); + as.setCustomName(ChatColor.translateAlternateColorCodes('&', "&a&l$" + reward)); + as.setCustomNameVisible(true); + as.setCanPickupItems(false); + as.setVisible(false); + as.setSmall(true); + as.setBasePlate(false); + as.setInvulnerable(true); + as.addPotionEffect(new PotionEffect(PotionEffectType.LEVITATION, 30, 0)); + Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(this.plugin, new Runnable() { + @Override + public void run() { + as.damage(0); + as.remove(); + } + }, 30L); + this.plugin.addKill(killer); + cop.onDestroy(victim); + } +} diff --git a/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/listeners/EntityListener.java b/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/listeners/EntityListener.java new file mode 100644 index 0000000..30499b8 --- /dev/null +++ b/wastedcops-master@4d070d71e37/src/main/java/com/j0ach1mmall3/wastedcops/listeners/EntityListener.java @@ -0,0 +1,207 @@ +package com.j0ach1mmall3.wastedcops.listeners; + +import java.util.ConcurrentModificationException; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Creature; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.entity.EntityTargetEvent; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.event.player.PlayerKickEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.world.ChunkUnloadEvent; + +import com.j0ach1mmall3.wastedcops.Main; +import com.j0ach1mmall3.wastedcops.api.Cop; +import com.j0ach1mmall3.wastedcops.api.events.CopDamagePlayerEvent; +import com.j0ach1mmall3.wastedcops.api.events.CopKillPlayerEvent; +import com.j0ach1mmall3.wastedcops.api.events.PlayerKillCopEvent; +import com.j0ach1mmall3.wastedguns.api.weapons.Weapon; + +import net.grandtheftmc.gtm.users.GTMUser; +import net.grandtheftmc.gtm.users.GTMUserManager; +import net.grandtheftmc.gtm.users.JobMode; + +public final class EntityListener implements Listener { + private final Main plugin; + private int multiplier = 800; + + public EntityListener(Main plugin) { + this.plugin = plugin; + Bukkit.getServer().getPluginManager().registerEvents(this, plugin); + /*Bukkit.getScheduler().scheduleSyncRepeatingTask(this.plugin, () -> Bukkit.getOnlinePlayers().stream().filter(p -> plugin.getWantedLevel(p) > 0).forEach(p -> { + Map<String, int[]> odds = plugin.getBabies().getGroups().get(plugin.getWantedLevel(p)); + if(odds != null) { + odds.entrySet().forEach(e -> { + Location spawnLocation = p.getLocation().add(20 * (Random.getBoolean() ? 1 : -1), 0, 20 * (Random.getBoolean() ? 1 : -1)); + plugin.getBabies().getCopProperties().stream().filter(c -> c.getIdentifier().equalsIgnoreCase(e.getKey())).findFirst().ifPresent(c -> { + int count = e.getValue()[0] == e.getValue()[1] ? e.getValue()[0] : Random.getInt(e.getValue()[0], e.getValue()[1]); + for(int i = 0;i < count;i++) { + plugin.spawnCopAtLocation(spawnLocation, c, p); + } + }); + }); + } + }), 300, 600);*/ + Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() { + @Override + public void run() { + for(Map.Entry<Player, Set<LivingEntity>> e : plugin.getCops().entrySet() ) { + try { + Player p = e.getKey(); + boolean isVisible = false; + for (LivingEntity z : e.getValue()) { + if (((Cop) z.getMetadata("Cop").get(0).value()).onTick(z, p)) isVisible = true; + } + if (isVisible) { + plugin.getNoTargetTicks().put(p, 0L); + } else { + plugin.getNoTargetTicks().put(p, plugin.getNoTargetTicks().getOrDefault(p, 0L) + 1); + } + if (plugin.getNoTargetTicks().getOrDefault(p, 0L) / EntityListener.this.multiplier >= 1) { + double level = plugin.getNoTargetTicks().getOrDefault(p, 0L) / EntityListener.this.multiplier; + int lostLevel = plugin.getWantedLevel(p) - (int)level; + if(lostLevel <= 0) { + plugin.getCops().getOrDefault(p, new HashSet<>()).forEach(LivingEntity::remove); + plugin.getCops().remove(p); + plugin.getNoTargetTicks().remove(p); + plugin.setWantedLevel(p, 0); + p.sendMessage(ChatColor.RED + "You lost the cops!"); + EntityListener.this.multiplier = 800; + return; + } else { + EntityListener.this.multiplier -= 150; + p.sendMessage(ChatColor.YELLOW + "The cops are losing you!"); + plugin.setWantedLevel(p, lostLevel); + plugin.getNoTargetTicks().put(p, plugin.getNoTargetTicks().get(p) - EntityListener.this.multiplier); + return; + } + } + continue; + } catch(ConcurrentModificationException exception) { + continue; + } + } + } + }, 1, 1); + } + + @EventHandler + public void onChunkUnload(ChunkUnloadEvent e) { + for(Entity entity : e.getChunk().getEntities()) { + if(entity.hasMetadata("Cop")) { + this.plugin.getCops().values().forEach(s -> s.remove(entity)); + entity.remove(); + } + } + } + + @EventHandler + public void onEntityDeath(EntityDeathEvent event) { + if(!(event.getEntity() instanceof LivingEntity)) return; + if(event.getEntity().getKiller() == null) return; + if(event.getEntity().hasMetadata("Cop") && event.getEntity().getKiller().getType() == EntityType.PLAYER) { + LivingEntity victim = event.getEntity(); + Player killer = victim.getKiller(); + Cop cop = (Cop)victim.getMetadata("Cop").get(0).value(); + PlayerKillCopEvent playerKillCopEvent = new PlayerKillCopEvent(cop, victim, killer, event.getDrops()); + Bukkit.getPluginManager().callEvent(playerKillCopEvent); + event.getDrops().clear(); + event.getDrops().addAll(playerKillCopEvent.getDrops()); + event.setDroppedExp(0); + } else if(event.getEntity().getKiller().hasMetadata("Cop") && event.getEntity().getType() == EntityType.PLAYER) { + if(event.getEntity().getType() != EntityType.PLAYER) return; + Cop killer = (Cop)event.getEntity().getKiller().getMetadata("Cop").get(0).value(); + Player victim = (Player)event.getEntity(); + CopKillPlayerEvent killPlayerEvent = new CopKillPlayerEvent(killer, victim, event.getDrops()); + Bukkit.getPluginManager().callEvent(killPlayerEvent); + event.getDrops().clear(); + event.getDrops().addAll(killPlayerEvent.getDrops()); + } + } + + @EventHandler(ignoreCancelled = true) + public void onEntityDamageByEntity(EntityDamageByEntityEvent event) { + if(event.getEntity().hasMetadata("Cop") && event.getDamager() instanceof Player) { + + // grab event variables + Player damager = (Player)event.getDamager(); + Creature cop = (Creature)event.getEntity(); + + GTMUser gtmUser = GTMUserManager.getInstance().getUser(damager.getUniqueId()).orElse(null); + if (gtmUser != null){ + if (gtmUser.getJobMode() == JobMode.COP){ + event.setCancelled(true); + return; + } + } + + if(this.plugin.getWantedLevel(damager) == 0) { + this.plugin.addKill(damager); + } + this.plugin.getNoTargetTicks().put(damager, 0L); + cop.setTarget(damager); + } else if(event.getDamager().hasMetadata("Cop") && event.getEntity().getType() == EntityType.PLAYER) { + Player victim = (Player)event.getEntity(); + Cop cop = (Cop)event.getDamager().getMetadata("Cop").get(0).value(); + this.plugin.getNoTargetTicks().put(victim, 0L); + Weapon weapon = cop.getWeapon(); + CopDamagePlayerEvent damageEvent = new CopDamagePlayerEvent(cop, victim, weapon, event.getDamage()); + this.plugin.getServer().getPluginManager().callEvent(damageEvent); + if(damageEvent.isCancelled()) { + event.setCancelled(true); + return; + } + event.setDamage(damageEvent.getDamageDealt()); + } + } + + @EventHandler + public void onPlayerInteractEntity(PlayerInteractEntityEvent e) { + if(e.getRightClicked().hasMetadata("Cop")) e.setCancelled(true); + } + + @EventHandler + public void onEntityTarget(EntityTargetEvent e) { + if(e.getEntity().hasMetadata("Cop")) e.setCancelled(true); + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent e) { + Player p = e.getPlayer(); + this.plugin.getCops().getOrDefault(p, new HashSet<>()).forEach(LivingEntity::remove); + this.plugin.getCops().remove(p); + this.plugin.getNoTargetTicks().remove(p); + this.plugin.resetWantedLevel(p); + } + + @EventHandler + public void onPlayerKick(PlayerKickEvent e) { + Player p = e.getPlayer(); + this.plugin.getCops().getOrDefault(p, new HashSet<>()).forEach(LivingEntity::remove); + this.plugin.getCops().remove(p); + this.plugin.getNoTargetTicks().remove(p); + this.plugin.resetWantedLevel(p); + } + + @EventHandler + public void onPlayerDeath(PlayerDeathEvent e) { + Player p = e.getEntity(); + this.plugin.getCops().getOrDefault(p, new HashSet<>()).forEach(LivingEntity::remove); + this.plugin.getCops().remove(p); + this.plugin.getNoTargetTicks().remove(p); + this.plugin.resetWantedLevel(p); + } +} diff --git a/wastedcops-master@4d070d71e37/src/main/resources/config.yml b/wastedcops-master@4d070d71e37/src/main/resources/config.yml new file mode 100644 index 0000000..c4a7920 --- /dev/null +++ b/wastedcops-master@4d070d71e37/src/main/resources/config.yml @@ -0,0 +1,88 @@ +Cops: + PoliceMan: + Entity: ZOMBIE + Health: 5.0 + WeaponDropChance: 15 + Name: '&3&lCop' + KillReward: 50 + Weapons: + - Pistol + - StunGun + FBI: + Entity: HUSK + Health: 10.0 + WeaponDropChance: 10 + Name: '&b&lFBI' + KillReward: 100 + Weapons: + - MicroSMG + - SawedOffShotgun + - PumpShotgun + SWAT: + Entity: PIG_ZOMBIE + Health: 15.0 + WeaponDropChance: 5 + Name: '&8&lSWAT' + KillReward: 250 + Weapons: + - AssaultShotgun + - BullpupRifle + PoliceDog: + Entity: WOLF + Health: 5.0 + WeaponDropChance: 0 + Name: '&9&lPoliceDog' + KillReward: 50 + Weapons: [] +Groups: + 1: + PoliceDog: + Min: 1 + Max: 1 + PoliceMan: + Min: 0 + Max: 1 + 2: + PoliceDog: + Min: 0 + Max: 1 + PoliceMan: + Min: 1 + Max: 2 + 3: + PoliceDog: + Min: 1 + Max: 2 + PoliceMan: + Min: 1 + Max: 3 + FBI: + Min: 0 + Max: 1 + 4: + PoliceDog: + Min: 1 + Max: 2 + PoliceMan: + Min: 2 + Max: 3 + FBI: + Min: 0 + Max: 2 + SWAT: + Min: 0 + Max: 1 + 5: + PoliceDog: + Min: 1 + Max: 3 + PoliceMan: + Min: 2 + Max: 5 + FBI: + Min: 2 + Max: 3 + SWAT: + Min: 1 + Max: 3 +DoNotChange: 1.0.0 diff --git a/wastedcops-master@4d070d71e37/src/main/resources/plugin.yml b/wastedcops-master@4d070d71e37/src/main/resources/plugin.yml new file mode 100644 index 0000000..8ded80b --- /dev/null +++ b/wastedcops-master@4d070d71e37/src/main/resources/plugin.yml @@ -0,0 +1,19 @@ +name: WastedCops +main: com.j0ach1mmall3.wastedcops.Main +version: 1.0.0 +author: j0ach1mmall3 +description: A Cops plugin for GTM +depend: [JLib, WastedGuns] +commands: + WCReload: + description: Reloads the config + usage: /<command> +permissions: + wc.*: + description: All the WastedCops permissions + default: op + children: + wc.reload: true + wc.reload: + description: Access to /wcreload + default: op \ No newline at end of file diff --git a/wastedguns-master@2e3501603b9/.gitignore b/wastedguns-master@2e3501603b9/.gitignore new file mode 100644 index 0000000..14f5663 --- /dev/null +++ b/wastedguns-master@2e3501603b9/.gitignore @@ -0,0 +1,102 @@ + +\.idea/ + +target/classes/ + +target/ + +*.iml + +/bin/ +/build/ + +##### Gradle ##### +.gradle +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache + +# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 +# gradle/wrapper/gradle-wrapper.properties + +##### Eclipse ##### +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders + +.project + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# PyDev specific (Python IDE for Eclipse) +*.pydevproject + +# CDT-specific (C/C++ Development Tooling) +.cproject + +# JDT-specific (Eclipse Java Development Tools) +.classpath + +# Java annotation processor (APT) +.factorypath + +# PDT-specific (PHP Development Tools) +.buildpath + +# sbteclipse plugin +.target + +# Tern plugin +.tern-project + +# TeXlipse plugin +.texlipse + +# STS (Spring Tool Suite) +.springBeans + +# Code Recommenders +.recommenders/ + +*.class + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear + +# Unit Testing +logs/ + +##### IntelliJ ##### +*.iml +*.ipr +*.iws +.idea/ + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +##### MacOS ##### +.DS_Store + diff --git a/wastedguns-master@2e3501603b9/README.md b/wastedguns-master@2e3501603b9/README.md new file mode 100644 index 0000000..fdaec0e --- /dev/null +++ b/wastedguns-master@2e3501603b9/README.md @@ -0,0 +1 @@ +First commit. \ No newline at end of file diff --git a/wastedguns-master@2e3501603b9/pom.xml b/wastedguns-master@2e3501603b9/pom.xml new file mode 100644 index 0000000..fb0c541 --- /dev/null +++ b/wastedguns-master@2e3501603b9/pom.xml @@ -0,0 +1,132 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>net.grandtheftmc</groupId> + <artifactId>wastedguns</artifactId> + <version>1.1.6</version> + <name>WastedGuns</name> + + <repositories> + <repository> + <id>jitpack.io</id> + <url>https://jitpack.io</url> + </repository> + <repository> + <id>nexus-release</id> + <url>http://nexus.grandtheftmc.net/content/repositories/releases</url> + </repository> + </repositories> + + <distributionManagement> + <repository> + <id>nexus-release</id> + <name>Internal Releases</name> + <url>http://nexus.grandtheftmc.net/content/repositories/releases</url> + </repository> + <snapshotRepository> + <id>nexus-snapshot</id> + <name>Internal Snapshots</name> + <url>http://nexus.grandtheftmc.net/content/repositories/snapshots</url> + </snapshotRepository> + </distributionManagement> + + <dependencies> + <dependency> + <groupId>de.slikey</groupId> + <artifactId>EffectLib</artifactId> + <version>5.2</version> + </dependency> + <dependency> + <groupId>org.spigotmc.1.12</groupId> + <artifactId>spigot</artifactId> + <version>1.12.0</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.comphenix.protocol</groupId> + <artifactId>ProtocolLib</artifactId> + <version>1.0.0</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.github.j0ach1mmall3</groupId> + <artifactId>JLib</artifactId> + <version>1.10.0</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>net.grandtheftmc</groupId> + <artifactId>wastedvehicles</artifactId> + <version>1.0.2.rewrite</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>net.grandtheftmc</groupId> + <artifactId>houses</artifactId> + <version>LATEST</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>net.grandtheftmc</groupId> + <artifactId>core</artifactId> + <version>2.3.9-mutex</version> + <scope>provided</scope> + </dependency> + </dependencies> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <maven.compiler.source>1.8</maven.compiler.source> + <maven.compiler.target>1.8</maven.compiler.target> + </properties> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-shade-plugin</artifactId> + <version>2.4.3</version> + <configuration> + <finalName>WastedGuns</finalName> + <artifactSet> + <includes> + <include>de.slikey:EffectLib</include> + <include>net.grandtheftmc:WastedVehicles</include> + </includes> + </artifactSet> + </configuration> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>shade</goal> + </goals> + </execution> + </executions> + </plugin> + + <!-- Nexus deploy --> + <plugin> + <groupId>org.sonatype.plugins</groupId> + <artifactId>nexus-staging-maven-plugin</artifactId> + <version>1.6.8</version> + <extensions>true</extensions> + <executions> + <execution> + <id>default-deploy</id> + <phase>deploy</phase> + <goals> + <goal>deploy</goal> + </goals> + </execution> + </executions> + <configuration> + <serverId>nexus</serverId> + <nexusUrl>http://nexus.grandtheftmc.net/</nexusUrl> + <skipStaging>true</skipStaging> + </configuration> + </plugin> + </plugins> + </build> +</project> \ No newline at end of file diff --git a/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/Main.java b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/Main.java new file mode 100644 index 0000000..c4306e3 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/Main.java @@ -0,0 +1,154 @@ +package com.j0ach1mmall3.wastedguns; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 5/05/2016 + */ +public final class Main { +// private final Map<LivingEntity, List<Integer>> shootingLivingEntities = new HashMap<>(); +// private final Map<LivingEntity, LivingEntity> homingTargets = new HashMap<>(); +// private final Map<LivingEntity, Set<Entity>> stickyBombs = new HashMap<>(); +// private final Set<LivingEntity> reloadingLivingEntities = new HashSet<>(); +// private final Map<String, Long> cooldownLivingEntities = new HashMap<>(); +// private final Map<LivingEntity, Integer> burstShots = new HashMap<>(); +// private final Map<LivingEntity, Integer> burstTicks = new HashMap<>(); + +// private final HashMap<UUID, PlayerCache> playerCacheMap = Maps.newHashMap(); +// +// private final Map<Block, Material> blockQueue = new HashMap<>(); +// private final Set<Entity> entityQueue = new HashSet<>(); +// +// private Collection<Material> ignoreBlocks = new ArrayList<>(); +// +// private Attachments attachments; +// private Explosives explosives; +// private Melee melee; +// private Ranged ranged; +// private Airstrikes airstrikes; +// +// private EffectManager manager; +// private static Main wastedGuns; +// +// @Override +// public void onEnable() { +// this.reload(); +// new PlayerListener(this); +// new EntityListener(this); +// new WeaponsListener(this); +// new GiveWeaponCommandHandler(this).registerCommand(new Command(this, "GiveWeapon", "wg.giveweapon", ChatColor.RED + "Usage: /giveweapon <identifier> <player>")); +// new WGReloadCommandHandler(this).registerCommand(new Command(this, "WGReload", "wg.reload", ChatColor.RED + "Usage: /wgreload")); +// this.manager = new EffectManager(this); +// wastedGuns = this; +// } +// +// @Override +// public void onDisable() { +// this.blockQueue.entrySet().forEach(e -> e.getKey().setType(e.getValue())); +// this.entityQueue.forEach(Entity::remove); +//// this.stickyBombs.entrySet().forEach(e -> e.getValue().stream().filter(ent -> !(ent instanceof Player)).forEach(Entity::remove)); +// manager.dispose(); +// } +// +// public void reload() { +// this.config = new Config(this); +// this.attachments = new Attachments(this); +// this.explosives = new Explosives(this); +// this.melee = new Melee(this); +// this.ranged = new Ranged(this); +// this.airstrikes = new Airstrikes(this); +// } +// +// public static Main getWastedGuns() { +// return wastedGuns; +// } +// +// public EffectManager getEffectManager() { +// return this.manager; +// } +// +// public HashMap<UUID, PlayerCache> getPlayerCacheMap() { +// return this.playerCacheMap; +// } +// +// public PlayerCache getPlayerCache(UUID uniqueId) { +// return this.playerCacheMap.containsKey(uniqueId) ? this.getPlayerCache(uniqueId) : null; +// } +// +// public Map<Block, Material> getBlockQueue() { +// return this.blockQueue; +// } +// +// public Set<Entity> getEntityQueue() { +// return this.entityQueue; +// } +// +// public Attachments getAttachments() { +// return this.attachments; +// } +// +// public Explosives getExplosives() { +// return this.explosives; +// } +// +// public Melee getMelee() { +// return this.melee; +// } +// +// public Ranged getRanged() { +// return this.ranged; +// } +// +// public Set<Weapon<?>> getWeapons() { +// return null; +// } + +// public Optional<Weapon> getWeapon(ItemStack itemStack) { +// if (itemStack == null || !itemStack.hasItemMeta() || !itemStack.getItemMeta().hasDisplayName()) return Optional.empty(); +// +// Optional<Weapon> weapon = WeaponType.getWeaponsFromType(WeaponType.Type.THROWABLE).stream().filter(w -> General.areSimilar(w.getItemStack(), itemStack)).findFirst(); +// if (!weapon.isPresent()) +// weapon = WeaponType.getWeaponsFromType(WeaponType.Type.DROPPABLE).stream().filter(w -> General.areSimilar(w.getItemStack(), itemStack)).findFirst(); +// if (!weapon.isPresent()) +// weapon = WeaponType.getWeaponsFromType(WeaponType.Type.MELEE).stream().filter(w -> w.getItemStack().getType() == itemStack.getType() && w.getItemStack().getData().equals(itemStack.getData())).findFirst(); +// if (!weapon.isPresent()) +// weapon = WeaponType.getWeaponsFromType(WeaponType.Type.RANGED).stream().filter(w -> w.getItemStack().getType() == itemStack.getType() && itemStack.getItemMeta().getDisplayName().contains("«") && itemStack.getItemMeta().getDisplayName().contains("»")).findFirst(); +// +// if (weapon.isPresent()) { +// Weapon w = weapon.get().clone(); +// Attachment.getAttachments(this, itemStack).forEach(a -> a.apply(w)); +// return Optional.of(w); +// } +// +// return weapon; +// } +// +// public Optional<Weapon> getWeapon(String identifier) { +// if (identifier == null) return Optional.empty(); +// Optional<Weapon> weapon = this.getWeapons().stream().filter(w -> w.getIdentifier().equalsIgnoreCase(identifier)).findFirst(); +// weapon.ifPresent(w -> { +// if (w instanceof ThrowableWeapon) return; +// try { +// w.setItemStack(NBTTags.setNbtTag(w.getItemStack(), "_", UUID.randomUUID().toString())); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// }); +// return weapon; +// } +// +// public Optional<Attachment> getAttachment(String identifier) { +// if (identifier == null) return Optional.empty(); +// return this.attachments.getAttachments().stream().filter(a -> a.getIdentifier().equalsIgnoreCase(identifier)).findFirst(); +// } +// +// public Collection<Material> getIgnoreBlocks() { +// if (this.ignoreBlocks == null || this.ignoreBlocks.isEmpty()) { +// this.ignoreBlocks = Arrays.asList(Material.SIGN, Material.SIGN_POST, +// Material.WALL_SIGN, Material.BREWING_STAND, Material.DROPPER, +// Material.CHEST, Material.ENDER_CHEST, Material.TRAPPED_CHEST, +// Material.IRON_DOOR_BLOCK, Material.IRON_DOOR, Material.ANVIL, +// Material.CARPET); +// } +// return this.ignoreBlocks; +// } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/MathUtil.java b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/MathUtil.java new file mode 100644 index 0000000..5076ab9 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/MathUtil.java @@ -0,0 +1,160 @@ +package com.j0ach1mmall3.wastedguns; + +import net.minecraft.server.v1_12_R1.AxisAlignedBB; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.craftbukkit.v1_12_R1.entity.CraftEntity; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.BlockIterator; +import org.bukkit.util.Vector; + +import java.util.Arrays; +import java.util.Set; +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 12/09/2016 + */ +public final class MathUtil { + private static final Set<Material> TRANSPARENT_BLOCKS = Arrays.asList(Material.values()).stream().filter(m -> m == Material.BARRIER || !m.isSolid()).collect(Collectors.toSet()); + + private MathUtil() { + } + + public static double getCrossProduct(LivingEntity livingEntity, Location target) { + if (livingEntity.getWorld() != target.getWorld()) return 1000; + + Location head = livingEntity.getLocation().add(0, livingEntity.getEyeHeight(), 0); + + Vector look = livingEntity.getLocation().getDirection().normalize(); + Vector direction = head.subtract(target).toVector().normalize(); + Vector cp = direction.crossProduct(look); + + return cp.length(); + } + + public static Stream<LivingEntity> getNearbyEntities(Entity entity, double range) { + return entity.getNearbyEntities(range, range, range).stream().filter(e -> e instanceof LivingEntity).map(e -> (LivingEntity) e); + } + + public static Stream<LivingEntity> getNearbyEntities(Entity entity, double x, double y, double z) { + return entity.getNearbyEntities(x, y, z).stream().filter(e -> e instanceof LivingEntity).map(e -> (LivingEntity) e); + } + + public static Object[] getNearestTarget(LivingEntity livingEntity, Location origin, Vector direction, int range) { + LivingEntity target = null; + Location intersection = null; + double distance = Double.MAX_VALUE; + for (LivingEntity e : getNearbyEntities(livingEntity, range).collect(Collectors.toList())) { + if (e.getType() == EntityType.PLAYER) { + Player player = (Player) e; + if (player.getGameMode() != GameMode.ADVENTURE && player.getGameMode() != GameMode.SURVIVAL) continue; + } + Location i = raytrace(origin, direction, getBoundingBox(e), range); + if (i != null && i.distance(origin) < distance) { + target = e; + intersection = i; + distance = i.distance(origin); + } + } + return target == null || intersection == null ? null : new Object[]{target, intersection}; + } + + @SuppressWarnings("deprecation") + public static Block getTargetBlock(Location origin, Vector direction, int range) { + ThreadLocalRandom random = ThreadLocalRandom.current(); + try { + BlockIterator blockIterator = new BlockIterator(origin.getWorld(), origin.toVector(), direction, 0, range); + while (blockIterator.hasNext()) { + Block b = blockIterator.next(); + if((b.getType() == Material.SIGN || b.getType().name().contains("FENCE")) && random.nextBoolean()) + continue; + + if (!TRANSPARENT_BLOCKS.contains(b.getType()) && !(b.getType().name().endsWith("DOOR") && (((b.getData() & 0x04) != 0) || ((b.getData() & 0x08) != 0 && b.getRelative(BlockFace.DOWN).getType() != Material.TRAP_DOOR && b.getRelative(BlockFace.DOWN).getType() != Material.IRON_TRAPDOOR && (b.getRelative(BlockFace.DOWN).getData() & 0x04) != 0)))) + return b; + } + } catch (IllegalStateException exception) { + } + return null; + } + + private static Location raytrace(Location origin, Vector direction, double[] boundingBox, int range) { + double invX = 1 / direction.getX(); + double invY = 1 / direction.getY(); + double invZ = 1 / direction.getZ(); + + double txmin = ((invX < 0 ? boundingBox[0] : boundingBox[3]) - origin.getX()) * invX; + double txmax = ((invX < 0 ? boundingBox[3] : boundingBox[0]) - origin.getX()) * invX; + double tymin = ((invY < 0 ? boundingBox[1] : boundingBox[4]) - origin.getY()) * invY; + double tymax = ((invY < 0 ? boundingBox[4] : boundingBox[1]) - origin.getY()) * invY; + double tzmin = ((invZ < 0 ? boundingBox[2] : boundingBox[5]) - origin.getZ()) * invZ; + double tzmax = ((invZ < 0 ? boundingBox[5] : boundingBox[2]) - origin.getZ()) * invZ; + + if (txmin > tymax || tymin > txmax) return null; + if (tymin > txmin) txmin = tymin; + if (tymax < txmax) txmax = tymax; + + if (txmin > tzmax || tzmin > txmax) return null; + if (tzmin > txmin) txmin = tzmin; + if (tzmax < txmax) txmax = tzmax; + + return txmin < range && txmax > 0 ? origin.clone().add(direction.clone().multiply(txmin - 0.1)) : null; + } + + private static double[] getBoundingBox(Entity entity) { + net.minecraft.server.v1_12_R1.Entity en = ((CraftEntity) entity).getHandle(); + AxisAlignedBB box = en.getBoundingBox(); + return new double[] {box.d, box.e, box.f, box.a, box.b, box.c}; + +// try { +// Object handle = ReflectionAPI.getHandle((Object) entity); +// Object boundingBox = handle.getClass().getMethod("getBoundingBox").invoke(handle); +// return new double[]{(double) ReflectionAPI.getNmsClass("AxisAlignedBB").getField("d").get(boundingBox), +// (double) ReflectionAPI.getNmsClass("AxisAlignedBB").getField("e").get(boundingBox), +// (double) ReflectionAPI.getNmsClass("AxisAlignedBB").getField("f").get(boundingBox), +// (double) ReflectionAPI.getNmsClass("AxisAlignedBB").getField("a").get(boundingBox), +// (double) ReflectionAPI.getNmsClass("AxisAlignedBB").getField("b").get(boundingBox), +// (double) ReflectionAPI.getNmsClass("AxisAlignedBB").getField("c").get(boundingBox)}; +// } catch (Exception e) { +// e.printStackTrace(); +// return null; +// } + } + + public static Vector getVelocity(Location from, Location to) { + double dX = from.getX() - to.getX(); + double dY = from.getY() - to.getY(); + double dZ = from.getZ() - to.getZ(); + double yaw = Math.atan2(dZ, dX); + double pitch = Math.atan2(Math.sqrt(dZ * dZ + dX * dX), dY) + 3.141592653589793D; + double x = Math.sin(pitch) * Math.cos(yaw); + double y = Math.sin(pitch) * Math.sin(yaw); + double z = Math.cos(pitch); + return new Vector(x, z, y); + } + + // + public static double getExplosionResistanceMultiplier(LivingEntity e) { + double total = 1; + ItemStack[] armor = e.getEquipment().getArmorContents(); + for(ItemStack is : armor) { + if(is==null) + continue; + if(!is.hasItemMeta() || !is.getItemMeta().hasEnchant(Enchantment.PROTECTION_EXPLOSIONS)) + continue; + total += is.getItemMeta().getEnchantLevel(Enchantment.PROTECTION_EXPLOSIONS); + } + return total / 2.0; + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/StringUtil.java b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/StringUtil.java new file mode 100644 index 0000000..9e91e06 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/StringUtil.java @@ -0,0 +1,78 @@ +package com.j0ach1mmall3.wastedguns; +/* + * Copyright (C) 2013-Current Carter Gale (Ktar5) <buildfresh@gmail.com> + * + * This file is part of wastedguns. + * + * wastedguns can not be copied and/or distributed without the express + * permission of the aforementioned owner. + */ + +import org.bukkit.ChatColor; + +import java.util.List; + +public class StringUtil { + /** + * Quickly color a string + */ + public static String colorString(String input) { + return input != null ? ChatColor.translateAlternateColorCodes('&', input) : null; + } + + /** + * Quickly remove color from a string + */ + public static String removeColor(String input) { + return ChatColor.stripColor(input); + } + + /** + * Color a list.. + */ + public static List<String> colorList(List<String> inputs) { + if (inputs == null) { + return null; + } + + for (int i = 0; i < inputs.size(); i++) + inputs.set(i, colorString(inputs.get(i))); + return inputs; + } + + /** + * Color us some strings matey! + */ + public static String[] colorArray(String[] inputs) { + for (int i = 0; i < inputs.length; i++) + inputs[i] = colorString(inputs[i]); + return inputs; + } + + public static String[] colorArray(String[] inputs, ChatColor color) { + for (int i = 0; i < inputs.length; i++) { + inputs[i] = color + inputs[i]; + } + + return inputs; + } + + /** + * Limits a string to an upper bound for its length + * + * @param string The string to limit + * @param limit The upper bound value length (char count) + * @return Returns the chopped up string if it goes over the limite, otherwise returns string + */ + public static String limitString(String string, int limit) { + return string.substring(0, Math.min(string.length(), limit)); + } + + public static String replace(String input, String toReplace, String replaceWith) { + return input.replace(toReplace, replaceWith); + } + + public static String replaceAndColor(String input, String toReplace, String replaceWith) { + return colorString(replace(input, toReplace, replaceWith)); + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/attachments/Attachment.java b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/attachments/Attachment.java new file mode 100644 index 0000000..f77f111 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/attachments/Attachment.java @@ -0,0 +1,167 @@ +package com.j0ach1mmall3.wastedguns.api.attachments; + +import com.j0ach1mmall3.jlib.inventory.CustomEnchantment; +import com.j0ach1mmall3.wastedguns.Main; +import net.grandtheftmc.guns.weapon.Weapon; +import org.bukkit.Sound; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.enchantments.EnchantmentTarget; +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 13/05/2016 + */ +public final class Attachment { + private final Main plugin; + private final String identifier; + private final double meleeDamageFactor; + private final double fireDelayFactor; + private final double walkSpeedFactor; + private final Sound useSound; + private final double damageFactor; + private final double accuracyFactor; + private final double recoilFactor; + private final double zoomFactor; + private final int magazineAmount; + private final double reloadTimeFactor; + private final double rangeFactor; + private final boolean pumpkinScope; + + private final Enchantment enchantment; + + public Attachment(Main plugin, String identifier, double meleeDamageFactor, double fireDelayFactor, double walkSpeedFactor, Sound useSound, double damageFactor, double accuracyFactor, double recoilFactor, double zoomFactor, int magazineAmount, double reloadTimeFactor, double rangeFactor, boolean pumpkinScope) { + this.plugin = plugin; + this.identifier = identifier; + this.meleeDamageFactor = meleeDamageFactor; + this.fireDelayFactor = fireDelayFactor; + this.walkSpeedFactor = walkSpeedFactor; + this.useSound = useSound; + this.damageFactor = damageFactor; + this.accuracyFactor = accuracyFactor; + this.recoilFactor = recoilFactor; + this.zoomFactor = zoomFactor; + this.magazineAmount = magazineAmount; + this.reloadTimeFactor = reloadTimeFactor; + this.rangeFactor = rangeFactor; + this.pumpkinScope = pumpkinScope; + + CustomEnchantment ce = new CustomEnchantment(this.identifier, new ArrayList<>(), EnchantmentTarget.ALL, 1, 1); + ce.register(); + this.enchantment = ce.getEnchantment(); + } + +// public String getIdentifier() { +// return this.identifier; +// } +// +// public double getMeleeDamageFactor() { +// return this.meleeDamageFactor; +// } +// +// public double getFireDelayFactor() { +// return this.fireDelayFactor; +// } +// +// public double getWalkSpeedFactor() { +// return this.walkSpeedFactor; +// } +// +// public Sound getUseSound() { +// return this.useSound; +// } +// +// public double getDamageFactor() { +// return this.damageFactor; +// } +// +// public double getAccuracyFactor() { +// return this.accuracyFactor; +// } +// +// public double getRecoilFactor() { +// return this.recoilFactor; +// } +// +// public double getZoomFactor() { +// return this.zoomFactor; +// } +// +// public int getMagazineAmount() { +// return this.magazineAmount; +// } +// +// public double getReloadTimeFactor() { +// return this.reloadTimeFactor; +// } +// +// public double getRangeFactor() { +// return this.rangeFactor; +// } +// +// public boolean isPumpkinScope() { +// return this.pumpkinScope; +// } +// +// public Enchantment getEnchantment() { +// return this.enchantment; +// } +// +// public ItemStack add(ItemStack itemStack) { +// Set<Attachment> attachments = getAttachments(this.plugin, itemStack); +// attachments.add(this); +// return setAttachments(itemStack, attachments); +// } +// +// public ItemStack remove(ItemStack itemStack) { +// Set<Attachment> attachments = getAttachments(this.plugin, itemStack); +// attachments.remove(this); +// return setAttachments(itemStack, attachments); +// } +// +// public boolean has(ItemStack itemStack) { +// return getAttachments(this.plugin, itemStack).contains(this); +// } +// +// public void apply(Weapon weapon) { +// weapon.setMeleeDamage(weapon.getMeleeDamage() * this.meleeDamageFactor); +// weapon.setFireDelay((long) (weapon.getFireDelay() * this.fireDelayFactor)); +// weapon.setWalkSpeed((float) (weapon.getWalkSpeed() * this.walkSpeedFactor)); +// if(this.useSound != null) weapon.setUseSound(this.useSound); +// +// if(weapon instanceof RangedWeapon) { +// RangedWeapon rangedWeapon = (RangedWeapon) weapon; +// rangedWeapon.setDamage(rangedWeapon.getDamage() * this.damageFactor); +// rangedWeapon.setAccuracy(rangedWeapon.getAccuracy() * this.accuracyFactor); +// rangedWeapon.setRecoil(rangedWeapon.getRecoil() * this.recoilFactor); +// rangedWeapon.setZoom((int) (rangedWeapon.getZoom() * this.zoomFactor)); +// rangedWeapon.setMagazine(rangedWeapon.getMagazine() + this.magazineAmount); +// rangedWeapon.setReloadTime((int) (rangedWeapon.getReloadTime() * this.reloadTimeFactor)); +// rangedWeapon.setRange((int) (rangedWeapon.getRange() * this.rangeFactor)); +// rangedWeapon.setPumpkinScope(this.pumpkinScope); +// } +// +// if(weapon instanceof EnergyWeapon) { +// EnergyWeapon energyWeapon = (EnergyWeapon) weapon; +// energyWeapon.setDamage(energyWeapon.getDamage() * this.damageFactor); +// energyWeapon.setRange(energyWeapon.getRange() * this.rangeFactor); +// } +// } +// +// public static Set<Attachment> getAttachments(Main plugin, ItemStack itemStack) { +// Set<Attachment> attachments = new HashSet<>(); +// itemStack.getEnchantments().keySet().stream().filter(e -> plugin.getAttachment(e.getName()).isPresent()).forEach(e -> attachments.add(plugin.getAttachment(e.getName()).get())); +// return attachments; +// } +// +// public static ItemStack setAttachments(ItemStack itemStack, Set<Attachment> attachments) { +// ItemStack is = itemStack.clone(); +// is.getEnchantments().forEach((e, i) -> is.removeEnchantment(e)); +// attachments.forEach(a -> is.addUnsafeEnchantment(a.enchantment, 1)); +// return is; +// } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/NetgunHitEvent.java b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/NetgunHitEvent.java new file mode 100644 index 0000000..bf8767e --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/NetgunHitEvent.java @@ -0,0 +1,135 @@ +package com.j0ach1mmall3.wastedguns.api.events; + +import java.util.Optional; + +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class NetgunHitEvent extends Event implements Cancellable { + + /** List of handlers for this event. */ + private static final HandlerList HANDLERS = new HandlerList(); + /** Whether or not this event is cancelled */ + private boolean cancelled; + /** The entity shooting the netgun */ + private final Entity shooter; + /** The entity getting hit by the netgun */ + private final Entity target; + /** The location of the hit, where the netgun explodes */ + private final Location location; + /** The number of ticks to keep the net alive for */ + private int duration; + + /** + * Construct a new NetgunHitEvent. + * <p> + * This should be constructed and fired whenever a netgun hits something. + * + * @param shooter - the shooter of the netgun + * @param target - the target of the netgun, if one exists + * @param location - the location where the net appears + * @param duration - the time, in ticks, that the nets live for + */ + public NetgunHitEvent(Entity shooter, Entity target, Location location, int duration) { + this.shooter = shooter; + this.target = target; + this.location = location; + this.duration = duration; + } + + /** + * {@inheritDoc} + */ + @Override + public HandlerList getHandlers() { + return HANDLERS; + } + + /** + * Get the list of handlers for this event. + * + * @return The handlers for this event. + */ + public static HandlerList getHandlerList() { + return HANDLERS; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isCancelled() { + return cancelled; + } + + /** + * {@inheritDoc} + */ + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + /** + * Get the entity that shot the netgun. + * + * @return The entity that shot the netgun. + */ + public Entity getShooter() { + return shooter; + } + + /** + * Get the target of the netgun, if one exists. + * + * @return The target of the netgun, if one exists, otherwise {@code empty}. + */ + public Optional<Entity> getTarget() { + if (target != null) { + return Optional.of(target); + } + + return Optional.empty(); + } + + /** + * Get the epicenter of the location for where the netgun hit. + * <p> + * This is used as a reference point for where to build the "webs". + * </p> + * + * @return The location for where the netgun hit. + */ + public Location getLocation() { + return location; + } + + /** + * Get the time, in ticks, that the webs from this netgun live for. + * <p> + * If the value is 20, that means the netgun's webs will stay on the server + * for 20 ticks or 1 second. + * </p> + * + * @return The time, in ticks that the webs will stay alive for. + */ + public int getDuration() { + return duration; + } + + /** + * Set the time, in ticks, that the webs from this netgun will live for. + * <p> + * If the value is 20, that means the netgun's webs will stay on the server + * for 20 ticks or 1 second. + * </p> + * + * @param duration - the time in ticks to live for the web + */ + public void setDuration(int duration) { + this.duration = duration; + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/WeaponDamageEvent.java b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/WeaponDamageEvent.java new file mode 100644 index 0000000..f477412 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/WeaponDamageEvent.java @@ -0,0 +1,99 @@ +package com.j0ach1mmall3.wastedguns.api.events; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.inventory.ItemStack; + +import net.grandtheftmc.guns.weapon.Weapon; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 7/05/2016 + */ +public final class WeaponDamageEvent extends WeaponEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + /** The damage involved in the event */ + private double damage; + /** The entity being damaged in the event */ + private final Entity entity; + /** The cause of the damage in the event */ + private final EntityDamageEvent.DamageCause cause; + + /** + * Construct a new WeaponDamageEvent. + * + * @param who - the living entity that owns the weapon + * @param weapon - the weapon in the event + * @param weaponItemStack - the weapon itemstack in the event + * @param damage - the damage for the event + * @param entity - the entity involved in the event that is getting damaged + * @param cause - the damage cause for the event + */ + public WeaponDamageEvent(LivingEntity who, Weapon weapon, ItemStack weaponItemStack, double damage, Entity entity, EntityDamageEvent.DamageCause cause) { + super(who, weapon, weaponItemStack); + this.damage = damage; + this.entity = entity; + this.cause = cause; + } + + /** + * Construct a new WeaponDamageEvent. + * + * @param who - the living entity that owns the weapon + * @param weapon - the weapon in the event + * @param damage - the damage for the event + * @param entity - the entity involved in the event that is getting damaged + * @param cause - the damage cause for the event + */ + public WeaponDamageEvent(LivingEntity who, Weapon weapon, double damage, Entity entity, EntityDamageEvent.DamageCause cause) { + this(who, weapon, null, damage, entity, cause); + } + + /** + * Get the amount of damage involved in the event. + * + * @return The amount of damage involved in the event. + */ + public double getDamage() { + return this.damage; + } + + /** + * Set the amount of damage involved in the event. + * + * @param damage - the amount of damage in the event + */ + public void setDamage(double damage) { + this.damage = damage; + } + + /** + * Get the entity involved in the event, that is being damaged. + * + * @return The entity being damaged. + */ + public Entity getEntity() { + return this.entity; + } + + /** + * Get the damage cause for the event. + * + * @return The damage cause for the event. + */ + public EntityDamageEvent.DamageCause getCause() { + return this.cause; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/WeaponDropEvent.java b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/WeaponDropEvent.java new file mode 100644 index 0000000..623c27e --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/WeaponDropEvent.java @@ -0,0 +1,34 @@ +package com.j0ach1mmall3.wastedguns.api.events; + +import net.grandtheftmc.guns.weapon.Weapon; +import org.bukkit.entity.Item; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.HandlerList; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 6/05/2016 + */ +public final class WeaponDropEvent extends WeaponEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final Item itemDrop; + + public WeaponDropEvent(LivingEntity who, Weapon weapon, Item itemDrop) { + super(who, weapon); + this.itemDrop = itemDrop; + } + + public Item getItemDrop() { + return this.itemDrop; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/WeaponEquipEvent.java b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/WeaponEquipEvent.java new file mode 100644 index 0000000..70a0be2 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/WeaponEquipEvent.java @@ -0,0 +1,40 @@ +package com.j0ach1mmall3.wastedguns.api.events; + +import net.grandtheftmc.guns.weapon.Weapon; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.ItemStack; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 29/09/2016 + */ +public final class WeaponEquipEvent extends WeaponEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final ItemStack previousItem; + private final ItemStack newItem; + + public WeaponEquipEvent(LivingEntity who, Weapon weapon, ItemStack previousItem, ItemStack newItem) { + super(who, weapon); + this.previousItem = previousItem; + this.newItem = newItem; + } + + public ItemStack getPreviousItem() { + return this.previousItem; + } + + public ItemStack getNewItem() { + return this.newItem; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/WeaponEvent.java b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/WeaponEvent.java new file mode 100644 index 0000000..085fab5 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/WeaponEvent.java @@ -0,0 +1,85 @@ +package com.j0ach1mmall3.wastedguns.api.events; + +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.inventory.ItemStack; + +import net.grandtheftmc.guns.weapon.Weapon; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 6/05/2016 + */ +public abstract class WeaponEvent extends Event implements Cancellable { + /** The weapon object involved in the event */ + protected final Weapon<?> weapon; + /** ItemStack representation for the weapon */ + protected final ItemStack weaponItemStack; + /** The living entity involved in the event */ + protected final LivingEntity livingEntity; + protected boolean cancelled; + + /** + * Construct a new WeaponEvent. + * + * @param who - the owner of the weapon + * @param weapon - the weapon involved + * @param weaponItemStack - the weapon itemstack involved + */ + protected WeaponEvent(LivingEntity who, Weapon<?> weapon, ItemStack weaponItemStack) { + this.livingEntity = who; + this.weapon = weapon; + this.weaponItemStack = weaponItemStack; + } + + /** + * Construct a new WeaponEvent. + * + * @param who - the owner of the weapon + * @param weapon - the weapon involved + */ + protected WeaponEvent(LivingEntity who, Weapon<?> weapon) { + this(who, weapon, null); + } + + /** + * Get the living entity involved in the event. + * <p> + * This is owner of the weapon. + * </p> + * + * @return The living entity involved in this event. + */ + public final LivingEntity getLivingEntity() { + return this.livingEntity; + } + + /** + * Get the weapon involved in this event. + * + * @return The weapon involved in this event. + */ + public final Weapon<?> getWeapon() { + return this.weapon; + } + + /** + * Get the weapon itemstack involved in this event. + * + * @return The weapon itemstack involved in this event. + */ + public final ItemStack getWeaponItemStack(){ + return this.weaponItemStack; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + @Override + public void setCancelled(boolean b) { + this.cancelled = b; + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/WeaponLeftClickEvent.java b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/WeaponLeftClickEvent.java new file mode 100644 index 0000000..b3de2f6 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/WeaponLeftClickEvent.java @@ -0,0 +1,26 @@ +package com.j0ach1mmall3.wastedguns.api.events; + +import net.grandtheftmc.guns.weapon.Weapon; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.HandlerList; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 6/05/2016 + */ +public final class WeaponLeftClickEvent extends WeaponEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + public WeaponLeftClickEvent(LivingEntity who, Weapon weapon) { + super(who, weapon); + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/WeaponPickupEvent.java b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/WeaponPickupEvent.java new file mode 100644 index 0000000..61b92b0 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/WeaponPickupEvent.java @@ -0,0 +1,34 @@ +package com.j0ach1mmall3.wastedguns.api.events; + +import net.grandtheftmc.guns.weapon.Weapon; +import org.bukkit.entity.Item; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.HandlerList; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 6/05/2016 + */ +public final class WeaponPickupEvent extends WeaponEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final Item item; + + public WeaponPickupEvent(LivingEntity who, Weapon weapon, Item item) { + super(who, weapon); + this.item = item; + } + + public Item getItem() { + return this.item; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/WeaponRightClickEvent.java b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/WeaponRightClickEvent.java new file mode 100644 index 0000000..b8eff2c --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/WeaponRightClickEvent.java @@ -0,0 +1,26 @@ +package com.j0ach1mmall3.wastedguns.api.events; + +import net.grandtheftmc.guns.weapon.Weapon; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.HandlerList; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 6/05/2016 + */ +public final class WeaponRightClickEvent extends WeaponEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + public WeaponRightClickEvent(LivingEntity who, Weapon weapon) { + super(who, weapon); + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/WeaponSneakEvent.java b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/WeaponSneakEvent.java new file mode 100644 index 0000000..3033c00 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/WeaponSneakEvent.java @@ -0,0 +1,33 @@ +package com.j0ach1mmall3.wastedguns.api.events; + +import net.grandtheftmc.guns.weapon.Weapon; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.HandlerList; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 6/05/2016 + */ +public final class WeaponSneakEvent extends WeaponEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final boolean sneaking; + + public WeaponSneakEvent(LivingEntity who, Weapon weapon, boolean sneaking) { + super(who, weapon); + this.sneaking = sneaking; + } + + public boolean isSneaking() { + return this.sneaking; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/explosives/ExplosionDamageEntityEvent.java b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/explosives/ExplosionDamageEntityEvent.java new file mode 100644 index 0000000..a4ea0ca --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/explosives/ExplosionDamageEntityEvent.java @@ -0,0 +1,65 @@ +package com.j0ach1mmall3.wastedguns.api.events.explosives; + +import com.j0ach1mmall3.wastedguns.api.events.WeaponEvent; +import net.grandtheftmc.guns.weapon.Weapon; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.EntityEvent; + +import java.util.Collection; + +public class ExplosionDamageEntityEvent extends WeaponEvent{ + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private Entity projectile; + private Collection<LivingEntity> victims; + private boolean cancelled; + private final LivingEntity shooter; + + public ExplosionDamageEntityEvent(LivingEntity shooter, Entity projectile, Collection<LivingEntity> victims, Weapon weapon) { + super(shooter, weapon); + this.projectile = projectile; + this.victims = victims; + this.shooter = shooter; + } + + public Entity getProjectile() { + return projectile; + } + + public Collection<LivingEntity> getVictims() { + return this.victims; + } + + public void setVictims(Collection<LivingEntity> victims) { + this.victims = victims; + } + + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } + + + public LivingEntity getShooter() { + return shooter; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean b) { + this.cancelled = b; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/ranged/AmmoUpdateEvent.java b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/ranged/AmmoUpdateEvent.java new file mode 100644 index 0000000..e5fec45 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/ranged/AmmoUpdateEvent.java @@ -0,0 +1,45 @@ +package com.j0ach1mmall3.wastedguns.api.events.ranged; + +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 16/07/2016 + */ +public final class AmmoUpdateEvent extends Event { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final Player player; + private Map<String, Integer> ammo = new HashMap<>(); + + + public AmmoUpdateEvent(Player player) { + this.player = player; + } + + public Player getPlayer() { + return this.player; + } + + public Map<String, Integer> getAmmo() { + return this.ammo; + } + + public void setAmmo(Map<String, Integer> ammo) { + this.ammo = ammo; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/ranged/RangedWeaponReloadEvent.java b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/ranged/RangedWeaponReloadEvent.java new file mode 100644 index 0000000..d8fafde --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/ranged/RangedWeaponReloadEvent.java @@ -0,0 +1,39 @@ +package com.j0ach1mmall3.wastedguns.api.events.ranged; + +import com.j0ach1mmall3.wastedguns.api.events.WeaponEvent; +import net.grandtheftmc.guns.weapon.Weapon; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.HandlerList; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 6/05/2016 + */ +public final class RangedWeaponReloadEvent extends WeaponEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private int ammoToReload; + + public RangedWeaponReloadEvent(LivingEntity who, Weapon weapon, int ammoToReload) { + super(who, weapon); + this.ammoToReload = ammoToReload; + } + + public int getAmmoToReload() { + return this.ammoToReload; + } + + public void setAmmoToReload(int ammoToReload) { + this.ammoToReload = ammoToReload; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } + +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/ranged/RangedWeaponShootEvent.java b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/ranged/RangedWeaponShootEvent.java new file mode 100644 index 0000000..a3f3db5 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/api/events/ranged/RangedWeaponShootEvent.java @@ -0,0 +1,28 @@ +package com.j0ach1mmall3.wastedguns.api.events.ranged; + +import com.j0ach1mmall3.wastedguns.api.events.WeaponEvent; +import net.grandtheftmc.guns.weapon.Weapon; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.HandlerList; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 6/05/2016 + */ +public final class RangedWeaponShootEvent extends WeaponEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + public RangedWeaponShootEvent(LivingEntity who, Weapon weapon) { + super(who, weapon); + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } + +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/commands/GiveWeaponCommandHandler.java b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/commands/GiveWeaponCommandHandler.java new file mode 100644 index 0000000..c9467a3 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/commands/GiveWeaponCommandHandler.java @@ -0,0 +1,70 @@ +package com.j0ach1mmall3.wastedguns.commands; + +import com.j0ach1mmall3.jlib.methods.General; +import net.grandtheftmc.core.commands.CoreCommand; +import net.grandtheftmc.core.commands.RankedCommand; +import net.grandtheftmc.core.users.UserRank; +import net.grandtheftmc.guns.GTMGuns; +import net.grandtheftmc.guns.WeaponManager; +import net.grandtheftmc.guns.weapon.Weapon; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.Optional; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 7/05/2016 + */ +public final class GiveWeaponCommandHandler extends CoreCommand<CommandSender> implements RankedCommand { + private final WeaponManager weaponManager; + + public GiveWeaponCommandHandler(WeaponManager weaponManager) { + super("giveweapon", "Gives a weapon to a player"); + this.weaponManager = weaponManager; + } + + @Override + public void execute(CommandSender sender, String[] strings) { + if(strings.length < 2) { + sender.sendMessage(ChatColor.RED + "Usage: /giveweapon <identifier> <player>"); + return; + } + + short id = -1; + try { + id = Short.parseShort(strings[0]); + } catch (NumberFormatException e) { + sender.sendMessage("Cannot convert '" + strings[0] + "' to a numeral."); + return; + } + + if(id == -1) { + sender.sendMessage("Cannot convert '" + strings[0] + "' to a numeral."); + return; + } + +// Optional<Weapon> weapon = this.plugin.getWeapon(strings[0]); + Optional<Weapon<?>> optional = weaponManager.getWeapon(id); + if(!optional.isPresent()) { + sender.sendMessage(ChatColor.RED + "Unknown weapon " + strings[0]); + return; + } + + Player p = General.getPlayerByName(strings[1], false); + if(p == null) { + sender.sendMessage(ChatColor.RED + "Unknown player " + strings[1]); + return; + } + + weaponManager.giveWeapon(p, optional.get().clone(), true); + sender.sendMessage(ChatColor.GREEN + "Successfully gave " + optional.get().getName() + " to " + p.getName()); + return; + } + + @Override + public UserRank requiredRank() { + return UserRank.ADMIN; + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/listeners/EntityListener.java b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/listeners/EntityListener.java new file mode 100644 index 0000000..4614558 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/listeners/EntityListener.java @@ -0,0 +1,131 @@ +package com.j0ach1mmall3.wastedguns.listeners; + +import com.j0ach1mmall3.wastedguns.Main; +import org.bukkit.event.Listener; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 6/05/2016 + */ +public final class EntityListener implements Listener { + private final Main plugin; + + public EntityListener(Main plugin) { + this.plugin = plugin; +// plugin.getServer().getPluginManager().registerEvents(this, plugin); +// Bukkit.getScheduler().scheduleSyncRepeatingTask(this.plugin, () -> { +// for (World world : Bukkit.getWorlds()) { +// for(Entity entity : world.getEntities()){ +// if(entity.hasMetadata("Explosive") && entity.isOnGround()){ +// ((Explosive) entity.getMetadata("Explosive").get(0).value()).onLand(entity); +// }else if(entity.hasMetadata("Airstrike") && entity.isOnGround()){ +// ((Airstrike) entity.getMetadata("Airstrike").get(0).value()).onLand(entity, (LivingEntity) entity.getMetadata("Shooter").get(0).value()); +// }else if(entity.hasMetadata("AirstrikeBomb") && entity instanceof ArmorStand && entity.isOnGround()){ +// ((Airstrike) entity.getMetadata("AirstrikeBomb").get(0).value()) +// .onExplode(entity, (LivingEntity) entity.getMetadata("Shooter").get(0).value()); +// entity.remove(); +// } +// } +// } +// }, 5, 5); + } + +// @EventHandler +// public void onProjectileHit(ProjectileHitEvent e) { +// Projectile projectile = e.getEntity(); +// +// if(!(e.getEntity().getShooter() instanceof LivingEntity)) return; +// +// LivingEntity who = (LivingEntity)e.getEntity().getShooter(); +// +// if(projectile.hasMetadata("Rocket")) ((Launcher) projectile.getMetadata("Rocket").get(0).value()).onHit(projectile); +// if(projectile.hasMetadata("Explosive")) ((Explosive) projectile.getMetadata("Explosive").get(0).value()).onExplode(projectile, who); +// } +// +// //TODO see if the every 1/4 second method is ok for this +// /* +// @EventHandler +// public void onEntityDamage(EntityDamageEvent event){ +// if(event.getEntity().hasMetadata("AirstrikeBomb") && event.getEntity() instanceof ArmorStand){ +// event.setDamage(0); +// Entity entity = event.getEntity(); +// ((Airstrike) entity.getMetadata("AirstrikeBomb").get(0).value()) +// .onExplode(entity, (LivingEntity) entity.getMetadata("Shooter").get(0).value()); +// event.getEntity().remove(); +// } +// }*/ +// +// @EventHandler +// public void onEntityDamageByEntity(EntityDamageByEntityEvent e) { +// if(e.getDamager().hasMetadata("StickyExplosive") && e.getDamager() instanceof Arrow && e.getEntity() instanceof LivingEntity && !(e.getEntity() instanceof ArmorStand)) { +// e.setDamage(0); +// Entity entity = e.getEntity(); +// Sounds.broadcastSound(Sound.ENTITY_ARROW_HIT, entity.getLocation()); +// Player player = (Player) e.getDamager().getMetadata("Shooter").get(0).value(); +// entity.setMetadata("StickyExplosive", new FixedMetadataValue(this.plugin, e.getDamager().getMetadata("StickyExplosive").get(0).value())); +// entity.setMetadata("Shooter", new FixedMetadataValue(this.plugin, player)); +// Set<Entity> stickyBombs = this.plugin.getStickyBombs().containsKey(player) ? this.plugin.getStickyBombs().get(player) : new HashSet<>(); +// stickyBombs.remove(e.getDamager()); +// stickyBombs.add(entity); +// this.plugin.getStickyBombs().put(player, stickyBombs); +// this.plugin.getEntityQueue().remove(e.getDamager()); +// e.getDamager().remove(); +// } +// } +// +// @SuppressWarnings("deprecation") +// @EventHandler +// public void onExplode(BlockExplodeEvent e) { +// if(this.plugin.getBabies().isFakeExplosionDebris()) { +// for (Block b : e.blockList()) { +// if(!b.getType().isSolid()) continue; +// Location l = b.getLocation(); +// l.setPitch(-Random.getInt(180)); +// l.setYaw(Random.getInt(360)); +// FallingBlock fb = l.getWorld().spawnFallingBlock(l, b.getType(), b.getData()); +// fb.setDropItem(false); +// fb.setHurtEntities(false); +// float x = -1.0F + (float)(Math.random() * 2.0D + 1.0D); +// float y = -2.0F + (float)(Math.random() * 4.0D + 1.0D); +// float z = -1.0F + (float)(Math.random() * 2.0D + 1.0D); +// fb.setVelocity(new Vector(x, y, z)); +// this.plugin.getEntityQueue().add(fb); +// Bukkit.getScheduler().scheduleSyncDelayedTask(this.plugin, () -> b.getState().update(), 5); +// } +// } +// e.blockList().clear(); +// } +// +// @SuppressWarnings("deprecation") +// @EventHandler +// public void onExplode(EntityExplodeEvent e) { +// if(this.plugin.getBabies().isFakeExplosionDebris()) { +// for (Block b : e.blockList()) { +// if(!b.getType().isSolid()) continue; +// Location l = b.getLocation(); +// l.setPitch(-Random.getInt(180)); +// l.setYaw(Random.getInt(360)); +// FallingBlock fb = l.getWorld().spawnFallingBlock(l, b.getType(), b.getData()); +// fb.setDropItem(false); +// fb.setHurtEntities(false); +// float x = -1.0F + (float)(Math.random() * 2.0D + 1.0D); +// float y = -2.0F + (float)(Math.random() * 4.0D + 1.0D); +// float z = -1.0F + (float)(Math.random() * 2.0D + 1.0D); +// fb.setVelocity(new Vector(x, y, z)); +// this.plugin.getEntityQueue().add(fb); +// Bukkit.getScheduler().scheduleSyncDelayedTask(this.plugin, () -> b.getState().update(), 5); +// } +// } +// e.blockList().clear(); +// } +// +// @EventHandler +// public void onEntityChangeBlock(EntityChangeBlockEvent e) { +// if(e.getEntity() instanceof FallingBlock) { +// this.plugin.getEntityQueue().remove(e.getEntity()); +// e.setCancelled(true); +// Block b = e.getBlock(); +// if(this.plugin.getBabies().isFakeExplosionDebrisParticles()) b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, e.getTo()); +// } +// } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/listeners/PlayerListener.java b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/listeners/PlayerListener.java new file mode 100644 index 0000000..738d2c9 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/listeners/PlayerListener.java @@ -0,0 +1,246 @@ +package com.j0ach1mmall3.wastedguns.listeners; + +import com.j0ach1mmall3.wastedguns.Main; +import org.bukkit.event.Listener; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 6/05/2016 + */ +public final class PlayerListener implements Listener { + private final Main plugin; + + public PlayerListener(Main plugin) { + this.plugin = plugin; +// plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + +// @EventHandler +// public void onPlayerInteractEntity(PlayerInteractEntityEvent e) { +// Player p = e.getPlayer(); +// ItemStack heldItem = p.getInventory().getItemInMainHand(); +// Optional<Weapon> weapon = this.plugin.getWeapon(heldItem); +// if(!weapon.isPresent()) return; +// +// WeaponRightClickEvent event = new WeaponRightClickEvent(p, weapon.get()); +// Bukkit.getPluginManager().callEvent(event); +// if(event.isCancelled()) e.setCancelled(true); +// } +// +// @EventHandler +// public void onPlayerToggleSneak(PlayerToggleSneakEvent e) { +// Player p = e.getPlayer(); +// PlayerCache playerCache = this.plugin.getPlayerCache(p.getUniqueId()); +// if(playerCache == null) return; +// +// if(e.isSneaking() && (playerCache.stickyBombs != null && !playerCache.stickyBombs.isEmpty())) { +// playerCache.stickyBombs.forEach(entity -> ((ThrowableWeapon) entity.getMetadata("StickyExplosive").get(0).value()).onExplode(entity, p)); +// playerCache.stickyBombs.clear(); +// } +// +// Optional<Weapon> weapon = this.plugin.getWeapon(p.getInventory().getItemInMainHand()); +// if(!weapon.isPresent()) return; +// +// WeaponSneakEvent event = new WeaponSneakEvent(p, weapon.get(), e.isSneaking()); +// Bukkit.getPluginManager().callEvent(event); +// if(event.isCancelled()) e.setCancelled(true); +// } +// +// @EventHandler +// public void onPlayerDropItem(PlayerDropItemEvent e) { +// Player p = e.getPlayer(); +// ItemStack itemStack = e.getItemDrop().getItemStack(); +// Optional<Weapon> weapon = this.plugin.getWeapon(itemStack); +// if(!weapon.isPresent()) return; +// +// WeaponDropEvent event = new WeaponDropEvent(p, weapon.get(), e.getItemDrop()); +// Bukkit.getPluginManager().callEvent(event); +// if(event.isCancelled()) e.setCancelled(true); +// } +// +// @EventHandler +// public void onPlayerPickupItem(PlayerPickupItemEvent e) { +// Player p = e.getPlayer(); +// +// if(e.getItem().hasMetadata("StickyExplosive") || e.getItem().hasMetadata("Explosive") || e.getItem().hasMetadata("ProximityExplosive")) { +// e.setCancelled(true); +// return; +// } +// +// Optional<Weapon> weapon = this.plugin.getWeapon(e.getItem().getItemStack()); +// if(!weapon.isPresent()) return; +// +// WeaponPickupEvent event = new WeaponPickupEvent(p, weapon.get(), e.getItem()); +// Bukkit.getPluginManager().callEvent(event); +// if(event.isCancelled()) e.setCancelled(true); +// } +// +// @EventHandler +// public void onPlayerSwapHandItems(PlayerSwapHandItemsEvent e) { +// Player p = e.getPlayer(); +// ItemStack previousItem = e.getMainHandItem(); +// ItemStack nextItem = e.getOffHandItem(); +// Optional<Weapon> previousWeapon = this.plugin.getWeapon(previousItem); +// Optional<Weapon> nextWeapon = this.plugin.getWeapon(nextItem); +// WeaponEquipEvent event = new WeaponEquipEvent(p, previousWeapon.isPresent() ? previousWeapon.get() : null, nextWeapon.isPresent() ? nextWeapon.get() : null, previousItem, nextItem); +// +// Bukkit.getPluginManager().callEvent(event); +// if (event.isCancelled()) e.setCancelled(true); +// } +// +// @EventHandler +// public void onPlayerItemHeld(PlayerItemHeldEvent e) { +// Player p = e.getPlayer(); +// ItemStack previousItem = p.getInventory().getItem(e.getPreviousSlot()); +// ItemStack nextItem = p.getInventory().getItem(e.getNewSlot()); +// Optional<Weapon> previousWeapon = this.plugin.getWeapon(previousItem); +// Optional<Weapon> nextWeapon = this.plugin.getWeapon(nextItem); +// WeaponEquipEvent event = new WeaponEquipEvent(p, previousWeapon.isPresent() ? previousWeapon.get() : null, nextWeapon.isPresent() ? nextWeapon.get() : null, previousItem, nextItem); +// +// Bukkit.getPluginManager().callEvent(event); +// if (event.isCancelled()) e.setCancelled(true); +// } +// +// @EventHandler +// public void onPlayerInteract(PlayerInteractEvent e) { +// Player p = e.getPlayer(); +// ItemStack heldItem = p.getInventory().getItemInMainHand(); +// Optional<Weapon> weapon = this.plugin.getWeapon(heldItem); +// if(!weapon.isPresent()) return; +// WeaponEvent event; +// switch (e.getAction()) { +// case LEFT_CLICK_AIR: +// case LEFT_CLICK_BLOCK: +// event = new WeaponLeftClickEvent(p, weapon.get()); +// break; +// case RIGHT_CLICK_AIR: +// case RIGHT_CLICK_BLOCK: +// event = new WeaponRightClickEvent(p, weapon.get()); +// break; +// default: +// return; +// } +// +// Bukkit.getPluginManager().callEvent(event); +// if(event.isCancelled()) e.setCancelled(true); +// } +// +// @EventHandler(priority = EventPriority.LOWEST) +// public void onEntityDamageByEntity(EntityDamageByEntityEvent e) { +// if(!(e.getDamager() instanceof LivingEntity)) return; +// +// LivingEntity l = (LivingEntity) e.getDamager(); +// +// Optional<Weapon> weapon = this.plugin.getWeapon(l.getEquipment().getItemInMainHand()); +// if(!weapon.isPresent() || e.getCause() != EntityDamageEvent.DamageCause.ENTITY_ATTACK) return; +// +// WeaponDamageEvent event = new WeaponDamageEvent(l, weapon.get(), e.getDamage(), e.getEntity(), e.getCause()); +// Bukkit.getPluginManager().callEvent(event); +// e.setDamage(event.getDamage()); +// if (event.isCancelled()) e.setCancelled(true); +// } +// +// @EventHandler +// public void onInventoryClick(InventoryClickEvent e) { +// Player p = (Player) e.getWhoClicked(); +// PlayerCache playerCache = this.plugin.getPlayerCache(p.getUniqueId()); +// if(playerCache == null) return; +// WeaponCache weaponCache = playerCache.getWeaponCache(p); +// if(weaponCache == null) return; +// +// if(playerCache.shootingLivingEntities != null && !playerCache.shootingLivingEntities.isEmpty()) +// e.setCancelled(true); +// +// weaponCache.reloading = false; +// +// if(!(e.getClickedInventory() instanceof PlayerInventory) && e.getCursor().getType() != Material.AIR) { +// ItemStack itemStack = e.getCursor(); +// Optional<Weapon> weapon = this.plugin.getWeapon(itemStack); +// if(weapon.isPresent() && weapon.get() instanceof RangedWeapon) { +// RangedWeapon rangedWeapon = (RangedWeapon) weapon.get(); +// rangedWeapon.setAmmo(itemStack, rangedWeapon.getAmmo(itemStack), 0); +// } +// } +// } +// +// @EventHandler +// public void onPlayerJoin(PlayerJoinEvent e) { +// Player p = e.getPlayer(); +// ItemStack heldItem = p.getInventory().getItemInMainHand(); +// Optional<Weapon> weapon = this.plugin.getWeapon(heldItem); +// if(!weapon.isPresent()) return; +// +// e.getPlayer().getAttribute(Attribute.GENERIC_ATTACK_SPEED).setBaseValue(16.0); +// } +// +// @EventHandler +// public void onPlayerMove(PlayerMoveEvent e) { +// Player p = e.getPlayer(); +// if(p.getGameMode() != GameMode.ADVENTURE) return; +// p.getNearbyEntities(2.0, 2.0, 2.0).stream().filter(ent -> ent instanceof Item && ent.hasMetadata("ProximityExplosive")).forEach(ent -> ((ThrowableWeapon) ent.getMetadata("ProximityExplosive").get(0).value()).onExplode(ent, p)); +// } +// +// @EventHandler +// public void onPlayerDeath(PlayerDeathEvent e) { +// Player p = e.getEntity(); +// Bukkit.getOnlinePlayers().forEach(player -> { +// player.hidePlayer(p); +// player.showPlayer(p); +// }); +// p.removePotionEffect(PotionEffectType.SLOW); +// p.updateInventory(); +// +// this.plugin.getReloadingLivingEntities().remove(p); +// +// Player killer = p.getKiller(); +// if(killer == null) return; +// +// ItemStack heldItem = killer.getInventory().getItemInMainHand(); +// Optional<Weapon> weapon = this.plugin.getWeapon(heldItem); +// if(!weapon.isPresent()) return; +// +// weapon.get().getDeathMessages().entrySet().stream().filter(d -> d.getKey() == p.getLastDamageCause().getCause()).forEach(d -> e.setDeathMessage(Placeholders.parse(d.getValue(), p).replace("%victim%", p.getName()).replace("%killer%", killer.getName()))); +// } +// +// @EventHandler +// public void onPlayerQuit(PlayerQuitEvent e) { +// Player p = e.getPlayer(); +// this.plugin.getReloadingLivingEntities().remove(p); +// if(this.plugin.getShootingLivingEntities().containsKey(p)) this.plugin.getShootingLivingEntities().get(p).forEach(Bukkit.getScheduler()::cancelTask); +// this.plugin.getShootingLivingEntities().remove(p); +// this.plugin.getHomingTargets().remove(p); +// this.plugin.getWeapons().forEach(w -> this.plugin.getCooldownLivingEntities().remove(p.getName() + '/' + w.getIdentifier())); +// this.plugin.getBurstShots().remove(p); +// this.plugin.getBurstTicks().remove(p); +// if(this.plugin.getStickyBombs().containsKey(p)) this.plugin.getStickyBombs().get(p).forEach(Entity::remove); +// this.plugin.getStickyBombs().remove(p); +// p.setWalkSpeed(0.2F); +// } +// +// @EventHandler +// public void onPlayerKick(PlayerKickEvent e) { +// Player p = e.getPlayer(); +// this.plugin.getReloadingLivingEntities().remove(p); +// if(this.plugin.getShootingLivingEntities().containsKey(p)) this.plugin.getShootingLivingEntities().get(p).forEach(Bukkit.getScheduler()::cancelTask); +// this.plugin.getShootingLivingEntities().remove(p); +// this.plugin.getHomingTargets().remove(p); +// this.plugin.getWeapons().forEach(w -> this.plugin.getCooldownLivingEntities().remove(p.getName() + '/' + w.getIdentifier())); +// this.plugin.getBurstShots().remove(p); +// this.plugin.getBurstTicks().remove(p); +// if(this.plugin.getStickyBombs().containsKey(p)) this.plugin.getStickyBombs().get(p).forEach(Entity::remove); +// this.plugin.getStickyBombs().remove(p); +// p.setWalkSpeed(0.2F); +// } +// +// @EventHandler +// public void onAmmoUpdate(AmmoUpdateEvent e) { +// Map<String, Integer> ammo = e.getAmmo(); +// Arrays.asList(e.getPlayer().getInventory().getContents()).stream().filter(i -> i != null).forEach(i -> { +// Optional<Weapon> weapon = this.plugin.getWeapon(i); +// if(weapon.isPresent() && weapon.get() instanceof RangedWeapon) { +// RangedWeapon rangedWeapon = (RangedWeapon) weapon.get(); +// rangedWeapon.setAmmo(i, rangedWeapon.getAmmo(i), ammo.getOrDefault(rangedWeapon.getAmmoType(), 0)); +// } +// }); +// } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/listeners/WeaponsListener.java b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/listeners/WeaponsListener.java new file mode 100644 index 0000000..95a3a7e --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/com/j0ach1mmall3/wastedguns/listeners/WeaponsListener.java @@ -0,0 +1,81 @@ +package com.j0ach1mmall3.wastedguns.listeners; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; + +import com.j0ach1mmall3.wastedguns.api.events.ranged.RangedWeaponShootEvent; + +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.Utils; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserManager; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.guns.GTMGuns; +import net.grandtheftmc.guns.weapon.ranged.RangedWeapon; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.TextComponent; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 6/05/2016 + */ +public final class WeaponsListener implements Listener { + + private final GTMGuns plugin; + private final HashMap<UUID, LinkedList<Long>> playerShots = new HashMap<>(); + + public WeaponsListener(GTMGuns plugin) { + this.plugin = plugin; + plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + + + @EventHandler(priority = EventPriority.HIGHEST) + public void onShoot(RangedWeaponShootEvent event){ + if(!(event.getLivingEntity() instanceof Player)) + return; + Player player = (Player)event.getLivingEntity(); + RangedWeapon<?> weapon = (RangedWeapon<?>)event.getWeapon(); + + if(!weapon.isAutomatic()) + return; + + double allowedSPS = 25.0; //bullets shot every tick (20 ticks = 1 sec) and have some buffer for lag. + + LinkedList<Long> shots = this.playerShots.getOrDefault(player.getUniqueId(), new LinkedList<Long>()); + + if(shots.size() >= allowedSPS) { + long difference = shots.getFirst() - shots.getLast(); + if(difference < 1000) { //player may be hacking. + BaseComponent[] components = TextComponent.fromLegacyText(Lang.ANTICHEAT.s() + Utils.f("&c" + player.getName() + "&7 has triggered &cFASTPLACE &7 event! &f&l" + (allowedSPS/TimeUnit.MILLISECONDS.toSeconds(difference)) + "/s (Normal is " + allowedSPS + "/s &7")); + for (BaseComponent c : components) { + c.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText(Utils.f("&7Reports&f: &7&oClick to inspect")))); + c.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/inspect " + player.getName())); + } + + ServerUtil.runTask(() -> { + for (User user : UserManager.getInstance().getUsers()) { + if (!user.isStaff()){ + continue; + } + Bukkit.getPlayer(user.getUUID()).spigot().sendMessage(components); + } + }); + } + shots.clear(); + } + + this.playerShots.put(player.getUniqueId(), shots); + + } +} \ No newline at end of file diff --git a/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/DamageDataHandler.java b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/DamageDataHandler.java new file mode 100644 index 0000000..c2e36be --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/DamageDataHandler.java @@ -0,0 +1,90 @@ +package net.grandtheftmc.guns; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; + +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +public class DamageDataHandler { + + /** The singleton instance of this handler */ + private static DamageDataHandler instance; + /** Maps uuid of entity to damage event cause */ + private Map<UUID, EntityDamageByEntityEvent> uuidToDamageEventCause; + + /** + * Construct a new DamageDataHandler. + * <p> + * This will be used to keep track of damage sources for damage events due + * to weapons. + * </p> + */ + private DamageDataHandler() { + this.uuidToDamageEventCause = new HashMap<>(); + } + + /** + * Get the instance of this handler. + * + * @return The instance of this handler. + */ + public static DamageDataHandler getInstance() { + if (instance == null) { + instance = new DamageDataHandler(); + } + + return instance; + } + + /** + * Add damage data for the given uuid. + * + * @param uuid - the uuid of the entity + * @param damageEvent - the damage event data to add + * + * @return {@code true} if the data was overwritten, {@code false} + * otherwise. + */ + public boolean addData(UUID uuid, EntityDamageByEntityEvent damageEvent) { + + boolean updated = false; + if (uuidToDamageEventCause.containsKey(uuid)) { + updated = true; + } + + uuidToDamageEventCause.put(uuid, damageEvent); + return updated; + } + + /** + * Removes the damage data for the given uuid. + * + * @param uuid - the uuid of the entity to remove data for + * + * @return The data regarding the uuid damage, otherwise empty. + */ + public Optional<EntityDamageByEntityEvent> removeData(UUID uuid) { + if (uuidToDamageEventCause.containsKey(uuid)) { + return Optional.of(uuidToDamageEventCause.remove(uuid)); + } + + return Optional.empty(); + } + + /** + * Get the damage data for the given entity. + * + * @param uuid - the uuid of the user to lookup + * + * @return The damage data for the given entity, if exists. + */ + public Optional<EntityDamageByEntityEvent> getData(UUID uuid) { + if (uuidToDamageEventCause.containsKey(uuid)) { + return Optional.of(uuidToDamageEventCause.get(uuid)); + } + + return Optional.empty(); + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/GTMGuns.java b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/GTMGuns.java new file mode 100644 index 0000000..237d27c --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/GTMGuns.java @@ -0,0 +1,49 @@ +package net.grandtheftmc.guns; + +import org.bukkit.plugin.java.JavaPlugin; + +import de.slikey.effectlib.EffectManager; + +/** + * Created by Luke Bingham on 19/07/2017. + */ +public final class GTMGuns extends JavaPlugin { + + public static final boolean DEBUG = false; + /** If using the star system */ + public static boolean STAR_SYSTEM = true; + /** If using the kill count system */ + public static boolean KILL_COUNT_SYSTEM = true; + /** If using the star system, max number of stars */ + public static int MAX_STARS = 3; + + private static GTMGuns instance; + private WeaponManager weaponManager; + private EffectManager effectManager; + + @Override + public final void onEnable() { + instance = this; + this.effectManager = new EffectManager(this); + this.weaponManager = new WeaponManager(); + WeaponHandler weaponHandler = new WeaponHandler(this, this.weaponManager); + //new WeaponsListener(this); + } + + @Override + public final void onDisable() { + instance = null; + } + + public WeaponManager getWeaponManager() { + return weaponManager; + } + + public static GTMGuns getInstance() { + return instance; + } + + public EffectManager getEffectManager() { + return this.effectManager; + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/TESTING.java b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/TESTING.java new file mode 100644 index 0000000..95534f3 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/TESTING.java @@ -0,0 +1,17 @@ +package net.grandtheftmc.guns; + +public class TESTING { + + public static void main(String[] args) { + int best = 80; + double result = getPercentBetweenValues(best, 36); + System.out.println(result); + + int result2 = (int) Math.floor(result) / 10; + System.out.println(result2); + } + + public static double getPercentBetweenValues(double goal, double value) { + return 100 - Math.abs(((goal - value) / goal) * 100); + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/WeaponCooldown.java b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/WeaponCooldown.java new file mode 100644 index 0000000..6c03558 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/WeaponCooldown.java @@ -0,0 +1,29 @@ +package net.grandtheftmc.guns; + +import net.grandtheftmc.guns.weapon.Weapon; +import net.grandtheftmc.guns.weapon.WeaponType; + +/** + * Created by Luke Bingham on 19/07/2017. + */ +public class WeaponCooldown { + private final Weapon weapon; + private long cooldown; + + public WeaponCooldown(Weapon weapon, long time) { + this.weapon = weapon; + this.cooldown = System.currentTimeMillis() + time; + } + + public WeaponCooldown(Weapon weapon, int time) { + this(weapon, (long) time); + } + + public final Weapon getWeaponType() { + return this.weapon; + } + + public boolean hasElapsed() { + return System.currentTimeMillis() >= this.cooldown; + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/WeaponHandler.java b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/WeaponHandler.java new file mode 100644 index 0000000..327da75 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/WeaponHandler.java @@ -0,0 +1,924 @@ +package net.grandtheftmc.guns; + +import java.util.HashMap; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; + +import org.apache.commons.lang.math.RandomUtils; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Effect; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.attribute.Attribute; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.entity.FallingBlock; +import org.bukkit.entity.Item; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.TNTPrimed; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockExplodeEvent; +import org.bukkit.event.entity.EntityChangeBlockEvent; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.entity.ProjectileHitEvent; +import org.bukkit.event.inventory.InventoryOpenEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerItemHeldEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerKickEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.PlayerSwapHandItemsEvent; +import org.bukkit.event.player.PlayerToggleSneakEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.metadata.MetadataValue; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.util.Vector; + +import com.google.common.collect.Maps; +import com.j0ach1mmall3.wastedguns.api.events.WeaponDamageEvent; +import com.j0ach1mmall3.wastedguns.api.events.WeaponDropEvent; +import com.j0ach1mmall3.wastedguns.api.events.WeaponEquipEvent; +import com.j0ach1mmall3.wastedguns.api.events.WeaponEvent; +import com.j0ach1mmall3.wastedguns.api.events.WeaponLeftClickEvent; +import com.j0ach1mmall3.wastedguns.api.events.WeaponPickupEvent; +import com.j0ach1mmall3.wastedguns.api.events.WeaponRightClickEvent; +import com.j0ach1mmall3.wastedguns.api.events.WeaponSneakEvent; +import com.j0ach1mmall3.wastedvehicles.Main; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.servers.ServerType; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.core.util.nbt.CoreNbt; +import net.grandtheftmc.core.util.nbt.NBTUtil1_12_2; +import net.grandtheftmc.guns.cache.PlayerCache; +import net.grandtheftmc.guns.weapon.MeleeWeapon; +import net.grandtheftmc.guns.weapon.ThrowableWeapon; +import net.grandtheftmc.guns.weapon.Weapon; +import net.grandtheftmc.guns.weapon.attribute.WeaponExplosive; +import net.grandtheftmc.guns.weapon.ranged.RangedWeapon; + +/** + * Created by Luke Bingham on 19/07/2017. + */ +public class WeaponHandler implements Listener { + private final HashMap<UUID, List<WeaponCooldown>> cooldownMap; + private final HashMap<UUID, Long> fastplace; + + private final GTMGuns plugin; + private final WeaponManager weaponManager; + + public WeaponHandler(GTMGuns plugin, WeaponManager weaponManager) { + this.plugin = plugin; + this.weaponManager = weaponManager; + this.cooldownMap = Maps.newHashMap(); + this.fastplace = Maps.newHashMap(); + + plugin.getServer().getPluginManager().registerEvents(this, plugin); + + + Bukkit.getScheduler().scheduleSyncRepeatingTask(this.plugin, () -> { + for (World world : Bukkit.getWorlds()) { + for(Entity entity : world.getEntities()){ + if(entity.hasMetadata("Explosive") && entity.isOnGround()){ + ((WeaponExplosive) entity.getMetadata("Explosive").get(0).value()).onLand(entity); + } +// else if(entity.hasMetadata("Airstrike") && entity.isOnGround()) { +// ((AirstrikeWeapon) entity.getMetadata("Airstrike").get(0).value()).onLand(entity); +// } + } + } + }, 5, 5); + +// Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, () -> { +// for(UUID uuid : weaponManager.playerCacheMap.keySet()) { +// Player player = Bukkit.getPlayer(uuid); +// if(player == null) { +// weaponManager.playerCacheMap.remove(uuid); +// continue; +// } +// +// PlayerCache playerCache = weaponManager.getPlayerCache(uuid); +// if(playerCache == null) continue; +// if(!playerCache.shooting) continue; +// +// ItemStack heldItem = player.getEquipment().getItemInMainHand(); +// if(heldItem == null || heldItem.getType() == Material.AIR) { +// playerCache.burst = 0; +// playerCache.shooting = false; +// continue; +// } +// WeaponCache weaponCache = weaponManager.getPlayerWeaponCache(player, heldItem.getDurability()); +// if(weaponCache == null) { +// playerCache.burst = 0; +// playerCache.shooting = false; +// continue; +// } +// +// Weapon<?> weapon = weaponManager.getPlayerWeapon(player, heldItem.getDurability()); +// if(weapon == null) continue; +// if(!(weapon instanceof RangedWeapon)) continue; +// RangedWeapon<?> rangedWeapon = (RangedWeapon<?>) weapon; +// +// if(rangedWeapon instanceof WeaponRPM) { +// if (playerCache.burst >= (((WeaponRPM) rangedWeapon).getRpm() > 0 ? 5 : 1)) { +// playerCache.burst = 0; +// playerCache.shooting = false; +// continue; +// } +// } +// +// playerCache.burst += 1; +// +// Location origin = player.getEyeLocation(); +// Vector direction = origin.getDirection(); +// +// rangedWeapon.shoot(player, origin, direction, playerCache, weaponCache); +// +// if (rangedWeapon.getRecoil() != 0 && !player.isSneaking()) +// player.setVelocity(player.getVelocity().add(direction.setY(0).multiply(-rangedWeapon.getRecoil()))); +// } +// }, 1, 1); + } + + @EventHandler + protected final void onPlayerInteract(PlayerInteractEvent event) { + Player player = event.getPlayer(); + ItemStack heldItem = event.getItem(); + if(player==null || heldItem==null) + return; + PlayerCache cache = weaponManager.getPlayerCache(event.getPlayer().getUniqueId()); + Weapon<?> weapon = cache.getOrAddWeapon(heldItem); + if(weapon == null) { + event.getPlayer().setWalkSpeed(0.2f); + if(event.getPlayer().hasPotionEffect(PotionEffectType.SLOW)) + event.getPlayer().removePotionEffect(PotionEffectType.SLOW); + return; + } + if(heldItem.getAmount()>1 && !(weapon instanceof ThrowableWeapon)) { + player.sendMessage(Lang.AMMO.f("&7You cannot do this action with a stacked " + weapon.getName())); + return; + } + + if(GTMGuns.DEBUG) + event.getPlayer().sendMessage(weapon.getName()); + + WeaponEvent weaponEvent = null; + switch (event.getAction()) { + case LEFT_CLICK_BLOCK: + case LEFT_CLICK_AIR: + weaponEvent = new WeaponLeftClickEvent(event.getPlayer(), weapon); + break; + + case RIGHT_CLICK_BLOCK: + case RIGHT_CLICK_AIR: + // Fast-Place check. + long lastClicked = this.fastplace.getOrDefault(player.getUniqueId(), -1L); + if (lastClicked == -1L) + this.fastplace.put(player.getUniqueId(), System.currentTimeMillis() + 150); + else { + if (System.currentTimeMillis() < lastClicked) { +// ServerUtil.debug("Weapon right click DENIED. (" + (System.currentTimeMillis() - lastClicked) + "ms)"); + break; + } + this.fastplace.put(player.getUniqueId(), System.currentTimeMillis() + 150); + } + + weaponEvent = new WeaponRightClickEvent(event.getPlayer(), weapon); + break; + + default: return; + } + + if (weaponEvent == null) return; + + Bukkit.getPluginManager().callEvent(weaponEvent); + if(weaponEvent.isCancelled()) event.setCancelled(true); + } + + @EventHandler + protected final void onPlayerInteract(PlayerInteractEntityEvent event) { + Player player = event.getPlayer(); + ItemStack heldItem = player.getInventory().getItemInMainHand(); + + PlayerCache cache = weaponManager.getPlayerCache(player.getUniqueId()); + Weapon<?> weapon = cache.getOrAddWeapon(heldItem); + if(weapon == null) { + event.getPlayer().setWalkSpeed(0.2f); + if(event.getPlayer().hasPotionEffect(PotionEffectType.SLOW)) + event.getPlayer().removePotionEffect(PotionEffectType.SLOW); + return; + } + if(heldItem.getAmount()>1) { + player.sendMessage(Lang.AMMO.f("&7You cannot do this action with a stacked weapon!")); + return; + } + if(GTMGuns.DEBUG) + event.getPlayer().sendMessage(weapon.getName()); + + WeaponRightClickEvent weaponRightClickEvent = new WeaponRightClickEvent(event.getPlayer(), weapon); + Bukkit.getPluginManager().callEvent(weaponRightClickEvent); + + if(weaponRightClickEvent.isCancelled()) + event.setCancelled(true); + } + + @EventHandler + protected final void onEntityDamageByEntity(EntityDamageByEntityEvent event) { + + // if the damager of the event is living + if (event.getDamager() != null && event.getDamager() instanceof LivingEntity) { + + // ignore targets that aren't living + if(!(event.getEntity() instanceof LivingEntity)){ + return; + } + + // grab event variables + LivingEntity damager = (LivingEntity) event.getDamager(); + LivingEntity target = (LivingEntity) event.getEntity(); + DamageCause damageCause = event.getCause(); + + // get damage data if exists, queued up by ranged weapons/explosions etc. + EntityDamageByEntityEvent edbee = DamageDataHandler.getInstance().getData(target.getUniqueId()).orElse(null); + if (edbee != null){ + event.setDamage(edbee.getDamage()); + + // remove the data from the handler + DamageDataHandler.getInstance().removeData(target.getUniqueId()); + return; + } + else{ + + // ONLY HANDLE MELEE ATTACKS + if (damageCause == DamageCause.ENTITY_ATTACK){ + + // grab the weapon itemstack from their hand + ItemStack weaponItemStack = damager.getEquipment().getItemInMainHand(); + + // get the weapon + Weapon<?> heldWeapon = weaponManager.getWeaponByItem(weaponItemStack); + + // if no held weapon + if(heldWeapon == null) { + if(damager instanceof Player) { + Player p = (Player) damager; + p.setWalkSpeed(0.2f); + if (p.hasPotionEffect(PotionEffectType.SLOW)) + p.removePotionEffect(PotionEffectType.SLOW); + + if (p.getInventory().getItemInMainHand() != null && p.getInventory().getItemInMainHand().getType() == Material.DIAMOND_SWORD) { + event.setDamage(1); + } + } + return; + } + + // if melee weapon set melee damage + if (heldWeapon instanceof MeleeWeapon){ + event.setDamage(((MeleeWeapon) heldWeapon).getMeleeDamage()); + } + + // this case only happens when melee hitting with a ranged weapon + if (heldWeapon instanceof RangedWeapon) { + event.setDamage(((RangedWeapon) heldWeapon).getMeleeDamage()); + } + + // this case only happens when melee hitting players with throwable + if (heldWeapon instanceof ThrowableWeapon){ + event.setDamage(((ThrowableWeapon) heldWeapon).getMeleeDamage()); + } + + // call a weapon damage event to see if we can carry out this damage + WeaponDamageEvent weaponDamageEvent = new WeaponDamageEvent(damager, heldWeapon, weaponItemStack, event.getDamage(), target, event.getCause()); + Bukkit.getPluginManager().callEvent(weaponDamageEvent); + + // if damage was cancelled + if (weaponDamageEvent.isCancelled()){ + event.setCancelled(true); + } + else{ + // set the damage of the weapon damage event + event.setDamage(weaponDamageEvent.getDamage()); + } + } + } + } + } + + @EventHandler + protected final void onPlayerToggleSneak(PlayerToggleSneakEvent event) { + if(event.getPlayer() == null) return; + + PlayerCache cache = weaponManager.getPlayerCache(event.getPlayer().getUniqueId()); + + if(event.isSneaking() && !cache.stickyBombs.isEmpty()) { + cache.stickyBombs.forEach(bomb -> { + if(bomb.hasMetadata("StickyExplosive")) { + ((WeaponExplosive) bomb.getMetadata("StickyExplosive").get(0).value()).onExplode(bomb, (Player) bomb.getMetadata("Shooter").get(0).value()); + } + bomb.remove(); + }); + cache.stickyBombs.clear(); + } + + Weapon<?> weapon = cache.getOrAddWeapon(event.getPlayer().getEquipment().getItemInMainHand()); + if(weapon == null) { + event.getPlayer().setWalkSpeed(0.2f); + if(event.getPlayer().hasPotionEffect(PotionEffectType.SLOW)) + event.getPlayer().removePotionEffect(PotionEffectType.SLOW); + return; + } + + WeaponSneakEvent weaponSneakEvent = new WeaponSneakEvent(event.getPlayer(), weapon, event.isSneaking()); + Bukkit.getPluginManager().callEvent(weaponSneakEvent); + + if(weaponSneakEvent.isCancelled()) + event.setCancelled(true); + } + + @EventHandler + protected final void onPlayerDropItem(PlayerDropItemEvent event) { + if(event.getItemDrop() == null) return; + + if (Core.getSettings().getType() != ServerType.VICE) { + weaponManager.updateOldWeapon(event.getPlayer(), event.getItemDrop().getItemStack()); + } + + Weapon<?> weapon = weaponManager.getWeaponByItem(event.getItemDrop().getItemStack()); + if(weapon == null) return; + + WeaponDropEvent weaponDropEvent = new WeaponDropEvent(event.getPlayer(), weapon, event.getItemDrop()); + Bukkit.getPluginManager().callEvent(weaponDropEvent); + + if(weaponDropEvent.isCancelled()) + event.setCancelled(true); + } + + @EventHandler + protected final void onPlayerItemPickup(PlayerPickupItemEvent event) { + Item item = event.getItem(); + if(item == null || item.getItemStack() == null) return; + + CoreNbt nbt = new NBTUtil1_12_2(item.getItemStack());//testing + if(nbt.hasNBTTag("weapon_type")) { + Core.log(nbt.getNBTTag("weapon_type").toString()); + } + + if (Core.getSettings().getType() != ServerType.VICE) { + weaponManager.updateOldWeapon(event.getPlayer(), item.getItemStack()); + } + + if(item.hasMetadata("StickyExplosive") || + item.hasMetadata("Explosive") || + item.hasMetadata("ProximityExplosive")) { + event.setCancelled(true); + return; + } + + Weapon<?> weapon = weaponManager.getWeaponByItem(item.getItemStack()); + if(weapon == null) return; + + WeaponPickupEvent weaponPickupEvent = new WeaponPickupEvent(event.getPlayer(), weapon, item); + Bukkit.getPluginManager().callEvent(weaponPickupEvent); + + if(weaponPickupEvent.isCancelled()) + event.setCancelled(true); + } + + @EventHandler + protected final void onPlayerSwapHandItems(PlayerSwapHandItemsEvent event) { + PlayerCache cache = weaponManager.getPlayerCache(event.getPlayer().getUniqueId()); + + Weapon<?> current = cache.getOrAddWeapon(event.getMainHandItem()); + if(current != null && current.getWeaponState() == WeaponState.SHOOTING) { + event.setCancelled(true); + return; + } + + Weapon<?> next = cache.getOrAddWeapon(event.getOffHandItem()); + if(next == null) { + event.getPlayer().setWalkSpeed(0.2f); + if(event.getPlayer().hasPotionEffect(PotionEffectType.SLOW)) + event.getPlayer().removePotionEffect(PotionEffectType.SLOW); + return; + } + + WeaponEquipEvent weaponEquipEvent = new WeaponEquipEvent(event.getPlayer(), next, event.getMainHandItem(), event.getOffHandItem()); + Bukkit.getPluginManager().callEvent(weaponEquipEvent); + + if(weaponEquipEvent.isCancelled()) + event.setCancelled(true); + } + + @EventHandler + protected final void onPlayerItemHeld(PlayerItemHeldEvent event) { + PlayerCache cache = weaponManager.getPlayerCache(event.getPlayer().getUniqueId()); + + ItemStack next = event.getPlayer().getInventory().getItem(event.getNewSlot()), + previous = event.getPlayer().getInventory().getItem(event.getPreviousSlot()); + Weapon<?> currentWeapon = cache.getOrAddWeapon(previous); + if(currentWeapon != null && currentWeapon.getWeaponState() == WeaponState.SHOOTING) { + event.setCancelled(true); + return; + } + + Weapon<?> weapon = cache.getOrAddWeapon(next); + if(weapon == null) { + event.getPlayer().setWalkSpeed(0.2f); + if(event.getPlayer().hasPotionEffect(PotionEffectType.SLOW)) + event.getPlayer().removePotionEffect(PotionEffectType.SLOW); + return; + } + + WeaponEquipEvent weaponEquipEvent = new WeaponEquipEvent(event.getPlayer(), weapon, previous, next); + Bukkit.getPluginManager().callEvent(weaponEquipEvent); + + if(weaponEquipEvent.isCancelled()) + event.setCancelled(true); + } + + @EventHandler + protected final void onPlayerMove(PlayerMoveEvent event) { + if(event.getPlayer().getGameMode() != GameMode.ADVENTURE && event.getPlayer().getGameMode() != GameMode.SURVIVAL) return; + if(event.getFrom().getWorld().getName().equalsIgnoreCase("spawn")) return; + + //This event will fire even when moving your mouse. + //We only want this to continue if a player is stood on a different block. + if(event.getFrom().getBlockX() == event.getTo().getBlockX() && + event.getFrom().getBlockZ() == event.getTo().getBlockZ() && + event.getFrom().getBlockY() == event.getTo().getBlockY()) return; + + event.getPlayer().getNearbyEntities(2.0, 2.0, 2.0).stream() + .filter(entity -> entity instanceof Item && entity.hasMetadata("ProximityExplosive")) + .forEach(entity -> ((ThrowableWeapon) entity.getMetadata("ProximityExplosive").get(0).value()).onExplode(entity, event.getPlayer())); + } + + @EventHandler + protected final void onPlayerDeath(PlayerDeathEvent event) { + Bukkit.getOnlinePlayers().forEach(player -> { + player.hidePlayer(event.getEntity()); + player.showPlayer(event.getEntity()); + }); + + event.getEntity().removePotionEffect(PotionEffectType.SLOW); + event.getEntity().updateInventory(); + + Player killer = event.getEntity().getKiller(); + if(killer != null) { + ItemStack heldItem = killer.getInventory().getItemInMainHand(); + + PlayerCache cache = weaponManager.getPlayerCache(killer.getUniqueId()); + cache.stickyBombs.forEach(Entity::remove); + cache.stickyBombs.clear(); + + Weapon<?> weapon = cache.getOrAddWeapon(heldItem); + if (weapon == null) return; + + if(GTMGuns.KILL_COUNT_SYSTEM) { + ItemStack newItem = Weapon.setKills(heldItem, Weapon.getKills(heldItem) + 1); + Weapon.updateLore(newItem); + + killer.getInventory().setItemInMainHand(newItem); + } + + //TODO Display death message + } + + PlayerCache cache = weaponManager.getPlayerCache(event.getEntity().getUniqueId()); + cache.getPlayerWeapons().forEach(w -> { + w.setWeaponCooldown(null); + w.setWeaponState(WeaponState.IDLE); + }); + + cache.getPlayerWeapons().clear(); + } + + @EventHandler + protected final void onPlayerJoin(PlayerJoinEvent event) { + if(event.getPlayer() == null) return; + event.getPlayer().getAttribute(Attribute.GENERIC_ATTACK_SPEED).setBaseValue(16.0); + + if (Core.getSettings().getType() != ServerType.VICE) { + for (ItemStack itemStack : event.getPlayer().getInventory().getContents()) + weaponManager.updateOldWeapon(event.getPlayer(), itemStack); + } + + event.getPlayer().updateInventory(); + } + + /** + * Remove from PlayerCache when player quits. + */ + @EventHandler + protected final void onPlayerQuit(PlayerQuitEvent event) { + if(event.getPlayer() == null) return; + event.getPlayer().setWalkSpeed(0.2f); + PlayerCache cache = weaponManager.getPlayerCache(event.getPlayer().getUniqueId()); + + this.fastplace.remove(event.getPlayer().getUniqueId()); + + cache.getPlayerWeapons().clear(); + + if(cache.stickyBombs != null && !cache.stickyBombs.isEmpty()) { + cache.stickyBombs.forEach(Entity::remove); + cache.stickyBombs.clear(); + } + + //TODO Remove bullets + + weaponManager.playerCacheMap.remove(event.getPlayer().getUniqueId()); + } + + @EventHandler + protected final void onPlayerKick(PlayerKickEvent event) { + if(event.getPlayer() == null) return; + event.getPlayer().setWalkSpeed(0.2f); + PlayerCache cache = weaponManager.getPlayerCache(event.getPlayer().getUniqueId()); + + cache.getPlayerWeapons().clear(); + + if(cache.stickyBombs != null && !cache.stickyBombs.isEmpty()) { + cache.stickyBombs.forEach(Entity::remove); + cache.stickyBombs.clear(); + } + + //TODO Remove bullets + + weaponManager.playerCacheMap.remove(event.getPlayer().getUniqueId()); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + protected final void onWeaponRightClick(WeaponRightClickEvent event) { + if(event.getLivingEntity() == null || event.getWeapon() == null) return; + LivingEntity entity = event.getLivingEntity(); + Weapon<?> weapon = event.getWeapon(); + + event.setCancelled(true); + + if(weapon.getWeaponCooldown() != null && !weapon.getWeaponCooldown().hasElapsed()) return; + + if(entity instanceof Player) { + if(((Player) entity).getGameMode() == GameMode.SPECTATOR) { + event.setCancelled(true); + return; + } + + //Check for Flamethrower ammo (Fuel) + if(weapon.getName().equalsIgnoreCase("flamethrower")) { + + ItemStack itemStack = Main.getPlugin(Main.class).getBabies().getJetpackFuelItem().clone(); + boolean found = false; + for (ItemStack item : ((Player) entity).getInventory().getContents()) { + if(item == null) continue; + if(item.getType() != itemStack.getType()) continue; + if(!item.hasItemMeta() || !itemStack.hasItemMeta()) continue; + if(!item.getItemMeta().getDisplayName().equals(itemStack.getItemMeta().getDisplayName())) continue; + + found = true; + break; + } + + if(!found) { + entity.sendMessage(Lang.AMMO.f("&7The &c&lFlamethrower &7requires (jetpack) fuel to use!")); + return; + } + } + weapon.onRightClick((Player) entity); + + if(weapon.getDelay() > 0) + weapon.setWeaponCooldown(new WeaponCooldown(weapon, weapon.getDelay() * 50)); + } + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + protected final void onWeaponLeftClick(WeaponLeftClickEvent event) { + event.setCancelled(true); + if(event.getWeapon().getWeaponState() == WeaponState.SHOOTING) return; + event.getWeapon().onLeftClick((Player) event.getLivingEntity()); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + protected final void onWeaponSneak(WeaponSneakEvent event) { + if(!(event.getLivingEntity() instanceof Player)) return; + event.getWeapon().onSneak((Player) event.getLivingEntity(), event.isSneaking()); + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + protected final void onWeaponDamage(WeaponDamageEvent event) { + + // grab event variables + LivingEntity shooter = event.getLivingEntity(); + Weapon<?> weapon = event.getWeapon(); + LivingEntity target = (LivingEntity) event.getEntity(); + DamageCause cause = event.getCause(); + + if(!(weapon instanceof RangedWeapon) && (weapon.getWeaponCooldown() != null && !weapon.getWeaponCooldown().hasElapsed())) { + event.setCancelled(true); + return; + } + + // initial modifier for damage is 1x + double initialModifier = 1.0; + + // if star system + if (GTMGuns.STAR_SYSTEM){ + ItemStack is = event.getWeaponItemStack(); + + if (is != null){ + + // get the number of stars on this itemstack + int numStars = Weapon.getRarity(is); + if (numStars > 0){ + switch(numStars){ + case 1: + initialModifier = 1.0; + break; + case 2: + initialModifier = 1.1; + break; + case 3: + initialModifier = 1.2; + break; + default: + initialModifier = 1.0; + break; + } + } + } + } + + if(!(weapon instanceof RangedWeapon)){ + weapon.setWeaponCooldown(new WeaponCooldown(weapon, weapon.getDelay() * 50)); + } + + // Note: LauncherWeapons and grenades call this with a specific damage cause + // instead of relying of last damage, which allows us to hook into the actual damage caused + if (cause == DamageCause.DRAGON_BREATH){ + + if(weapon instanceof RangedWeapon){ + event.setDamage(((RangedWeapon) weapon).getDamage() * initialModifier); + } + + else if(weapon instanceof MeleeWeapon){ + event.setDamage(((MeleeWeapon) weapon).getMeleeDamage() * initialModifier); + } + + else if(weapon instanceof ThrowableWeapon){ + event.setDamage(((ThrowableWeapon) weapon).getDamage() * initialModifier); + } + } + // else melee damage + else{ + + if(weapon instanceof RangedWeapon){ + event.setDamage(((RangedWeapon) weapon).getMeleeDamage() * initialModifier); + } + + else if(weapon instanceof MeleeWeapon){ + event.setDamage(((MeleeWeapon) weapon).getMeleeDamage() * initialModifier); + } + + else if(weapon instanceof ThrowableWeapon){ + event.setDamage(((ThrowableWeapon) weapon).getMeleeDamage() * initialModifier); + } + } + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + protected final void onWeaponEquip(WeaponEquipEvent event) { + Weapon<?> weapon = weaponManager.getPlayerCache(event.getLivingEntity().getUniqueId()).getOrAddWeapon(event.getPreviousItem()); + if(weapon != null) { + event.getLivingEntity().removePotionEffect(PotionEffectType.SLOW); + if(event.getLivingEntity() instanceof Player) { + if(weapon instanceof RangedWeapon) + ((RangedWeapon) weapon).updateAmmo(event.getPreviousItem(), (Player) event.getLivingEntity()); + ((Player) event.getLivingEntity()).setWalkSpeed(0.2f); + weapon.onSneak((Player) event.getLivingEntity(), false); + } + } + + if(event.getWeapon() != null) { + if(event.getWeapon() instanceof RangedWeapon) + ((RangedWeapon) event.getWeapon()).updateAmmo(event.getNewItem(), (Player) event.getLivingEntity()); + ((Player) event.getLivingEntity()).setWalkSpeed((float) event.getWeapon().getWalkSpeed()); + } + } + +// @EventHandler +// protected final void onAmmoUpdate(AmmoUpdateEvent event) { +//// Arrays.stream(event.getPlayer().getInventory().getContents()).filter(item -> item != null && item.getType() != Material.AIR).forEach(item -> { +//// Optional<Weapon> weaponOptional = WeaponHandler.this.weaponManager.getPlayerWeapon(event.getPlayer(), item.getType(), item.getDurability()); +//// if(weaponOptional.isPresent() && weaponOptional.get() instanceof RangedWeapon) { +//// RangedWeapon rangedWeapon = (RangedWeapon) weaponOptional.get(); +//// rangedWeapon.setAmmo(item, rangedWeapon.getAmmo(item), event.getAmmo().getOrDefault(rangedWeapon.getAmmoType(), 0)); +//// } +//// }); +// } +// + @EventHandler + protected final void onProjectileHit(ProjectileHitEvent event) { + if(event.getEntity() == null) return; + if(event.getEntity().getShooter() == null) return; + if(!(event.getEntity().getShooter() instanceof LivingEntity)) return; + + if(event.getEntity().hasMetadata("Rocket")) ((WeaponExplosive) event.getEntity().getMetadata("Rocket").get(0).value()).onExplode(event.getEntity(), (Player) event.getEntity().getShooter()); + if(event.getEntity().hasMetadata("Explosive")) ((WeaponExplosive) event.getEntity().getMetadata("Explosive").get(0).value()).onExplode(event.getEntity(), (Player) event.getEntity().getShooter()); + } + +// @EventHandler +// protected final void onEntityDamage(EntityDamageEvent event) { +// if(event.getEntity() == null) return; +// if(event.getEntity().hasMetadata("AirstrikeBomb") && event.getEntity() instanceof ArmorStand) { +// event.setDamage(0); +//// ((AirstrikeWeapon) event.getEntity().getMetadata("AirstrikeBomb").get(0).value()).onExplode(event.getEntity(), (LivingEntity) event.getEntity().getMetadata("Shooter").get(0).value()); +// event.getEntity().remove(); +// } +// } + + @EventHandler + protected final void onBlockExplode(BlockExplodeEvent event) { + if (Core.getSettings().getType() == ServerType.GTM) { + event.setCancelled(true); + return; + } + + for(Block block : event.blockList()) { + if(!block.getType().isSolid()) continue; + if(RandomUtils.nextInt(10) != 1) continue;//Only spawn a few visuals + + Location l = block.getLocation(); + l.setPitch(-Utils.getRandom().nextInt(180)); + l.setYaw(Utils.getRandom().nextInt(360)); + FallingBlock fb = l.getWorld().spawnFallingBlock(l, block.getType(), block.getData()); + fb.setMetadata("EXPLOSION", new FixedMetadataValue(this.plugin, true)); + fb.setDropItem(false); + fb.setHurtEntities(false); + float x = -1.0F + (float)(Math.random() * 2.0D + 1.0D); + float y = -2.0F + (float)(Math.random() * 4.0D + 1.0D); + float z = -1.0F + (float)(Math.random() * 2.0D + 1.0D); + fb.setVelocity(new Vector(x, y, z)); + this.weaponManager.entityQueue.add(fb); +// block.getState().update(); + } +// event.blockList().clear(); + } + + //@EventHandler Disabled because it doesn't work. Makes the potency of the explosions very small. + protected final void onEntityExplode(EntityExplodeEvent event) { + if (Core.getSettings().getType() == ServerType.GTM) { +// event.setCancelled(true); + return; + } + + for (Block block : event.blockList()) { + if(!block.getType().isSolid()) continue; + if(RandomUtils.nextInt(10) != 1) continue;//Only spawn a few visuals + + Location l = block.getLocation(); + l.setPitch(-Utils.getRandom().nextInt(180)); + l.setYaw(Utils.getRandom().nextInt(360)); + FallingBlock fb = l.getWorld().spawnFallingBlock(l, block.getType(), block.getData()); + fb.setMetadata("EXPLOSION", new FixedMetadataValue(this.plugin, true)); + fb.setDropItem(false); + fb.setHurtEntities(false); + float x = -1.0F + (float)(Math.random() * 2.0D + 1.0D); + float y = -2.0F + (float)(Math.random() * 4.0D + 1.0D); + float z = -1.0F + (float)(Math.random() * 2.0D + 1.0D); + fb.setVelocity(new Vector(x, y, z)); + this.weaponManager.entityQueue.add(fb); +// block.getState().update(); + } +// event.blockList().clear(); + } + + @EventHandler + protected final void onEntityBlockChange(EntityChangeBlockEvent event) { + if(event.getEntity() == null) return; + if(!(event.getEntity() instanceof FallingBlock)) return; + if(!event.getEntity().hasMetadata("EXPLOSION")) + return; + + if(this.weaponManager == null || this.weaponManager.entityQueue == null) + return; + + this.weaponManager.entityQueue.remove(event.getEntity()); + event.setCancelled(true); + event.getBlock().getWorld().playEffect(event.getBlock().getLocation(), Effect.STEP_SOUND, event.getTo()); + } + +// @EventHandler +// protected final void onWeaponStack(ItemStackEvent event) { +// if(event.getItemStack() == null) return; +// if(event.getItemStack().getType() != Material.DIAMOND_SWORD) return; +// +// if(event.getItemStack().getDurability() <= 751 || event.getItemStack().getDurability() >= 800) { +// event.setCancelled(true); +// event.setClickOnly(true); +// } +// } + + @EventHandler(ignoreCancelled = true) + protected final void onInventoryOpen(InventoryOpenEvent event) { + if(event.getInventory() == null) return; + if(event.getPlayer() == null) return; + + if (Core.getSettings().getType() == ServerType.VICE) return; + + String name = ChatColor.stripColor(event.getInventory().getName()).toLowerCase(); + if(name.contains("kits") + || name.contains("stats") + || name.contains("cheat codes") + || name.contains("ranks") + || name.contains("choose the villager's job") + || name.contains("token shop") + || name.contains("crate rewards") + || name.contains("christmas shop") + || name.contains("preferences") + || name.contains("contacts") + || name.contains("vehicle shop") + || name.contains("choose category") + || name.contains("sell drugs") + || name.contains("buy machines") + || name.contains("choose category") + || name.contains("buy supplies") + || name.contains("choose gun ategory") + || name.contains("choose gun category") + || name.contains("buy blocks") + || name.contains("purchase throwable") + || name.contains("purchase melee") + || name.contains("purchase pistol") + || name.contains("purchase lmg") + || name.equals("Chest") + || name.equals("") + || name.contains("purchase smg") + || name.contains("purchase shotgun") + || name.contains("purchase assault") + || name.contains("purchase launcher") + || name.contains("purchase sniper") + || name.contains("purchase special") + || name.contains("taxi") + || name.contains("machine mechanic") + || name.contains("chamber") + || name.contains("distillery") + || name.contains("processor") + || name.contains("condenser") + || name.contains("producer") + || name.contains("sugar box")){ + return; + } + + for(ItemStack item : event.getInventory().getContents()) + weaponManager.updateOldWeapon((Player) event.getPlayer(), item); + + ((Player) event.getPlayer()).updateInventory(); + } + + @EventHandler + protected final void onPlayerExplode(EntityDamageByEntityEvent event) { + if (Core.getSettings().getType() == ServerType.GTM) { + if (event.getDamager() != null && event.getDamager() instanceof TNTPrimed) { + TNTPrimed tntPrimed = (TNTPrimed) event.getDamager(); + + if (tntPrimed.hasMetadata("entity_damage")){ + List<MetadataValue> md = tntPrimed.getMetadata("entity_damage"); + if (md != null && !md.isEmpty()){ + boolean damage = md.get(0).asBoolean(); + + if (damage){ + //event.setDamage((event.getDamage() / 4) * 3); + } + else{ + // ignore damage + //event.setDamage(0); + event.setCancelled(true); + } + } + } + } + } + } + + @EventHandler + protected final void onEntityDamage(EntityDamageEvent event) { + if (event.getCause() != EntityDamageEvent.DamageCause.FIRE_TICK) return; + if (Core.getSettings().getType() != ServerType.GTM) return; + event.setCancelled(ThreadLocalRandom.current().nextBoolean()); + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/WeaponManager.java b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/WeaponManager.java new file mode 100644 index 0000000..d00e38d --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/WeaponManager.java @@ -0,0 +1,302 @@ +package net.grandtheftmc.guns; + +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import com.google.common.collect.Sets; +import com.j0ach1mmall3.wastedguns.commands.GiveWeaponCommandHandler; + +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.users.UserManager; +import net.grandtheftmc.guns.cache.PlayerCache; +import net.grandtheftmc.guns.weapon.MeleeWeapon; +import net.grandtheftmc.guns.weapon.Weapon; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.ranged.RangedWeapon; + +/** + * Created by Luke Bingham on 19/07/2017. + */ +public final class WeaponManager { + protected final ConcurrentHashMap<UUID, PlayerCache> playerCacheMap; + protected final Set<Entity> entityQueue; + protected final Set<Material> ignoredBlocks; + protected final Set<Weapon<?>> weapons; + + public WeaponManager() { + this.playerCacheMap = new ConcurrentHashMap<UUID, PlayerCache>(); + this.entityQueue = Sets.newHashSet(); + this.ignoredBlocks = Sets.newHashSet(); + this.weapons = Sets.newHashSet(); + + //Register giveweapon command. + new GiveWeaponCommandHandler(this); + } + + public ConcurrentHashMap<UUID, PlayerCache> getPlayerCacheMap() { + return playerCacheMap; + } + + public Set<Entity> getEntityQueue() { + return entityQueue; + } + + public Set<Material> getIgnoredBlocks() { + return ignoredBlocks; + } + + public Set<Weapon<?>> getRegisteredWeapons() { + return weapons; + } + + public void registerWeapons(List<Weapon<?>> list) { + weapons.addAll(list); + } + + public Optional<Weapon<?>> getWeapon(short durability) { + return this.weapons.stream().filter(weapon -> { + if (weapon.getWeaponSkins() != null) { + for (WeaponSkin skin : weapon.getWeaponSkins()) { + if (skin.getIdentifier() == durability) { + return true; + } + } + } + + return weapon.getWeaponIdentifier() == durability; + }).findFirst(); + } + + public Optional<Weapon<?>> getWeaponFromUniqueIdentifier(short uniqueIdentifier) { + return this.weapons.stream().filter(weapon -> { + return weapon.getUniqueIdentifier() == uniqueIdentifier; + }).findFirst(); + } + + public Optional<Weapon<?>> getWeapon(String name){ + return this.weapons.stream().filter(weapon -> weapon.getName().equalsIgnoreCase(name) || weapon.getCompactName().equalsIgnoreCase(name)).findFirst(); + } + + /** + * Get the weapon based off the itemstack representation. + * <p> + * This is a costly operation and iterates over the whole set + * and compares each weapon's base itemstack to this one + * and possible skin lookups. + * </p> + * + * @param is - the itemstack to get the weapon for + * + * @return The weapon, that has the base representation as this item, if it exists. + */ + public Optional<Weapon<?>> getWeapon(ItemStack is){ + if (is == null){ + return Optional.empty(); + } + + for (Weapon weapon : this.weapons){ + ItemStack base = weapon.getBaseItemStack(); + + if (base != null){ + + // if the same type + if (is.getType() == base.getType() && is.getTypeId() == base.getTypeId()){ + + // if same durability + if (is.getDurability() == base.getDurability()){ + return Optional.of(weapon); + } + + if (weapon.getWeaponSkins() != null){ + for (WeaponSkin skin : weapon.getWeaponSkins()){ + if (is.getDurability() == skin.getIdentifier()){ + return Optional.of(weapon); + } + } + } + } + } + } + return Optional.empty(); + //return this.weapons.stream().filter(weapon -> weapon.getBaseItemStack().isSimilar(is)).findFirst(); + } + + public Weapon<?> getWeaponInHand(LivingEntity livingEntity) { + return getWeaponByItem(livingEntity.getEquipment().getItemInMainHand()); + } + + public Weapon<?> getWeaponByItem(ItemStack itemStack) { + if(itemStack == null || itemStack.getType() != Material.DIAMOND_SWORD) return null; + Optional<Weapon<?>> optional = getWeapon(itemStack.getDurability()); + return optional.orElse(null); + } + + public PlayerCache getPlayerCache(UUID uuid) { + return this.playerCacheMap.computeIfAbsent(uuid, k -> new PlayerCache()); + } + + public void giveWeapon(Player player, Weapon<?> weapon, boolean freshWeapon, short... skin) { +// ItemMeta itemMeta = weapon.getItemStack().getItemMeta(); +// if(freshWeapon) { +// if (weapon instanceof RangedWeapon) +// itemMeta.setDisplayName(Utils.f("&6" + weapon.getName() + " &8«&f" + ((RangedWeapon<?>) weapon).getMagazineSize() + "&8»")); +// else +// itemMeta.setDisplayName(Utils.f("&6" + weapon.getName())); +// } +// itemMeta.setUnbreakable(true); +// itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES); +// itemMeta.addItemFlags(ItemFlag.HIDE_UNBREAKABLE); +// weapon.getItemStack().setItemMeta(itemMeta); + + player.getInventory().addItem(weapon.createItemStack()); +// if(skin != null && skin.length > 0) setSkin(player, weapon, skin[0]); + player.updateInventory(); + } + + public Weapon<?> isWeapon(ItemStack itemStack) { + if(itemStack == null || itemStack.getType() != Material.DIAMOND_SWORD) return null; + + Optional<Weapon<?>> optional = weapons.stream().filter(weapon -> { + if (weapon.getWeaponSkins() != null) { + for (WeaponSkin skin : weapon.getWeaponSkins()) { + if (skin.getIdentifier() == itemStack.getDurability()) { + return true; + } + } + } + + return weapon.getWeaponIdentifier() == itemStack.getDurability(); + }).findFirst(); + + return optional.orElse(null); + } + + /** + * @deprecated This method does nothing, as createItemStack returns an ItemStack. + */ + @Deprecated + public void setSkin(Player player, Weapon<?> weapon, String skinName) { + WeaponSkin[] weaponSkins = null; + if(weapon instanceof RangedWeapon) + weaponSkins = ((RangedWeapon) weapon).getWeaponSkins(); + + if(weapon instanceof MeleeWeapon) + weaponSkins = ((MeleeWeapon) weapon).getWeaponSkins(); + + if(weaponSkins == null) return; + + for(WeaponSkin skin : weaponSkins) { + if(!skinName.equalsIgnoreCase(skin.getDisplayName())) continue; + + weapon.createItemStack(1, skin); + } + } + + /** + * @deprecated This method does nothing, as createItemStack returns an ItemStack. + */ + @Deprecated + public void setSkin(Player player, Weapon<?> weapon, short id) { + WeaponSkin[] weaponSkins = null; + if(weapon instanceof RangedWeapon) + weaponSkins = ((RangedWeapon) weapon).getWeaponSkins(); + + if(weapon instanceof MeleeWeapon) + weaponSkins = ((MeleeWeapon) weapon).getWeaponSkins(); + + if(weaponSkins == null) return; + + for(WeaponSkin skin : weaponSkins) { + if(weapon.getWeaponIdentifier() + id != skin.getIdentifier()) continue; + //weapon.getItemStack().setDurability(skin.getIdentifier()); + } + } + + public void updateOldWeapon(Player player, ItemStack item) { + if(player == null || (item == null || item.getType() == Material.AIR)) return; + if(!item.hasItemMeta() && !item.getItemMeta().hasDisplayName()) return; + + if(item.getItemMeta().getDisplayName()!=null && item.getItemMeta().getDisplayName().contains("Devil's Snowball")) + return; + + // grab core user + User user = UserManager.getInstance().getUser(player.getUniqueId()).orElse(null); + + if (user == null || user.hasEditMode()){ + return; + } + + Weapon<?> w = null; + for(Weapon<?> weapon : this.weapons) { + if(weapon.getOldItemStack().getType() == Material.FLINT_AND_STEEL && item.getType() == Material.FLINT_AND_STEEL) { + if(ChatColor.stripColor(item.getItemMeta().getDisplayName()).equalsIgnoreCase("Katana")) { + if(weapon.getName().equalsIgnoreCase("Katana")) { + w = weapon; + break; + } + } + + if(ChatColor.stripColor(item.getItemMeta().getDisplayName()).equalsIgnoreCase("Flamethrower")) { + if(weapon.getName().equalsIgnoreCase("Flamethrower")) { + w = weapon; + break; + } + } + } + else { + if(weapon.getOldItemStack().getType() == item.getType() && weapon.getOldItemStack().getData().getData() == item.getData().getData()) { + if(item.getDurability() == 0) { + w = weapon; + break; + } + else { + if(ChatColor.stripColor(item.getItemMeta().getDisplayName()).equalsIgnoreCase("Minigun")) { + if(weapon.getName().equalsIgnoreCase("Gold Minigun")) { + w = weapon; + break; + } + } + } + } + } + } + + if(w == null) return; + ItemStack newItem = w.getBaseItemStack().clone(); + item.setType(newItem.getType()); + item.setDurability(newItem.getDurability()); + item.setData(newItem.getData()); + item.setItemMeta(newItem.getItemMeta()); + +// net.minecraft.server.v1_12_R1.ItemStack nmsItem = CraftItemStack.asNMSCopy(item); +// NBTTagCompound compound; +// if (nmsItem.getTag() == null) compound = new NBTTagCompound(); +// else compound = nmsItem.getTag(); +// +// compound.set("stack_fix", new NBTTagString(UUID.randomUUID().toString())); +// compound.set("weapon_type", new NBTTagString(optional.get().getWeaponType().name())); +// +// compound.set("weapon_range", new NBTTagDouble(((RangedWeapon<?>) optional.get()).getRange())); +// compound.set("weapon_accuracy", new NBTTagDouble(((RangedWeapon<?>) optional.get()).getAccuracy())); +// compound.set("weapon_melee-damage", new NBTTagDouble(((MeleeWeapon) optional.get()).getMeleeDamage())); +// +// if(optional.get() instanceof RangedWeapon<?>) +// compound.set("weapon_damage", new NBTTagDouble(((RangedWeapon<?>) optional.get()).getDamage())); +// +// if(optional.get() instanceof WeaponRPM) +// compound.set("weapon_rpm", new NBTTagInt(((WeaponRPM) optional.get()).getRpm())); +// +// nmsItem.setTag(compound); +// item.setItemMeta(CraftItemStack.asBukkitCopy(nmsItem).getItemMeta()); + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/WeaponState.java b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/WeaponState.java new file mode 100644 index 0000000..19fe35b --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/WeaponState.java @@ -0,0 +1,34 @@ +package net.grandtheftmc.guns; + +/** + * Created by Luke Bingham on 24/07/2017. + */ +public enum WeaponState { + + /** + * This state will be used when the player is reloading their Weapon. + */ + RELOADING, + + /** + * This state will be used when the player is shooting their Weapon. + */ + SHOOTING, + + /** + * This state will be used when the player is bursting with their Weapon. + */ + BURSTING, + + /** + * This state will be used when the weapon is not doing anything. + */ + IDLE, + + /** + * This state will be used when the Weapon is no longer being used. + */ + NONE, + + ; +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/cache/PlayerCache.java b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/cache/PlayerCache.java new file mode 100644 index 0000000..2b647b4 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/cache/PlayerCache.java @@ -0,0 +1,93 @@ +package net.grandtheftmc.guns.cache; + +import java.util.HashSet; +import java.util.Optional; +import java.util.Set; + +import org.bukkit.Material; +import org.bukkit.entity.Entity; +import org.bukkit.inventory.ItemStack; + +import com.google.common.collect.Sets; + +import net.grandtheftmc.guns.GTMGuns; +import net.grandtheftmc.guns.weapon.Weapon; +import net.grandtheftmc.guns.weapon.WeaponSkin; + +/** + * Created by Luke Bingham on 19/07/2017. + */ +public class PlayerCache { + private final HashSet<Weapon<?>> playerWeapons; + public final Set<Entity> stickyBombs; + + public boolean shooting = false; + public int burst = 0, tick = 0; + + public PlayerCache() { + this.playerWeapons = Sets.newHashSet(); + this.stickyBombs = Sets.newHashSet(); + } + + public HashSet<Weapon<?>> getPlayerWeapons() { + return playerWeapons; + } + + public boolean hasWeapon(ItemStack itemStack) { + if(itemStack == null || itemStack.getType() != Material.DIAMOND_SWORD) return false; + + return playerWeapons.stream().anyMatch(weapon -> { + if (weapon.getWeaponSkins() != null) { + for (WeaponSkin skin : weapon.getWeaponSkins()) { + if (skin.getIdentifier() == itemStack.getDurability()) { + return true; + } + } + } + + return weapon.getWeaponIdentifier() == itemStack.getDurability(); + }); + } + + public Weapon<?> getCachedWeapon(ItemStack itemStack) { + if(itemStack == null || itemStack.getType() != Material.DIAMOND_SWORD) return null; + return this.getCachedWeapon(itemStack.getDurability()); + } + + public Weapon<?> getCachedWeapon(short identifier) { + Optional<Weapon<?>> optional = playerWeapons.stream().filter(weapon -> { + if (weapon.getWeaponSkins() != null) { + for (WeaponSkin skin : weapon.getWeaponSkins()) { + if (skin.getIdentifier() == identifier) { + return true; + } + } + } + + return weapon.getWeaponIdentifier() == identifier; + }).findFirst(); + + return optional.orElse(null); + } + + public Weapon<?> getOrAddWeapon(ItemStack itemStack) { + if(itemStack == null || itemStack.getType() != Material.DIAMOND_SWORD) return null; + Weapon<?> weapon = getCachedWeapon(itemStack); + if(weapon == null) { + Optional<Weapon<?>> optional = GTMGuns.getInstance().getWeaponManager().getWeapon(itemStack.getDurability()); + weapon = optional.<Weapon<?>>map(Weapon::clone).orElse(null); + if(weapon != null) playerWeapons.add(weapon); + } + return weapon; + } + + public Weapon<?> getOrAddWeapon(short identifier) { + Weapon<?> weapon = getCachedWeapon(identifier); + if(weapon == null) { + Optional<Weapon<?>> optional = GTMGuns.getInstance().getWeaponManager().getWeapon(identifier); + weapon = optional.<Weapon<?>>map(Weapon::clone).orElse(null); + if(weapon != null) playerWeapons.add(weapon); + } + return weapon; + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/cache/WeaponCache.java b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/cache/WeaponCache.java new file mode 100644 index 0000000..88c123e --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/cache/WeaponCache.java @@ -0,0 +1,18 @@ +package net.grandtheftmc.guns.cache; + +import net.grandtheftmc.guns.WeaponCooldown; +import net.grandtheftmc.guns.WeaponState; +import net.grandtheftmc.guns.weapon.Weapon; +import org.bukkit.entity.LivingEntity; + +/** + * Created by Luke Bingham on 19/07/2017. + */ +public class WeaponCache { + public WeaponCooldown cooldown; + public int burstShots, burstTicks, clip = -1; + public LivingEntity homingEntity; + public WeaponState weaponState = WeaponState.NONE; + + public Weapon<?> weapon = null; +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/AirstrikeWeapon.java b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/AirstrikeWeapon.java new file mode 100644 index 0000000..15e5375 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/AirstrikeWeapon.java @@ -0,0 +1,135 @@ +package net.grandtheftmc.guns.weapon; + +import org.bukkit.Sound; +import org.bukkit.inventory.ItemStack; + +/** + * Created by Luke Bingham on 18/07/2017. + */ +public class AirstrikeWeapon extends Weapon<AirstrikeWeapon> { + +// protected final boolean useBeacon = false; +// protected final Effect beaconParticle = null, explosionParticle = null; +// protected int beaconRadius = 3, circleParticles = 60, beaconLineParticles = 13, updateTicks = 5, rotationDegrees = 1, targetLength = 5; +// protected double damage = 0.0, explosionSize = 5.0, explosionStrength = 2.0; +// protected ItemStack bombItemStack, hydraItemStack; + + /** + * Construct a new Weapon. + */ + public AirstrikeWeapon(short uniqueIdentifier, String name, WeaponType weaponType, AmmoType ammoType, ItemStack itemStack, Sound[] sounds) { + super(uniqueIdentifier, name, weaponType, ammoType, itemStack, sounds); + } + + @Override + public String[] getStatsBar() { + return new String[] {"null"}; + } + + @Override + public AirstrikeWeapon clone() { + return null; + } + +// /** +// * Get the particle used for the beacon visuals. +// * +// * @return particle type +// */ +// public Effect getBeaconParticle() { +// return beaconParticle; +// } +// +// /** +// * Get the particles used to visualise the explosion. +// * +// * @return particle type +// */ +// public Effect getExplosionParticle() { +// return explosionParticle; +// } +// +// /** +// * Check if the airstrike weapon is using beacon. +// * +// * @return beacon status +// */ +// public boolean isUsingBeacon() { +// return useBeacon; +// } +// +// public int getBeaconRadius() { +// return beaconRadius; +// } +// +// public int getCircleParticles() { +// return circleParticles; +// } +// +// public int getBeaconLineParticles() { +// return beaconLineParticles; +// } +// +// public int getUpdateTicks() { +// return updateTicks; +// } +// +// public int getRotationDegrees() { +// return rotationDegrees; +// } +// +// public int getTargetLength() { +// return targetLength; +// } +// +// public double getDamage() { +// return damage; +// } +// +// public double getExplosionSize() { +// return explosionSize; +// } +// +// public double getExplosionStrength() { +// return explosionStrength; +// } +// +// /** +// * Get the Bomb Itemstack. +// * +// * @return bomb item +// */ +// public ItemStack getBombItemStack() { +// return bombItemStack; +//// ItemStack itemStack = new ItemStack(Material.STONE); +//// ItemMeta itemMeta = itemStack.getItemMeta(); +//// itemMeta.setDisplayName(Utils.f("&6Grenade")); +//// itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES); +//// itemStack.setItemMeta(itemMeta); +//// return itemStack; +// } +// +// /** +// * Get the Hydra Itemstack. +// * +// * @return hydra item +// */ +// public ItemStack getHydraItemStack() { +// return hydraItemStack; +//// ItemStack itemStack = new ItemStack(Material.QUARTZ_ORE); +//// ItemMeta itemMeta = itemStack.getItemMeta(); +//// itemMeta.setDisplayName(Utils.f("&4&lHydra")); +//// itemMeta.setLore(Collections.singletonList(Utils.f("&7Type: &a&lPlane"))); +//// itemStack.setItemMeta(itemMeta); +//// return itemStack; +// } +// +// /** +// * Get the fire delay for the airstrike. +// * +// * @return fire delay +// */ +// public int getFireDelay() { +// return 20; +// } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/AmmoType.java b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/AmmoType.java new file mode 100644 index 0000000..df852a7 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/AmmoType.java @@ -0,0 +1,39 @@ +package net.grandtheftmc.guns.weapon; + +/** + * Created by Luke Bingham on 21/07/2017. + */ +public enum AmmoType { + NONE("NONE"), + MELEE("MELEE"), + + //RANGED + PISTOL("PISTOL"), + SMG("SMG"), + SHOTGUN("SHOTGUN"), + LMG("MG"), + SNIPER("SNIPER"), + LAUNCHER("ROCKET"), + ASSAULT_RIFLE("ASSAULT_RIFLE"), + ROCKET("ROCKET"), + + MINIGUN("MINIGUN"), + + //EXTRA + EXPLOSIVE("EXPLOSIVE"), + ENERGY("ENERGY"), + GRENADE("GRENADE"), + + FUEL("FUEL"), + ; + + private String type; + + AmmoType(String type) { + this.type = type; + } + + public String getType() { + return type; + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/MeleeWeapon.java b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/MeleeWeapon.java new file mode 100644 index 0000000..4ef8efa --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/MeleeWeapon.java @@ -0,0 +1,116 @@ +package net.grandtheftmc.guns.weapon; + +import org.bukkit.ChatColor; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Vector; + +import com.j0ach1mmall3.jlib.methods.Sounds; +import com.j0ach1mmall3.wastedguns.MathUtil; + +import net.grandtheftmc.core.util.C; + +/** + * Created by Luke Bingham on 18/07/2017. + */ +public class MeleeWeapon extends Weapon<MeleeWeapon> { + + protected double meleeDamage = 0.0, range = 0.0; + + /** + * Construct a new Weapon. + */ + public MeleeWeapon(short uniqueIdentifier, String name, WeaponType weaponType, AmmoType ammoType, ItemStack itemStack, Sound[] sounds) { + super(uniqueIdentifier, name, weaponType, ammoType, itemStack, sounds); + + this.weaponSkins = new WeaponSkin[] { + new WeaponSkin(weaponType, itemStack.getDurability(), "&e&lDefault") + }; + } + + @Override + public void onRightClick(Player player){ + if(getName().equalsIgnoreCase("Chainsaw")) { + MathUtil.getNearbyEntities(player, this.range).forEach(e -> { + if (player.hasLineOfSight(e)) { + Vector toEntity = e.getLocation().toVector().subtract(player.getLocation().toVector()); + double dot = toEntity.normalize().dot(player.getLocation().getDirection()); + if (dot <= 1 && dot >= 0) { + e.setNoDamageTicks(0); + e.damage(getMeleeDamage(), player); + } + } + }); + Sounds.broadcastSound(getSounds()[0], player.getEyeLocation()); + } + } + + @Override + public String[] getStatsBar() { + String[] output = new String[1]; + String symbol = ":", + done = ChatColor.GREEN.toString() + ChatColor.BOLD, + empty = ChatColor.DARK_GRAY.toString() + ChatColor.BOLD; + int bars = 10; + double best = 0; + double result; + int stat; + for(int i = 0; i < 1; i ++) { + if(i == 0) { + output[i] = ""; + best = 15.0; + + result = net.grandtheftmc.core.util.MathUtil.getPercentBetweenValues(best, this.meleeDamage); + stat = (int) Math.floor(result) / 10; + for(int x = 0; x < bars; x++) { + output[i] += (x <= stat ? done : empty) + symbol; + } + output[i] += C.GRAY + " Damage"; + } +// else if(x == 1) { +// output[x] = "Range "; +// best = 100.0; +// for(int i = 1; i < (bars+1); i++) { +// if(i * (best / bars) > this.range) output[x] += done+symbol; +// else output[x] += empty+symbol; +// } +// } + } + + return output; + } + + @Override + public MeleeWeapon clone() { + MeleeWeapon weapon = new MeleeWeapon(getUniqueIdentifier(), getName(), getWeaponType(), getAmmoType(), getBaseItemStack().clone(), getSounds()); + weapon.oldItemStack = super.oldItemStack.clone(); + weapon.deathMessages = super.deathMessages; + weapon.walkSpeed = super.walkSpeed; + weapon.delay = super.delay; + weapon.meleeDamage = this.meleeDamage; + weapon.range = this.range; + return weapon; + } + + public double getMeleeDamage() { + return meleeDamage; + } + + public double getRange() { + return range; + } + + @Override + public WeaponSkin[] getWeaponSkins() { + return weaponSkins; + } + + protected void setWeaponSkins(WeaponSkin... skins) { + WeaponSkin defaultSkin = this.weaponSkins[0]; + this.weaponSkins = new WeaponSkin[skins.length + 1]; + for(int i = 0; i < skins.length; i++) + this.weaponSkins[i + 1] = skins[i]; + this.weaponSkins[0] = defaultSkin; + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ThrowableWeapon.java b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ThrowableWeapon.java new file mode 100644 index 0000000..a9770b1 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ThrowableWeapon.java @@ -0,0 +1,435 @@ +package net.grandtheftmc.guns.weapon; + +import java.util.Collection; +import java.util.stream.Collectors; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Effect; +import org.bukkit.GameMode; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.entity.AreaEffectCloud; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Item; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.TNTPrimed; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import com.j0ach1mmall3.jlib.inventory.CustomItem; +import com.j0ach1mmall3.jlib.methods.Random; +import com.j0ach1mmall3.jlib.methods.Sounds; +import com.j0ach1mmall3.wastedguns.MathUtil; +import com.j0ach1mmall3.wastedguns.api.events.explosives.ExplosionDamageEntityEvent; + +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.guns.DamageDataHandler; +import net.grandtheftmc.guns.GTMGuns; +import net.grandtheftmc.guns.cache.PlayerCache; +import net.grandtheftmc.guns.weapon.attribute.WeaponExplosive; + +/** + * Created by Luke Bingham on 18/07/2017. + */ +public class ThrowableWeapon extends Weapon<ThrowableWeapon> implements WeaponExplosive { + + protected Effect particles; + /** Does damage scale off of distance from projectile landing */ + protected boolean scaledDamage = false; + protected boolean sticky = false, proximity = false, flammable = false, teargas = false; + protected double damage = 0.0, meleeDamage = 0.0, explosionSize = 0.0, explosionStrength = 0.0; + protected int explosionDelay = 0, duration = 0, tntFuseDelay = 1; + + /** + * Construct a new Weapon. + */ + public ThrowableWeapon(short uniqueIdentifier, String name, WeaponType weaponType, AmmoType ammoType, ItemStack itemStack, Sound[] sounds) { + super(uniqueIdentifier, name, weaponType, ammoType, itemStack, sounds); + } + + @Override + public String[] getStatsBar() { + String[] output = new String[2]; + String symbol = ":", + done = ChatColor.GREEN.toString() + ChatColor.BOLD, + empty = ChatColor.DARK_GRAY.toString() + ChatColor.BOLD; + int bars = 10; + double best = 0; + double result; + int stat; + for(int i = 0; i < 2; i ++) { + if(i == 0) { + output[i] = ""; + best = 55.0; + + result = net.grandtheftmc.core.util.MathUtil.getPercentBetweenValues(best, this.damage); + stat = (int) Math.floor(result) / 10; + for(int x = 0; x < bars; x++) { + output[i] += (x <= stat ? done : empty) + symbol; + } + output[i] += C.GRAY + " Damage"; + } + + if(i == 1) { + output[i] = ""; + best = 3.0; + + result = net.grandtheftmc.core.util.MathUtil.getPercentBetweenValues(best, this.explosionStrength); + stat = (int) Math.floor(result) / 10; + for(int x = 0; x < bars; x++) { + output[i] += (x <= stat ? done : empty) + symbol; + } + output[i] += C.GRAY + " Strength"; + } +// else if(x == 1) { +// output[x] = "Range "; +// best = 100.0; +// for(int i = 1; i < (bars+1); i++) { +// if(i * (best / bars) > this.range) output[x] += done+symbol; +// else output[x] += empty+symbol; +// } +// } + } + + return output; + } + + public Effect getParticle() { + return particles; + } + + public boolean isSticky() { + return sticky; + } + + public boolean isProximity() { + return proximity; + } + + /** + * Get the generic damage of the Weapon. + * + * @return damage value + */ + public double getDamage() { + return damage; + } + + /** + * Get the Melee damage of the Weapon. + * + * @return damage value + */ + public double getMeleeDamage() { + return meleeDamage; + } + + /** + * Get the size of the explosion. + * + * @return explosion size + */ + public double getExplosionSize() { + return explosionSize; + } + + /** + * Get the strength of the explosion. + * + * @return explosion strength + */ + public double getExplosionStrength() { + return explosionStrength; + } + + /** + * Get the delay time of the explosion. + * + * @return delay value (in ticks) + */ + public int getExplosionDelay() { + return explosionDelay; + } + + public boolean isFlammable() { + return flammable; + } + + public boolean isTeargas() { + return teargas; + } + + public int getDuration() { + return duration; + } + + /** + * Get whether or not this launcher weapon does scaled damage. + * + * @return {@code true} if the damage is scaled from origin of projectile hit, {@code false} otherwise. + */ + public boolean isScaledDamage() { + return scaledDamage; + } + + @Override + public void onRightClick(Player player) { + PlayerCache cache = GTMGuns.getInstance().getWeaponManager().getPlayerCache(player.getUniqueId()); + if(this.sticky && cache.stickyBombs.size() >= 5) return; + + this.launchProjectile(player); + + ItemStack heldItem = player.getEquipment().getItemInMainHand(); + heldItem.setAmount(heldItem.getAmount() - 1); + player.getEquipment().setItemInMainHand(heldItem); + Sounds.broadcastSound(this.getSounds()[0], player.getEyeLocation()); + } + + @Override + public void onExplode(Entity explosive, Player shooter) { + + Collection<LivingEntity> eventVictims = MathUtil.getNearbyEntities(explosive, this.explosionSize, 1, this.explosionSize).collect(Collectors.toList()); + ExplosionDamageEntityEvent damageEntityEvent = new ExplosionDamageEntityEvent(shooter, explosive, eventVictims, this); + Bukkit.getServer().getPluginManager().callEvent(damageEntityEvent); + if (damageEntityEvent.isCancelled()) { + GTMGuns.getInstance().getWeaponManager().getEntityQueue().remove(explosive); + if (!(explosive instanceof Player)) explosive.remove(); + return; + } + + Collection<LivingEntity> victims = damageEntityEvent.getVictims(); + if (this.duration != 0) { + AreaEffectCloud areaEffectCloud = null; + if(this.isFlammable()) + areaEffectCloud = explosive.getWorld().spawn(explosive.getLocation().add(0, 0.5, 0), AreaEffectCloud.class); + + if(this.isTeargas()) + areaEffectCloud = explosive.getWorld().spawn(explosive.getLocation().add(0, 1.0, 0), AreaEffectCloud.class); + + if(areaEffectCloud == null) return; + + areaEffectCloud.setWaitTime(0); + areaEffectCloud.setDuration(this.duration); + areaEffectCloud.setParticle(Particle.valueOf(this.particles.name())); + areaEffectCloud.setRadius((float) this.explosionSize); + + new BukkitRunnable() { + private int count = 0; + @Override public void run() { + + // every tick, get nearby entities + victims.clear(); + victims.addAll(MathUtil.getNearbyEntities(explosive, explosionSize, 1, explosionSize).collect(Collectors.toList())); + + victims.forEach(e -> { + if(isTeargas()) { + PotionEffectType[] effectTypes = new PotionEffectType[] { + PotionEffectType.SLOW, + PotionEffectType.BLINDNESS, + PotionEffectType.WEAKNESS, + PotionEffectType.CONFUSION, + PotionEffectType.SLOW_DIGGING + }; + + for (PotionEffectType effectType : effectTypes) { + if (e.hasPotionEffect(effectType)) { + PotionEffect effect = e.getPotionEffect(effectType); + + // if no effect, add it, 1/4 of the duration + if (effect == null) { + e.addPotionEffect(new PotionEffect(effectType, duration / 4, 0, true, false)); + continue; + } + + // if less than 1/4 of the duration remains + if (effect.getDuration() < (duration / 4)){ + e.removePotionEffect(effectType); + e.addPotionEffect(new PotionEffect(effectType, duration / 4, 0, true, false)); + } + + continue; + } + + e.addPotionEffect(new PotionEffect(effectType, duration / 4, 0, true, false)); + } + } + + if(isFlammable()) + e.setFireTicks(duration); + }); + + if(this.count++ * 10 > duration) { + this.cancel(); + GTMGuns.getInstance().getWeaponManager().getEntityQueue().remove(explosive); + if (!(explosive instanceof Player)) explosive.remove(); + } + } + }.runTaskTimer(GTMGuns.getInstance(), 0, 10L); + } + + else { +// Vice + if (tntFuseDelay <= 1) { + TNTPrimed entity = (TNTPrimed) explosive.getWorld().spawnEntity(explosive.getLocation(), EntityType.PRIMED_TNT); + entity.setCustomName("EXPLOSIVE"); + entity.setCustomNameVisible(false); + entity.setFuseTicks(1); + // add metadata to see if this should do entity damage + entity.setMetadata("entity_damage", new FixedMetadataValue(GTMGuns.getInstance(), false)); + + } else { + ServerUtil.runTaskLater(() -> { + TNTPrimed entity = (TNTPrimed) explosive.getWorld().spawnEntity(explosive.getLocation(), EntityType.PRIMED_TNT); + entity.setCustomName("EXPLOSIVE"); + entity.setCustomNameVisible(false); + entity.setFuseTicks(1); + // add metadata to see if this should do entity damage + entity.setMetadata("entity_damage", new FixedMetadataValue(GTMGuns.getInstance(), false)); + + }, tntFuseDelay); + } +// explosive.getWorld().createExplosion(explosive.getLocation(), 1.8f); + +// GTM +// explosive.getWorld().spigot().playEffect(explosive.getLocation(), this.particles, 0, 0, 0, 0, 0, 0.01F, 1, 50); + if(!victims.isEmpty()) { + + for (LivingEntity e : victims) { + + if(e.getType() == EntityType.PLAYER) { + Player victim = (Player) e; + if (victim.getGameMode() != GameMode.ADVENTURE && victim.getGameMode() != GameMode.SURVIVAL) return; + } + + // send entities flying away from this explosion + if (!(e instanceof ArmorStand)) e.setVelocity(e.getLocation().getDirection().multiply(-this.explosionStrength)); + + // the initial damage modifier they should take + double scaledDamage = 1.0; + + if (isScaledDamage()){ + + // the distance sq from the origin + double distanceSq = explosive.getLocation().distanceSquared(e.getLocation()); + + // if there is an explosion size + if (getExplosionSize() > 0){ + + // ratio is (explosionSize squared - distanceSq) DIVIDED BY explosionSize squared + // look below for example calculations + // assume explosionSize for all is 10 + // if distanceSq = 4, 100 - 4 = 96/100 = 96% + // if distanceSq = 9, 100 - 9 = 91/100 = 91% + // if distanceSq = 81, 100 - 81 = 19/100 = 19% + double ratio = (Math.pow(explosionSize, 2) - distanceSq) / Math.pow(explosionSize, 2); + + // CLAMP percent of damage to always be at least 10% + if (ratio <= 0.10){ + ratio = 0.10; + } + // 90% accurate should do 100% damage + // b/c to the user it always does less than max damage + if (ratio >= 0.90){ + ratio = 1.0; + } + + scaledDamage = ratio; + } + } + + // absolute value this just in case + // 19% of getDamage would be the total damage + double totalDamage = Math.abs(scaledDamage * getDamage()); + + // create entity damage by entity event and add to data handler + EntityDamageByEntityEvent edbee = new EntityDamageByEntityEvent(shooter, e, DamageCause.DRAGON_BREATH, totalDamage); + DamageDataHandler.getInstance().addData(e.getUniqueId(), edbee); + + // damage the entity and set last damage cause + e.damage(totalDamage, shooter); + // reset damage ticks so they can take damage again + e.setNoDamageTicks(0); + e.setLastDamageCause(edbee); + } + } + GTMGuns.getInstance().getWeaponManager().getEntityQueue().remove(explosive); + if (!(explosive instanceof Player)) explosive.remove(); + } + Sounds.broadcastSound(this.getSounds()[3], explosive.getLocation()); + } + + public void launchProjectile(Player player) { + PlayerCache cache = GTMGuns.getInstance().getWeaponManager().getPlayerCache(player.getUniqueId()); + Entity projectile; + + if(this.sticky) { + projectile = player.launchProjectile(Arrow.class); + projectile.setVelocity(projectile.getVelocity().multiply(1.2).setY(player.getEyeHeight())); + ((Arrow) projectile).setBounce(false); + projectile.setMetadata("StickyExplosive", new FixedMetadataValue(GTMGuns.getInstance(), this)); + cache.stickyBombs.add(projectile); + } + else { + + // TODO add skin support here (if we change say grenade skins) + ItemStack stack = super.createItemStack(); + CustomItem ci = new CustomItem(stack); + ci.setAmount(1); + ci.setName(Random.getString(16, true, true)); + projectile = player.getWorld().dropItemNaturally(player.getEyeLocation(), ci); + if (!this.proximity) ((Item) projectile).setPickupDelay(Integer.MAX_VALUE); + projectile.setMetadata("Explosive", new FixedMetadataValue(GTMGuns.getInstance(), this)); + } + + projectile.setVelocity(player.getEyeLocation().getDirection().multiply(1.5f)); + projectile.setMetadata("Shooter", new FixedMetadataValue(GTMGuns.getInstance(), player)); + GTMGuns.getInstance().getWeaponManager().getEntityQueue().add(projectile); + + if(this.explosionDelay != 0) { + Bukkit.getScheduler().scheduleSyncDelayedTask(GTMGuns.getInstance(), () -> + this.onExplode(projectile, player), this.explosionDelay); + } + } + + @Override + public void onLand(Entity explosive) { + if(!isProximity()) return; + explosive.removeMetadata("Explosive", GTMGuns.getInstance()); + explosive.setMetadata("ProximityExplosive", new FixedMetadataValue(GTMGuns.getInstance(), this)); + } + + @Override + public ThrowableWeapon clone() { + ThrowableWeapon weapon = new ThrowableWeapon(getUniqueIdentifier(), getName(), getWeaponType(), getAmmoType(), getBaseItemStack().clone(), getSounds()); + weapon.oldItemStack = super.oldItemStack.clone(); + weapon.deathMessages = super.deathMessages; + weapon.walkSpeed = super.walkSpeed; + weapon.delay = super.delay; + + weapon.particles = this.particles; + weapon.sticky = this.sticky; + weapon.tntFuseDelay = this.tntFuseDelay; + weapon.proximity = this.proximity; + weapon.flammable = this.flammable; + weapon.teargas = this.teargas; + weapon.damage = this.damage; + weapon.meleeDamage = this.meleeDamage; + weapon.explosionSize = this.explosionSize; + weapon.explosionStrength = this.explosionStrength; + weapon.explosionDelay = this.explosionDelay; + weapon.duration = this.duration; + weapon.scaledDamage = this.scaledDamage; + return weapon; + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/Weapon.java b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/Weapon.java new file mode 100644 index 0000000..8fae3e2 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/Weapon.java @@ -0,0 +1,636 @@ +package net.grandtheftmc.guns.weapon; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import org.bukkit.ChatColor; +import org.bukkit.Sound; +import org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.servers.ServerType; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.guns.GTMGuns; +import net.grandtheftmc.guns.WeaponCooldown; +import net.grandtheftmc.guns.WeaponState; +import net.grandtheftmc.guns.weapon.ranged.RangedWeapon; +import net.minecraft.server.v1_12_R1.NBTTagCompound; +import net.minecraft.server.v1_12_R1.NBTTagInt; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public abstract class Weapon<T extends Weapon> { + + /** + * Extra colour codes to make it unique, extra c, d and l standing for + * custom damage lore + */ + public static final String CUSTOM_DAMAGE_LORE_PREFIX = "\247c\247d\247l\2477"; + + /** + * Damage prefix on the lore line. + */ + public static final String DAMAGE_PREFIX = "" + ChatColor.RESET + ChatColor.GRAY + "Stars: " + ChatColor.WHITE; + + private final short uniqueIdentifier; + private final short weaponIdentifier; + + private final String name; + private final WeaponType weaponType; + private final AmmoType ammoType; + private ItemStack itemStack; + protected ItemStack oldItemStack; + private final Sound[] sounds; + protected WeaponSkin[] weaponSkins; + protected Map<EntityDamageEvent.DamageCause, String> deathMessages; + private String[] description; + + protected double walkSpeed = 0.2; + /** The time, in ticks, that must wait before firing again. */ + protected int delay = 0; + + private WeaponCooldown weaponCooldown; + protected WeaponState weaponState = WeaponState.IDLE; + + /** + * Construct a new Weapon. + */ + public Weapon(short uniqueIdentifier, String name, WeaponType weaponType, AmmoType ammoType, ItemStack itemStack, Sound[] sounds) { + this.uniqueIdentifier = uniqueIdentifier; + this.weaponIdentifier = itemStack.getDurability(); + + this.name = name; + this.weaponType = weaponType; + this.ammoType = ammoType; + this.itemStack = itemStack; + this.sounds = sounds; + } + + @Override + public abstract T clone(); + + public void onRightClick(Player player) { + } + + public void onLeftClick(Player player) { + } + + public void onSneak(Player player, boolean sneaking) { + } + + public short getUniqueIdentifier() { + return this.uniqueIdentifier; + } + + public short getWeaponIdentifier() { + return this.weaponIdentifier; + } + + public String getName() { + return this.name; + } + + public String getCompactName() { + return this.name.replace(" ", ""); + } + + public WeaponType getWeaponType() { + return weaponType; + } + + public AmmoType getAmmoType() { + return this.ammoType; + } + + /** + * Get the base representation of this weapon, without any lore, values, or + * data. + * + * @return The basic itemstack representation for this weapon. + */ + public ItemStack getBaseItemStack() { + return this.itemStack; + } + + /** + * Get the weapon lore for this itemstack. + * <p> + * Note: ItemMeta is required because we're still building rules from + * getItemStack() above. + * </p> + * + * @param is - the current itemstack + * @param im - the current item meta for the itemstack + * + * @return The lore for the weapon. + */ + public List<String> getWeaponLore(ItemStack is, ItemMeta im) { + + // do not include weapon lore for vice + if (Core.getSettings().getType() == ServerType.VICE) + return Lists.newArrayList(); + + List<String> lore = Lists.newArrayList(); + + // if we have a star system + if (GTMGuns.STAR_SYSTEM) { + int rarity = getRarity(is); + + // add lore for the "star" system + if (rarity > 0) { + String builder = "" + ChatColor.GOLD; + + // add each "star" rarity + for (int i = 0; i < rarity; i++){ + builder += "✮"; + } + + builder += "" + ChatColor.DARK_GRAY; + + // for each star not on the item + for (int i = 0; i < (GTMGuns.MAX_STARS - rarity); i++){ + builder += "✩"; + } + + lore.add(builder); + lore.add(""); + } + } + + if (GTMGuns.KILL_COUNT_SYSTEM) { + lore.add(ChatColor.GRAY + "Kills: " + getKills(is)); + lore.add(""); + } + + if(this.description != null) { + for (String desc : this.description) + lore.add(Utils.f("&7&o" + desc)); + } + + lore.add(""); + lore.addAll(Arrays.asList(this.getStatsBar())); + + return lore; + } + + /** + * Create a new ItemStack for this weapon. + * <p> + * This will clone the ItemStack representation of this weapon, and add + * default star rating and default skins if applicable. + * </p> + * + * @return The newly created ItemStack that represents this weapon. + */ + public ItemStack createItemStack() { + + // clone the initial itemstack + ItemStack result = this.itemStack.clone(); + + // if item has no rarity + if (!hasRarity(result)) { + + // if we have a star system + if (GTMGuns.STAR_SYSTEM) { + // default is 1 rarity (1 star) + result = setRarity(result, 1); + } + } + + // If item has no kill counter + if(!hasKills(result)) { + if(GTMGuns.KILL_COUNT_SYSTEM) { + result = setKills(result, 0); + } + } + + // get the item meta + ItemMeta itemMeta = result.getItemMeta(); + + if (this instanceof RangedWeapon) + itemMeta.setDisplayName(Utils.f("&6" + getName() + " &8«&f" + ((RangedWeapon<?>) this).getMagazineSize() + "&8»")); + else + itemMeta.setDisplayName(Utils.f("&6" + getName())); + + // add the weapon lore + List<String> lore = getWeaponLore(result, itemMeta); + itemMeta.setLore(lore); + itemMeta.setUnbreakable(true); + itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES); + itemMeta.addItemFlags(ItemFlag.HIDE_UNBREAKABLE); + result.setItemMeta(itemMeta); + + return result; + } + + /** + * Create a new ItemStack for this weapon with a skin. + * <p> + * This will clone the ItemStack representation of this weapon, and add + * default star rating and default skins if applicable. + * </p> + * + * @param skin The skin + * @return The newly created ItemStack that represents this weapon. + */ + public ItemStack createItemStack(WeaponSkin skin) { + // clone the initial itemstack + ItemStack result = this.itemStack.clone(); + + // if item has no rarity + if (!hasRarity(result)) { + + // if we have a star system + if (GTMGuns.STAR_SYSTEM) { + // default is 1 rarity (1 star) + result = setRarity(result, 1); + } + } + + // If item has no kill counter + if(!hasKills(result)) { + if(GTMGuns.KILL_COUNT_SYSTEM) { + result = setKills(result, 0); + } + } + + // Set the skin + if(skin != null) { + result.setDurability(skin.getIdentifier()); + } + + // get the item meta + ItemMeta itemMeta = result.getItemMeta(); + + if (this instanceof RangedWeapon) + itemMeta.setDisplayName(Utils.f("&6" + getName() + " &8«&f" + ((RangedWeapon<?>) this).getMagazineSize() + "&8»")); + else + itemMeta.setDisplayName(Utils.f("&6" + getName())); + + // add the weapon lore + List<String> lore = getWeaponLore(result, itemMeta); + itemMeta.setLore(lore); + itemMeta.setUnbreakable(true); + itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES); + itemMeta.addItemFlags(ItemFlag.HIDE_UNBREAKABLE); + result.setItemMeta(itemMeta); + + return result; + } + + /** + * Create a new ItemStack for this weapon, based off the old ItemStack + * parameter. + * <p> + * This methods attempts to copy some meta values off the old ItemStack and + * create them on the new ItemStack. + * </p> + * + * @param old - the old itemstack that needs to be replaced + * + * @return The newly created ItemStack that represents this weapon. + */ + public ItemStack createItemStack(ItemStack old) { + + ItemStack result = getBaseItemStack().clone(); + + // if we have a star system + if (GTMGuns.STAR_SYSTEM) { + // get rarity of old "itemstack" + int prevStars = getRarity(old); + if (prevStars > 1) { + result = setRarity(result, prevStars); + } + else { + result = setRarity(result, 1); + } + } + + // If item has no kill counter + if(GTMGuns.KILL_COUNT_SYSTEM) { + result = setKills(result, getKills(old)); + } + + // get the base item meta + ItemMeta itemMeta = result.getItemMeta(); + + // set weapon skin here based off old + result.setDurability(old.getDurability()); + + if (this instanceof RangedWeapon) + itemMeta.setDisplayName(Utils.f("&6" + getName() + " &8«&f" + ((RangedWeapon<?>) this).getMagazineSize() + "&8»")); + else + itemMeta.setDisplayName(Utils.f("&6" + getName())); + + // add the weapon lore + List<String> lore = getWeaponLore(result, itemMeta); + itemMeta.setLore(lore); + itemMeta.setUnbreakable(true); + itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES); + itemMeta.addItemFlags(ItemFlag.HIDE_UNBREAKABLE); + result.setItemMeta(itemMeta); + + return result; + } + + /** + * Create a new ItemStack for this weapon. + * <p> + * This methods creates a baseline representation for an item with the + * specified star value and skin. + * </p> + * + * @param stars - the number of stars associated with this weapon + * @param skin - the skin for the weapon + * + * @return The newly created ItemStack that represents this weapon. + */ + public ItemStack createItemStack(int stars, WeaponSkin skin) { + + // get the base itemstack representation for this weapon + ItemStack representation = getBaseItemStack().clone(); + + // if we have a star system + if (GTMGuns.STAR_SYSTEM) { + representation = setRarity(representation, stars); + } + + // If item has no kill counter + if(!hasKills(representation)) { + if(GTMGuns.KILL_COUNT_SYSTEM) { + representation = setKills(representation, 0); + } + } + + // get the base item meta + ItemMeta itemMeta = representation.getItemMeta(); + + // Set weapon skin + if(skin != null) { + representation.setDurability(skin.getIdentifier()); + } + + if (this instanceof RangedWeapon) + itemMeta.setDisplayName(Utils.f("&6" + getName() + " &8«&f" + ((RangedWeapon<?>) this).getMagazineSize() + "&8»")); + else + itemMeta.setDisplayName(Utils.f("&6" + getName())); + + // add the weapon lore + List<String> lore = getWeaponLore(representation, itemMeta); + itemMeta.setLore(lore); + itemMeta.setUnbreakable(true); + itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES); + itemMeta.addItemFlags(ItemFlag.HIDE_UNBREAKABLE); + representation.setItemMeta(itemMeta); + + return representation; + } + + public abstract String[] getStatsBar(); + + public void setItemStack(ItemStack itemStack) { + this.itemStack = itemStack; + } + + public ItemStack getOldItemStack() { + return oldItemStack; + } + + public void setOldItemStack(ItemStack oldItemStack) { + this.oldItemStack = oldItemStack; + } + + public Sound[] getSounds() { + return this.sounds; + } + + public Map<EntityDamageEvent.DamageCause, String> getDeathMessages() { + return this.deathMessages; + } + + public Weapon addDeathMessage(EntityDamageEvent.DamageCause damageCause, String message) { + if (this.deathMessages == null) + this.deathMessages = Maps.newHashMap(); + this.deathMessages.put(damageCause, message); + return this; + } + + /** + * Get the walk speed attribute of the Weapon + * + * @return walk speed value + */ + public double getWalkSpeed() { + return this.walkSpeed; + } + + public WeaponSkin[] getWeaponSkins() { + return this.weaponSkins; + } + + /** + * Get the delay that is required to be met before the weapon can be used again. + * <p> + * This is in ticks, as the value ends up getting multiplied by 50, + * representing a "Minecraft tick" in milliseconds. + * + * Therefore, if this value is 5, that means 250 milliseconds must elapse before firing again. + * </p> + * + * @return The time, in ticks, required for this weapon to be fired again. + */ + public int getDelay() { + return this.delay; + } + + public WeaponCooldown getWeaponCooldown() { + return weaponCooldown; + } + + public void setWeaponCooldown(WeaponCooldown weaponCooldown) { + this.weaponCooldown = weaponCooldown; + } + + public WeaponState getWeaponState() { + return weaponState; + } + + public void setWeaponState(WeaponState weaponState) { + this.weaponState = weaponState; + } + + public String[] getDescription() { + return description; + } + + public void setDescription(String... description) { + this.description = description; + } + + /** + * Get whether or not this weapon has a rarity associated with it. + * + * @param is - the itemstack representation of the weapon + * + * @return {@code true} if the item has a rarity associated with it, + * {@code false} otherwise. + */ + public static boolean hasRarity(ItemStack is) { + + // convert to NMS itemstack + net.minecraft.server.v1_12_R1.ItemStack nmsStack = CraftItemStack.asNMSCopy(is); + + // if tag system exists + if (nmsStack.getTag() != null) { + NBTTagCompound tag = nmsStack.getTag(); + + // if key exists, this has a rarity + if (tag.hasKey("rarity")) { + return true; + } + } + + return false; + } + + /** + * Get the rarity of the specified weapon, given the itemstack + * representation. + * + * @param is - the itemstack representation of the weapon + * + * @return The rarity, in a rating system, where the lower the number the + * lower the rarity. -1 if there is no rarity. + */ + public static int getRarity(ItemStack is) { + + // can get rarity if it exists + if (hasRarity(is)) { + + // convert to NMS itemstack + net.minecraft.server.v1_12_R1.ItemStack nmsStack = CraftItemStack.asNMSCopy(is); + + // if tag system exists + if (nmsStack.getTag() != null) { + NBTTagCompound tag = nmsStack.getTag(); + + try { + return Integer.parseInt(tag.get("rarity").toString()); + } + catch (Exception e) { + e.printStackTrace(); + } + } + } + + return -1; + } + + /** + * Set the rarity of the specified weapon. + * + * @param is - the itemstack representation of the weapon + * @param value - the higher the value, the more rare it is + * + * @return The ItemStack that was newly created and copied. + */ + public static ItemStack setRarity(ItemStack is, int value) { + + // convert to NMS itemstack + net.minecraft.server.v1_12_R1.ItemStack nmsStack = CraftItemStack.asNMSCopy(is); + NBTTagCompound compound = (nmsStack.hasTag()) ? nmsStack.getTag() : new NBTTagCompound(); + compound.set("rarity", new NBTTagInt(value)); + + nmsStack.setTag(compound); + return CraftItemStack.asBukkitCopy(nmsStack); + } + + /** + * Get whether or not this weapon has kills associated with it. + * + * @param is - the itemstack representation of the weapon + * + * @return {@code true} if the item has kills associated with it, + * {@code false} otherwise. + */ + public static boolean hasKills(ItemStack is) { + net.minecraft.server.v1_12_R1.ItemStack nmsStack = CraftItemStack.asNMSCopy(is); + + if (nmsStack.getTag() != null) { + NBTTagCompound tag = nmsStack.getTag(); + + if (tag.hasKey("weapon_kills")) { + return true; + } + } + + return false; + } + + /** + * Set the kills of the specified weapon. + * + * @param is - the itemstack representation of the weapon + * @param value - the amount of kills + * + * @return The ItemStack that was newly created and copied. + */ + public static ItemStack setKills(ItemStack is, int value) { + net.minecraft.server.v1_12_R1.ItemStack nmsStack = CraftItemStack.asNMSCopy(is); + NBTTagCompound compound = (nmsStack.hasTag()) ? nmsStack.getTag() : new NBTTagCompound(); + compound.set("weapon_kills", new NBTTagInt(value)); + nmsStack.setTag(compound); + + return CraftItemStack.asBukkitCopy(nmsStack); + } + + /** + * Get the kills of the specified weapon, given the itemstack + * representation. + * + * @param is - the itemstack representation of the weapon + * + * @return The amount of kills + */ + public static int getKills(ItemStack is) { + if (hasKills(is)) { + net.minecraft.server.v1_12_R1.ItemStack nmsStack = CraftItemStack.asNMSCopy(is); + + if (nmsStack.getTag() != null) { + NBTTagCompound tag = nmsStack.getTag(); + + try { + return Integer.parseInt(tag.get("weapon_kills").toString()); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + return 0; + } + + /** + * Updates the lore of the specified weapon. + * + * @param is - the itemstack representation of the weapon + */ + public static void updateLore(ItemStack is) { + Weapon<?> weapon = GTMGuns.getInstance().getWeaponManager().getWeaponByItem(is); + + ItemMeta meta = is.getItemMeta(); + meta.setLore(weapon.getWeaponLore(is, meta)); + + is.setItemMeta(meta); + } +} \ No newline at end of file diff --git a/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/WeaponSkin.java b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/WeaponSkin.java new file mode 100644 index 0000000..e67e161 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/WeaponSkin.java @@ -0,0 +1,36 @@ +package net.grandtheftmc.guns.weapon; + +import net.grandtheftmc.core.util.Similarity; + +/** + * Created by Luke Bingham on 21/07/2017. + */ +public class WeaponSkin implements Similarity<WeaponSkin> { + + private final WeaponType weaponType; + private final short identifier; + private final String displayName; + + public WeaponSkin(WeaponType weaponType, short identifier, String displayName) { + this.weaponType = weaponType; + this.identifier = identifier; + this.displayName = displayName; + } + + public final WeaponType getWeaponType() { + return weaponType; + } + + public final short getIdentifier() { + return identifier; + } + + public final String getDisplayName() { + return displayName; + } + + @Override + public boolean isSimilar(WeaponSkin weaponSkin) { + return this.weaponType == weaponSkin.weaponType && this.identifier == weaponSkin.identifier; + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/WeaponType.java b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/WeaponType.java new file mode 100644 index 0000000..745d818 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/WeaponType.java @@ -0,0 +1,156 @@ +package net.grandtheftmc.guns.weapon; + +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public enum WeaponType { + + /* Ranged Weapons */ + PISTOL, SMG, SHOTGUN, ASSAULT, LMG, SNIPER, + + /* Unkown / Special */ + SPECIAL, MINIGUN, NETGUN, FLAMETHROWER, CLAUSINATOR, + + /* Rocket Launcher */ + LAUNCHER, + + /* Hand held Melee Weapons */ + MELEE, + + /* Throwable Weapons (Grenade) */ + THROWABLE, + + /* Droppable 'Weapons' (Airstrike, Nuke) */ + DROPPABLE + ; + +// /* PISTOLS */ +// PISTOL("Pistol", new Pistol(), Type.RANGED, AmmoType.PISTOL), +// STUN_GUN("Stun Gun", new StunGun(), Type.RANGED, AmmoType.PISTOL), +// COMBAT_PISTOL("Combat Pistol", new CombatPistol(), Type.RANGED, AmmoType.PISTOL), +// HEAVY_PISTOL("Heavy Pistol", new HeavyPistol(), Type.RANGED, AmmoType.PISTOL), +// MARKSMAN_PISTOL("Marksman Pistol", new MarksmanPistol(), Type.RANGED, AmmoType.PISTOL), +// +// /* SUB MACHINE GUNS */ +// MICRO_SMG("Micro SMG", new MicroSMG(), Type.RANGED, AmmoType.SMG), +// SMG("SMG", new SMG(), Type.RANGED, AmmoType.SMG), +// ASSAULT_SMG("Assault SMG", new AssaultSMG(), Type.RANGED, AmmoType.SMG), +// COMBAT_PDW("Combat PDW", new CombatPDW(), Type.RANGED, AmmoType.SMG), +// GUSENBERG_SWEEPER("Gusenberg Sweeper", new GusenbergSweeper(), Type.RANGED, AmmoType.SMG), +// +// /* SHOTGUNS */ +// SAWEDOFF_SHOTGUN("Sawdoff Shotgun", new SawedoffShotgun(), Type.RANGED, AmmoType.SHOTGUN), +// PUMP_SHOTGUN("Pump Shotgun", new PumpShotgun(), Type.RANGED, AmmoType.SHOTGUN), +// MUSKET("Musket", new Musket(), Type.RANGED, AmmoType.SHOTGUN), +// ASSAULT_SHOTGUN("Assault Shotgun", new AssaultShotgun(), Type.RANGED, AmmoType.SHOTGUN), +// HEAVY_SHOTGUN("Heavy Shotgun", new HeavyShotgun(), Type.RANGED, AmmoType.SHOTGUN), +// +// /* ASSULT RIFLES */ +// ASSAULT_RIFLE("Assault Rifle", new AssaultRifle(), Type.RANGED, AmmoType.ASSAULT_RIFLE), +// CARBINE_RIFLE("Carbine Rifle", new CarbineRifle(), Type.RANGED, AmmoType.ASSAULT_RIFLE), +// BULLPUP_RIFLE("Bullpup Rifle", new BullpupRifle(), Type.RANGED, AmmoType.ASSAULT_RIFLE), +// ADVANCED_RIFLE("Advanced Rifle", new AdvancedRifle(), Type.RANGED, AmmoType.ASSAULT_RIFLE), +// SPECIAL_CARBINE("Special Carbine", new SpecialCarbine(), Type.RANGED, AmmoType.ASSAULT_RIFLE), +// +// /* MG */ +// MG("MG", new MG(), Type.RANGED, AmmoType.LMG), +// COMBAT_MG("Combat MG", new CombatMG(), Type.RANGED, AmmoType.LMG), +// +// /* SNIPER RIFLES */ +// SNIPER_RIFLE("Sniper Rifle", new SniperRifle(), Type.RANGED, AmmoType.SNIPER), +// HEAVY_SNIPER("Heavy Sniper", new HeavySniper(), Type.RANGED, AmmoType.SNIPER), +// +// /* SPECIAL */ +// MINIGUN("Minigun", new Minigun(), Type.RANGED, AmmoType.MINIGUN), +// +// /* LAUNCHERS */ +// RPG("RPG", new RPG(), Type.RANGED, AmmoType.LAUNCHER), +// HOMING_LAUNCHER("Homing Launcher", new HomingLauncher(), Type.RANGED, AmmoType.LAUNCHER), +// GRENADE_LAUNCHER("Grenade Launcher", new GrenadeLauncher(), Type.RANGED, AmmoType.EXPLOSIVE), +// +// /* MELEE */ +// RAKE("Rake", new Rake(), Type.MELEE, AmmoType.MELEE), +// NIGHT_STICK("Night Stick", new NightStick(), Type.MELEE, AmmoType.MELEE), +// BASEBALL_BAT("Baseball Bat", new BaseballBat(), Type.MELEE, AmmoType.MELEE), +// KNIFE("Knife", new Knife(), Type.MELEE, AmmoType.MELEE), +// CHAINSAW("Chainsaw", new Chainsaw(), Type.MELEE, AmmoType.ENERGY), +// +// /* EXPLOSIVES */ +// GRENADE("Grenade", new Grenade(), Type.THROWABLE, AmmoType.EXPLOSIVE), +// TEAR_GAS("Tear Gas", new TearGas(), Type.THROWABLE, AmmoType.EXPLOSIVE), +// MOLOTOV_COCKTAIL("Molotov Cocktail", new MolotovCocktail(), Type.THROWABLE, AmmoType.EXPLOSIVE), +// STICKY_BOMB("Sticky Bomb", new StickyBomb(), Type.THROWABLE, AmmoType.EXPLOSIVE), +// PROXIMITY_MINE("Proximity Mine", new ProximityMine(), Type.THROWABLE, AmmoType.EXPLOSIVE), +// +// /* DROPPABLE */ +// AIRSTRIKE("Airstrike", new Airstrike(), Type.DROPPABLE), +// NUKE("Nuke", new Nuke(), Type.DROPPABLE), +// ; +// +// private static final HashSet<Weapon> ALL_WEAPONS = Sets.newHashSet(); +// private static final HashMap<Type, HashSet<Weapon>> TYPE_WEAPONS = Maps.newHashMap(); +// +// private final String name; +// private final Weapon weapon; +// private final Type type; +// private AmmoType ammoType; +// +// WeaponType(String name, Weapon weapon, Type type) { +// this.name = name; +// this.weapon = weapon; +// this.type = type; +// } +// +// WeaponType(String name, Weapon weapon, Type type, AmmoType ammoType) { +// this.name = name; +// this.weapon = weapon; +// this.type = type; +// this.ammoType = ammoType; +// } +// +// public String getName() { +// return name; +// } +// +// public Weapon getWeapon() { +// return weapon; +// } +// +// public Type getType() { +// return type; +// } +// +// public AmmoType getAmmoType() { +// return ammoType; +// } +// +// public static HashSet<Weapon> getWeaponsFromType(Type type) { +// if(!TYPE_WEAPONS.containsKey(type)) { +// HashSet<Weapon> temp = Sets.newHashSet(); +// for (WeaponType weaponType : values()) { +// if (weaponType.type != type) continue; +// temp.add(weaponType.getWeapon()); +// } +// TYPE_WEAPONS.put(type, temp); +// } +// +// return TYPE_WEAPONS.get(type); +// } +// +// public static HashSet<Weapon> getWeapons() { +// if (ALL_WEAPONS.isEmpty()) +// for (WeaponType weaponType : values()) ALL_WEAPONS.add(weaponType.getWeapon()); +// +// return ALL_WEAPONS; +// } +// +// public enum Type { +// RANGED, THROWABLE, MELEE, DROPPABLE; +// } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/attribute/RankedWeapon.java b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/attribute/RankedWeapon.java new file mode 100644 index 0000000..90e3770 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/attribute/RankedWeapon.java @@ -0,0 +1,10 @@ +package net.grandtheftmc.guns.weapon.attribute; + +import net.grandtheftmc.core.users.UserRank; + +/** + * Created by Luke Bingham on 15/08/2017. + */ +public interface RankedWeapon { + UserRank requiredRank(); +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/attribute/StarAttribute.java b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/attribute/StarAttribute.java new file mode 100644 index 0000000..0116201 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/attribute/StarAttribute.java @@ -0,0 +1,32 @@ +package net.grandtheftmc.guns.weapon.attribute; + +import org.bukkit.inventory.ItemStack; + +/** + * @deprecated - Unused as these methods were turned to static in Weapon. + */ +@Deprecated +public interface StarAttribute { + + /** + * Get the amount of stars assigned to this attribute. + * <p> + * Generally, stars are indicative of the power for this attribute. + * </p> + * @param is - the itemstack representation + * + * @return The number of stars for this attribute, -1 if not found. + */ + int getStars(ItemStack is); + + /** + * Set the number of stars assigned to this attribute. + * + * @param is - the itemstack representation + * @param stars - the new star amount + * + * @return {@code true} if the stars was set for this item, {@code false} otherwise. + */ + boolean setStars(ItemStack is, int stars); + +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/attribute/WeaponAttribute.java b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/attribute/WeaponAttribute.java new file mode 100644 index 0000000..251fe6b --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/attribute/WeaponAttribute.java @@ -0,0 +1,7 @@ +package net.grandtheftmc.guns.weapon.attribute; + +/** + * Created by Luke Bingham on 24/07/2017. + */ +public abstract interface WeaponAttribute { +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/attribute/WeaponExplosive.java b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/attribute/WeaponExplosive.java new file mode 100644 index 0000000..631d680 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/attribute/WeaponExplosive.java @@ -0,0 +1,14 @@ +package net.grandtheftmc.guns.weapon.attribute; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +/** + * Created by Luke Bingham on 07/08/2017. + */ +public interface WeaponExplosive extends WeaponAttribute { + + void onExplode(Entity explosive, Player shooter); + + default void onLand(Entity explosive) {} +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/attribute/WeaponRPM.java b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/attribute/WeaponRPM.java new file mode 100644 index 0000000..ebc29ad --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/attribute/WeaponRPM.java @@ -0,0 +1,47 @@ +package net.grandtheftmc.guns.weapon.attribute; + +/** + * Created by Luke Bingham on 24/07/2017. + */ +public interface WeaponRPM extends WeaponAttribute { + + /** + * Get the amount of revolutions this weapon uses per second. + * <p> + * Note: Minecraft runs 20 ticks per second, so if this value is 10, that + * means 10 bullets are fired per second. + * </p> + * + * @return The number of revolutions this weapon uses per second. + */ + int getRPS(); + + /** + * Get the amount of revolutions this weapon uses per minute. + * <p> + * Note: Only increments of 60 effect this value. + * </p> + * + * @return The number of revolutions this weapon uses per minute. + * + * @deprecated - Please use {@link #getRPS()} instead as it's hard to + * calculate the rpm of a gun and assume it's true RPM value. + */ + @Deprecated + int getRpm(); + + /** + * Get the burst rate of the weapon. + * <p> + * Note: If the burst rate of the weapon is say 5, then that means it will + * attempt to fire it's clip through 5 ticks before stopping. + * + * If the burst rate is 20, then that means it will attempt to fire through all 20 ticks before stopping. + * </p> + * + * @return The burst rate of the weapon, in ticks, before this weapon stops trying to fire. + */ + default int getBurstRate(){ + return 5; + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ranged/RangedWeapon.java b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ranged/RangedWeapon.java new file mode 100644 index 0000000..30fd40b --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ranged/RangedWeapon.java @@ -0,0 +1,1097 @@ +package net.grandtheftmc.guns.weapon.ranged; + +import java.util.HashMap; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.BlockPosition; +import com.google.common.collect.Maps; +import com.j0ach1mmall3.jlib.methods.Random; +import com.j0ach1mmall3.jlib.methods.Sounds; +import com.j0ach1mmall3.wastedguns.MathUtil; +import com.j0ach1mmall3.wastedguns.api.events.WeaponDamageEvent; +import com.j0ach1mmall3.wastedguns.api.events.ranged.AmmoUpdateEvent; +import com.j0ach1mmall3.wastedguns.api.events.ranged.RangedWeaponReloadEvent; +import com.j0ach1mmall3.wastedguns.api.events.ranged.RangedWeaponShootEvent; +import com.j0ach1mmall3.wastedvehicles.Main; + +import de.slikey.effectlib.effect.ExplodeEffect; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.users.Pref; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.C; +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.guns.DamageDataHandler; +import net.grandtheftmc.guns.GTMGuns; +import net.grandtheftmc.guns.WeaponState; +import net.grandtheftmc.guns.cache.PlayerCache; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.Weapon; +import net.grandtheftmc.guns.weapon.WeaponSkin; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.attribute.WeaponRPM; +import net.grandtheftmc.guns.weapon.ranged.attachment.Attachment; +import net.grandtheftmc.guns.weapon.ranged.guns.PistolWeapon; +import net.grandtheftmc.guns.weapon.ranged.guns.ShotgunWeapon; +import net.grandtheftmc.guns.weapon.ranged.guns.SpecialWeapon; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.TextComponent; + +/** + * Created by Luke Bingham on 17/07/2017. + */ +public abstract class RangedWeapon<T extends Weapon> extends Weapon<T> { + + protected HashMap<Attachment, Object> attachments; + protected Attachment[] supportedAttachments = null; + protected Effect effect; + + protected double damage = 0d, meleeDamage = 0d, accuracy = 0d, recoil = 0; + protected int magSize = 1, reloadTime = 40, range = 20, penetration = 1, zoom = 0; + protected boolean reloadShoot = false; + /** + * Can this weapon fire multiple times even if it's not done firing the first round. + * Typically burst weapons will burst over a task, and still allow to fire. + */ + protected boolean multiShoot = false; + + /** + * Construct a new Weapon. + */ + public RangedWeapon(short uniqueIdentifier, String name, WeaponType weaponType, AmmoType ammoType, ItemStack itemStack, Sound[] sounds, Effect effect) { + super(uniqueIdentifier, name, weaponType, ammoType, itemStack, sounds); + this.attachments = Maps.newHashMap(); + this.effect = effect; + + this.weaponSkins = new WeaponSkin[] { + new WeaponSkin(weaponType, itemStack.getDurability(), "&e&lDefault") + }; + } + + public Effect getEffect() { + return this.effect; + } + + public Object getAttachment(Attachment attachment) { + return this.attachments.getOrDefault(attachment, null); + } + + public boolean hasAttachment(Attachment attachment) { + return this.attachments.containsKey(attachment); + } + + public void addAttachment(Attachment attachment) { + if(this.supportedAttachments == null) return; + + boolean supported = false; + for(Attachment a : this.supportedAttachments) { + if (a != attachment) continue; + supported = true; + break; + } + + if(!supported) return; + Object obj = null; + switch (attachment) {//TODO + case SUPPRESSOR: + obj = 0; + break; + case GRIP: obj = 0; break; + case EXTENDED_MAGS: obj = 0; break; + case SCOPE: obj = 0; break; + } + + this.attachments.put(attachment, obj); + } + + public Attachment[] getSupportedAttachments() { + return supportedAttachments; + } + + public void setSupportedAttachments(Attachment... supportedAttachments) { + this.supportedAttachments = supportedAttachments; + } + + @Override + public WeaponSkin[] getWeaponSkins() { + return weaponSkins; + } + + protected void setWeaponSkins(WeaponSkin... skins) { + WeaponSkin defaultSkin = this.weaponSkins[0]; + this.weaponSkins = new WeaponSkin[skins.length + 1]; + for(int i = 0; i < skins.length; i++) + this.weaponSkins[i + 1] = skins[i]; + this.weaponSkins[0] = defaultSkin; + } + + @Override + public String[] getStatsBar() { + String[] output = new String[4]; + String symbol = ":", + done = ChatColor.GREEN.toString() + ChatColor.BOLD, + empty = ChatColor.DARK_GRAY.toString() + ChatColor.BOLD; + int bars = 10; + double best = 0; + double result; + int stat; + for(int i = 0; i < 4; i++) { + switch (i) { + case 0: + output[i] = ""; + best = 30.0; + result = net.grandtheftmc.core.util.MathUtil.getPercentBetweenValues(best, (this instanceof ShotgunWeapon ? this.damage * ((ShotgunWeapon) this).getShellSize() : this.damage)); + stat = (int) Math.floor(result) / 10; + for(int x = 0; x < bars; x++) { + output[i] += (x <= stat ? done : empty) + symbol; + } + output[i] += C.GRAY + " Damage"; + break; + + case 1: + output[i] = ""; + best = this instanceof WeaponRPM ? (500.0 - 300) / 60 + 1 : 2; + if(this instanceof ShotgunWeapon) { + result = net.grandtheftmc.core.util.MathUtil.getPercentBetweenValuesReverse(best, this.delay); + } else if(this instanceof WeaponRPM) { + result = net.grandtheftmc.core.util.MathUtil.getPercentBetweenValues(best, ((WeaponRPM) this).getRpm()); + } else { + result = net.grandtheftmc.core.util.MathUtil.getPercentBetweenValuesReverse(best, this.delay); + } + stat = (int) Math.floor(result) / 10; + for(int x = 0; x < bars; x++) { + output[i] += (x <= stat ? done : empty) + symbol; + } + output[i] += C.GRAY + " Fire Rate"; + break; + + case 2: + output[i] = ""; + best = 0.008; + result = net.grandtheftmc.core.util.MathUtil.getPercentBetweenValuesReverse(best, this.accuracy); + stat = (int) Math.floor(result) / 10; + for(int x = 0; x < bars; x++) { + output[i] += (x <= stat ? done : empty) + symbol; + } + output[i] += C.GRAY + " Accuracy"; + break; + + case 3: + output[i] = ""; + best = 80.0; + result = net.grandtheftmc.core.util.MathUtil.getPercentBetweenValues(best, this.range); + stat = (int) Math.floor(result) / 10; + for(int x = 0; x < bars; x++) { + output[i] += (x <= stat ? done : empty) + symbol; + } + output[i] += C.GRAY + " Range"; + break; + } + } + + return output; + } + + /** + * Get the generic damage of the Weapon. + * + * @return damage value + */ + public double getDamage() { + return this.damage; + } + + /** + * Get the Melee damage of the Weapon. + * + * @return damage value + */ + public double getMeleeDamage() { + return this.meleeDamage; + } + + /** + * Get the Accuracy of the Weapon. + * + * @return Accuracy value + */ + public double getAccuracy() { + return this.accuracy; + } + + /** + * Get the Magazine size of the Weapon. + * + * @return Magazine size + */ + public int getMagazineSize() { + return this.magSize + (int) this.attachments.getOrDefault(Attachment.EXTENDED_MAGS, 0); + } + + /** + * Get the reload time for the Weapon. + * + * @return Reload time in ticks + */ + public int getReloadTime() { + return this.reloadTime; + } + + /** + * Check if reloading while shooting is allowed. + * + * @return reload state + */ + public boolean isAllowingReloadShooting() { + return this.reloadShoot; + } + + /** + * Get the fire range of the Weapon. + * + * @return fire range (Measured in Blocks) + */ + public int getRange() { + return this.range; + } + + /** + * Get the amount of entities to pierce from a single Bullet. + * + * @return Penetration value + */ + public int getPenetration() { + return this.penetration; + } + + /** + * Get the Zoom identifier for the Weapon. + * + * @return Zoom value + */ + public int getZoomValue() { + return this.zoom; + } + + /** + * Get the Recoil of the Weapon. + * + * @return Recoil value + */ + public double getRecoil() { + return this.recoil; + } + + public abstract boolean isAutomatic(); + + private boolean minigun() { + if(!(this instanceof SpecialWeapon)) return false; + return ((SpecialWeapon) this).isMinigun(); + } + + @Override + public void onSneak(Player player, boolean sneaking) { + if(sneaking && this.weaponState != WeaponState.RELOADING) { + player.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, Integer.MAX_VALUE, this.zoom - 1, true, false)); + return; + } + + player.removePotionEffect(PotionEffectType.SLOW); + } + + @Override + public void onRightClick(Player player) { + onWeaponShoot(player, true, GTMGuns.getInstance().getWeaponManager().getPlayerCache(player.getUniqueId())); + } + + @Override + public void onLeftClick(Player player) { + int ammo = this.getAmmo(player.getInventory().getItemInMainHand()); + if(ammo >= magSize) return; + reload(player, GTMGuns.getInstance().getWeaponManager().getPlayerCache(player.getUniqueId())); + } + + public void onWeaponShoot(Player player, boolean subtractammo, PlayerCache playerCache) { + + // how many revolutions per second should this be + // convert to ticks, so 1 = 1 per 20 ticks + int rps = this instanceof WeaponRPM ? ((WeaponRPM) this).getRPS() : 0; + + // TODO remove for compatibility purposes + // if not defined + if (rps == 0){ + rps = this instanceof WeaponRPM ? ((WeaponRPM) this).getRpm() : 0; + } + + // TODO debug remove + // Core.log("[RangedWeapon][DEBUG] onWeaponShoot for " + player.getName() + ", weapon=" + this.getName() + ", rps=" + rps + ", automatic=" + this.isAutomatic() + ", delay=" + this.delay + ", multiShoot=" + this.multiShoot); + + if(player == null) return; + if(playerCache == null) return; + + // if the weapon is reloading do not call + if(this.weaponState == WeaponState.RELOADING) return; + + // if weapon cannot multi shoot, check state and cancel + if (!multiShoot){ + if(this.weaponState == WeaponState.BURSTING || weaponState == WeaponState.SHOOTING){ + return; + } + } + + RangedWeaponShootEvent rangedWeaponShootEvent = new RangedWeaponShootEvent(player, this); + Bukkit.getPluginManager().callEvent(rangedWeaponShootEvent); + if(rangedWeaponShootEvent.isCancelled()) return; + +// AmmoUpdateEvent ammoUpdateEvent = new AmmoUpdateEvent(player); +// Bukkit.getPluginManager().callEvent(ammoUpdateEvent); +// int totalAmmo = ammoUpdateEvent.getAmmo().getOrDefault(getAmmoType().getType(), 0); + + weaponState = WeaponState.SHOOTING; + + if(this.isAutomatic()) { + playerCache.shooting = true; + playerCache.burst = 1; + + new BukkitRunnable() { + @Override public void run() { + + // TODO debug remove + // Core.log("[RangedWeapon][DEBUG] weaponState on tick= " + weaponState); + + if(RangedWeapon.this.weaponState == WeaponState.RELOADING) { + this.cancel(); + playerCache.burst = 1; + playerCache.shooting = false; + return; + } + + if (RangedWeapon.this instanceof WeaponRPM){ + + // get the max burst tick possible + int maxBurst = ((WeaponRPM) RangedWeapon.this).getBurstRate(); + + // clamp to valid values + if (maxBurst <= 0){ + maxBurst = 0; + } + if (maxBurst >= 20){ + maxBurst = 20; + } + + if (playerCache.burst >= maxBurst){ + + // TODO debug remove + // Core.log("[RangedWeapon][DEBUG] playerCache.burst=" + playerCache.burst + " is >= " + maxBurst); + this.cancel(); + playerCache.burst = 1; + playerCache.shooting = false; + weaponState = WeaponState.IDLE; + return; + } + } + + playerCache.burst += 1; + + if(isAutomatic()) { + weaponState = WeaponState.BURSTING; + + int tick = playerCache.tick; + playerCache.tick = (tick >= 20) ? 1 : (tick + 1); + if (!RangedWeapon.this.isValid(playerCache.tick)){ + // TODO debug remove + // Core.log("[RangedWeapon][DEBUG] Ranged weapon is not valid, playerCache.tick=" + playerCache.tick); + + return; + } + } + + Location origin = player.getEyeLocation(); + Vector direction = origin.getDirection(); + + RangedWeapon.this.shoot(player, origin, direction, playerCache, true); + } + }.runTaskTimer(GTMGuns.getInstance(), 1, 1); + return; + } + + Location origin = player.getEyeLocation(); + Vector direction = origin.getDirection(); + + this.shoot(player, origin, direction, playerCache, false); + + if (this.recoil != 0 && !player.isSneaking()) + player.setVelocity(player.getVelocity().add(direction.setY(0).multiply(-this.recoil))); + } + + public void onWeaponVehicleShoot(Player player, boolean subtractammo, PlayerCache playerCache) { + + // TODO debug remove + // Core.log("[RangedWeapon][DEBUG] onWeaponVehicleShoot for " + player.getName()); + + if(player == null) return; + if(playerCache == null) return; + + // if the weapon is reloading do not call + if(this.weaponState == WeaponState.RELOADING) return; + + // if weapon cannot multi shoot, check state and cancel + if (!multiShoot){ + if(this.weaponState == WeaponState.BURSTING || weaponState == WeaponState.SHOOTING){ + return; + } + } + + RangedWeaponShootEvent rangedWeaponShootEvent = new RangedWeaponShootEvent(player, this); + Bukkit.getPluginManager().callEvent(rangedWeaponShootEvent); + if(rangedWeaponShootEvent.isCancelled()) return; + +// AmmoUpdateEvent ammoUpdateEvent = new AmmoUpdateEvent(player); +// Bukkit.getPluginManager().callEvent(ammoUpdateEvent); +// int totalAmmo = ammoUpdateEvent.getAmmo().getOrDefault(getAmmoType().getType(), 0); + + weaponState = WeaponState.SHOOTING; + + if(this.isAutomatic()) { + playerCache.shooting = true; + playerCache.burst = 1; + + new BukkitRunnable() { + @Override public void run() { + if(RangedWeapon.this.weaponState == WeaponState.RELOADING) { + this.cancel(); + playerCache.burst = 1; + playerCache.shooting = false; + return; + } + + if (RangedWeapon.this instanceof WeaponRPM){ + + // get the max burst tick possible + int maxBurst = ((WeaponRPM) RangedWeapon.this).getBurstRate(); + + // clamp to valid values + if (maxBurst <= 0){ + maxBurst = 0; + } + if (maxBurst >= 20){ + maxBurst = 20; + } + + if (playerCache.burst >= maxBurst){ + + // TODO debug remove + // Core.log("[RangedWeapon][DEBUG] playerCache.burst=" + playerCache.burst + " is >= " + (((WeaponRPM) RangedWeapon.this).getRpm() > 0 ? 5 : 1)); + this.cancel(); + playerCache.burst = 1; + playerCache.shooting = false; + weaponState = WeaponState.IDLE; + return; + } + } + + playerCache.burst += 1; + + if(isAutomatic()) { + weaponState = WeaponState.BURSTING; + + int tick = playerCache.tick; + playerCache.tick = (tick >= 20) ? 1 : (tick + 1); + if (!RangedWeapon.this.isValid(playerCache.tick)){ + // TODO debug remove + // Core.log("[RangedWeapon][DEBUG] Ranged weapon is not valid, playerCache.tick=" + playerCache.tick); + return; + } + } + + Location origin = player.getEyeLocation(); + Vector direction = origin.getDirection(); + + RangedWeapon.this.vehicleShoot(player, origin, direction, true); + } + }.runTaskTimer(GTMGuns.getInstance(), 1, 1); + + return; + } + + Location origin = player.getEyeLocation(); + Vector direction = origin.getDirection(); + + this.shoot(player, origin, direction, playerCache, false); + +// if (this.recoil != 0 && !player.isSneaking()) +// player.setVelocity(player.getVelocity().add(direction.setY(0).multiply(-this.recoil))); + } + + public void shoot(Player player, Location origin, Vector direction, PlayerCache playerCache, boolean auto) { + origin = player.getEyeLocation(); + direction = origin.getDirection(); + + User shooterUser = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if(shooterUser == null) return; + boolean useParticles = shooterUser.getPref(Pref.SHOW_PARTICLES); + + boolean flamethrower = getWeaponType() == WeaponType.FLAMETHROWER; + int ammountOfBullets = 1; + if(getWeaponType() == WeaponType.SHOTGUN && this instanceof ShotgunWeapon) + ammountOfBullets = ((ShotgunWeapon) this).getShellSize(); + + AmmoUpdateEvent ammoUpdateEvent = new AmmoUpdateEvent(player); + Bukkit.getPluginManager().callEvent(ammoUpdateEvent); + int totalAmmo = ammoUpdateEvent.getAmmo().getOrDefault(getAmmoType().getType(), 0); + + ItemStack newHeldItem = player.getEquipment().getItemInMainHand(); + int ammo = this.getAmmo(newHeldItem); + if(ammo <= 0) { + if(getAmmoType() != AmmoType.NONE && totalAmmo > 0) { + reload(player, playerCache); + return; + } + weaponState = WeaponState.IDLE; + return; + } + + newHeldItem = this.setAmmo(newHeldItem, ammo - 1, totalAmmo); + player.getEquipment().getItemInMainHand().setItemMeta(newHeldItem.getItemMeta()); + player.updateInventory(); + if (ammo - 1 <= 0) reload(player, playerCache); + else { + if(!auto) weaponState = WeaponState.IDLE; + } + + // logic behind calculating accuracy: https://imgur.com/a/erSo2? + for (int i = 0; i < ammountOfBullets; i++){ + + // 2 TIMES accuracy gives the DIAMETER around the initial direction + // RANDOM TIMES this accuracy gives a value between the left lower + // limit and the right upper limit. + // subtracting the accuracy gets the point centered around the origin + + double dx = (2 * accuracy) * Math.random() - accuracy; + double dy = (2 * accuracy) * Math.random() - accuracy; + double dz = (2 * accuracy) * Math.random() - accuracy; + + if (getWeaponType() == WeaponType.SNIPER && player.isSneaking()){ + dx = 0; + dy = 0; + dz = 0; + } + + double newX = direction.getX() + dx; + double newY = direction.getY() + dy; + double newZ = direction.getZ() + dz; + + Vector vector = new Vector(newX, newY, newZ); + + double range = this.range; + Object[] o = MathUtil.getNearestTarget(player, origin, vector, this.range); + Block b = MathUtil.getTargetBlock(origin, vector, this.range); + + if (o != null) { + if (b == null || player.getLocation().distance((Location) o[1]) < player.getLocation().distance(b.getLocation())) { + LivingEntity target = (LivingEntity) o[0]; + Location intersection = (Location) o[1]; + + //Blood particles on Hit. +// target.getWorld().spigot().playEffect(intersection, Effect.COLOURED_DUST, 0, 0, 255, 0, 0, 1, 0, 64); + + // call weapon damage to see if we modify the event + WeaponDamageEvent weaponDamageEvent = new WeaponDamageEvent(player, this, newHeldItem, getDamage(), target, DamageCause.DRAGON_BREATH); + Bukkit.getPluginManager().callEvent(weaponDamageEvent); + + if (weaponDamageEvent.isCancelled()){ + return; + } + + // create entity damage by entity event and add to data handler + EntityDamageByEntityEvent edbee = new EntityDamageByEntityEvent(player, target, DamageCause.DRAGON_BREATH, weaponDamageEvent.getDamage()); + DamageDataHandler.getInstance().addData(target.getUniqueId(), edbee); + + // damage the entity and set last damage cause + target.damage(weaponDamageEvent.getDamage(), player); + // reset damage ticks so they can take damage again + target.setNoDamageTicks(0); + target.setLastDamageCause(edbee); + + // TODO this was removed because target.damage(amount, Entity) called EntityDamageByEntityEvent which called the logic for melee damage. + //target.setNoDamageTicks(0); + //target.damage(this.damage, player); + //target.setLastDamageCause(new EntityDamageEvent(player, EntityDamageEvent.DamageCause.DRAGON_BREATH, this.damage)); + + if (getWeaponType() == WeaponType.PISTOL && this instanceof PistolWeapon && ((PistolWeapon) this).isStun()) { + if(target.getLocation().getWorld() != null && !target.getLocation().getWorld().getName().equalsIgnoreCase("spawn")) { + int stunDuration = ((PistolWeapon) this).getDuration(); + target.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, stunDuration, 2, true, false)); + target.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, stunDuration, 2, true, false)); + target.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS, stunDuration, 2, true, false)); + target.addPotionEffect(new PotionEffect(PotionEffectType.CONFUSION, stunDuration, 2, true, false)); + target.addPotionEffect(new PotionEffect(PotionEffectType.SLOW_DIGGING, stunDuration, 2, true, false)); + } + } + + else if(getWeaponType() == WeaponType.FLAMETHROWER) { + if(target.getLocation().getWorld() != null && !target.getLocation().getWorld().getName().equalsIgnoreCase("spawn")) { + target.setFireTicks(100); + } + } + else if(getWeaponType()==WeaponType.CLAUSINATOR) { + if(!target.getWorld().getName().equalsIgnoreCase("spawn")){ + int cSlow = target.hasPotionEffect(PotionEffectType.SLOW) ? target.getPotionEffect(PotionEffectType.SLOW).getAmplifier() : -1; + cSlow += 1; + if(cSlow>=5) + cSlow = 5; + target.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 20*6, cSlow), true); + target.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 10, 0), true); + + ExplodeEffect explodeEffect = new ExplodeEffect(GTMGuns.getInstance().getEffectManager()); + explodeEffect.sound = Sound.ENTITY_BLAZE_SHOOT; + explodeEffect.setLocation(target.getLocation()); + explodeEffect.start(); + } + } + range = player.getLocation().distance((Location) o[1]); + } + + } + if (b != null) { + Location l = b.getLocation(); + if (!flamethrower) b.getWorld().playEffect(l, Effect.STEP_SOUND, b.getType()); + + if (!flamethrower) { + //Block damage particle + b.getWorld().playEffect(l, Effect.STEP_SOUND, b.getType()); + + //Block damage crack + if (GTMGuns.getInstance().getWeaponManager().getIgnoredBlocks().contains(b.getType())) return; + PacketContainer packetContainer = new PacketContainer(PacketType.Play.Server.BLOCK_BREAK_ANIMATION); + packetContainer.getIntegers().write(0, Random.getInt()); + packetContainer.getBlockPositionModifier().write(0, new BlockPosition(l.getBlockX(), l.getBlockY(), l.getBlockZ())); + packetContainer.getIntegers().write(1, Random.getInt(10)); + ProtocolLibrary.getProtocolManager().broadcastServerPacket(packetContainer); + } + range = player.getLocation().distance(l); + } + Location l = origin.clone(); + vector.multiply(0.5); + for (double k = 0; k < range * 2; k++) { + if (useParticles) l.getWorld().spigot().playEffect(l, getEffect(), 0, 0, 0, 0, 0, 0, 1, 64); + l.add(vector.getX(), vector.getY(), vector.getZ()); + } + } + Sounds.broadcastSound(getSounds()[0], origin); + if (RangedWeapon.this.recoil != 0 && !player.isSneaking()) + player.setVelocity(player.getVelocity().add(direction.setY(0).multiply(-(RangedWeapon.this.recoil/2)))); + } + + public void vehicleShoot(Player player, Location origin, Vector direction, boolean auto) { +// origin = player.getEyeLocation(); +// direction = origin.getDirection(); + + User shooterUser = Core.getUserManager().getLoadedUser(player.getUniqueId()); + if(shooterUser == null) return; + boolean useParticles = shooterUser.getPref(Pref.SHOW_PARTICLES); + +// boolean flamethrower = getWeaponType() == WeaponType.FLAMETHROWER; +// int ammountOfBullets = 1; +// if(getWeaponType() == WeaponType.SHOTGUN && this instanceof ShotgunWeapon) +// ammountOfBullets = ((ShotgunWeapon) this).getShellSize(); + + AmmoUpdateEvent ammoUpdateEvent = new AmmoUpdateEvent(player); + Bukkit.getPluginManager().callEvent(ammoUpdateEvent); + int totalAmmo = ammoUpdateEvent.getAmmo().getOrDefault(getAmmoType().getType(), 0); +// +// ItemStack newHeldItem = player.getEquipment().getItemInMainHand(); +// int ammo = this.getAmmo(newHeldItem); +// if(ammo <= 0) { +// if(getAmmoType() != AmmoType.NONE && totalAmmo > 0) { +// this.reload(player, playerCache); +// return; +// } +// weaponState = WeaponState.IDLE; +// return; +// } + +// newHeldItem = this.setAmmo(newHeldItem, ammo - 1, totalAmmo); +// player.getEquipment().getItemInMainHand().setItemMeta(newHeldItem.getItemMeta()); +// player.updateInventory(); +// if (ammo - 1 <= 0) this.reload(player, playerCache); +// else { +// if(!auto) weaponState = WeaponState.IDLE; +// } + +// for (int i = 0; i < ammountOfBullets; i++) { + double newX = direction.getX() + 2 * this.accuracy * Math.random() - this.accuracy; + double newY = direction.getY() + 2 * this.accuracy * Math.random() - this.accuracy; + double newZ = direction.getZ() + 2 * this.accuracy * Math.random() - this.accuracy; + + Vector vector = new Vector(newX, newY, newZ); + + double range = this.range; + Object[] o = MathUtil.getNearestTarget(player, origin, vector, this.range); + Block b = MathUtil.getTargetBlock(origin, vector, this.range); + + if (o != null) { + if (b == null || player.getLocation().distance((Location) o[1]) < player.getLocation().distance(b.getLocation())) { + LivingEntity target = (LivingEntity) o[0]; + Location intersection = (Location) o[1]; + + //Blood particles on Hit. +// target.getWorld().spigot().playEffect(intersection, Effect.COLOURED_DUST, 0, 0, 255, 0, 0, 1, 0, 64); + + // create entity damage by entity event and add to data handler + EntityDamageByEntityEvent edbee = new EntityDamageByEntityEvent(player, target, DamageCause.DRAGON_BREATH, this.damage); + DamageDataHandler.getInstance().addData(target.getUniqueId(), edbee); + + target.damage(this.damage, player); + target.setNoDamageTicks(0); + target.setLastDamageCause(edbee); + + if (getWeaponType() == WeaponType.PISTOL && this instanceof PistolWeapon && ((PistolWeapon) this).isStun()) { + if(target.getLocation().getWorld() != null && !target.getLocation().getWorld().getName().equalsIgnoreCase("spawn")) { + int stunDuration = ((PistolWeapon) this).getDuration(); + target.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, stunDuration, 2, true, false)); + target.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, stunDuration, 2, true, false)); + target.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS, stunDuration, 2, true, false)); + target.addPotionEffect(new PotionEffect(PotionEffectType.CONFUSION, stunDuration, 2, true, false)); + target.addPotionEffect(new PotionEffect(PotionEffectType.SLOW_DIGGING, stunDuration, 2, true, false)); + } + } + + if(getWeaponType() == WeaponType.FLAMETHROWER) { + if(target.getLocation().getWorld() != null && !target.getLocation().getWorld().getName().equalsIgnoreCase("spawn")) { + target.setFireTicks(100); + } + } + range = player.getLocation().distance((Location) o[1]); + } + + } + if (b != null) { + Location l = b.getLocation(); +// if (!flamethrower) b.getWorld().playEffect(l, Effect.STEP_SOUND, b.getType()); +// +// if (!flamethrower) { +// //Block damage particle +// b.getWorld().playEffect(l, Effect.STEP_SOUND, b.getType()); +// +// //Block damage crack +// if (GTMGuns.getInstance().getWeaponManager().getIgnoredBlocks().contains(b.getType())) return; +// PacketContainer packetContainer = new PacketContainer(PacketType.Play.Server.BLOCK_BREAK_ANIMATION); +// packetContainer.getIntegers().write(0, Random.getInt()); +// packetContainer.getBlockPositionModifier().write(0, new BlockPosition(l.getBlockX(), l.getBlockY(), l.getBlockZ())); +// packetContainer.getIntegers().write(1, Random.getInt(10)); +// ProtocolLibrary.getProtocolManager().broadcastServerPacket(packetContainer); +// } + range = player.getLocation().distance(l); + } + + Location l = origin.clone(); + vector.multiply(0.5); + for (double k = 0; k < range * 2; k++) { + if (useParticles) l.getWorld().spigot().playEffect(l, getEffect(), 0, 0, 0, 0, 0, 0, 1, 64); + l.add(vector.getX(), vector.getY(), vector.getZ()); + } +// } + + Sounds.broadcastSound(getSounds()[0], origin); +// if (RangedWeapon.this.recoil != 0 && !player.isSneaking()) +// player.setVelocity(player.getVelocity().add(direction.setY(0).multiply(-(RangedWeapon.this.recoil/2)))); + } + + public void reload(Player player, PlayerCache playerCache) { + if(player == null || playerCache == null) return; + if(this.getName().equalsIgnoreCase("clausinator")) { + int ammo = getAmmo(player.getInventory().getItemInMainHand()); + if(ammo!=0) { + player.sendMessage(Lang.GTM.f("&cThe clip must be empty in order to reload")); + return; + } + TextComponent tc = new TextComponent("Click Here to Reload Clausinator For $100,000"); + tc.setColor(net.md_5.bungee.api.ChatColor.AQUA); + tc.setBold(true); + tc.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/christmas clausinator")); + player.spigot().sendMessage(tc); + return; + } + if(this.weaponState == WeaponState.RELOADING) return; + + + if(this.getWeaponType() == WeaponType.FLAMETHROWER) { + ItemStack itemStack = Main.getPlugin(Main.class).getBabies().getJetpackFuelItem().clone(); + boolean found = false; + for (ItemStack item : player.getInventory().getContents()) { + if(item == null) continue; + if(item.getType() != itemStack.getType()) continue; + if(!item.hasItemMeta() || !itemStack.hasItemMeta()) continue; + if(!item.getItemMeta().getDisplayName().equals(itemStack.getItemMeta().getDisplayName())) continue; + + if (item.getAmount() == 1) player.getInventory().remove(item); + else item.setAmount(item.getAmount() - 1); + + found = true; + break; + } + + if(!found) { + player.sendMessage(Lang.AMMO.f("&7The &c&lFlamethrower &7requires (jetpack) fuel to use!")); + return; + } + + player.updateInventory(); + } + + this.weaponState = WeaponState.RELOADING; + playerCache.burst = 0; + playerCache.shooting = false; + + int ammo = getAmmo(player.getEquipment().getItemInMainHand()); + int ammoToReload = this.magSize - ammo; + new BukkitRunnable() { + private int i; + + @Override + public void run() { + if (RangedWeapon.this.weaponState != WeaponState.RELOADING) { + this.cancel(); + return; + } + + ItemStack heldItem = player.getEquipment().getItemInMainHand(); + if(heldItem == null || heldItem.getType() == Material.AIR) { + RangedWeapon.this.weaponState = WeaponState.IDLE; + playerCache.burst = 0; + playerCache.shooting = false; + this.cancel(); + return; + } + + Weapon<?> weaponInHand = playerCache.getOrAddWeapon(heldItem); + + boolean checkSkins = false; + for(WeaponSkin skin : RangedWeapon.this.getWeaponSkins()) { + if(heldItem.getDurability() == skin.getIdentifier()) { + checkSkins = true; + } + } + + if (weaponInHand == null || (!RangedWeapon.this.getName().equals(weaponInHand.getName()) && RangedWeapon.this.getWeaponIdentifier() != weaponInHand.getWeaponIdentifier() && !checkSkins)) { + RangedWeapon.this.weaponState = WeaponState.IDLE; + playerCache.burst = 0; + playerCache.shooting = false; + this.cancel(); + return; + } + + RangedWeaponReloadEvent event = new RangedWeaponReloadEvent(player, RangedWeapon.this, 1); + Bukkit.getPluginManager().callEvent(event); + if (event.isCancelled()) { + RangedWeapon.this.weaponState = WeaponState.IDLE; + playerCache.burst = 0; + playerCache.shooting = false; + this.cancel(); + return; + } + + this.i += event.getAmmoToReload(); + int totalAmmo = 0; + + AmmoUpdateEvent event1 = new AmmoUpdateEvent(player); + Bukkit.getPluginManager().callEvent(event1); + totalAmmo = event1.getAmmo().getOrDefault(RangedWeapon.this.getAmmoType().getType(), 0); + + heldItem = RangedWeapon.this.setAmmo(heldItem, ammo + this.i, totalAmmo); + player.getEquipment().setItemInMainHand(heldItem); + Sounds.broadcastSound(RangedWeapon.this.getSounds()[3], player.getEyeLocation()); + + if (this.i >= ammoToReload) { + RangedWeapon.this.weaponState = WeaponState.IDLE; + playerCache.burst = 0; + playerCache.shooting = false; + this.cancel(); + } + } + }.runTaskTimer(GTMGuns.getInstance(), this.reloadTime / this.magSize, this.reloadTime / this.magSize); + } + + public boolean isValid(int tick) { + + // how many revolutions per second should this be + // convert to ticks, so 1 = 1 per 20 ticks + int rps = this instanceof WeaponRPM ? ((WeaponRPM) this).getRPS() : 0; + + // TODO remove for compatibility purposes + // if not defined + if (rps == 0){ + rps = this instanceof WeaponRPM ? ((WeaponRPM) this).getRpm() : 0; + } + + switch (rps) { + case 1: + // fires on tick 1 + return tick == 1; + case 2: + // fires on tick 1,11 + return tick % 10 == 1; + case 3: + // fires on tick 6,12,18 + return tick % 6 == 0; + case 4: + // fires on tick 5,10,15,20 + return tick % 5 == 0; + case 5: + // fires on tick 4,8,12,16,20 + return tick % 4 == 0; + case 6: + // fires on tick 3,6,9,12,15,18 + return tick % 3 == 0; + case 7: + // fires on tick 1,4,7,10,13,16,19 + return tick % 3 == 1; + case 8: + // fires on tick 1,3,6,8,11,13,16,18 + return tick % 5 == 1 || tick % 5 == 3; + case 9: + // fires on tick 1,3,5,8,10,12,15,17,19 + return tick % 7 == 1 || tick % 7 == 3 || tick % 7 == 5; + case 10: + // fires on tick 1,3,5,7,9,11,13,15,17,19 + return tick % 2 == 1; + case 11: + // fires on tick 1,2,4,6,8,10,12,14,16,18,20 + return tick % 2 == 0 || tick == 1; + case 12: + // fires on tick 1,2,4,6,8,10,11,12,14,16,18,20 + return tick % 2 == 0 || tick == 1 || tick == 11; + case 13: + // fires on tick 1,2,4,6,8,10,11,12,14,16,18,19,20 + return tick % 2 == 0 || tick == 1 || tick == 11 || tick == 19; + case 14: + // fires on tick 1,2,4,5,7,8,10,11,13,14,16,17,19,20 + return tick % 3 != 0; + case 15: + // fires on tick 1,2,3,5,6,7,9,10,11,13,14,15,17,18,19 + return tick % 4 != 0; + case 16: + // fires on tick 1,2,3,4,6,7,8,9,11,12,13,14,16,17,18,19 + return tick % 5 != 0; + case 17: + // fires on tick 1,2,3,4,5,6,7,8,9,11,12,13,14,16,17,18,19 + return tick != 10 && tick != 15 && tick != 20; + case 18: + // fires on tick 1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19 + return tick != 10 && tick != 20; + case 19: + // fires on tick 1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19,20 + return tick != 10; + case 20: + // fires on ticks 1-20 + return tick > 0 && tick <= 20; + default: + return true; +// case 1: +// return tick % 4 == 1; +// case 2: +// tick %= 7; +// return tick == 1 || tick == 4; +// case 3: +// return tick % 3 == 1; +// case 4: +// tick %= 5; +// return tick == 1 || tick == 3; +// case 5: +// tick %= 7; +// return tick == 1 || tick == 3 || tick == 5; +// case 6: +// return (tick & 1) == 1; +// case 7: +// return tick == 2 || (tick & 1) == 1; +// case 8: +// tick %= 5; +// return tick == 1 || tick == 2 || tick == 4; +// case 9: +// tick %= 6; +// return tick != 2 && tick != 0; +// case 10: +// return tick % 3 != 0; +// case 11: +// return tick % 4 != 0; +// case 12: +// return tick % 5 != 0; +// case 13: +// return tick % 6 != 0; +// case 14: +// return tick % 10 != 0; +// case 15: +// return tick != 20; +// default: +// return true; + } + } + + public int getAmmo(ItemStack weapon) {//GunName «16/1254» OR «5» + if (weapon == null) return 0; + if (!weapon.hasItemMeta()) return 0; + if (weapon.getItemMeta().getDisplayName() == null) return 0; + String s = ChatColor.stripColor(weapon.getItemMeta().getDisplayName()), middle = ""; + + if(!s.contains("«") || !s.contains("»")) return 0; + middle = s.split("«")[1].split("»")[0]; + + try { + if(middle.contains("/")) return Integer.valueOf(middle.split("/")[0]); + else return Integer.valueOf(middle); + } catch (NumberFormatException exception) { + return 1; + } + } + + public ItemStack setAmmo(ItemStack weapon, int amount, int totalAmmo) { + if (weapon == null) return null; + if (!weapon.hasItemMeta()) return weapon; + ItemMeta im = weapon.getItemMeta(); + String s = ChatColor.stripColor(im.getDisplayName()); + String displayName = getAmmoType() != AmmoType.NONE ? "&6" + s.split("«")[0] + "&8«&f" + amount + "&8/&7" + totalAmmo + "&8»" + (s.split("»").length == 1 ? "" : s.split("»")[1]) : "&6" + s.split("«")[0] + "&8«&f" + amount + "&8»" + (s.split("»").length == 1 ? "" : s.split("»")[1]); + im.setDisplayName(Utils.f(displayName)); + weapon.setItemMeta(im); + return weapon; + } + + public ItemStack updateAmmo(ItemStack weapon, Player player) { + AmmoUpdateEvent event = new AmmoUpdateEvent(player); + Bukkit.getPluginManager().callEvent(event); + return this.setAmmo(weapon, this.getAmmo(weapon), event.getAmmo().getOrDefault(this.getAmmoType().getType(), 0)); + } + + /** + * Get whether or not this weapon can multi fire. + * <p> + * Typically weapons that have burst or automatic might be bursting over a task + * period and can be fired if this again with another burst task in concurrency. + * </p> + * + * @return {@code true} if the weapon can fire again even if it's already firing. + */ + public boolean canMultiShoot() { + return multiShoot; + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ranged/attachment/Attachment.java b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ranged/attachment/Attachment.java new file mode 100644 index 0000000..6b1bcbd --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ranged/attachment/Attachment.java @@ -0,0 +1,33 @@ +package net.grandtheftmc.guns.weapon.ranged.attachment; + +/** + * Created by Luke Bingham on 21/07/2017. + */ +public enum Attachment { + + /** + * + */ + SUPPRESSOR(), + + /** + * + */ + GRIP(), + + /** + * + */ + EXTENDED_MAGS(), + + /** + * + */ + SCOPE(), + + /** + * + */ + ADVANCED_SCOPE(), + ; +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ranged/guns/AssultRifleWeapon.java b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ranged/guns/AssultRifleWeapon.java new file mode 100644 index 0000000..6b808dd --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ranged/guns/AssultRifleWeapon.java @@ -0,0 +1,80 @@ +package net.grandtheftmc.guns.weapon.ranged.guns; + +import org.bukkit.Effect; +import org.bukkit.Sound; +import org.bukkit.inventory.ItemStack; + +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.attribute.WeaponRPM; +import net.grandtheftmc.guns.weapon.ranged.RangedWeapon; + +/** + * Created by Luke Bingham on 21/07/2017. + */ +public class AssultRifleWeapon extends RangedWeapon<AssultRifleWeapon> implements WeaponRPM { + + /** The revs/fires per second for this weapon */ + protected int rps; + /** + * The revs/fires per minute for this weapon + * @deprecated - Please use rps and related values from now on. + */ + @Deprecated + protected int rpm; + + /** + * Construct a new Weapon. + */ + public AssultRifleWeapon(short uniqueIdentifier, String name, WeaponType weaponType, AmmoType ammoType, ItemStack itemStack, Sound[] sounds, Effect effect) { + super(uniqueIdentifier, name, weaponType, ammoType, itemStack, sounds, effect); + } + + @Override + public boolean isAutomatic() { + return this.rpm > 0; + } + + /** + * {@inheritDoc} + */ + @Override + public int getRPS() { + return rps; + } + + @Override + public int getRpm() { + //return (rpm - 300) / 60 + 1; + return (rpm - 300) / 60 + 5; + } + + @Override + public AssultRifleWeapon clone() { + AssultRifleWeapon weapon = new AssultRifleWeapon(getUniqueIdentifier(), getName(), getWeaponType(), getAmmoType(), getBaseItemStack().clone(), getSounds(), getEffect()); + weapon.oldItemStack = super.oldItemStack.clone(); + weapon.deathMessages = super.deathMessages; + weapon.walkSpeed = super.walkSpeed; + weapon.delay = super.delay; + + weapon.attachments = super.attachments; + weapon.supportedAttachments = super.supportedAttachments; + weapon.weaponSkins = super.weaponSkins; + weapon.effect = super.effect; + weapon.damage = super.damage; + weapon.meleeDamage = super.meleeDamage; + weapon.accuracy = super.accuracy; + weapon.recoil = super.recoil; + weapon.magSize = super.magSize; + weapon.reloadTime = super.reloadTime; + weapon.range = super.range; + weapon.penetration = super.penetration; + weapon.zoom = super.zoom; + weapon.reloadShoot = super.reloadShoot; + weapon.multiShoot = super.multiShoot; + + weapon.rpm = this.rpm; + weapon.rps = this.rps; + return weapon; + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ranged/guns/LMGWeapon.java b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ranged/guns/LMGWeapon.java new file mode 100644 index 0000000..3b39e17 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ranged/guns/LMGWeapon.java @@ -0,0 +1,80 @@ +package net.grandtheftmc.guns.weapon.ranged.guns; + +import org.bukkit.Effect; +import org.bukkit.Sound; +import org.bukkit.inventory.ItemStack; + +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.attribute.WeaponRPM; +import net.grandtheftmc.guns.weapon.ranged.RangedWeapon; + +/** + * Created by Luke Bingham on 21/07/2017. + */ +public class LMGWeapon extends RangedWeapon<LMGWeapon> implements WeaponRPM { + + /** The revs/fires per second for this weapon */ + protected int rps; + /** + * The revs/fires per minute for this weapon + * @deprecated - Please use rps and related values from now on. + */ + @Deprecated + protected int rpm; + + /** + * Construct a new Weapon. + */ + public LMGWeapon(short uniqueIdentifier, String name, WeaponType weaponType, AmmoType ammoType, ItemStack itemStack, Sound[] sounds, Effect effect) { + super(uniqueIdentifier, name, weaponType, ammoType, itemStack, sounds, effect); + } + + @Override + public boolean isAutomatic() { + return this.rpm > 0; + } + + /** + * {@inheritDoc} + */ + @Override + public int getRPS() { + return rps; + } + + @Override + public int getRpm() { + //return (rpm - 300) / 60 + 1; + return (rpm - 300) / 60 + 5; + } + + @Override + public LMGWeapon clone() { + LMGWeapon weapon = new LMGWeapon(getUniqueIdentifier(), getName(), getWeaponType(), getAmmoType(), getBaseItemStack().clone(), getSounds(), getEffect()); + weapon.oldItemStack = super.oldItemStack.clone(); + weapon.deathMessages = super.deathMessages; + weapon.walkSpeed = super.walkSpeed; + weapon.delay = super.delay; + + weapon.attachments = super.attachments; + weapon.supportedAttachments = super.supportedAttachments; + weapon.weaponSkins = super.weaponSkins; + weapon.effect = super.effect; + weapon.damage = super.damage; + weapon.meleeDamage = super.meleeDamage; + weapon.accuracy = super.accuracy; + weapon.recoil = super.recoil; + weapon.magSize = super.magSize; + weapon.reloadTime = super.reloadTime; + weapon.range = super.range; + weapon.penetration = super.penetration; + weapon.zoom = super.zoom; + weapon.reloadShoot = super.reloadShoot; + weapon.multiShoot = super.multiShoot; + + weapon.rpm = this.rpm; + weapon.rps = this.rps; + return weapon; + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ranged/guns/LauncherWeapon.java b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ranged/guns/LauncherWeapon.java new file mode 100644 index 0000000..97b2837 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ranged/guns/LauncherWeapon.java @@ -0,0 +1,552 @@ +package net.grandtheftmc.guns.weapon.ranged.guns; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Projectile; +import org.bukkit.entity.SmallFireball; +import org.bukkit.entity.Snowball; +import org.bukkit.entity.TNTPrimed; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +import com.google.common.collect.Sets; +import com.j0ach1mmall3.jlib.methods.Sounds; +import com.j0ach1mmall3.jlib.player.JLibPlayer; +import com.j0ach1mmall3.wastedguns.MathUtil; +import com.j0ach1mmall3.wastedguns.api.events.NetgunHitEvent; +import com.j0ach1mmall3.wastedguns.api.events.WeaponDamageEvent; +import com.j0ach1mmall3.wastedguns.api.events.explosives.ExplosionDamageEntityEvent; +import com.j0ach1mmall3.wastedguns.api.events.ranged.AmmoUpdateEvent; +import com.j0ach1mmall3.wastedvehicles.api.VehicleType; +import com.j0ach1mmall3.wastedvehicles.api.vehicles.WastedVehicle; + +import net.grandtheftmc.core.util.Utils; +import net.grandtheftmc.guns.DamageDataHandler; +import net.grandtheftmc.guns.GTMGuns; +import net.grandtheftmc.guns.WeaponState; +import net.grandtheftmc.guns.cache.PlayerCache; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.attribute.WeaponExplosive; +import net.grandtheftmc.guns.weapon.ranged.RangedWeapon; +import net.grandtheftmc.houses.Houses; +import net.grandtheftmc.houses.users.HouseUser; + +/** + * Created by Luke Bingham on 21/07/2017. + */ +public class LauncherWeapon extends RangedWeapon<LauncherWeapon> implements WeaponExplosive { + + protected boolean homingLauncher = false, blowOnHit = true; + /** Does damage scale off of distance from projectile landing */ + protected boolean scaledDamage = false; + protected int blowDelay = 0; + protected double explosionStrength = 1d, rocketSpeed = 1d, explosionSize = 1d; + /** The number of ticks that an entity will remain stunned */ + protected int baseNetgunStun = 0; + + protected LivingEntity lockedTarget; + protected final Set<Projectile> rockets = Sets.newHashSet(); + + /** + * Construct a new Weapon. + */ + public LauncherWeapon(short uniqueIdentifier, String name, WeaponType weaponType, AmmoType ammoType, ItemStack itemStack, Sound[] sounds, Effect effect) { + super(uniqueIdentifier, name, weaponType, ammoType, itemStack, sounds, effect); + } + + @Override + public void onRightClick(Player player) { + super.onWeaponShoot(player, true, GTMGuns.getInstance().getWeaponManager().getPlayerCache(player.getUniqueId())); + } + + @Override + public void onSneak(Player player, boolean sneaking) { + if(!this.homingLauncher) return; + if(getAmmo(player.getEquipment().getItemInMainHand()) <= 0) return; + if(!sneaking) return; + if(super.weaponState == WeaponState.RELOADING) return; + + new BukkitRunnable() { + private int i = 0; + @Override + public void run() { + JLibPlayer libPlayer = new JLibPlayer(player); + if(!player.isSneaking() || weaponState == WeaponState.RELOADING) { + libPlayer.playSound(Sound.ENTITY_ENDERDRAGON_GROWL); + //libPlayer.sendActionBar(Utils.f("&7Cancelled lock!")); + Utils.sendActionBar(player, Utils.f("&7Cancelled lock!")); + this.cancel(); + return; + } + + if(this.i >= 3) { + this.cancel(); + Location origin = player.getEyeLocation(); + Vector direction = origin.getDirection(); + Object[] objs = MathUtil.getNearestTarget(player, origin, direction, LauncherWeapon.this.range); + Block block = MathUtil.getTargetBlock(origin, direction, LauncherWeapon.this.range); + if (objs == null || (block != null && player.getLocation().distance((Location) objs[1]) > player.getLocation().distance(block.getLocation()))) { + libPlayer.playSound(Sound.ENTITY_ENDERDRAGON_GROWL); + //libPlayer.sendActionBar(Utils.f("&7Cancelled failed!")); + Utils.sendActionBar(player, Utils.f("&7Cancelled lock!")); + return; + } + + LivingEntity target = (LivingEntity) objs[0]; + libPlayer.playSound(Sound.ENTITY_EXPERIENCE_ORB_PICKUP); + libPlayer.sendActionBar(ChatColor.GRAY + "Locked on " + ChatColor.GREEN + ChatColor.BOLD + (target.getCustomName() == null ? target.getName() : target.getCustomName()) + ChatColor.GRAY + '!'); + LauncherWeapon.this.lockedTarget = target; + return; + } + + this.i += 1; + libPlayer.playSound(Sound.BLOCK_METAL_PRESSUREPLATE_CLICK_ON); + //libPlayer.sendActionBar(Utils.f("&7Locking...")); + Utils.sendActionBar(player, Utils.f("&7Locking...")); + } + }.runTaskTimer(GTMGuns.getInstance(), 0, 5); + } + + @Override + public void shoot(Player player, Location origin, Vector direction, PlayerCache playerCache, boolean auto) { + AmmoUpdateEvent ammoUpdateEvent = new AmmoUpdateEvent(player); + Bukkit.getPluginManager().callEvent(ammoUpdateEvent); + int totalAmmo = ammoUpdateEvent.getAmmo().getOrDefault(getAmmoType().getType(), 0); + + ItemStack newHeldItem = player.getEquipment().getItemInMainHand(); + int ammo = this.getAmmo(newHeldItem); + if (ammo <= 0) { + if (getAmmoType() != AmmoType.NONE && totalAmmo > 0) { + reload(player, playerCache); + return; + } + super.weaponState = WeaponState.IDLE; + return; + } + + newHeldItem = this.setAmmo(newHeldItem, ammo - 1, totalAmmo); + player.getEquipment().getItemInMainHand().setItemMeta(newHeldItem.getItemMeta()); + player.updateInventory(); + if (ammo - 1 <= 0) reload(player, playerCache); + else { + if (!auto) super.weaponState = WeaponState.IDLE; + } + + double newX = direction.getX() + 2 * this.accuracy * Math.random() - this.accuracy; + double newY = direction.getY() + 2 * this.accuracy * Math.random() - this.accuracy; + double newZ = direction.getZ() + 2 * this.accuracy * Math.random() - this.accuracy; + + Vector vector = new Vector(newX, newY, newZ); + + if(player.isInsideVehicle() && player.getVehicle().hasMetadata("WastedVehicle")) { + WastedVehicle vehicle = (WastedVehicle) player.getVehicle().getMetadata("WastedVehicle").get(0).value(); + if(vehicle.getVehicleProperties().getVehicleType() == VehicleType.CAR) { + if(player.getLocation().getPitch() >= 20) + origin.setPitch(Math.min(player.getLocation().getPitch(), 35)); + origin.setPitch(Math.min(player.getLocation().getPitch(), -10)); + } + } + + final Projectile[] projectile = {null}; + if(super.getAmmoType() == AmmoType.GRENADE) { + projectile[0] = origin.getWorld().spawn(origin, Snowball.class); + projectile[0].setVelocity(vector.multiply(this.rocketSpeed)); + projectile[0].setShooter(player); + projectile[0].setMetadata("Rocket", new FixedMetadataValue(GTMGuns.getInstance(), this)); + projectile[0].setMetadata("Shooter", new FixedMetadataValue(GTMGuns.getInstance(), player)); + projectile[0].setInvulnerable(true); + } + else { + projectile[0] = origin.getWorld().spawn(origin, SmallFireball.class); + projectile[0].setVelocity(vector.multiply(this.rocketSpeed)); + projectile[0].setShooter(player); + projectile[0].setMetadata("Rocket", new FixedMetadataValue(GTMGuns.getInstance(), this)); + projectile[0].setMetadata("Shooter", new FixedMetadataValue(GTMGuns.getInstance(), player)); + projectile[0].setInvulnerable(true); + ((SmallFireball)projectile[0]).setIsIncendiary(false); + } + + rockets.add(projectile[0]); + Sounds.broadcastSound(getSounds()[0], origin); + if(getName().equalsIgnoreCase("net launcher") && player.getWorld().getName().equalsIgnoreCase("minesantos")) { + Location eyeLocation = player.getEyeLocation(); + Vector originDirection = origin.getDirection(); + Object[] objs = MathUtil.getNearestTarget(player, eyeLocation, originDirection, this.range); + if(objs != null) { + if(objs[0] == null) { + if(objs[1] instanceof Location) { + onNetgunHit((Location) objs[1], player, null);} + } else { + if(objs[0] instanceof LivingEntity) { + LivingEntity target = (LivingEntity) objs[0]; + HouseUser houseUser = Houses.getUserManager().getLoadedUser(target.getUniqueId()); + if (houseUser != null && (houseUser.isInsidePremiumHouse() || houseUser.isInsideHouse())) return; + if (!target.hasMetadata("WastedBarrel") && !(target.getLocation().distance(player.getLocation()) < 5)) { + + // create entity damage by entity event and add to data handler + EntityDamageByEntityEvent edbee = new EntityDamageByEntityEvent(player, target, DamageCause.DRAGON_BREATH, getDamage()); + DamageDataHandler.getInstance().addData(target.getUniqueId(), edbee); + + // damage the entity and set last damage cause + target.damage(getDamage(), player); + // reset damage ticks so they can take damage again + target.setNoDamageTicks(0); + target.setLastDamageCause(edbee); + + onNetgunHit(target.getLocation(), player, target); + } + } + } + + rockets.remove(projectile[0]); + projectile[0].remove(); + return; + } + else { + Optional<LivingEntity> optional = MathUtil.getNearbyEntities(player, this.range).filter(e -> { + if(!(e instanceof Player)) return false; + return MathUtil.getCrossProduct(player, e.getLocation()) < 0.12; + }).findFirst(); + + if(optional.isPresent()) { + LivingEntity target = optional.get(); + + // create entity damage by entity event and add to data handler + EntityDamageByEntityEvent edbee = new EntityDamageByEntityEvent(player, target, DamageCause.DRAGON_BREATH, getDamage()); + DamageDataHandler.getInstance().addData(target.getUniqueId(), edbee); + + // damage the entity and set last damage cause + target.damage(getDamage(), player); + // reset damage ticks so they can take damage again + target.setNoDamageTicks(0); + target.setLastDamageCause(edbee); + + onNetgunHit(target.getLocation(), player, target); + rockets.remove(projectile[0]); + projectile[0].remove(); + } + } + } + + new BukkitRunnable() { + @Override + public void run() { + if(projectile[0] == null || projectile[0].isDead() || !projectile[0].isValid()) { + this.cancel(); + return; + } + + if(projectile[0].getWorld() != player.getWorld()) return; + if(projectile[0].getLocation().distance(player.getLocation()) > getRange()) { + onExplode(projectile[0], (Player) projectile[0].getShooter()); + this.cancel(); + } + + Optional<Entity> nearestTarget = projectile[0].getNearbyEntities(1, 1, 1).stream().filter(entity -> entity instanceof LivingEntity).findFirst(); + if(nearestTarget.isPresent() && nearestTarget.get() != player) { + onExplode(projectile[0], (Player) projectile[0].getShooter()); + this.cancel(); + } + } + }.runTaskTimer(GTMGuns.getInstance(), 0, 1); + + new BukkitRunnable() { + private int i; + + @Override + public void run() { + if(projectile[0] == null || !projectile[0].isValid() || projectile[0].isDead() || this.i++ > 200) { + rockets.remove(projectile[0]); + projectile[0].remove(); + this.cancel(); + } + else { + if(!getName().equalsIgnoreCase("net launcher")) projectile[0].getWorld().spigot().playEffect(projectile[0].getLocation(), LauncherWeapon.this.getEffect(), 0, 0, 0, 0, 0, 0, 1, 64); + if(lockedTarget != null && LauncherWeapon.this.homingLauncher) { + if(!lockedTarget.getWorld().equals(player.getWorld()) || lockedTarget.getLocation().distance(player.getLocation())>200){ + lockedTarget = null; + new JLibPlayer(player).sendActionBar(Utils.f("&cTarget lock fail! The player is too far away!")); + return; + } + Vector vec = MathUtil.getVelocity(projectile[0].getLocation(), lockedTarget.getLocation()); + projectile[0].setVelocity(vec.multiply(LauncherWeapon.this.rocketSpeed)); + } + } + } + }.runTaskTimerAsynchronously(GTMGuns.getInstance(), 0, 1); + } + + /** + * Called when the netgun hits an entity. + * + * @param location - the location of the hit + * @param shooter - the shooter of the netgun + * @param target - the target being shot, if one is specified + */ + public void onNetgunHit(Location location, Player shooter, LivingEntity target) { + + // base stun duration + int netDuration = baseNetgunStun; + + // create netgun hit event and fire it + NetgunHitEvent nhe = new NetgunHitEvent(shooter, target, location, netDuration); + Bukkit.getPluginManager().callEvent(nhe); + + if (nhe.isCancelled()){ + return; + } + + if (nhe.getDuration() > 0){ + createNetgunWeb(location, nhe.getDuration()); + } + } + + /** + * Create the netgun web blocks at the specified location for the given duration. + * + * @param location - the location to create the web blocks + * @param netDuration - the number of ticks to keep the web blocks up for + */ + public void createNetgunWeb(Location location, int netDuration) { + + // create a list of cobwebs + Collection<Block> cobs = new ArrayList<>(); + + // grab initial location + int blockX = location.getBlockX(); + int blockY = location.getBlockY(); + int blockZ = location.getBlockZ(); + + // iterate around location + for (int x = 0; x < 2; x++) { + for (int y = 0; y < 3; y++) { + for (int z = 0; z < 2; z++) { + + // grab blocks and set to web + Block block = location.getWorld().getBlockAt(blockX + x, blockY + y, blockZ + z); + if (block.isEmpty()) { + block.setType(Material.WEB); + cobs.add(block); + } + } + } + } + + // delay task and reset to normal + new BukkitRunnable() { + @Override + public void run() { + cobs.forEach(block -> block.setType(Material.AIR)); + } + }.runTaskLater(GTMGuns.getInstance(), netDuration); + } + + @Override + public void onExplode(Entity projectile, Player shooter) { + + // get nearby entities to explosion + Collection<LivingEntity> eventVictims = MathUtil.getNearbyEntities(projectile, this.explosionSize).collect(Collectors.toList()); + + // call event + ExplosionDamageEntityEvent damageEntityEvent = new ExplosionDamageEntityEvent(shooter, projectile, eventVictims, this); + Bukkit.getPluginManager().callEvent(damageEntityEvent); + + // if event is cancelled, remove projectile + if (damageEntityEvent.isCancelled()) { + rockets.remove(projectile); + projectile.remove(); + return; + } + + // for each victim + Collection<LivingEntity> victims = damageEntityEvent.getVictims(); + if (!victims.isEmpty()) { + victims.forEach(e -> { + + // if not the same world + if (projectile.getWorld() != e.getWorld()) return; + + // send entities flying away from this explosion + if (!(e instanceof ArmorStand)) e.setVelocity(e.getLocation().getDirection().multiply(-this.explosionStrength)); + + // call weapon damage to see if we modify the event + WeaponDamageEvent weaponDamageEvent = new WeaponDamageEvent(shooter, this, getDamage(), e, DamageCause.DRAGON_BREATH); + Bukkit.getPluginManager().callEvent(weaponDamageEvent); + + if (weaponDamageEvent.isCancelled()){ + return; + } + + // the initial damage modifier they should take + double scaledDamage = 1.0; + + if (isScaledDamage()){ + + // the distance sq from the origin + double distanceSq = projectile.getLocation().distanceSquared(e.getLocation()); + + // if there is an explosion size + if (getExplosionSize() > 0){ + + // ratio is (explosionSize squared - distanceSq) DIVIDED BY explosionSize squared + // look below for example calculations + // assume explosionSize for all is 10 + // if distanceSq = 4, 100 - 4 = 96/100 = 96% + // if distanceSq = 9, 100 - 9 = 91/100 = 91% + // if distanceSq = 81, 100 - 81 = 19/100 = 19% + double ratio = (Math.pow(explosionSize, 2) - distanceSq) / Math.pow(explosionSize, 2); + + // CLAMP percent of damage to always be at least 10% + if (ratio <= 0.10){ + ratio = 0.10; + } + // 90% accurate should do 100% damage + // b/c to the user it always does less than max damage + if (ratio >= 0.90){ + ratio = 1.0; + } + + scaledDamage = ratio; + } + } + + // absolute value this just in case + // 19% of getDamage would be the total damage + double totalDamage = Math.abs(scaledDamage * weaponDamageEvent.getDamage()); + + // create entity damage by entity event and add to data handler + EntityDamageByEntityEvent edbee = new EntityDamageByEntityEvent(shooter, e, DamageCause.DRAGON_BREATH, totalDamage); + DamageDataHandler.getInstance().addData(e.getUniqueId(), edbee); + + // damage the entity and set last damage cause + e.damage(totalDamage, shooter); + // reset damage ticks so they can take damage again + e.setNoDamageTicks(0); + e.setLastDamageCause(edbee); + + // if this is a net launcher, add effects + if (getName().equalsIgnoreCase("net launcher")) { + e.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 80, 2, true, false)); + e.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS, 80, 2, true, false)); + e.addPotionEffect(new PotionEffect(PotionEffectType.CONFUSION, 80, 2, true, false)); + } + }); + } + + if(getName().equalsIgnoreCase("net launcher")) onNetgunHit(projectile.getLocation(), shooter, null); + else { +// Vice + TNTPrimed entity = (TNTPrimed) projectile.getWorld().spawnEntity(projectile.getLocation(), EntityType.PRIMED_TNT); + entity.setCustomName("EXPLOSIVE"); + entity.setCustomNameVisible(false); + entity.setFuseTicks(1); + + // add meta about the damage type of the explosion + entity.setMetadata("entity_damage", new FixedMetadataValue(GTMGuns.getInstance(), false)); + entity.setMetadata("entity_damage", new FixedMetadataValue(GTMGuns.getInstance(), false)); + + projectile.getWorld().spigot().playEffect(projectile.getLocation(), Effect.EXPLOSION_HUGE, 0, 0, 0, 0, 0, 0.01F, 1, 50); + projectile.getWorld().playSound(projectile.getLocation(), Sound.ENTITY_GENERIC_EXPLODE, 5.0F, 5.0F); + } + + rockets.remove(projectile); + projectile.remove(); + } + + @Override + public boolean isAutomatic() { + return false; + } + + public boolean isHomingLauncher() { + return homingLauncher; + } + + public boolean isBlowOnHit() { + return blowOnHit; + } + + public int getBlowDelay() { + return blowDelay; + } + + public double getExplosionStrength() { + return explosionStrength; + } + + public double getRocketSpeed() { + return rocketSpeed; + } + + public double getExplosionSize() { + return explosionSize; + } + + /** + * Get whether or not this launcher weapon does scaled damage. + * + * @return {@code true} if the damage is scaled from origin of projectile hit, {@code false} otherwise. + */ + public boolean isScaledDamage() { + return scaledDamage; + } + + @Override + public LauncherWeapon clone() { + LauncherWeapon weapon = new LauncherWeapon(getUniqueIdentifier(), getName(), getWeaponType(), getAmmoType(), getBaseItemStack().clone(), getSounds(), getEffect()); + weapon.oldItemStack = super.oldItemStack.clone(); + weapon.deathMessages = super.deathMessages; + weapon.walkSpeed = super.walkSpeed; + weapon.delay = super.delay; + + weapon.attachments = super.attachments; + weapon.supportedAttachments = super.supportedAttachments; + weapon.weaponSkins = super.weaponSkins; + weapon.effect = super.effect; + weapon.damage = super.damage; + weapon.meleeDamage = super.meleeDamage; + weapon.accuracy = super.accuracy; + weapon.recoil = super.recoil; + weapon.magSize = super.magSize; + weapon.reloadTime = super.reloadTime; + weapon.range = super.range; + weapon.penetration = super.penetration; + weapon.zoom = super.zoom; + weapon.reloadShoot = super.reloadShoot; + + weapon.homingLauncher = this.homingLauncher; + weapon.blowOnHit = this.blowOnHit; + weapon.blowDelay = this.blowDelay; + weapon.explosionStrength = this.explosionStrength; + weapon.rocketSpeed = this.rocketSpeed; + weapon.explosionSize = this.explosionSize; + weapon.scaledDamage = this.scaledDamage; + weapon.multiShoot = super.multiShoot; + weapon.baseNetgunStun = this.baseNetgunStun; + + return weapon; + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ranged/guns/PistolWeapon.java b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ranged/guns/PistolWeapon.java new file mode 100644 index 0000000..b7f74b0 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ranged/guns/PistolWeapon.java @@ -0,0 +1,68 @@ +package net.grandtheftmc.guns.weapon.ranged.guns; + +import org.bukkit.Effect; +import org.bukkit.Sound; +import org.bukkit.inventory.ItemStack; + +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.RangedWeapon; + +/** + * Created by Luke Bingham on 21/07/2017. + */ +public class PistolWeapon extends RangedWeapon<PistolWeapon> { + + protected boolean stun = false; + protected int duration = 0; + + /** + * Construct a new Weapon. + */ + public PistolWeapon(short uniqueIdentifier, String name, WeaponType weaponType, AmmoType ammoType, ItemStack itemStack, Sound[] sounds, Effect effect) { + super(uniqueIdentifier, name, weaponType, ammoType, itemStack, sounds, effect); + } + + @Override + public boolean isAutomatic() { + return false; + } + + public boolean isStun() { + return stun; + } + + public int getDuration() { + return duration; + } + + @Override + public PistolWeapon clone() { + PistolWeapon weapon = new PistolWeapon(getUniqueIdentifier(), getName(), getWeaponType(), getAmmoType(), getBaseItemStack().clone(), getSounds(), getEffect()); + weapon.oldItemStack = super.oldItemStack.clone(); + weapon.deathMessages = super.deathMessages; + weapon.walkSpeed = super.walkSpeed; + weapon.delay = super.delay; + + weapon.attachments = super.attachments; + weapon.supportedAttachments = super.supportedAttachments; + weapon.weaponSkins = super.weaponSkins; + weapon.effect = super.effect; + weapon.damage = super.damage; + weapon.meleeDamage = super.meleeDamage; + weapon.accuracy = super.accuracy; + weapon.recoil = super.recoil; + weapon.magSize = super.magSize; + weapon.reloadTime = super.reloadTime; + weapon.range = super.range; + weapon.penetration = super.penetration; + weapon.zoom = super.zoom; + weapon.reloadShoot = super.reloadShoot; + + weapon.stun = this.stun; + weapon.duration = this.duration; + weapon.multiShoot = super.multiShoot; + + return weapon; + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ranged/guns/SMGWeapon.java b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ranged/guns/SMGWeapon.java new file mode 100644 index 0000000..e1869e6 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ranged/guns/SMGWeapon.java @@ -0,0 +1,80 @@ +package net.grandtheftmc.guns.weapon.ranged.guns; + +import org.bukkit.Effect; +import org.bukkit.Sound; +import org.bukkit.inventory.ItemStack; + +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.attribute.WeaponRPM; +import net.grandtheftmc.guns.weapon.ranged.RangedWeapon; + +/** + * Created by Luke Bingham on 21/07/2017. + */ +public class SMGWeapon extends RangedWeapon<SMGWeapon> implements WeaponRPM { + + /** The revs/fires per second for this weapon */ + protected int rps; + /** + * The revs/fires per minute for this weapon + * @deprecated - Please use rps and related values from now on. + */ + @Deprecated + protected int rpm; + + /** + * Construct a new Weapon. + */ + public SMGWeapon(short uniqueIdentifier, String name, WeaponType weaponType, AmmoType ammoType, ItemStack itemStack, Sound[] sounds, Effect effect) { + super(uniqueIdentifier, name, weaponType, ammoType, itemStack, sounds, effect); + } + + @Override + public boolean isAutomatic() { + return this.rpm > 0; + } + + /** + * {@inheritDoc} + */ + @Override + public int getRPS() { + return rps; + } + + @Override + public int getRpm() { + //return (rpm - 300) / 60 + 1; + return (rpm - 300) / 60 + 5; + } + + @Override + public SMGWeapon clone() { + SMGWeapon weapon = new SMGWeapon(getUniqueIdentifier(), getName(), getWeaponType(), getAmmoType(), getBaseItemStack().clone(), getSounds(), getEffect()); + weapon.oldItemStack = super.oldItemStack.clone(); + weapon.deathMessages = super.deathMessages; + weapon.walkSpeed = super.walkSpeed; + weapon.delay = super.delay; + + weapon.attachments = super.attachments; + weapon.supportedAttachments = super.supportedAttachments; + weapon.weaponSkins = super.weaponSkins; + weapon.effect = super.effect; + weapon.damage = super.damage; + weapon.meleeDamage = super.meleeDamage; + weapon.accuracy = super.accuracy; + weapon.recoil = super.recoil; + weapon.magSize = super.magSize; + weapon.reloadTime = super.reloadTime; + weapon.range = super.range; + weapon.penetration = super.penetration; + weapon.zoom = super.zoom; + weapon.reloadShoot = super.reloadShoot; + weapon.multiShoot = super.multiShoot; + + weapon.rpm = this.rpm; + weapon.rps = this.rps; + return weapon; + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ranged/guns/ShotgunWeapon.java b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ranged/guns/ShotgunWeapon.java new file mode 100644 index 0000000..8240447 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ranged/guns/ShotgunWeapon.java @@ -0,0 +1,75 @@ +package net.grandtheftmc.guns.weapon.ranged.guns; + +import org.bukkit.Effect; +import org.bukkit.Sound; +import org.bukkit.inventory.ItemStack; + +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.attribute.WeaponRPM; +import net.grandtheftmc.guns.weapon.ranged.RangedWeapon; + +/** + * Created by Luke Bingham on 21/07/2017. + */ +public class ShotgunWeapon extends RangedWeapon<ShotgunWeapon> implements WeaponRPM { + protected int shellSize; + + /** + * Construct a new Weapon. + */ + public ShotgunWeapon(short uniqueIdentifier, String name, WeaponType weaponType, AmmoType ammoType, ItemStack itemStack, Sound[] sounds, Effect effect) { + super(uniqueIdentifier, name, weaponType, ammoType, itemStack, sounds, effect); + } + + @Override + public int getRpm() { + return 0; + } + + /** + * {@inheritDoc} + */ + @Override + public int getRPS() { + return 0; + } + + @Override + public boolean isAutomatic() { + return false; + } + + public int getShellSize() { + return shellSize; + } + + @Override + public ShotgunWeapon clone() { + ShotgunWeapon weapon = new ShotgunWeapon(getUniqueIdentifier(), getName(), getWeaponType(), getAmmoType(), getBaseItemStack().clone(), getSounds(), getEffect()); + weapon.oldItemStack = super.oldItemStack.clone(); + weapon.deathMessages = super.deathMessages; + weapon.walkSpeed = super.walkSpeed; + weapon.delay = super.delay; + + weapon.attachments = super.attachments; + weapon.supportedAttachments = super.supportedAttachments; + weapon.weaponSkins = super.weaponSkins; + weapon.effect = super.effect; + weapon.damage = super.damage; + weapon.meleeDamage = super.meleeDamage; + weapon.accuracy = super.accuracy; + weapon.recoil = super.recoil; + weapon.magSize = super.magSize; + weapon.reloadTime = super.reloadTime; + weapon.range = super.range; + weapon.penetration = super.penetration; + weapon.zoom = super.zoom; + + weapon.shellSize = this.shellSize; + weapon.reloadShoot = super.reloadShoot; + weapon.multiShoot = super.multiShoot; + + return weapon; + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ranged/guns/SniperWeapon.java b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ranged/guns/SniperWeapon.java new file mode 100644 index 0000000..917f2e6 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ranged/guns/SniperWeapon.java @@ -0,0 +1,86 @@ +package net.grandtheftmc.guns.weapon.ranged.guns; + +import java.lang.reflect.InvocationTargetException; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.events.PacketContainer; + +import net.grandtheftmc.guns.WeaponState; +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.ranged.RangedWeapon; + +/** + * Created by Luke Bingham on 21/07/2017. + */ +public class SniperWeapon extends RangedWeapon<SniperWeapon> { + + /** + * Construct a new Weapon. + */ + public SniperWeapon(short uniqueIdentifier, String name, WeaponType weaponType, AmmoType ammoType, ItemStack itemStack, Sound[] sounds, Effect effect) { + super(uniqueIdentifier, name, weaponType, ammoType, itemStack, sounds, effect); + } + + @Override + public boolean isAutomatic() { + return false; + } + + @Override + public void onSneak(Player player, boolean sneaking) { + if(sneaking && this.weaponState != WeaponState.RELOADING) { + PacketContainer packetContainer = new PacketContainer(PacketType.Play.Server.SET_SLOT); + packetContainer.getIntegers().write(0, 0); + packetContainer.getIntegers().write(1, 5); + packetContainer.getItemModifier().write(0, new ItemStack(Material.PUMPKIN)); + try { + ProtocolLibrary.getProtocolManager().sendServerPacket(player, packetContainer); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + + player.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, Integer.MAX_VALUE, this.zoom - 1, true, false)); + return; + } + + player.removePotionEffect(PotionEffectType.SLOW); + player.updateInventory(); + } + + @Override + public SniperWeapon clone() { + SniperWeapon weapon = new SniperWeapon(getUniqueIdentifier(), getName(), getWeaponType(), getAmmoType(), getBaseItemStack().clone(), getSounds(), getEffect()); + weapon.oldItemStack = super.oldItemStack.clone(); + weapon.deathMessages = super.deathMessages; + weapon.walkSpeed = super.walkSpeed; + weapon.delay = super.delay; + + weapon.attachments = super.attachments; + weapon.supportedAttachments = super.supportedAttachments; + weapon.weaponSkins = super.weaponSkins; + weapon.effect = super.effect; + weapon.damage = super.damage; + weapon.meleeDamage = super.meleeDamage; + weapon.accuracy = super.accuracy; + weapon.recoil = super.recoil; + weapon.magSize = super.magSize; + weapon.reloadTime = super.reloadTime; + weapon.range = super.range; + weapon.penetration = super.penetration; + weapon.zoom = super.zoom; + weapon.reloadShoot = super.reloadShoot; + weapon.multiShoot = super.multiShoot; + + return weapon; + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ranged/guns/SpecialWeapon.java b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ranged/guns/SpecialWeapon.java new file mode 100644 index 0000000..e822a38 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/java/net/grandtheftmc/guns/weapon/ranged/guns/SpecialWeapon.java @@ -0,0 +1,93 @@ +package net.grandtheftmc.guns.weapon.ranged.guns; + +import org.bukkit.Effect; +import org.bukkit.Sound; +import org.bukkit.inventory.ItemStack; + +import net.grandtheftmc.guns.weapon.AmmoType; +import net.grandtheftmc.guns.weapon.WeaponType; +import net.grandtheftmc.guns.weapon.attribute.WeaponRPM; +import net.grandtheftmc.guns.weapon.ranged.RangedWeapon; + +/** + * Created by Luke Bingham on 21/07/2017. + */ +public class SpecialWeapon extends RangedWeapon<SpecialWeapon> implements WeaponRPM { + + protected boolean minigun = false, netgun = false, flamethrower = false; + /** The revs/fires per second for this weapon */ + protected int rps; + /** + * The revs/fires per minute for this weapon + * @deprecated - Please use rps and related values from now on. + */ + @Deprecated + protected int rpm; + + /** + * Construct a new Weapon. + */ + public SpecialWeapon(short uniqueIdentifier, String name, WeaponType weaponType, AmmoType ammoType, ItemStack itemStack, Sound[] sounds, Effect effect) { + super(uniqueIdentifier, name, weaponType, ammoType, itemStack, sounds, effect); + } + + @Override + public boolean isAutomatic() { + return this.rpm > 0; + } + + /** + * {@inheritDoc} + */ + @Override + public int getRPS() { + return rps; + } + + @Override + public int getRpm() { + //return (rpm - 300) / 60 + 1; + return (rpm - 300) / 60 + 5; + } + + public boolean isMinigun() { + return minigun; + } + + public boolean isNetgun() { + return netgun; + } + + public boolean isFlamethrower() { + return flamethrower; + } + + @Override + public SpecialWeapon clone() { + SpecialWeapon weapon = new SpecialWeapon(getUniqueIdentifier(), getName(), getWeaponType(), getAmmoType(), getBaseItemStack().clone(), getSounds(), getEffect()); + weapon.oldItemStack = super.oldItemStack.clone(); + weapon.deathMessages = super.deathMessages; + weapon.walkSpeed = super.walkSpeed; + weapon.delay = super.delay; + + weapon.attachments = super.attachments; + weapon.supportedAttachments = super.supportedAttachments; + weapon.weaponSkins = super.weaponSkins; + weapon.effect = super.effect; + weapon.damage = super.damage; + weapon.meleeDamage = super.meleeDamage; + weapon.accuracy = super.accuracy; + weapon.recoil = super.recoil; + weapon.magSize = super.magSize; + weapon.reloadTime = super.reloadTime; + weapon.range = super.range; + weapon.penetration = super.penetration; + weapon.zoom = super.zoom; + weapon.reloadShoot = super.reloadShoot; + weapon.multiShoot = super.multiShoot; + + weapon.rpm = this.rpm; + weapon.rps = this.rps; + return weapon; + } +} diff --git a/wastedguns-master@2e3501603b9/src/main/resources/airstrikes.yml b/wastedguns-master@2e3501603b9/src/main/resources/airstrikes.yml new file mode 100644 index 0000000..a8e1035 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/resources/airstrikes.yml @@ -0,0 +1,59 @@ +Airstrikes: + Airstrike: + Item: '143 name:&aAirstrike itemflag:hide_attributes' + UseSound: ENTITY_SKELETON_SHOOT + DropSound: ENTITY_BAT_TAKEOFF + PickupSound: ENTITY_BAT_TAKEOFF + BeaconRadius: 3 + BeaconCircleParticles: 60 + BeaconLineParticles: 13 + BeaconUpdateTicks: 5 + BeaconRotationDegree: 1 + #temp using ParticleEffect.java + BeaconParticle: REDSTONE + # The delay before the nuke launches + TargetLength: 20 + # The damage of the Explosive + Damage: 50 + # The explosion radius size + ExplosionSize: 5.0 + # The explosion strength (for knockback) + ExplosionStrength: 2.0 + # The explosion sound + ExplosionSound: ENTITY_GENERIC_EXPLODE + # The explosion particles + ExplosionParticles: EXPLOSION_HUGE + BombItemStack: '1 name:&6Grenade itemflag:hide_attributes' + HydraItemStack: '153 name:&4&lHydra lore:&7Type:_&a&lPlane' + FireDelay: 20 + UseBeacon: true + Nuke: + Item: '143 name:&bNuke itemflag:hide_attributes' + UseSound: ENTITY_SKELETON_SHOOT + DropSound: ENTITY_BAT_TAKEOFF + PickupSound: ENTITY_BAT_TAKEOFF + BeaconRadius: 3 + BeaconCircleParticles: 60 + BeaconLineParticles: 13 + BeaconUpdateTicks: 5 + BeaconRotationDegree: 1 + #temp using ParticleEffect.java + BeaconParticle: REDSTONE + # The delay before the nuke launches + TargetLength: 20 + # The damage of the Explosive + Damage: 50 + # The explosion radius size + ExplosionSize: 5.0 + # The explosion strength (for knockback) + ExplosionStrength: 2.0 + # The explosion sound + ExplosionSound: ENTITY_GENERIC_EXPLODE + # The explosion particles + ExplosionParticles: EXPLOSION_HUGE + BombItemStack: '1 name:&6Grenade itemflag:hide_attributes' + HydraItemStack: '153 name:&4&lHydra lore:&7Type:_&a&lPlane' + FireDelay: 20 + #set to false because we want to fire immediately + UseBeacon: false +DoNotChange: 1.0.0 diff --git a/wastedguns-master@2e3501603b9/src/main/resources/attachments.yml b/wastedguns-master@2e3501603b9/src/main/resources/attachments.yml new file mode 100644 index 0000000..5865229 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/resources/attachments.yml @@ -0,0 +1,171 @@ +Attachments: + Surpressor: + MeleeDamageFactor: 1.0 + FireDelayFactor: 1.0 + WalkSpeedFactor: 1.0 + UseSound: BLOCK_LAVA_POP + DamageFactor: 0.95 + AccuracyFactor: 1.0 + RecoilFactor: 1.0 + ZoomFactor: 1.0 + MagazineAmount: 0 + ReloadTimeFactor: 1.0 + RangeFactor: 0.9 + PumpkinScope: false + ExtendedClip4: + MeleeDamageFactor: 1.0 + FireDelayFactor: 1.0 + WalkSpeedFactor: 1.0 + UseSound: + DamageFactor: 1.0 + AccuracyFactor: 1.0 + RecoilFactor: 1.0 + ZoomFactor: 1.0 + MagazineAmount: 4 + ReloadTimeFactor: 1.0 + RangeFactor: 1.0 + PumpkinScope: false + ExtendedClip6: + MeleeDamageFactor: 1.0 + FireDelayFactor: 1.0 + WalkSpeedFactor: 1.0 + UseSound: + DamageFactor: 1.0 + AccuracyFactor: 1.0 + RecoilFactor: 1.0 + ZoomFactor: 1.0 + MagazineAmount: 6 + ReloadTimeFactor: 1.0 + RangeFactor: 1.0 + PumpkinScope: false + ExtendedClip14: + MeleeDamageFactor: 1.0 + FireDelayFactor: 1.0 + WalkSpeedFactor: 1.0 + UseSound: + DamageFactor: 1.0 + AccuracyFactor: 1.0 + RecoilFactor: 1.0 + ZoomFactor: 1.0 + MagazineAmount: 14 + ReloadTimeFactor: 1.0 + RangeFactor: 1.0 + PumpkinScope: false + ExtendedClip18: + MeleeDamageFactor: 1.0 + FireDelayFactor: 1.0 + WalkSpeedFactor: 1.0 + UseSound: + DamageFactor: 1.0 + AccuracyFactor: 1.0 + RecoilFactor: 1.0 + ZoomFactor: 1.0 + MagazineAmount: 18 + ReloadTimeFactor: 1.0 + RangeFactor: 1.0 + PumpkinScope: false + ExtendedClip24: + MeleeDamageFactor: 1.0 + FireDelayFactor: 1.0 + WalkSpeedFactor: 1.0 + UseSound: + DamageFactor: 1.0 + AccuracyFactor: 1.0 + RecoilFactor: 1.0 + ZoomFactor: 1.0 + MagazineAmount: 24 + ReloadTimeFactor: 1.0 + RangeFactor: 1.0 + PumpkinScope: false + ExtendedClip30: + MeleeDamageFactor: 1.0 + FireDelayFactor: 1.0 + WalkSpeedFactor: 1.0 + UseSound: + DamageFactor: 1.0 + AccuracyFactor: 1.0 + RecoilFactor: 1.0 + ZoomFactor: 1.0 + MagazineAmount: 30 + ReloadTimeFactor: 1.0 + RangeFactor: 1.0 + PumpkinScope: false + ExtendedClip46: + MeleeDamageFactor: 1.0 + FireDelayFactor: 1.0 + WalkSpeedFactor: 1.0 + UseSound: + DamageFactor: 1.0 + AccuracyFactor: 1.0 + RecoilFactor: 1.0 + ZoomFactor: 1.0 + MagazineAmount: 46 + ReloadTimeFactor: 1.0 + RangeFactor: 1.0 + PumpkinScope: false + ExtendedClip50: + MeleeDamageFactor: 1.0 + FireDelayFactor: 1.0 + WalkSpeedFactor: 1.0 + UseSound: + DamageFactor: 1.0 + AccuracyFactor: 1.0 + RecoilFactor: 1.0 + ZoomFactor: 1.0 + MagazineAmount: 50 + ReloadTimeFactor: 1.0 + RangeFactor: 1.0 + PumpkinScope: false + ExtendedClip100: + MeleeDamageFactor: 1.0 + FireDelayFactor: 1.0 + WalkSpeedFactor: 1.0 + UseSound: + DamageFactor: 1.0 + AccuracyFactor: 1.0 + RecoilFactor: 1.0 + ZoomFactor: 1.0 + MagazineAmount: 100 + ReloadTimeFactor: 1.0 + RangeFactor: 1.0 + PumpkinScope: false + Grip: + MeleeDamageFactor: 1.0 + FireDelayFactor: 1.0 + WalkSpeedFactor: 1.0 + UseSound: + DamageFactor: 1.0 + AccuracyFactor: 0.9 + RecoilFactor: 0.8 + ZoomFactor: 1.0 + MagazineAmount: 0 + ReloadTimeFactor: 1.0 + RangeFactor: 1.0 + PumpkinScope: false + Scope: + MeleeDamageFactor: 1.0 + FireDelayFactor: 1.0 + WalkSpeedFactor: 1.0 + UseSound: + DamageFactor: 1.0 + AccuracyFactor: 0.8 + RecoilFactor: 1.0 + ZoomFactor: 1.0 + MagazineAmount: 0 + ReloadTimeFactor: 1.0 + RangeFactor: 1.0 + PumpkinScope: true + AdvancedScope: + MeleeDamageFactor: 1.0 + FireDelayFactor: 1.0 + WalkSpeedFactor: 1.0 + UseSound: + DamageFactor: 1.0 + AccuracyFactor: 0.8 + RecoilFactor: 1.0 + ZoomFactor: 1.0 + MagazineAmount: 0 + ReloadTimeFactor: 1.0 + RangeFactor: 1.0 + PumpkinScope: false +DoNotChange: 1.0.0 \ No newline at end of file diff --git a/wastedguns-master@2e3501603b9/src/main/resources/config.yml b/wastedguns-master@2e3501603b9/src/main/resources/config.yml new file mode 100644 index 0000000..9d2b1d5 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/resources/config.yml @@ -0,0 +1,6 @@ +CrackBlocksWhenHit: true +BlockParticlesWhenHit: true +FakeExplosionDebris: true +FakeExplosionDebrisParticles: true +BloodParticlesOnHit: true +DoNotChange: 1.0.0 \ No newline at end of file diff --git a/wastedguns-master@2e3501603b9/src/main/resources/explosives.yml b/wastedguns-master@2e3501603b9/src/main/resources/explosives.yml new file mode 100644 index 0000000..2c8bf3f --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/resources/explosives.yml @@ -0,0 +1,112 @@ +Explosives: + Grenade: + Item: '402 name:&6Grenade itemflag:hide_attributes' + MeleeDamage: 0.0 + AmmoType: EXPLOSIVE + FireDelay: 30 + WalkSpeed: 0.2 + UseSound: ENTITY_SKELETON_SHOOT + DropSound: ENTITY_BAT_TAKEOFF + PickupSound: ENTITY_BAT_TAKEOFF + AllowedAttachments: [] + # The delay before this Explosive will explode + ExplosionDelay: 60 + # The damage of the Explosive + Damage: 50 + # The explosion radius size + ExplosionSize: 5.0 + # The explosion strength (for knockback) + ExplosionStrength: 2.0 + # The explosion sound + ExplosionSound: ENTITY_GENERIC_EXPLODE + # The explosion particles + ExplosionParticles: EXPLOSION_HUGE + # The duration of the TearGas effect, only enable if this is a TearGas explosive + TearGasDuration: 0 + # The duration of the player burn, only enable if this is a MolotovCocktail explosive + BurnDuration: 0 + # Whether this explosive should stick, only enable if this is a StickyBomb explosive + Sticky: false + # Whether this explosive activates upon proximity, only enable if this is a ProximityMine explosive + Proximity: false + TearGas: + Item: '370 name:&6Tear_Gas itemflag:hide_attributes' + MeleeDamage: 0.0 + AmmoType: EXPLOSIVE + FireDelay: 30 + WalkSpeed: 0.2 + UseSound: ENTITY_SKELETON_SHOOT + DropSound: ENTITY_BAT_TAKEOFF + PickupSound: ENTITY_BAT_TAKEOFF + AllowedAttachments: [] + ExplosionDelay: 60 + Damage: 5 + ExplosionSize: 5.0 + ExplosionStrength: 0.0 + ExplosionSound: BLOCK_LAVA_EXTINGUISH + ExplosionParticles: CLOUD + TearGasDuration: 100 + BurnDuration: 0 + Sticky: false + Proximity: false + MolotovCocktail: + Item: '378 name:&6Molotov_Cocktail itemflag:hide_attributes' + MeleeDamage: 0.0 + AmmoType: EXPLOSIVE + FireDelay: 30 + WalkSpeed: 0.2 + UseSound: ENTITY_SKELETON_SHOOT + DropSound: ENTITY_BAT_TAKEOFF + PickupSound: ENTITY_BAT_TAKEOFF + AllowedAttachments: [] + ExplosionDelay: 60 + Damage: 25 + ExplosionSize: 5.0 + ExplosionStrength: 0.0 + ExplosionSound: ENTITY_SPLASH_POTION_BREAK + ExplosionParticles: FLAME + TearGasDuration: 0 + BurnDuration: 100 + Sticky: false + Proximity: false + StickyBomb: + Item: '385 name:&6Sticky_Bomb itemflag:hide_attributes' + MeleeDamage: 0.0 + AmmoType: EXPLOSIVE + FireDelay: 20 + WalkSpeed: 0.2 + UseSound: ENTITY_SKELETON_SHOOT + DropSound: ENTITY_BAT_TAKEOFF + PickupSound: ENTITY_BAT_TAKEOFF + AllowedAttachments: [] + ExplosionDelay: 0 + Damage: 50 + ExplosionSize: 5.0 + ExplosionStrength: 2.0 + ExplosionSound: ENTITY_GENERIC_EXPLODE + ExplosionParticles: EXPLOSION_HUGE + TearGasDuration: 0 + BurnDuration: 0 + Sticky: true + Proximity: false + ProximityMine: + Item: '348 name:&6Proximity_Mine itemflag:hide_attributes' + MeleeDamage: 0.0 + AmmoType: EXPLOSIVE + FireDelay: 20 + WalkSpeed: 0.2 + UseSound: ENTITY_SKELETON_SHOOT + DropSound: ENTITY_BAT_TAKEOFF + PickupSound: ENTITY_BAT_TAKEOFF + AllowedAttachments: [] + ExplosionDelay: 0 + Damage: 50 + ExplosionSize: 5.0 + ExplosionStrength: 2.0 + ExplosionSound: ENTITY_GENERIC_EXPLODE + ExplosionParticles: EXPLOSION_HUGE + TearGasDuration: 0 + BurnDuration: 0 + Sticky: false + Proximity: true +DoNotChange: 1.0.0 \ No newline at end of file diff --git a/wastedguns-master@2e3501603b9/src/main/resources/melee.yml b/wastedguns-master@2e3501603b9/src/main/resources/melee.yml new file mode 100644 index 0000000..23bd78d --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/resources/melee.yml @@ -0,0 +1,66 @@ +MeleeWeapons: + Rake: + # General formatting applies: https://github.com/j0ach1mmall3/JLib/wiki/The-new-Item-Format + Item: '280 name:&6Rake itemflag:hide_attributes' + # The melee damage 2 = 1 heart (Not specified in spreadsheet) + MeleeDamage: 6.0 + # The AmmoType (Can be MELEE, PISTOL, SMG, MG, ASSAULT_RIFLE, SHOTGUN, SNIPER, ROCKET, GRENADE, MINIGUN) + AmmoType: MELEE + # The amount of ticks to wait between using + FireDelay: 15 + # The walk speed (default walk speed is 0.2, can be between 0 and 1) + WalkSpeed: 0.2 + # The Sound when shooting + UseSound: ENTITY_PLAYER_ATTACK_NODAMAGE + # The Sound when dropping + DropSound: ITEM_ARMOR_EQUIP_GENERIC + # The Sound when picking up + PickupSound: ITEM_ARMOR_EQUIP_GENERIC + # The Attachment identifiers that are allowed + AllowedAttachments: [] + NightStick: + Item: '369 name:&6Night_Stick itemflag:hide_attributes' + MeleeDamage: 8.0 + AmmoType: MELEE + FireDelay: 12 + WalkSpeed: 0.2 + UseSound: ENTITY_PLAYER_ATTACK_WEAK + DropSound: ITEM_ARMOR_EQUIP_GENERIC + PickupSound: ITEM_ARMOR_EQUIP_GENERIC + AllowedAttachments: [] + BaseballBat: + Item: '417 name:&6Baseball_Bat itemflag:hide_attributes' + MeleeDamage: 12.0 + AmmoType: MELEE + FireDelay: 15 + WalkSpeed: 0.2 + UseSound: ENTITY_PLAYER_ATTACK_STRONG + DropSound: ITEM_ARMOR_EQUIP_GENERIC + PickupSound: ITEM_ARMOR_EQUIP_GENERIC + AllowedAttachments: [] + Knife: + Item: '418 name:&6Knife itemflag:hide_attributes' + MeleeDamage: 15.0 + AmmoType: MELEE + FireDelay: 10 + WalkSpeed: 0.2 + UseSound: ENTITY_SKELETON_SHOOT + DropSound: ITEM_ARMOR_EQUIP_GENERIC + PickupSound: ITEM_ARMOR_EQUIP_GENERIC + AllowedAttachments: [] +EnergyWeapons: + Chainsaw: + Item: '419 name:&6Chainsaw itemflag:hide_attributes' + MeleeDamage: 5.0 + AmmoType: ENERGY + FireDelay: 5 + WalkSpeed: 0.14 + UseSound: ENTITY_WOLF_GROWL + DropSound: ITEM_ARMOR_EQUIP_GENERIC + PickupSound: ITEM_ARMOR_EQUIP_GENERIC + AllowedAttachments: [] + # The damage to be dealt + Damage: 5.0 + # The radius in which all Living Entities will be damaged + Range: 2.0 +DoNotChange: 1.0.0 \ No newline at end of file diff --git a/wastedguns-master@2e3501603b9/src/main/resources/plugin.yml b/wastedguns-master@2e3501603b9/src/main/resources/plugin.yml new file mode 100644 index 0000000..6540cd8 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/resources/plugin.yml @@ -0,0 +1,23 @@ +name: WastedGuns +main: net.grandtheftmc.guns.GTMGuns +version: 1.0.0 +author: Teddeh +description: A Guns plugin for GTM +depend: [JLib, ProtocolLib] +commands: + WGReload: + description: Reload the WastedGuns config + usage: /<command> +permissions: + wg.*: + description: All the WastedGuns permissions + default: op + children: + wg.giveweapon: true + wg.reload: true + wg.giveweapon: + description: Access to /giveweapon + default: op + wg.reload: + description: Access to /wgreload + default: op diff --git a/wastedguns-master@2e3501603b9/src/main/resources/ranged.yml b/wastedguns-master@2e3501603b9/src/main/resources/ranged.yml new file mode 100644 index 0000000..e038239 --- /dev/null +++ b/wastedguns-master@2e3501603b9/src/main/resources/ranged.yml @@ -0,0 +1,840 @@ +Guns: + # PISTOL + Pistol: + Item: '268 name:&6Pistol_&7«12» itemflag:hide_attributes ' + MeleeDamage: 3.0 + AmmoType: PISTOL + FireDelay: 7 + WalkSpeed: 0.2 + UseSound: ENTITY_FIREWORK_BLAST + DropSound: ITEM_ARMOR_EQUIP_LEATHER + PickupSound: ITEM_ARMOR_EQUIP_LEATHER + AllowedAttachments: + - Surpressor + - ExtendedClip4 + - Grip + - Scope + # The damage, 2 = 1 heart + Damage: 5.0 + # The accuracy + Accuracy: 0.025 + # Multiplication factor for backwards velocity + Recoil: 0.0 + # The amount of degrees to go up + # Speed Potion effect with the following multiplier + Zoom: 4 + # The magazine + Magazine: 12 + # The time in ticks to reload + ReloadTime: 40 + # The range in blocks + Range: 25 + # The Sound when reloading + ReloadSound: BLOCK_NOTE_HAT + # The particles to display, can be one of (https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Effect.html) + Particles: CRIT + # The warmup time in ticks (Not used currently) + WarmupTime: 0 + # Whether we should apply a pumpkin effect as scope + PumpkinScope: false + # The amount of bullets to shoot at the same time + AmmountOfBullets: 1 + # The amount of entities to pierce with 1 bullet + BulletPenetration: 1 + # The duration in ticks of the Stun Gun effect + StunDuration: 0 + # Whether we should allow shooting during reloading + AllowReloadShooting: false + # The RPM for Fully Automatic (Set to 0 to disable, can't be < 300, FireDelay needs to be 0) + AutomaticRPM: 0 + StunGun: + Item: '269 name:&6Stun_Gun_&7«1» itemflag:hide_attributes' + MeleeDamage: 3.0 + AmmoType: NONE + FireDelay: 57 + WalkSpeed: 0.2 + UseSound: BLOCK_DISPENSER_DISPENSE + DropSound: ITEM_ARMOR_EQUIP_LEATHER + PickupSound: ITEM_ARMOR_EQUIP_LEATHER + Damage: 1.0 + Accuracy: 0.0 + Recoil: 0.0 + Zoom: 0 + Magazine: 1 + ReloadTime: 60 + Range: 10 + ReloadSound: BLOCK_NOTE_HAT + Particles: MAGIC_CRIT + WarmupTime: 0 + PumpkinScope: false + AmmountOfBullets: 1 + BulletPenetration: 1 + StunDuration: 80 + AllowReloadShooting: false + AutomaticRPM: 0 + CombatPistol: + Item: '270 name:&6Combat_Pistol_&7«12» itemflag:hide_attributes' + MeleeDamage: 3.0 + AmmoType: PISTOL + FireDelay: 7 + WalkSpeed: 0.2 + UseSound: ENTITY_FIREWORK_BLAST + DropSound: ITEM_ARMOR_EQUIP_LEATHER + PickupSound: ITEM_ARMOR_EQUIP_LEATHER + AllowedAttachments: + - Surpressor + - ExtendedClip4 + - Grip + - Scope + Damage: 6.0 + Accuracy: 0.02 + Recoil: 0.0 + Zoom: 3 + Magazine: 12 + ReloadTime: 30 + Range: 30 + ReloadSound: BLOCK_NOTE_HAT + Particles: CRIT + WarmupTime: 0 + PumpkinScope: false + AmmountOfBullets: 1 + BulletPenetration: 1 + StunDuration: 0 + AllowReloadShooting: false + AutomaticRPM: 0 + HeavyPistol: + Item: '271 name:&6Heavy_Pistol_&7«18» itemflag:hide_attributes' + MeleeDamage: 4.0 + AmmoType: PISTOL + FireDelay: 8 + WalkSpeed: 0.2 + UseSound: ENTITY_FIREWORK_BLAST + DropSound: ITEM_ARMOR_EQUIP_LEATHER + PickupSound: ITEM_ARMOR_EQUIP_LEATHER + AllowedAttachments: + - Surpressor + - ExtendedClip18 + - Grip + - Scope + Damage: 8.0 + Accuracy: 0.02 + Recoil: 0.0 + Zoom: 3 + Magazine: 18 + ReloadTime: 40 + Range: 30 + ReloadSound: BLOCK_NOTE_HAT + Particles: CRIT + WarmupTime: 0 + PumpkinScope: false + AmmountOfBullets: 1 + BulletPenetration: 1 + StunDuration: 0 + AllowReloadShooting: false + AutomaticRPM: 0 + MarksmanPistol: + Item: '290 name:&6Marksman_Pistol_&7«1» itemflag:hide_attributes' + MeleeDamage: 4.0 + AmmoType: PISTOL + FireDelay: 57 + WalkSpeed: 0.2 + UseSound: ENTITY_FIREWORK_BLAST + DropSound: ITEM_ARMOR_EQUIP_LEATHER + PickupSound: ITEM_ARMOR_EQUIP_LEATHER + Damage: 20.0 + Accuracy: 0.035 + Recoil: 1.0 + Zoom: 4 + Magazine: 1 + ReloadTime: 100 + Range: 10 + ReloadSound: BLOCK_NOTE_HAT + Particles: CRIT + WarmupTime: 0 + PumpkinScope: false + AmmountOfBullets: 1 + BulletPenetration: 1 + StunDuration: 0 + AllowReloadShooting: false + AutomaticRPM: 0 + # SMG + MicroSMG: + Item: '267 name:&6Micro_SMG_&7«16» itemflag:hide_attributes' + MeleeDamage: 4.0 + AmmoType: SMG + FireDelay: 0 + WalkSpeed: 0.2 + UseSound: ENTITY_BLAZE_HURT + DropSound: ITEM_ARMOR_EQUIP_GOLD + PickupSound: ITEM_ARMOR_EQUIP_GOLD + AllowedAttachments: + - Surpressor + - ExtendedClip14 + - Grip + - Scope + Damage: 4.0 + Accuracy: 0.035 + Recoil: 0.0 + Zoom: 4 + Magazine: 16 + ReloadTime: 40 + Range: 25 + ReloadSound: BLOCK_WOODEN_DOOR_OPEN + Particles: FLYING_GLYPH + WarmupTime: 0 + PumpkinScope: false + AmmountOfBullets: 1 + BulletPenetration: 1 + StunDuration: 0 + AllowReloadShooting: false + AutomaticRPM: 600 + SMG: + Item: '256 name:&6SMG_&7«30» itemflag:hide_attributes' + MeleeDamage: 4.0 + AmmoType: SMG + FireDelay: 0 + WalkSpeed: 0.2 + UseSound: ENTITY_BLAZE_HURT + DropSound: ITEM_ARMOR_EQUIP_GOLD + PickupSound: ITEM_ARMOR_EQUIP_GOLD + AllowedAttachments: + - Surpressor + - ExtendedClip30 + - Grip + - Scope + Damage: 4.0 + Accuracy: 0.025 + Recoil: 0.0 + Zoom: 4 + Magazine: 30 + ReloadTime: 50 + Range: 35 + ReloadSound: BLOCK_WOODEN_DOOR_OPEN + Particles: FLYING_GLYPH + WarmupTime: 0 + PumpkinScope: false + AmmountOfBullets: 1 + BulletPenetration: 1 + StunDuration: 0 + AllowReloadShooting: false + AutomaticRPM: 510 + AssaultSMG: + Item: '257 name:&6Assault_SMG_&7«30» itemflag:hide_attributes' + MeleeDamage: 4.0 + AmmoType: SMG + FireDelay: 0 + WalkSpeed: 0.2 + UseSound: ENTITY_BLAZE_HURT + DropSound: ITEM_ARMOR_EQUIP_GOLD + PickupSound: ITEM_ARMOR_EQUIP_GOLD + AllowedAttachments: + - Surpressor + - ExtendedClip30 + - Grip + - Scope + Damage: 5.0 + Accuracy: 0.025 + Recoil: 0.0 + Zoom: 4 + Magazine: 30 + ReloadTime: 50 + Range: 35 + ReloadSound: BLOCK_WOODEN_DOOR_OPEN + Particles: FLYING_GLYPH + WarmupTime: 0 + PumpkinScope: false + AmmountOfBullets: 1 + BulletPenetration: 1 + StunDuration: 0 + AllowReloadShooting: false + AutomaticRPM: 460 + CombatPDW: + Item: '258 name:&6Combat_PDW_&7«30» itemflag:hide_attributes' + MeleeDamage: 4.0 + AmmoType: SMG + FireDelay: 0 + WalkSpeed: 0.2 + UseSound: ENTITY_BLAZE_HURT + DropSound: ITEM_ARMOR_EQUIP_GOLD + PickupSound: ITEM_ARMOR_EQUIP_GOLD + AllowedAttachments: + - Surpressor + - ExtendedClip30 + - Grip + - Scope + Damage: 6.0 + Accuracy: 0.025 + Recoil: 0.0 + Zoom: 4 + Magazine: 30 + ReloadTime: 40 + Range: 35 + ReloadSound: BLOCK_WOODEN_DOOR_OPEN + Particles: FLYING_GLYPH + WarmupTime: 0 + PumpkinScope: false + AmmountOfBullets: 1 + BulletPenetration: 1 + StunDuration: 0 + AllowReloadShooting: false + AutomaticRPM: 450 + GusenbergSweeper: + Item: '292 name:&6Gusenberg_Sweeper_&7«50» itemflag:hide_attributes' + MeleeDamage: 5.0 + AmmoType: SMG + FireDelay: 0 + WalkSpeed: 0.2 + UseSound: ENTITY_BLAZE_HURT + DropSound: ITEM_ARMOR_EQUIP_GOLD + PickupSound: ITEM_ARMOR_EQUIP_GOLD + AllowedAttachments: + - Surpressor + - ExtendedClip50 + - Grip + Damage: 6.0 + Accuracy: 0.016 + Recoil: 0.0 + Zoom: 2 + Magazine: 50 + ReloadTime: 50 + Range: 47 + ReloadSound: BLOCK_WOODEN_DOOR_OPEN + Particles: FLYING_GLYPH + WarmupTime: 0 + PumpkinScope: false + AmmountOfBullets: 1 + BulletPenetration: 1 + StunDuration: 0 + AllowReloadShooting: false + AutomaticRPM: 555 + # SHOTGUN + SawedoffShotgun: + Item: '283 name:&6Sawed-off_Shotgun_&7«8» itemflag:hide_attributes' + MeleeDamage: 4.0 + AmmoType: SHOTGUN + FireDelay: 70 + WalkSpeed: 0.16 + UseSound: ENTITY_ZOMBIE_ATTACK_DOOR_WOOD + DropSound: ITEM_ARMOR_EQUIP_CHAIN + PickupSound: ITEM_ARMOR_EQUIP_CHAIN + AllowedAttachments: [] + Damage: 3.0 + Accuracy: 0.075 + Recoil: 1.0 + Zoom: 6 + Magazine: 8 + ReloadTime: 56 + Range: 15 + ReloadSound: ENTITY_IRONGOLEM_ATTACK + Particles: PARTICLE_SMOKE + WarmupTime: 0 + PumpkinScope: false + AmmountOfBullets: 5 + BulletPenetration: 1 + StunDuration: 0 + AllowReloadShooting: true + AutomaticRPM: 0 + PumpShotgun: + Item: '284 name:&6Pump_Shotgun_&7«8» itemflag:hide_attributes' + MeleeDamage: 5.0 + AmmoType: SHOTGUN + FireDelay: 70 + WalkSpeed: 0.14 + UseSound: ENTITY_ZOMBIE_ATTACK_DOOR_WOOD + DropSound: ITEM_ARMOR_EQUIP_CHAIN + PickupSound: ITEM_ARMOR_EQUIP_CHAIN + AllowedAttachments: [] + Damage: 3.0 + Accuracy: 0.05 + Recoil: 0.7 + Zoom: 5 + Magazine: 8 + ReloadTime: 56 + Range: 20 + ReloadSound: ENTITY_IRONGOLEM_ATTACK + Particles: PARTICLE_SMOKE + WarmupTime: 0 + PumpkinScope: false + AmmountOfBullets: 4 + BulletPenetration: 1 + StunDuration: 0 + AllowReloadShooting: true + AutomaticRPM: 0 + Musket: + Item: '285 name:&6Musket_&7«1» itemflag:hide_attributes' + MeleeDamage: 4.0 + AmmoType: SHOTGUN + FireDelay: 92 + WalkSpeed: 0.14 + UseSound: ENTITY_ZOMBIE_ATTACK_DOOR_WOOD + DropSound: ITEM_ARMOR_EQUIP_CHAIN + PickupSound: ITEM_ARMOR_EQUIP_CHAIN + AllowedAttachments: [] + Damage: 30.0 + Accuracy: 0.025 + Recoil: 1.0 + Zoom: 4 + Magazine: 1 + ReloadTime: 100 + Range: 25 + ReloadSound: ENTITY_IRONGOLEM_ATTACK + Particles: PARTICLE_SMOKE + WarmupTime: 0 + PumpkinScope: false + AmmountOfBullets: 1 + BulletPenetration: 1 + StunDuration: 0 + AllowReloadShooting: false + AutomaticRPM: 0 + AssaultShotgun: + Item: '286 name:&6Assault_Shotgun_&7«8» itemflag:hide_attributes' + MeleeDamage: 5.0 + AmmoType: SHOTGUN + FireDelay: 5 + WalkSpeed: 0.14 + UseSound: ENTITY_ZOMBIE_ATTACK_DOOR_WOOD + DropSound: ITEM_ARMOR_EQUIP_CHAIN + PickupSound: ITEM_ARMOR_EQUIP_CHAIN + AllowedAttachments: + - Surpressor + - ExtendedClip24 + - Grip + - Scope + Damage: 3.0 + Accuracy: 0.018 + Recoil: 0.5 + Zoom: 2 + Magazine: 8 + ReloadTime: 40 + Range: 20 + ReloadSound: ENTITY_IRONGOLEM_ATTACK + Particles: PARTICLE_SMOKE + WarmupTime: 0 + PumpkinScope: false + AmmountOfBullets: 3 + BulletPenetration: 1 + StunDuration: 0 + AllowReloadShooting: false + AutomaticRPM: 0 + HeavyShotgun: + Item: '294 name:&6Heavy_Shotgun_&7«6» itemflag:hide_attributes' + MeleeDamage: 6.0 + AmmoType: SHOTGUN + FireDelay: 6 + WalkSpeed: 0.12 + UseSound: ENTITY_ZOMBIE_ATTACK_DOOR_WOOD + DropSound: ITEM_ARMOR_EQUIP_CHAIN + PickupSound: ITEM_ARMOR_EQUIP_CHAIN + Damage: 5.0 + AllowedAttachments: + - Surpressor + - ExtendedClip6 + - Grip + - Scope + Accuracy: 0.022 + Recoil: 0.6 + Zoom: 3 + Magazine: 6 + ReloadTime: 40 + Range: 20 + ReloadSound: ENTITY_IRONGOLEM_ATTACK + Particles: PARTICLE_SMOKE + WarmupTime: 0 + PumpkinScope: false + AmmountOfBullets: 3 + BulletPenetration: 1 + StunDuration: 0 + AllowReloadShooting: false + AutomaticRPM: 0 + # ASSAULT RIFLE + AssaultRifle: + Item: '272 name:&6Assault_Rifle_&7«30» itemflag:hide_attributes' + MeleeDamage: 5.0 + AmmoType: ASSAULT_RIFLE + FireDelay: 0 + WalkSpeed: 0.18 + UseSound: ENTITY_ITEM_BREAK + DropSound: ITEM_ARMOR_EQUIP_IRON + PickupSound: ITEM_ARMOR_EQUIP_IRON + AllowedAttachments: + - Surpressor + - ExtendedClip30 + - Grip + - Scope + Damage: 6.0 + Accuracy: 0.022 + Recoil: 0.4 + Zoom: 3 + Magazine: 30 + ReloadTime: 40 + Range: 45 + ReloadSound: ENTITY_SKELETON_AMBIENT + Particles: VOID_FOG + WarmupTime: 0 + PumpkinScope: false + AmmountOfBullets: 1 + BulletPenetration: 1 + StunDuration: 0 + AllowReloadShooting: false + AutomaticRPM: 380 + CarbineRifle: + Item: '273 name:&6Carbine_Rifle_&7«30» itemflag:hide_attributes' + MeleeDamage: 5.0 + AmmoType: ASSAULT_RIFLE + FireDelay: 0 + WalkSpeed: 0.18 + UseSound: ENTITY_ITEM_BREAK + DropSound: ITEM_ARMOR_EQUIP_IRON + PickupSound: ITEM_ARMOR_EQUIP_IRON + AllowedAttachments: + - Surpressor + - ExtendedClip30 + - Grip + - Scope + Damage: 7.0 + Accuracy: 0.018 + Recoil: 0.4 + Zoom: 2 + Magazine: 30 + ReloadTime: 40 + Range: 45 + ReloadSound: ENTITY_SKELETON_AMBIENT + Particles: VOID_FOG + WarmupTime: 0 + PumpkinScope: false + AmmountOfBullets: 1 + BulletPenetration: 1 + StunDuration: 0 + AllowReloadShooting: false + AutomaticRPM: 445 + BullpupRifle: + Item: '274 name:&6Bullpup_Rifle_&7«30» itemflag:hide_attributes' + MeleeDamage: 5.0 + AmmoType: ASSAULT_RIFLE + FireDelay: 0 + WalkSpeed: 0.18 + UseSound: ENTITY_ITEM_BREAK + DropSound: ITEM_ARMOR_EQUIP_IRON + PickupSound: ITEM_ARMOR_EQUIP_IRON + AllowedAttachments: + - Surpressor + - ExtendedClip30 + - Grip + - Scope + Damage: 7.0 + Accuracy: 0.016 + Recoil: 0.3 + Zoom: 2 + Magazine: 30 + ReloadTime: 40 + Range: 45 + ReloadSound: ENTITY_SKELETON_AMBIENT + Particles: VOID_FOG + WarmupTime: 0 + PumpkinScope: false + AmmountOfBullets: 1 + BulletPenetration: 1 + StunDuration: 0 + AllowReloadShooting: false + AutomaticRPM: 500 + AdvancedRifle: + Item: '275 name:&6Advanced_Rifle_&7«30» itemflag:hide_attributes' + MeleeDamage: 5.0 + AmmoType: ASSAULT_RIFLE + FireDelay: 0 + WalkSpeed: 0.18 + UseSound: ENTITY_ITEM_BREAK + DropSound: ITEM_ARMOR_EQUIP_IRON + PickupSound: ITEM_ARMOR_EQUIP_IRON + AllowedAttachments: + - Surpressor + - ExtendedClip30 + - Grip + - Scope + Damage: 8.0 + Accuracy: 0.02 + Recoil: 0.2 + Zoom: 3 + Magazine: 30 + ReloadTime: 35 + Range: 45 + ReloadSound: ENTITY_SKELETON_AMBIENT + Particles: VOID_FOG + WarmupTime: 0 + PumpkinScope: false + AmmountOfBullets: 1 + BulletPenetration: 1 + StunDuration: 0 + AllowReloadShooting: false + AutomaticRPM: 500 + SpecialCarbine: + Item: '291 name:&6Special_Carbine_&7«30» itemflag:hide_attributes' + MeleeDamage: 5.0 + AmmoType: ASSAULT_RIFLE + FireDelay: 0 + WalkSpeed: 0.18 + UseSound: ENTITY_ITEM_BREAK + DropSound: ITEM_ARMOR_EQUIP_IRON + PickupSound: ITEM_ARMOR_EQUIP_IRON + AllowedAttachments: + - Surpressor + - ExtendedClip30 + - Grip + - Scope + Damage: 9.0 + Accuracy: 0.016 + Recoil: 0.2 + Zoom: 2 + Magazine: 30 + ReloadTime: 35 + Range: 45 + ReloadSound: ENTITY_SKELETON_AMBIENT + Particles: VOID_FOG + WarmupTime: 0 + PumpkinScope: false + AmmountOfBullets: 1 + BulletPenetration: 1 + StunDuration: 0 + AllowReloadShooting: false + AutomaticRPM: 445 + # MG + MG: + Item: '276 name:&6MG_&7«54» itemflag:hide_attributes' + MeleeDamage: 6.0 + AmmoType: MG + FireDelay: 0 + WalkSpeed: 0.14 + UseSound: BLOCK_NOTE_SNARE + DropSound: ITEM_ARMOR_EQUIP_DIAMOND + PickupSound: ITEM_ARMOR_EQUIP_DIAMOND + AllowedAttachments: + - Surpressor + - ExtendedClip46 + - Grip + - Scope + Damage: 8.0 + Accuracy: 0.025 + Recoil: 0.2 + Zoom: 3 + Magazine: 54 + ReloadTime: 60 + Range: 60 + ReloadSound: ENTITY_SKELETON_STEP + Particles: VOID_FOG + WarmupTime: 0 + PumpkinScope: false + AmmountOfBullets: 1 + BulletPenetration: 1 + StunDuration: 0 + AllowReloadShooting: false + AutomaticRPM: 440 + CombatMG: + Item: '277 name:&6Combat_MG_&7«100» itemflag:hide_attributes' + MeleeDamage: 6.0 + AmmoType: MG + FireDelay: 0 + WalkSpeed: 0.14 + UseSound: BLOCK_NOTE_SNARE + DropSound: ITEM_ARMOR_EQUIP_DIAMOND + PickupSound: ITEM_ARMOR_EQUIP_DIAMOND + AllowedAttachments: + - Surpressor + - ExtendedClip100 + - Grip + - Scope + Damage: 9.0 + Accuracy: 0.02 + Recoil: 0.1 + Zoom: 5 + Magazine: 100 + ReloadTime: 50 + Range: 60 + ReloadSound: ENTITY_SKELETON_STEP + Particles: VOID_FOG + WarmupTime: 0 + PumpkinScope: false + AmmountOfBullets: 1 + BulletPenetration: 1 + StunDuration: 0 + AllowReloadShooting: false + AutomaticRPM: 550 + # SNIPER + SniperRifle: + Item: '278 name:&6Sniper_Rifle_&7«10» itemflag:hide_attributes' + MeleeDamage: 5.0 + AmmoType: SNIPER + FireDelay: 32 + WalkSpeed: 0.14 + UseSound: ENTITY_IRONGOLEM_HURT + DropSound: ITEM_ARMOR_EQUIP_DIAMOND + PickupSound: ITEM_ARMOR_EQUIP_DIAMOND + AllowedAttachments: + - Surpressor + - Grip + - AdvancedScope + Damage: 20.0 + Accuracy: 0.014 + Recoil: 0.3 + Zoom: 8 + Magazine: 10 + ReloadTime: 80 + Range: 95 + ReloadSound: BLOCK_PISTON_EXTEND + Particles: CLOUD + WarmupTime: 0 + PumpkinScope: true + AmmountOfBullets: 1 + BulletPenetration: 1 + StunDuration: 0 + AllowReloadShooting: false + AutomaticRPM: 0 + HeavySniper: + Item: '279 name:&6Heavy_Sniper_&7«6» itemflag:hide_attributes' + MeleeDamage: 6.0 + AmmoType: SNIPER + FireDelay: 41 + WalkSpeed: 0.14 + UseSound: ENTITY_IRONGOLEM_HURT + DropSound: ITEM_ARMOR_EQUIP_DIAMOND + PickupSound: ITEM_ARMOR_EQUIP_DIAMOND + AllowedAttachments: + - Surpressor + - Grip + - AdvancedScope + Damage: 30.0 + Accuracy: 0.011 + Recoil: 0.3 + Zoom: 9 + Magazine: 6 + ReloadTime: 80 + Range: 100 + ReloadSound: BLOCK_PISTON_EXTEND + Particles: CLOUD + WarmupTime: 0 + PumpkinScope: true + AmmountOfBullets: 1 + BulletPenetration: 1 + StunDuration: 0 + AllowReloadShooting: false + Minigun: + Item: '293 name:&6Minigun_&7«600» itemflag:hide_attributes' + MeleeDamage: 8.0 + AmmoType: MINIGUN + FireDelay: 0 + WalkSpeed: 0.1 + UseSound: ENTITY_ZOMBIE_ATTACK_IRON_DOOR + DropSound: ITEM_ARMOR_EQUIP_DIAMOND + PickupSound: ITEM_ARMOR_EQUIP_DIAMOND + AllowedAttachments: + - Grip + Damage: 10.0 + Accuracy: 0.025 + Recoil: 0.1 + Zoom: 3 + Magazine: 600 + ReloadTime: 100 + Range: 55 + ReloadSound: ITEM_FLINTANDSTEEL_USE + Particles: FLYING_GLYPH + WarmupTime: 50 + PumpkinScope: false + AmmountOfBullets: 1 + BulletPenetration: 1 + StunDuration: 0 + AllowReloadShooting: false + AutomaticRPM: 1200 +Launchers: + RPG: + Item: '288 name:&6RPG_&7«1» itemflag:hide_attributes' + MeleeDamage: 7.0 + AmmoType: ROCKET + FireDelay: 80 + WalkSpeed: 0.12 + UseSound: ENTITY_FIREWORK_LAUNCH + DropSound: ITEM_ARMOR_EQUIP_DIAMOND + PickupSound: ITEM_ARMOR_EQUIP_DIAMOND + AllowedAttachments: + - Grip + Damage: 500.0 + Accuracy: 0.005 + Recoil: 1.0 + Zoom: 1 + Magazine: 1 + ReloadTime: 60 + Range: 70 + ReloadSound: BLOCK_PISTON_CONTRACT + Particles: FIREWORKS_SPARK + WarmupTime: 0 + PumpkinScope: false + AmmountOfBullets: 1 + BulletPenetration: 1 + AllowReloadShooting: false + AutomaticRPM: 0 + # The speed of the rocket + RocketSpeed: 3.0 + # The explosion radius size + ExplosionSize: 5.0 + # The explosion strength (for knockback) + ExplosionStrength: 2.0 + # Whether this is a homing launcher + Homing: false + HomingLauncher: + Item: '289 name:&6Homing_Launcher_&7«1» itemflag:hide_attributes' + MeleeDamage: 7.0 + AmmoType: ROCKET + FireDelay: 80 + WalkSpeed: 0.12 + UseSound: ENTITY_FIREWORK_LAUNCH + DropSound: ITEM_ARMOR_EQUIP_DIAMOND + PickupSound: ITEM_ARMOR_EQUIP_DIAMOND + AllowedAttachments: + - Grip + Damage: 500.0 + Accuracy: 0.005 + Recoil: 1.0 + Zoom: 1 + Magazine: 1 + ReloadTime: 60 + Range: 70 + ReloadSound: BLOCK_PISTON_CONTRACT + Particles: FIREWORKS_SPARK + WarmupTime: 0 + PumpkinScope: false + AmmountOfBullets: 1 + BulletPenetration: 1 + AllowReloadShooting: false + AutomaticRPM: 0 + RocketSpeed: 1.0 + ExplosionSize: 5.0 + ExplosionStrength: 2.0 + Homing: true +ExplosiveLaunchers: + GrenadeLauncher: + Item: '359 name:&6Grenade_Launcher_&7«6» itemflag:hide_attributes' + MeleeDamage: 6.0 + AmmoType: GRENADE + FireDelay: 16 + WalkSpeed: 0.12 + UseSound: ENTITY_CHICKEN_EGG + DropSound: ITEM_ARMOR_EQUIP_DIAMOND + PickupSound: ITEM_ARMOR_EQUIP_DIAMOND + AllowedAttachments: + - Grip + Damage: 500.0 + Accuracy: 0.005 + Recoil: 0.5 + Zoom: 1 + Magazine: 6 + ReloadTime: 50 + Range: 50 + ReloadSound: BLOCK_PISTON_CONTRACT + Particles: FIREWORKS_SPARK + WarmupTime: 0 + PumpkinScope: false + AmmountOfBullets: 1 + BulletPenetration: 1 + StunDuration: 0 + AllowReloadShooting: false + AutomaticRPM: 0 + Explosive: Grenade +DoNotChange: 1.0.0 \ No newline at end of file diff --git a/wastedvehicles-master@5cac11d6d43/.gitignore b/wastedvehicles-master@5cac11d6d43/.gitignore new file mode 100644 index 0000000..631a4a8 --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/.gitignore @@ -0,0 +1,101 @@ + +\.idea/ + +target/classes/ + +target/ + +*.iml + +/bin/ +/build/ + +##### Gradle ##### +.gradle +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache + +# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 +# gradle/wrapper/gradle-wrapper.properties + +##### Eclipse ##### +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders + +.project + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# PyDev specific (Python IDE for Eclipse) +*.pydevproject + +# CDT-specific (C/C++ Development Tooling) +.cproject + +# JDT-specific (Eclipse Java Development Tools) +.classpath + +# Java annotation processor (APT) +.factorypath + +# PDT-specific (PHP Development Tools) +.buildpath + +# sbteclipse plugin +.target + +# Tern plugin +.tern-project + +# TeXlipse plugin +.texlipse + +# STS (Spring Tool Suite) +.springBeans + +# Code Recommenders +.recommenders/ + +*.class + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear + +# Unit Testing +logs/ + +##### IntelliJ ##### +*.iml +*.ipr +*.iws +.idea/ + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +##### MacOS ##### +.DS_Store diff --git a/wastedvehicles-master@5cac11d6d43/README.md b/wastedvehicles-master@5cac11d6d43/README.md new file mode 100644 index 0000000..87f5476 --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/README.md @@ -0,0 +1,3 @@ +First commit. +<br> +test \ No newline at end of file diff --git a/wastedvehicles-master@5cac11d6d43/circle.yml b/wastedvehicles-master@5cac11d6d43/circle.yml new file mode 100644 index 0000000..ba8d480 --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/circle.yml @@ -0,0 +1,5 @@ +deployment: + staging: + branch: master + commands: + - sh ./deploy.sh Build-$CIRCLE_BUILD_NUM Build-$CIRCLE_BUILD_NUM "$CIRCLE_PROJECT_REPONAME automated build $CIRCLE_BUILD_NUM" target/$CIRCLE_PROJECT_REPONAME.jar $CIRCLE_PROJECT_REPONAME.jar 4eedfd44a69246519654006ba7fc7d39b731fc69 \ No newline at end of file diff --git a/wastedvehicles-master@5cac11d6d43/deploy.sh b/wastedvehicles-master@5cac11d6d43/deploy.sh new file mode 100644 index 0000000..ac29ad7 --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/deploy.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +sudo apt-get install jq + +usage() { + echo "$0 <tagname> <releasename> <body> <artifact> <artifactname> <token>" +} + +response=$( + curl --fail \ + --location \ + --data "{\"tag_name\": \"$1\", \"name\": \"$2\", \"body\": \"$3\"}" \ + --header "Content-Type: application/json" \ + --header "Authorization: token $6" \ + "https://api.github.com/repos/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/releases" +) + +url2="$(echo "$response" | jq -r .upload_url | sed -e "s/{?name,label}//")" + +curl --header "Content-Type:application/gzip" \ + --header "Authorization: token $6" \ + --data-binary "@$4" \ + "$url2?name=$5" \ No newline at end of file diff --git a/wastedvehicles-master@5cac11d6d43/pom.xml b/wastedvehicles-master@5cac11d6d43/pom.xml new file mode 100644 index 0000000..be3b443 --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/pom.xml @@ -0,0 +1,109 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>net.grandtheftmc</groupId> + <artifactId>wastedvehicles</artifactId> + <version>1.0.5.rewrite</version> + <name>WastedVehicles</name> + + <repositories> + <repository> + <id>nexus-release</id> + <url>http://nexus.grandtheftmc.net/content/repositories/releases</url> + </repository> + </repositories> + + <distributionManagement> + <repository> + <id>nexus-release</id> + <name>Internal Releases</name> + <url>http://nexus.grandtheftmc.net/content/repositories/releases</url> + </repository> + <snapshotRepository> + <id>nexus-snapshot</id> + <name>Internal Snapshots</name> + <url>http://nexus.grandtheftmc.net/content/repositories/snapshots</url> + </snapshotRepository> + </distributionManagement> + + <dependencies> + <dependency> + <groupId>org.spigotmc.1.12</groupId> + <artifactId>spigot</artifactId> + <version>1.12.0</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.comphenix.protocol</groupId> + <artifactId>ProtocolLib</artifactId> + <version>LATEST</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.github.j0ach1mmall3</groupId> + <artifactId>JLib</artifactId> + <version>1.10.0</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>net.grandtheftmc</groupId> + <artifactId>wastedguns</artifactId> + <version>1.0.9.rewrite</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>net.grandtheftmc</groupId> + <artifactId>core</artifactId> + <version>2.3</version> + <scope>provided</scope> + </dependency> + </dependencies> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <maven.compiler.source>1.8</maven.compiler.source> + <maven.compiler.target>1.8</maven.compiler.target> + </properties> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-shade-plugin</artifactId> + <configuration> + <finalName>WastedVehicles</finalName> + </configuration> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>shade</goal> + </goals> + </execution> + </executions> + </plugin> + + <!-- Nexus deploy --> + <plugin> + <groupId>org.sonatype.plugins</groupId> + <artifactId>nexus-staging-maven-plugin</artifactId> + <version>1.6.8</version> + <extensions>true</extensions> + <executions> + <execution> + <id>default-deploy</id> + <phase>deploy</phase> + <goals> + <goal>deploy</goal> + </goals> + </execution> + </executions> + <configuration> + <serverId>nexus</serverId> + <nexusUrl>http://nexus.grandtheftmc.net/</nexusUrl> + <skipStaging>true</skipStaging> + </configuration> + </plugin> + </plugins> + </build> +</project> \ No newline at end of file diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/Main.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/Main.java new file mode 100644 index 0000000..38bd157 --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/Main.java @@ -0,0 +1,211 @@ +package com.j0ach1mmall3.wastedvehicles; + +import com.j0ach1mmall3.jlib.commands.Command; +import com.j0ach1mmall3.jlib.inventory.JLibItem; +import com.j0ach1mmall3.jlib.nms.nbt.NBTTag; +import com.j0ach1mmall3.jlib.plugin.JLibPlugin; +import com.j0ach1mmall3.wastedvehicles.api.VehicleProperties; +import com.j0ach1mmall3.wastedvehicles.api.events.VehicleCreateEvent; +import com.j0ach1mmall3.wastedvehicles.api.vehicles.*; +import com.j0ach1mmall3.wastedvehicles.commands.FixVehiclesCommandHandler; +import com.j0ach1mmall3.wastedvehicles.commands.GiveVehicleCommandHandler; +import com.j0ach1mmall3.wastedvehicles.commands.WVReloadCommandHandler; +import com.j0ach1mmall3.wastedvehicles.config.Config; +import com.j0ach1mmall3.wastedvehicles.listeners.JetpackListener; +import com.j0ach1mmall3.wastedvehicles.listeners.VehicleListener; +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.servers.ServerType; +import net.grandtheftmc.core.util.ServerUtil; +import org.bukkit.*; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 5/05/2016 + */ +public final class Main extends JLibPlugin<Config> { + private final Set<ArmorStand> entityQueue = Collections.newSetFromMap(new ConcurrentHashMap<>()); + + @Override + public void onEnable() { + this.reload(); + new JetpackListener(this); + new VehicleListener(this); + new GiveVehicleCommandHandler(this).registerCommand(new Command("GiveVehicle", "wv.givevehicle", ChatColor.RED + "Usage: /givevehicle <identifier> <player>")); + new WVReloadCommandHandler(this).registerCommand(new Command("WVReload", "wv.reload", ChatColor.RED + "Usage: /wvreload")); + new FixVehiclesCommandHandler(this).registerCommand(new Command("fixvehicles", "wv.fix", ChatColor.RED + "Usage: /fixvehicles")); + new BukkitRunnable() { + @Override + public void run() { + for(World world : Bukkit.getWorlds()) { + + if (world.getName().equals("spawn")) continue; + + for (Entity entity : world.getEntities()) { + if (entity.getType() != EntityType.ARMOR_STAND) continue; + if (entity.hasMetadata("WastedVehicle") || entity.hasMetadata("WastedVehiclePassenger")) + continue; + if(entity.hasMetadata("CUSTOM")) continue; + if (entity.getCustomName() == null || entity.getCustomName().isEmpty()) { + entity.remove(); + } + } + } + } + }.runTaskLater(this, 500); + + if(Core.getSettings().getType() != ServerType.GTM) return; + ServerUtil.runTaskLater(() -> { + for(VehicleProperties vehicle : this.config.getVehicleProperties()) { + Core.log(vehicle.getIdentifier()); + + World world = Bukkit.getWorld("spawn"); + if(world == null) continue; + + Location loc = null; + switch (vehicle.getIdentifier()) { + case "Zentorno": loc = new Location(world, -277.5, 26, 226.5, 0, 0); break;// + case "Entity_XF": loc = new Location(world, -287.5, 26, 228.5, 0, 0); break; + case "9F": loc = new Location(world, -272.5, 26, 225.9, 0, 0); break;// + case "ArmoredKuruma": loc = new Location(world, -267.5, 26, 224.5, 0, 0); break;// + case "Primo": loc = new Location(world, -282.5, 26, 227.5, 0, 0); break;// + case "BMX": loc = new Location(world, -296.5, 26, 224.5, -180, 0); break;// + case "Rhino": loc = new Location(world, -269.5, 26, 240.5, 90, 0); break;// + case "Hydra": loc = new Location(world, -286.5, 26.3, 213.5, 0, 20); break;// + case "Maverick": loc = new Location(world, -271.5, 26, 213.5, 0, 0); break;// + case "AttackMaverick": loc = new Location(world, -279.5, 26, 213.5, 0, 0); break;// + case "Dinghy": loc = new Location(world, -264.25, 24.4, 213.5, 0, 0); break;// +// case "Akuma": loc = new Location(world, ); break; + + default: break; + } + + //If location is null, continue the loop. + if(loc == null) continue; + if (!loc.getChunk().isLoaded()) loc.getChunk().load(); + + //Remove existing entities if any. + world.getNearbyEntities(loc, 1, 1, 1).stream().filter(entity -> entity instanceof ArmorStand).forEach(Entity::remove); + + //Create new showcase entity. + ArmorStand stand = world.spawn(loc, ArmorStand.class); + stand.setHelmet(vehicle.getItem() == null ? new ItemStack(Material.DIRT) : vehicle.getItem()); + stand.setMetadata("VehicleStatue", new FixedMetadataValue(this, vehicle)); + stand.setMetadata("CUSTOM", new FixedMetadataValue(this, VehicleProperties.class)); + stand.setInvulnerable(true); + stand.setGravity(false); + stand.setVisible(false); + stand.setCanPickupItems(false); + stand.setArms(false); + stand.setBasePlate(false); + stand.setAI(false); + stand.setMarker(true); + stand.setRemoveWhenFarAway(false); + } + }, 15*20); + } + + @Override + public void onDisable() { + for(World world : Bukkit.getWorlds()) { + + if (world.getName().equals("spawn")) continue; + + for (Entity entity : world.getEntities()) { + if (entity.getType() != EntityType.ARMOR_STAND) continue; + if (entity.hasMetadata("WastedVehicle")) { + WastedVehicle vehicle = (WastedVehicle) entity.getMetadata("WastedVehicle").get(0).value(); + vehicle.onDestroy((ArmorStand) entity); + } + if (entity.hasMetadata("WastedVehiclePassenger")) { + entity.remove(); + } + } + } + } + + public void reload() { + this.config = new Config(this); + } + + public Set<ArmorStand> getEntityQueue() { + return this.entityQueue; + } + + public Optional<VehicleProperties> getVehicle(String identifier) { + return this.config.getVehicleProperties().stream().filter(v -> v.getIdentifier().equalsIgnoreCase(identifier)).findFirst(); + } + + public Optional<VehicleProperties> getVehicle(ItemStack itemStack) { + return this.config.getVehicleProperties().stream().filter(v -> Objects.equals(v.getItem().getData(), itemStack.getData()) && itemStack.hasItemMeta() && itemStack.getItemMeta().hasDisplayName()).findFirst(); + } + + public ItemStack addHealth(ItemStack itemStack, double health) { + try { + JLibItem jLibItem = new JLibItem(itemStack); + NBTTag nbtTag = jLibItem.getNBTTag(); + Map<String, NBTTag> map = nbtTag.getMap(); + map.put("WastedVehicleHealth", new NBTTag(NBTTag.DOUBLE, (Object) health)); + nbtTag.setMap(map); + jLibItem.setNbtTag(nbtTag); + return jLibItem.getItemStack(); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public ArmorStand spawnVehicle(VehicleProperties vehicleProperties, Location location, Player player, double health) { + WastedVehicle vehicle = null; + switch (vehicleProperties.getVehicleType()) { + case CAR: + vehicle = new Car(this, vehicleProperties); + break; + case HELICOPTER: + vehicle = new Helicopter(this, vehicleProperties); + break; + case PLANE: + vehicle = new Plane(this, vehicleProperties); + break; + case BOAT: + vehicle = new Boat(this, vehicleProperties); + break; + case SUBMARINE: + vehicle = new Submarine(this, vehicleProperties); + break; + } + VehicleCreateEvent event = new VehicleCreateEvent(vehicle, player); + Bukkit.getPluginManager().callEvent(event); + if(!event.isCancelled()) { + ArmorStand armorStand = location.getWorld().spawn(location.add(0, 1, 0), ArmorStand.class); + vehicle.onCreate(armorStand, player, location, health); + armorStand.setMetadata("WastedVehicle", new FixedMetadataValue(this, vehicle)); + this.entityQueue.add(armorStand); + return armorStand; + } + return null; + } + + public String formatHealth(double health, double maxHealth) { + double amount = Math.floor((health <= 1 ? 0 : health) / maxHealth * 10); + ChatColor color = amount > 6 ? ChatColor.GREEN : amount > 4 ? ChatColor.YELLOW : amount > 2 ? ChatColor.RED : ChatColor.DARK_RED; + String s = color.toString(); + for(int i = 0; i < amount; i++) { + s += "▍"; + } + s += ChatColor.GRAY; + for(int i = 0; s.length() < 14; i++) { + s += "▍"; + } + return color + s; + } +} diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/SpeedBoost.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/SpeedBoost.java new file mode 100644 index 0000000..c100b64 --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/SpeedBoost.java @@ -0,0 +1,31 @@ +package com.j0ach1mmall3.wastedvehicles.api; + +import org.bukkit.inventory.ItemStack; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 15/05/2016 + */ +public final class SpeedBoost { + private final ItemStack itemStack; + private final double speedBoost; + private final int duration; + + public SpeedBoost(ItemStack itemStack, double speedBoost, int duration) { + this.itemStack = itemStack; + this.speedBoost = speedBoost; + this.duration = duration; + } + + public ItemStack getItemStack() { + return this.itemStack; + } + + public double getSpeedBoost() { + return this.speedBoost; + } + + public int getDuration() { + return this.duration; + } +} diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/VehicleProperties.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/VehicleProperties.java new file mode 100644 index 0000000..2779cec --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/VehicleProperties.java @@ -0,0 +1,166 @@ +package com.j0ach1mmall3.wastedvehicles.api; + +import org.bukkit.inventory.ItemStack; + +import java.util.List; +import java.util.Set; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 15/05/2016 + */ +public final class VehicleProperties { + private final String identifier; + private final VehicleType vehicleType; + private final double acceleration; + private final double deceleration; + private final double takeOffSpeed; + private final double rotationSpeed; + private final boolean invisible; + private final ItemStack item; + private final float boundingBoxWidth; + private final float boundingBoxHeight; + private final double launchLocationMultiplier; + private final double launchLocationYOffset; + private final double maxHealth; + private final boolean explode; + private final boolean damageVehicleOnPlayerHit; + private final int knockOutChance; + private final int passengers; + private final Set<SpeedBoost> speedBoosts; + private final double maxSpeed; + private final double defaultSpeed; + private final double collisionDamage; + private final String wastedGunsWeapon; + private final List<String> allowedWeapons; + private final List<String> allowedBlocks; + private final List<String> displayBlocks; + + public VehicleProperties(String identifier, VehicleType vehicleType, double acceleration, double deceleration, double takeOffSpeed, double rotationSpeed, boolean invisible, ItemStack item, float boundingBoxWidth, float boundingBoxHeight, double launchLocationMultiplier, double launchLocationYOffset, double maxHealth, boolean explode, boolean damageVehicleOnPlayerHit, int knockOutChance, int passengers, Set<SpeedBoost> speedBoosts, double maxSpeed, double defaultSpeed, double collisionDamage, String wastedGunsWeapon, List<String> allowedWeapons, List<String> allowedBlocks, List<String> displayBlocks) { + this.identifier = identifier; + this.vehicleType = vehicleType; + this.acceleration = acceleration; + this.deceleration = deceleration; + this.takeOffSpeed = takeOffSpeed; + this.rotationSpeed = rotationSpeed; + this.invisible = invisible; + this.item = item; + this.boundingBoxWidth = boundingBoxWidth; + this.boundingBoxHeight = boundingBoxHeight; + this.launchLocationMultiplier = launchLocationMultiplier; + this.launchLocationYOffset = launchLocationYOffset; + this.maxHealth = maxHealth; + this.explode = explode; + this.damageVehicleOnPlayerHit = damageVehicleOnPlayerHit; + this.knockOutChance = knockOutChance; + this.passengers = passengers; + this.speedBoosts = speedBoosts; + this.maxSpeed = maxSpeed; + this.defaultSpeed = defaultSpeed; + this.collisionDamage = collisionDamage; + this.wastedGunsWeapon = wastedGunsWeapon; + this.allowedWeapons = allowedWeapons; + this.allowedBlocks = allowedBlocks; + this.displayBlocks = displayBlocks; + } + + public String getIdentifier() { + return this.identifier; + } + + public VehicleType getVehicleType() { + return this.vehicleType; + } + + public double getAcceleration() { + return this.acceleration; + } + + public double getDeceleration() { + return this.deceleration; + } + + public double getTakeOffSpeed() { + return this.takeOffSpeed; + } + + public double getRotationSpeed() { + return this.rotationSpeed; + } + + public boolean isInvisible() { + return this.invisible; + } + + public ItemStack getItem() { + return this.item; + } + + public float getBoundingBoxWidth() { + return this.boundingBoxWidth; + } + + public float getBoundingBoxHeight() { + return this.boundingBoxHeight; + } + + public double getLaunchLocationMultiplier() { + return this.launchLocationMultiplier; + } + + public double getLaunchLocationYOffset() { + return this.launchLocationYOffset; + } + + public double getMaxHealth() { + return this.maxHealth; + } + + public boolean isExplode() { + return this.explode; + } + + public boolean isDamageVehicleOnPlayerHit() { + return this.damageVehicleOnPlayerHit; + } + + public int getKnockOutChance() { + return this.knockOutChance; + } + + public int getPassengers() { + return this.passengers; + } + + public Set<SpeedBoost> getSpeedBoosts() { + return this.speedBoosts; + } + + public double getMaxSpeed() { + return this.maxSpeed; + } + + public double getDefaultSpeed() { + return this.defaultSpeed; + } + + public double getCollisionDamage() { + return this.collisionDamage; + } + + public String getWastedGunsWeapon() { + return this.wastedGunsWeapon; + } + + public List<String> getAllowedWeapons() { + return this.allowedWeapons; + } + + public List<String> getAllowedBlocks() { + return this.allowedBlocks; + } + + public List<String> getDisplayBlocks() { + return this.displayBlocks; + } +} diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/VehicleType.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/VehicleType.java new file mode 100644 index 0000000..67ee32a --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/VehicleType.java @@ -0,0 +1,13 @@ +package com.j0ach1mmall3.wastedvehicles.api; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 26/06/2016 + */ +public enum VehicleType { + CAR, + HELICOPTER, + PLANE, + BOAT, + SUBMARINE +} diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/FuelUseEvent.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/FuelUseEvent.java new file mode 100644 index 0000000..599f723 --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/FuelUseEvent.java @@ -0,0 +1,45 @@ +package com.j0ach1mmall3.wastedvehicles.api.events; + + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * Created by Timothy Lampen on 8/22/2017. + */ +public class FuelUseEvent extends Event implements Cancellable { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private boolean cancelled; + private Player player; + + public FuelUseEvent(Player player){ + this.player = player; + } + + public Player getPlayer() { + return this.player; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean b) { + this.cancelled = b; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + +} diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/JetpackFlyEvent.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/JetpackFlyEvent.java new file mode 100644 index 0000000..27f9c66 --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/JetpackFlyEvent.java @@ -0,0 +1,54 @@ +package com.j0ach1mmall3.wastedvehicles.api.events; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public final class JetpackFlyEvent extends Event implements Cancellable { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final Player player; + private boolean cancelled; + private String message; + + public JetpackFlyEvent(Player player) { + this.player = player; + } + + public Player getPlayer() { + return this.player; + } + + public void cancel(String msg) { + this.cancelled = true; + this.message = msg; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + public String getMessage() { + return this.message; + } + + public void setMessage(String message) { + this.message = message; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleCreateEvent.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleCreateEvent.java new file mode 100644 index 0000000..f883e96 --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleCreateEvent.java @@ -0,0 +1,29 @@ +package com.j0ach1mmall3.wastedvehicles.api.events; + +import com.j0ach1mmall3.wastedvehicles.api.vehicles.WastedVehicle; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +public final class VehicleCreateEvent extends VehicleEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final Player player; + + public VehicleCreateEvent(WastedVehicle vehicle, Player player) { + super(vehicle); + this.player = player; + } + + public Player getPlayer() { + return this.player; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleDamageEvent.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleDamageEvent.java new file mode 100644 index 0000000..f38cfc2 --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleDamageEvent.java @@ -0,0 +1,46 @@ +package com.j0ach1mmall3.wastedvehicles.api.events; + +import com.j0ach1mmall3.wastedvehicles.api.vehicles.WastedVehicle; +import org.bukkit.entity.ArmorStand; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.EntityDamageEvent; + +public final class VehicleDamageEvent extends VehicleEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final ArmorStand armorStand; + private final EntityDamageEvent.DamageCause cause; + private double damage; + + public VehicleDamageEvent(WastedVehicle vehicle, ArmorStand armorStand, EntityDamageEvent.DamageCause cause, double damage) { + super(vehicle); + this.armorStand = armorStand; + this.cause = cause; + this.damage = damage; + } + + public ArmorStand getArmorStand() { + return this.armorStand; + } + + public EntityDamageEvent.DamageCause getCause() { + return this.cause; + } + + public double getDamage() { + return this.damage; + } + + public void setDamage(double damage) { + this.damage = damage; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleDestroyEvent.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleDestroyEvent.java new file mode 100644 index 0000000..9155e7e --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleDestroyEvent.java @@ -0,0 +1,29 @@ +package com.j0ach1mmall3.wastedvehicles.api.events; + +import com.j0ach1mmall3.wastedvehicles.api.vehicles.WastedVehicle; +import org.bukkit.entity.ArmorStand; +import org.bukkit.event.HandlerList; + +public final class VehicleDestroyEvent extends VehicleEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final ArmorStand armorStand; + + public VehicleDestroyEvent(WastedVehicle vehicle, ArmorStand armorStand) { + super(vehicle); + this.armorStand = armorStand; + } + + public ArmorStand getArmorStand() { + return this.armorStand; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleEnterEvent.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleEnterEvent.java new file mode 100644 index 0000000..0806c7b --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleEnterEvent.java @@ -0,0 +1,36 @@ +package com.j0ach1mmall3.wastedvehicles.api.events; + +import com.j0ach1mmall3.wastedvehicles.api.vehicles.WastedVehicle; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +public final class VehicleEnterEvent extends VehicleEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final Player player; + private final ArmorStand armorStand; + + public VehicleEnterEvent(WastedVehicle vehicle, Player player, ArmorStand armorStand) { + super(vehicle); + this.player = player; + this.armorStand = armorStand; + } + + public Player getPlayer() { + return this.player; + } + + public ArmorStand getArmorStand() { + return this.armorStand; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleEvent.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleEvent.java new file mode 100644 index 0000000..c156197 --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleEvent.java @@ -0,0 +1,28 @@ +package com.j0ach1mmall3.wastedvehicles.api.events; + +import com.j0ach1mmall3.wastedvehicles.api.vehicles.WastedVehicle; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; + +public abstract class VehicleEvent extends Event implements Cancellable { + private final WastedVehicle vehicle; + private boolean cancelled; + + protected VehicleEvent(WastedVehicle vehicle) { + this.vehicle = vehicle; + } + + public WastedVehicle getVehicle() { + return this.vehicle; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } +} diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleIgniteEvent.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleIgniteEvent.java new file mode 100644 index 0000000..2e806a3 --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleIgniteEvent.java @@ -0,0 +1,29 @@ +package com.j0ach1mmall3.wastedvehicles.api.events; + +import com.j0ach1mmall3.wastedvehicles.api.vehicles.WastedVehicle; +import org.bukkit.entity.ArmorStand; +import org.bukkit.event.HandlerList; + +public final class VehicleIgniteEvent extends VehicleEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final ArmorStand armorStand; + + public VehicleIgniteEvent(WastedVehicle vehicle, ArmorStand armorStand) { + super(vehicle); + this.armorStand = armorStand; + } + + public ArmorStand getArmorStand() { + return this.armorStand; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleImpactEntityEvent.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleImpactEntityEvent.java new file mode 100644 index 0000000..7eb0d23 --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleImpactEntityEvent.java @@ -0,0 +1,49 @@ +package com.j0ach1mmall3.wastedvehicles.api.events; + +import com.j0ach1mmall3.wastedvehicles.api.vehicles.WastedVehicle; +import com.j0ach1mmall3.wastedvehicles.util.SteerDirection; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +public class VehicleImpactEntityEvent extends VehicleEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + private final Player driver; + private final LivingEntity impactedEntity; + private final ArmorStand armorStand; + private final SteerDirection steerDirection; + + public VehicleImpactEntityEvent(WastedVehicle vehicle, Player driver, LivingEntity impactedEntity, ArmorStand armorStand, SteerDirection steerDirection) { + super(vehicle); + this.impactedEntity = impactedEntity; + this.driver = driver; + this.armorStand = armorStand; + this.steerDirection = steerDirection; + } + + public Player getDriver() { + return this.driver; + } + + public LivingEntity getImpactedEntity() { + return this.impactedEntity; + } + + public ArmorStand getArmorStand() { + return this.armorStand; + } + + public SteerDirection getSteerDirection() { + return this.steerDirection; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleImpactVehicleEvent.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleImpactVehicleEvent.java new file mode 100644 index 0000000..0e2159d --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleImpactVehicleEvent.java @@ -0,0 +1,60 @@ +package com.j0ach1mmall3.wastedvehicles.api.events; + +import com.j0ach1mmall3.wastedvehicles.api.vehicles.WastedVehicle; +import com.j0ach1mmall3.wastedvehicles.util.SteerDirection; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +public class VehicleImpactVehicleEvent extends VehicleEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + private final Player driver; + private final WastedVehicle collidedWith; + private final Player collidedWithDriver; + private final ArmorStand armorStand; + private final SteerDirection steerDirection; + private final ArmorStand collidedStand; + + public VehicleImpactVehicleEvent(WastedVehicle vehicle, Player driver, WastedVehicle collidedWith, Player collidedWithDriver, ArmorStand armorStand, ArmorStand collidedStand, SteerDirection steerDirection) { + super(vehicle); + this.driver = driver; + this.collidedWith = collidedWith; + this.collidedWithDriver = collidedWithDriver; + this.armorStand = armorStand; + this.steerDirection = steerDirection; + this.collidedStand = collidedStand; + } + + public Player getDriver() { + return this.driver; + } + + public WastedVehicle getCollidedWith() { + return this.collidedWith; + } + + public Player getCollidedWithDriver() { + return this.collidedWithDriver; + } + + public ArmorStand getArmorStand() { + return this.armorStand; + } + + public SteerDirection getSteerDirection() { + return this.steerDirection; + } + + public ArmorStand getCollidedStand() { + return this.collidedStand; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleLeaveEvent.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleLeaveEvent.java new file mode 100644 index 0000000..062a4a1 --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleLeaveEvent.java @@ -0,0 +1,36 @@ +package com.j0ach1mmall3.wastedvehicles.api.events; + +import com.j0ach1mmall3.wastedvehicles.api.vehicles.WastedVehicle; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +public final class VehicleLeaveEvent extends VehicleEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final Player player; + private final ArmorStand armorStand; + + public VehicleLeaveEvent(WastedVehicle vehicle, Player player, ArmorStand armorStand) { + super(vehicle); + this.player = player; + this.armorStand = armorStand; + } + + public Player getPlayer() { + return this.player; + } + + public ArmorStand getArmorStand() { + return this.armorStand; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehiclePassengerEnterEvent.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehiclePassengerEnterEvent.java new file mode 100644 index 0000000..0b4ad44 --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehiclePassengerEnterEvent.java @@ -0,0 +1,36 @@ +package com.j0ach1mmall3.wastedvehicles.api.events; + +import com.j0ach1mmall3.wastedvehicles.api.vehicles.WastedVehicle; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +public class VehiclePassengerEnterEvent extends VehicleEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final Player player; + private final ArmorStand armorStand; + + public VehiclePassengerEnterEvent(WastedVehicle vehicle, Player player, ArmorStand armorStand) { + super(vehicle); + this.player = player; + this.armorStand = armorStand; + } + + public Player getPlayer() { + return this.player; + } + + public ArmorStand getArmorStand() { + return this.armorStand; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleShootEvent.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleShootEvent.java new file mode 100644 index 0000000..eb958bb --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleShootEvent.java @@ -0,0 +1,42 @@ +package com.j0ach1mmall3.wastedvehicles.api.events; + +import com.j0ach1mmall3.wastedvehicles.api.vehicles.WastedVehicle; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Created by Timothy Lampen on 1/4/2018. + */ +public class VehicleShootEvent extends VehicleEvent implements Cancellable{ + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final ArmorStand armorStand; + private final Player shooter; + + + public VehicleShootEvent(WastedVehicle vehicle, ArmorStand armorStand, Player shooter) { + super(vehicle); + this.armorStand = armorStand; + this.shooter = shooter; + } + + public Player getShooter() { + return shooter; + } + + + public ArmorStand getArmorStand() { + return this.armorStand; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleSpeedBoostEvent.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleSpeedBoostEvent.java new file mode 100644 index 0000000..2684457 --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/events/VehicleSpeedBoostEvent.java @@ -0,0 +1,47 @@ +package com.j0ach1mmall3.wastedvehicles.api.events; + +import com.j0ach1mmall3.wastedvehicles.api.SpeedBoost; +import com.j0ach1mmall3.wastedvehicles.api.vehicles.WastedVehicle; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +public final class VehicleSpeedBoostEvent extends VehicleEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final Player player; + private final ArmorStand armorStand; + private SpeedBoost speedBoost; + + public VehicleSpeedBoostEvent(WastedVehicle vehicle, Player player, ArmorStand armorStand, SpeedBoost speedBoost) { + super(vehicle); + this.player = player; + this.armorStand = armorStand; + this.speedBoost = speedBoost; + } + + public Player getPlayer() { + return this.player; + } + + public ArmorStand getArmorStand() { + return this.armorStand; + } + + public SpeedBoost getSpeedBoost() { + return this.speedBoost; + } + + public void setSpeedBoost(SpeedBoost speedBoost) { + this.speedBoost = speedBoost; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/vehicles/Boat.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/vehicles/Boat.java new file mode 100644 index 0000000..591cfe9 --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/vehicles/Boat.java @@ -0,0 +1,62 @@ +package com.j0ach1mmall3.wastedvehicles.api.vehicles; + +import com.j0ach1mmall3.wastedvehicles.Main; +import com.j0ach1mmall3.wastedvehicles.api.VehicleProperties; +import com.j0ach1mmall3.wastedvehicles.util.SteerDirection; +import com.j0ach1mmall3.wastedvehicles.util.VehicleUtils; +import org.bukkit.Material; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import java.util.List; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 2/07/2016 + */ +public final class Boat extends WastedVehicle { + public Boat(Main plugin, VehicleProperties vehicleProperties) { + super(plugin, vehicleProperties); + } + + @Override + public void onSteer(ArmorStand armorStand, Player player, SteerDirection steerDirection) { + Material material = armorStand.getLocation().add(0, this.vehicleProperties.getBoundingBoxHeight(), 0).getBlock().getType(); + + if(material == Material.WATER || material == Material.STATIONARY_WATER) { + double boost = this.speedBoosts.isEmpty() ? 1 : this.speedBoosts.get(0); + + if(steerDirection.isLeft()) VehicleUtils.setYaw(armorStand, armorStand.getLocation().getYaw() - (float) this.vehicleProperties.getRotationSpeed()); + if(steerDirection.isRight()) VehicleUtils.setYaw(armorStand, armorStand.getLocation().getYaw() + (float) this.vehicleProperties.getRotationSpeed()); + if(steerDirection.isForward() && this.speed < this.vehicleProperties.getMaxSpeed()) this.speed += this.vehicleProperties.getAcceleration() * boost; + if(steerDirection.isBackward() && this.speed > -this.vehicleProperties.getMaxSpeed() / 2) this.speed -= this.vehicleProperties.getAcceleration() * boost / 2; + + VehicleUtils.makeJumping(armorStand); + armorStand.setVelocity(armorStand.getEyeLocation().getDirection().multiply(this.speed * boost).setY(0.05)); + } + } + + @Override + public void onTick(ArmorStand armorStand) { + Material material = armorStand.getLocation().add(0, this.vehicleProperties.getBoundingBoxHeight(), 0).getBlock().getType(); + if(material == Material.AIR) armorStand.setVelocity(new Vector(0, -0.5, 0)); + else { + if(this.speed > 0 && this.speed - this.vehicleProperties.getDeceleration() > 0) this.speed -= this.vehicleProperties.getDeceleration(); + if(this.speed < 0 && this.speed + this.vehicleProperties.getDeceleration() < 0) this.speed += this.vehicleProperties.getDeceleration(); + + double boost = this.speedBoosts.isEmpty() ? 1 : this.speedBoosts.get(0); + armorStand.setVelocity(armorStand.getEyeLocation().getDirection().multiply(this.speed * boost).setY(0)); + } + } + + @Override + public Vector getWeaponDirection(ArmorStand armorStand, Player player) { + return armorStand.getEyeLocation().getDirection().setY(0); + } + + @Override + public List<ArmorStand> getPassengers() { + return this.passengers; + } +} diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/vehicles/Car.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/vehicles/Car.java new file mode 100644 index 0000000..bbc28cf --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/vehicles/Car.java @@ -0,0 +1,64 @@ +package com.j0ach1mmall3.wastedvehicles.api.vehicles; + +import com.j0ach1mmall3.wastedvehicles.Main; +import com.j0ach1mmall3.wastedvehicles.api.VehicleProperties; +import com.j0ach1mmall3.wastedvehicles.util.SteerDirection; +import com.j0ach1mmall3.wastedvehicles.util.VehicleUtils; +import org.bukkit.Material; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import java.util.List; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 17/05/2016 + */ +public final class Car extends WastedVehicle { + public Car(Main plugin, VehicleProperties vehicleProperties) { + super(plugin, vehicleProperties); + } + + @Override + public void onSteer(ArmorStand armorStand, Player player, SteerDirection steerDirection) { + double boost = this.speedBoosts.isEmpty() ? 1 : this.speedBoosts.get(0); + if(steerDirection.isLeft()) VehicleUtils.setYaw(armorStand, armorStand.getEyeLocation().getYaw() - (float) this.vehicleProperties.getRotationSpeed()); + if(steerDirection.isRight()) VehicleUtils.setYaw(armorStand, armorStand.getEyeLocation().getYaw() + (float) this.vehicleProperties.getRotationSpeed()); + if(steerDirection.isForward() && this.speed < this.vehicleProperties.getMaxSpeed()) this.speed += this.vehicleProperties.getAcceleration() * boost; + if(steerDirection.isBackward() && this.speed > -this.vehicleProperties.getMaxSpeed() / 2) this.speed -= this.vehicleProperties.getAcceleration() * boost / 2; + + VehicleUtils.makeJumping(armorStand); + + for(ArmorStand passenger : this.passengers) { + VehicleUtils.makeJumping(passenger); + } + } + + @Override + public void onTick(ArmorStand armorStand) { + if(armorStand.hasMetadata("WastedVehiclePassenger")) return; + armorStand.setFireTicks(0); + if(this.speed > 0 && this.speed - this.vehicleProperties.getDeceleration() > 0) this.speed -= this.vehicleProperties.getDeceleration(); + if(this.speed < 0 && this.speed + this.vehicleProperties.getDeceleration() < 0) this.speed += this.vehicleProperties.getDeceleration(); + + double boost = this.speedBoosts.isEmpty() ? 1 : this.speedBoosts.get(0); + armorStand.setVelocity(armorStand.getEyeLocation().getDirection().multiply(this.speed * boost).setY(MINECRAFT_GRAVITY)); + this.passengers.forEach(passenger -> { + VehicleUtils.teleport(passenger, armorStand.getLocation().add(0.75, -0.20, 0)); + passenger.setFireTicks(0); + VehicleUtils.setYaw(passenger, armorStand.getEyeLocation().getYaw()); + }); + if(armorStand.getLocation().getBlock().getType() == Material.WATER || armorStand.getLocation().getBlock().getType() == Material.STATIONARY_WATER) this.explode(armorStand); + } + + @Override + public Vector getWeaponDirection(ArmorStand armorStand, Player player) { + return armorStand.getEyeLocation().getDirection().setY(0); + } + + @Override + public List<ArmorStand> getPassengers() { + return this.passengers; + } +} \ No newline at end of file diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/vehicles/Helicopter.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/vehicles/Helicopter.java new file mode 100644 index 0000000..b4c6dc8 --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/vehicles/Helicopter.java @@ -0,0 +1,45 @@ +package com.j0ach1mmall3.wastedvehicles.api.vehicles; + +import com.j0ach1mmall3.wastedvehicles.Main; +import com.j0ach1mmall3.wastedvehicles.api.VehicleProperties; +import com.j0ach1mmall3.wastedvehicles.util.SteerDirection; +import com.j0ach1mmall3.wastedvehicles.util.VehicleUtils; +import org.bukkit.Material; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import java.util.List; + +public final class Helicopter extends WastedVehicle { + public Helicopter(Main plugin, VehicleProperties vehicleProperties) { + super(plugin, vehicleProperties); + } + + @Override + public void onSteer(ArmorStand armorStand, Player player, SteerDirection steerDirection) { + double boost = this.speedBoosts.isEmpty() ? 1 : this.speedBoosts.get(0); + + VehicleUtils.setYaw(armorStand, player.getEyeLocation().getYaw()); + + Vector velocity = new Vector(0, 0, 0); + if(steerDirection.getForMotion() != 0.0) velocity.add(player.getEyeLocation().getDirection().setY(0).multiply(steerDirection.getForMotion()).multiply(this.speed * boost)); + if(steerDirection.getSideMotion() != 0.0) velocity.setY(-0.5 * steerDirection.getSideMotion()); + armorStand.setVelocity(velocity); + } + + @Override + public void onTick(ArmorStand armorStand) { + if(armorStand.getLocation().getBlock().getType() == Material.WATER || armorStand.getLocation().getBlock().getType() == Material.STATIONARY_WATER) this.explode(armorStand); + } + + @Override + public Vector getWeaponDirection(ArmorStand armorStand, Player player) { + return armorStand.getEyeLocation().getDirection().setY(-Math.PI / 4); + } + + @Override + public List<ArmorStand> getPassengers() { + return this.passengers; + } +} diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/vehicles/Plane.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/vehicles/Plane.java new file mode 100644 index 0000000..8c8228a --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/vehicles/Plane.java @@ -0,0 +1,62 @@ +package com.j0ach1mmall3.wastedvehicles.api.vehicles; + +import com.j0ach1mmall3.wastedvehicles.Main; +import com.j0ach1mmall3.wastedvehicles.api.VehicleProperties; +import com.j0ach1mmall3.wastedvehicles.util.SteerDirection; +import com.j0ach1mmall3.wastedvehicles.util.VehicleUtils; +import org.bukkit.Material; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; +import org.bukkit.util.EulerAngle; +import org.bukkit.util.Vector; + +import java.util.List; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 17/05/2016 + */ +public final class Plane extends WastedVehicle { + public Plane(Main plugin, VehicleProperties vehicleProperties) { + super(plugin, vehicleProperties); + } + + @Override + public void onSteer(ArmorStand armorStand, Player player, SteerDirection steerDirection) { + double boost = this.speedBoosts.isEmpty() ? 1 : this.speedBoosts.get(0); + + VehicleUtils.setYaw(armorStand, player.getEyeLocation().getYaw()); + VehicleUtils.setPitch(armorStand, player.getEyeLocation().getPitch()); + armorStand.setHeadPose(new EulerAngle(Math.toRadians(player.getEyeLocation().getPitch()), 0, 0)); + + if(steerDirection.isForward() && this.speed < this.vehicleProperties.getMaxSpeed()) this.speed += this.vehicleProperties.getAcceleration() * boost; + if(steerDirection.isBackward() && this.speed > -this.vehicleProperties.getMaxSpeed() / 2) this.speed -= this.vehicleProperties.getAcceleration() * boost / 2; + + VehicleUtils.makeJumping(armorStand); + } + + @Override + public void onTick(ArmorStand armorStand) { + if(armorStand.getPassenger() == null) { + if(this.speed > 0 && this.speed - this.vehicleProperties.getDeceleration() > 0) this.speed -= this.vehicleProperties.getDeceleration(); + if(this.speed < 0 && this.speed + this.vehicleProperties.getDeceleration() < 0) this.speed += this.vehicleProperties.getDeceleration(); + } + + double boost = this.speedBoosts.isEmpty() ? 1 : this.speedBoosts.get(0); + Vector direction = armorStand.getEyeLocation().getDirection(); + if(this.speed < this.vehicleProperties.getTakeOffSpeed() && this.speed > -this.vehicleProperties.getTakeOffSpeed()) armorStand.setVelocity(direction.multiply(this.speed * boost).setY(4 * MINECRAFT_GRAVITY)); + else armorStand.setVelocity(direction.multiply(this.speed * boost)); + armorStand.setVelocity(direction.multiply(this.speed * boost)); + if(armorStand.getLocation().getBlock().getType() == Material.WATER || armorStand.getLocation().getBlock().getType() == Material.STATIONARY_WATER) this.explode(armorStand); + } + + @Override + public Vector getWeaponDirection(ArmorStand armorStand, Player player) { + return player.getEyeLocation().getDirection(); + } + + @Override + public List<ArmorStand> getPassengers() { + return this.passengers; + } +} \ No newline at end of file diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/vehicles/Submarine.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/vehicles/Submarine.java new file mode 100644 index 0000000..839a6f9 --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/vehicles/Submarine.java @@ -0,0 +1,56 @@ +package com.j0ach1mmall3.wastedvehicles.api.vehicles; + +import com.j0ach1mmall3.wastedvehicles.Main; +import com.j0ach1mmall3.wastedvehicles.api.VehicleProperties; +import com.j0ach1mmall3.wastedvehicles.util.SteerDirection; +import com.j0ach1mmall3.wastedvehicles.util.VehicleUtils; +import org.bukkit.Material; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import java.util.List; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 2/07/2016 + */ +public final class Submarine extends WastedVehicle { + public Submarine(Main plugin, VehicleProperties vehicleProperties) { + super(plugin, vehicleProperties); + } + + @Override + public void onSteer(ArmorStand armorStand, Player player, SteerDirection steerDirection) { + Material material = armorStand.getLocation().getBlock().getType(); + Material material2 = player.getEyeLocation().getBlock().getType(); + if((material == Material.WATER || material == Material.STATIONARY_WATER) && (material2 == Material.WATER || material2 == Material.STATIONARY_WATER)) { + player.setRemainingAir(player.getMaximumAir()); + + double boost = this.speedBoosts.isEmpty() ? 1 : this.speedBoosts.get(0); + + VehicleUtils.setYaw(armorStand, player.getEyeLocation().getYaw()); + + Vector velocity = new Vector(0, 0, 0); + if(steerDirection.getForMotion() != 0.0) velocity.add(player.getEyeLocation().getDirection().setY(0).multiply(steerDirection.getForMotion()).multiply(this.speed * boost)); + if(steerDirection.getSideMotion() != 0.0) velocity.setY(-0.5 * steerDirection.getSideMotion()); + armorStand.setVelocity(velocity); + } + } + + @Override + public void onTick(ArmorStand armorStand) { + Material material = armorStand.getLocation().getBlock().getType(); + if(armorStand.getPassenger() == null && (material == Material.WATER || material == Material.STATIONARY_WATER)) armorStand.setVelocity(new Vector(0, 0, 0)); + } + + @Override + public Vector getWeaponDirection(ArmorStand armorStand, Player player) { + return armorStand.getEyeLocation().getDirection().setY(-Math.PI / 4); + } + + @Override + public List<ArmorStand> getPassengers() { + return this.passengers; + } +} diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/vehicles/WastedVehicle.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/vehicles/WastedVehicle.java new file mode 100644 index 0000000..8e2955a --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/api/vehicles/WastedVehicle.java @@ -0,0 +1,396 @@ +package com.j0ach1mmall3.wastedvehicles.api.vehicles; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Projectile; +import org.bukkit.entity.SmallFireball; +import org.bukkit.entity.TNTPrimed; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +import com.j0ach1mmall3.jlib.methods.Parsing; +import com.j0ach1mmall3.jlib.methods.ReflectionAPI; +import com.j0ach1mmall3.wastedvehicles.Main; +import com.j0ach1mmall3.wastedvehicles.api.SpeedBoost; +import com.j0ach1mmall3.wastedvehicles.api.VehicleProperties; +import com.j0ach1mmall3.wastedvehicles.api.events.VehicleDestroyEvent; +import com.j0ach1mmall3.wastedvehicles.api.events.VehicleIgniteEvent; +import com.j0ach1mmall3.wastedvehicles.api.events.VehiclePassengerEnterEvent; +import com.j0ach1mmall3.wastedvehicles.util.MiscUtil; +import com.j0ach1mmall3.wastedvehicles.util.SteerDirection; + +import net.grandtheftmc.core.Lang; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 17/05/2016 + */ +public abstract class WastedVehicle { + public static final double MINECRAFT_GRAVITY = -0.9; + + protected final Main plugin; + protected final VehicleProperties vehicleProperties; + protected final List<Double> speedBoosts = new ArrayList<>(); + protected ArmorStand driver; + protected double speed; + protected boolean cooldown; + protected boolean tick = true; + protected int displayBlock; + protected UUID creator; + protected List<ArmorStand> passengers = new ArrayList<>(); + + protected WastedVehicle(Main plugin, VehicleProperties vehicleProperties) { + this.plugin = plugin; + this.vehicleProperties = vehicleProperties; + } + + public final VehicleProperties getVehicleProperties() { + return this.vehicleProperties; + } + + public final double getSpeed() { + return this.speed; + } + + public final void setSpeed(double speed) { + this.speed = speed; + } + + public final boolean isCooldown() { + return this.cooldown; + } + + public final void setCooldown(boolean cooldown) { + this.cooldown = cooldown; + } + + public final boolean isTick() { + return this.tick; + } + + public final void setTick(boolean tick) { + this.tick = tick; + } + + public final UUID getCreator() { + return this.creator; + } + + public final void setCreator(UUID creator) { + this.creator = creator; + } + + public final ItemStack getNextDisplayBlock() { + if(this.displayBlock >= this.vehicleProperties.getDisplayBlocks().size()) this.displayBlock = 0; + return Parsing.parseItemStack(this.vehicleProperties.getDisplayBlocks().get(this.displayBlock++)); + } + + public void shootWeapon(Player player){ + double speed, blocksAhead; + switch (getVehicleProperties().getIdentifier().toLowerCase()) { + case "hydra": + speed = 15; + blocksAhead = 20; + case "rhino": + speed = 3; + blocksAhead =4; + Vector vector = this.driver.getEyeLocation().clone().getDirection().setY(-.03); + + + Projectile projectile = this.driver.getEyeLocation().clone().add(0,1,0).getWorld().spawn(this.driver.getEyeLocation().clone().add(0,1,0).add(this.driver.getEyeLocation().getDirection().clone().setY(0).normalize().multiply(blocksAhead)), SmallFireball.class); + projectile.setVelocity(vector.multiply(speed)); + projectile.setShooter(player); + projectile.setInvulnerable(true); + ((SmallFireball)projectile).setIsIncendiary(false); + + + + new BukkitRunnable() { + @Override + public void run() { + if(projectile.isDead() || !projectile.isValid() || projectile.getLocation().distance(player.getLocation())>200) { + this.cancel(); + return; + } + + if(projectile.getWorld() != player.getWorld()){ + this.cancel(); + return; + } + + Optional<Entity> nearestTarget = projectile.getNearbyEntities(1, 1, 1).stream().filter(entity -> entity instanceof LivingEntity).findFirst(); + if((nearestTarget.isPresent() && nearestTarget.get() != player && nearestTarget.get() != driver) || MiscUtil.getMiscUtil().getBlocksInRadius(projectile.getLocation(), 2).stream().anyMatch(block -> block.getType()!= Material.AIR)) { + TNTPrimed entity = (TNTPrimed) projectile.getWorld().spawnEntity(projectile.getLocation(), EntityType.PRIMED_TNT); + entity.setCustomName("EXPLOSIVE"); + entity.setCustomNameVisible(false); + entity.setFuseTicks(1); + projectile.getWorld().spigot().playEffect(projectile.getLocation(), Effect.EXPLOSION_HUGE, 0, 0, 0, 0, 0, 0.01F, 1, 50); + projectile.getWorld().playSound(projectile.getLocation(), Sound.ENTITY_GENERIC_EXPLODE, 5.0F, 5.0F); + this.cancel(); + } + } + }.runTaskTimer(plugin, 0, 1); + break; + } + } + + public final void onSpeedBoost(SpeedBoost speedBoost) { + this.speedBoosts.add(speedBoost.getSpeedBoost()); + Bukkit.getScheduler().scheduleSyncDelayedTask(this.plugin, () -> this.speedBoosts.remove(0), speedBoost.getDuration()); + } + + public final void onCreate(ArmorStand armorStand, Player player, Location l, double health) { + this.driver = armorStand; + armorStand.setVisible(false); + armorStand.setArms(false); + armorStand.setRemoveWhenFarAway(true); + armorStand.setCanPickupItems(false); + armorStand.setBasePlate(false); + armorStand.setMaxHealth(this.vehicleProperties.getMaxHealth()); + armorStand.setHealth(health); + armorStand.setHelmet(this.getNextDisplayBlock()); + armorStand.setCustomNameVisible(true); + this.updateName(armorStand, null); + + for(int i = 0; i < this.vehicleProperties.getPassengers(); i++) { + ArmorStand passenger = (ArmorStand)armorStand.getWorld().spawnEntity(l.add(1, 0, 0), EntityType.ARMOR_STAND); + passenger.setVisible(false); + passenger.setArms(false); + passenger.setRemoveWhenFarAway(true); + passenger.setCanPickupItems(false); + passenger.setBasePlate(false); + passenger.setGravity(false); + passenger.setMaxHealth(this.vehicleProperties.getMaxHealth()); + passenger.setHealth(health); + passenger.setMetadata("WastedVehiclePassenger", new FixedMetadataValue(this.plugin, this)); + passenger.setCollidable(true); + this.passengers.add(passenger); + try { + Object handle = ReflectionAPI.getHandle((Object) passenger); + handle.getClass().getMethod("setSize", float.class, float.class).invoke(handle, this.vehicleProperties.getBoundingBoxWidth(), this.vehicleProperties.getBoundingBoxHeight()); + } catch (Exception e) { + e.printStackTrace(); + } + } + + try { + Object handle = ReflectionAPI.getHandle((Object) armorStand); + handle.getClass().getMethod("setSize", float.class, float.class).invoke(handle, this.vehicleProperties.getBoundingBoxWidth(), this.vehicleProperties.getBoundingBoxHeight()); + } catch (Exception e) { + e.printStackTrace(); + } + + armorStand.teleport(l); + armorStand.setMetadata("WastedVehicle", new FixedMetadataValue(this.plugin, this)); + this.creator = player.getUniqueId(); + } + + public final void onDestroy(ArmorStand armorStand) { + VehicleDestroyEvent event = new VehicleDestroyEvent(this, armorStand); + Bukkit.getPluginManager().callEvent(event); + if(!event.isCancelled()) { + this.onDismount(armorStand); + this.plugin.getEntityQueue().remove(armorStand); + armorStand.setHelmet(null); + armorStand.remove(); + this.passengers.forEach(passenger -> { + if(passenger.getPassenger() != null) passenger.eject(); + passenger.setHealth(0); + passenger.remove(); + }); + } + } + + public final void passengerMount(ArmorStand armorStand, Player player) { + if(armorStand.getHealth() <= 1) return; + if(!armorStand.hasMetadata("WastedVehiclePassenger")) return; + WastedVehicle wastedVehicle = (WastedVehicle)armorStand.getMetadata("WastedVehiclePassenger").get(0).value(); + VehiclePassengerEnterEvent enterEvent = new VehiclePassengerEnterEvent(wastedVehicle, player, armorStand); + Bukkit.getPluginManager().callEvent(enterEvent); + if(enterEvent.isCancelled()) return; + if(armorStand.getPassenger() == null) { + if(wastedVehicle.getDriver().getPassenger() == null) { + if(Objects.equals(wastedVehicle.getCreator().toString(), player.getUniqueId().toString())) { + wastedVehicle.onRightClick(wastedVehicle.getDriver(), player); + return; + } + } + if(this.vehicleProperties.isInvisible()) { + Bukkit.getOnlinePlayers().forEach(p -> p.hidePlayer(player)); + player.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, Integer.MAX_VALUE, 0, true, false)); + } + armorStand.setPassenger(player); + player.sendMessage(Lang.VEHICLES.f("&7You entered the passenger seat of a Vehicle")); + } else { + if(this.passengers.stream().noneMatch(passenger -> passenger.getPassenger() == null)) { + player.sendMessage(Lang.VEHICLES.f("&7No seats left!")); + return; + } + this.passengers.forEach(passenger -> { + if(passenger.getPassenger() == null) { + passenger.setPassenger(player); + Bukkit.getOnlinePlayers().forEach(p -> p.hidePlayer(player)); + player.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, Integer.MAX_VALUE, 0, true, false)); + player.sendMessage(Lang.VEHICLES.f("&7You entered the passenger seat of a Vehicle")); + return; + } + }); + } + } + + public final void onRightClick(ArmorStand armorStand, Player player) { + if(armorStand.getHealth() <= 1) return; + if(armorStand.hasMetadata("WastedVehiclePassenger")) return; + if(armorStand.getPassenger() == null) { + Location l = armorStand.getLocation(); + l.setYaw(player.getEyeLocation().getYaw()); + l.setPitch(0); + armorStand.teleport(l); + if(this.vehicleProperties.isInvisible()) { + Bukkit.getOnlinePlayers().forEach(p -> p.hidePlayer(player)); + player.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, Integer.MAX_VALUE, 0, true, false)); + } + armorStand.setPassenger(player); + this.updateName(armorStand, player); + this.speed = this.vehicleProperties.getDefaultSpeed(); + } + } + + public final void onDismount(ArmorStand armorStand) { + Player player = (Player) armorStand.getPassenger(); + if(player != null) { +// armorStand.eject(); + Bukkit.getOnlinePlayers().forEach(p -> p.showPlayer(player)); + player.removePotionEffect(PotionEffectType.INVISIBILITY); +// player.teleport(armorStand.getLocation().add(0, 1, 0)); + } + if(!armorStand.hasMetadata("WastedVehiclePassenger")) this.updateName(armorStand, null); + } + + public final void onDamage(ArmorStand armorStand, EntityDamageEvent.DamageCause damageCause, double damage) { + if(armorStand.hasMetadata("WastedVehiclePassenger")) return; + if(armorStand.getHealth() <= 1) return; + + switch (damageCause) { + case FALL: + case SUFFOCATION: + case DROWNING: + return; + case ENTITY_EXPLOSION: + case BLOCK_EXPLOSION: + if(!this.vehicleProperties.isExplode()) break; + armorStand.setHealth(1); + this.explode(armorStand); + return; + case CONTACT: + armorStand.setHealth(damage); + return; + } + + if(armorStand.getHealth() - damage > 1) armorStand.setHealth(armorStand.getHealth() - damage); + else armorStand.setHealth(1); + this.updateName(armorStand, (Player) armorStand.getPassenger()); + if(armorStand.getHealth() <= 1) { + if(this.vehicleProperties.isExplode()) { + VehicleIgniteEvent event = new VehicleIgniteEvent(this, armorStand); + Bukkit.getPluginManager().callEvent(event); + if(!event.isCancelled()) { + new BukkitRunnable() { + private int i; + @Override + public void run() { + if(this.i > 100) { + WastedVehicle.this.explode(armorStand); + this.cancel(); + } else { + this.i++; + armorStand.getWorld().spigot().playEffect(armorStand.getLocation().add(0, WastedVehicle.this.vehicleProperties.getBoundingBoxHeight() / 2, 0), Effect.FLAME, 0, 0, 0.5F, 0.5F, 0.5F, 0.001F, 20, 50); + } + } + }.runTaskTimer(this.plugin, 1, 1); + } + } else this.onDestroy(armorStand); + } + } + + public final void explode(ArmorStand armorStand) { + if(armorStand.hasMetadata("WastedVehiclePassenger")) return; + if(this.vehicleProperties.isExplode()) { + armorStand.getNearbyEntities(2.0, 2.0, 2.0).stream().filter(e -> e instanceof LivingEntity).map(e -> (LivingEntity) e).forEach(l -> { + + // TODO distance uses square root function, inefficient + double distance = l.getLocation().distance(armorStand.getLocation()); + + if (distance <= 0.2){ + // kill the entity + l.setHealth(0); + } + else{ + double newHealth = l.getHealth() - (20 / distance); + + // bounds check + if (newHealth >= l.getMaxHealth()){ + newHealth = l.getMaxHealth(); + } + if (newHealth <= 0){ + newHealth = 0; + } + + l.setHealth(newHealth); + } + }); + armorStand.getWorld().createExplosion(armorStand.getLocation(), 2, false); + if(armorStand.getPassenger() != null && armorStand.getPassenger().getType() == EntityType.PLAYER) { +// armorStand.getPassenger().eject(); + ((Player) armorStand.getPassenger()).setHealth(0); + } + } + this.onDestroy(armorStand); + } + + public final void updateName(ArmorStand armorStand, Player passenger) { + armorStand.setCustomName((passenger == null + ? + this.vehicleProperties.getItem().getItemMeta().getDisplayName() + : + ChatColor.GREEN.toString() + ChatColor.BOLD + passenger.getName()) + + + " (" + this.plugin.formatHealth(armorStand.getHealth(), this.vehicleProperties.getMaxHealth()) + ChatColor.GRAY + ')'); + } + + public ArmorStand getDriver() { + return this.driver; + } + + public abstract Vector getWeaponDirection(ArmorStand armorStand, Player player); + + public abstract void onSteer(ArmorStand armorStand, Player player, SteerDirection steerDirection); + + public abstract void onTick(ArmorStand armorStand); + + public abstract List<ArmorStand> getPassengers(); + + public void setPassengers(List<ArmorStand> passengers) { + this.passengers = passengers; + } +} diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/commands/FixVehiclesCommandHandler.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/commands/FixVehiclesCommandHandler.java new file mode 100644 index 0000000..c6ba4d5 --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/commands/FixVehiclesCommandHandler.java @@ -0,0 +1,63 @@ +package com.j0ach1mmall3.wastedvehicles.commands; + +import com.j0ach1mmall3.jlib.commands.CommandHandler; +import com.j0ach1mmall3.wastedvehicles.Main; +import com.j0ach1mmall3.wastedvehicles.api.vehicles.WastedVehicle; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; + +import java.util.Optional; + +/** + * Created by colt on 12/21/16. + */ +public class FixVehiclesCommandHandler extends CommandHandler<Main> { + public FixVehiclesCommandHandler(Main plugin) { + super(plugin); + } + + @Override + protected boolean handleCommand(CommandSender commandSender, String[] strings) { + if (!(commandSender instanceof Player)) { + commandSender.sendMessage("Players only!"); + return true; + } + Player sender = (Player) commandSender; + if(sender.getWorld().getName().equalsIgnoreCase("spawn")) { + sender.sendMessage("This cannot be used in spawn!"); + return true; + } + sender.getNearbyEntities(5, 5, 5).forEach(entity -> { + if (entity.getType() != EntityType.ARMOR_STAND) return; + ArmorStand armorStand = (ArmorStand) entity; + if(armorStand.hasMetadata("WastedVehiclePassenger")) return; + if (armorStand.hasMetadata("WastedVehicle")) { + if(armorStand.getPassenger() != null) return; + Optional<WastedVehicle> wastedVehicle = Optional.of((WastedVehicle) armorStand.getMetadata("WastedVehicle").get(0).value()); + if (wastedVehicle.isPresent()) { + wastedVehicle.get().onDestroy(armorStand); + } else { + armorStand.setHelmet(null); + armorStand.remove(); + } + } else if(armorStand.getHelmet() != null) { + armorStand.setHelmet(null); + armorStand.remove(); + } + }); + for(Entity entity : Bukkit.getWorld("minesantos").getEntities()) { + if(entity.getType() != EntityType.ARMOR_STAND) continue; + if(entity.hasMetadata("WastedVehicle") || entity.hasMetadata("WastedVehiclePassenger")) continue; + if(entity.getCustomName() == null || entity.getCustomName().isEmpty()) { + entity.remove(); + } + } + commandSender.sendMessage(ChatColor.GREEN + "Broken vehicle(s) cleared!"); + return true; + } +} diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/commands/GiveVehicleCommandHandler.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/commands/GiveVehicleCommandHandler.java new file mode 100644 index 0000000..9f0aed1 --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/commands/GiveVehicleCommandHandler.java @@ -0,0 +1,45 @@ +package com.j0ach1mmall3.wastedvehicles.commands; + +import com.j0ach1mmall3.jlib.commands.CommandHandler; +import com.j0ach1mmall3.jlib.methods.General; +import com.j0ach1mmall3.wastedvehicles.Main; +import com.j0ach1mmall3.wastedvehicles.api.VehicleProperties; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.Optional; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 27/06/2016 + */ +public final class GiveVehicleCommandHandler extends CommandHandler<Main> { + public GiveVehicleCommandHandler(Main plugin) { + super(plugin); + } + + @Override + protected boolean handleCommand(CommandSender commandSender, String[] strings) { + if(strings.length < 2) { + commandSender.sendMessage(ChatColor.RED + "Usage: /givevehicle <identifier> <player>"); + return true; + } + + Optional<VehicleProperties> vehicle = this.plugin.getBabies().getVehicleProperties().stream().filter(v -> v.getIdentifier().equalsIgnoreCase(strings[0])).findFirst(); + if(!vehicle.isPresent()) { + commandSender.sendMessage(ChatColor.RED + "Unknown vehicle " + strings[0]); + return true; + } + + Player p = General.getPlayerByName(strings[1], false); + if(p == null) { + commandSender.sendMessage(ChatColor.RED + "Unknown player " + strings[1]); + return true; + } + + p.getInventory().addItem(vehicle.get().getItem()); + commandSender.sendMessage(ChatColor.GREEN + "Successfully gave " + vehicle.get().getIdentifier() + " to " + p.getName()); + return true; + } +} diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/commands/WVReloadCommandHandler.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/commands/WVReloadCommandHandler.java new file mode 100644 index 0000000..b2f8b17 --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/commands/WVReloadCommandHandler.java @@ -0,0 +1,23 @@ +package com.j0ach1mmall3.wastedvehicles.commands; + +import com.j0ach1mmall3.jlib.commands.CommandHandler; +import com.j0ach1mmall3.wastedvehicles.Main; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 31/08/2016 + */ +public final class WVReloadCommandHandler extends CommandHandler<Main> { + public WVReloadCommandHandler(Main plugin) { + super(plugin); + } + + @Override + protected boolean handleCommand(CommandSender commandSender, String[] strings) { + this.plugin.reload(); + commandSender.sendMessage(ChatColor.GREEN + "Reloaded config!"); + return true; + } +} diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/config/Config.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/config/Config.java new file mode 100644 index 0000000..719fa33 --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/config/Config.java @@ -0,0 +1,100 @@ +package com.j0ach1mmall3.wastedvehicles.config; + +import com.j0ach1mmall3.jlib.storage.file.yaml.ConfigLoader; +import com.j0ach1mmall3.wastedvehicles.Main; +import com.j0ach1mmall3.wastedvehicles.api.SpeedBoost; +import com.j0ach1mmall3.wastedvehicles.api.VehicleProperties; +import com.j0ach1mmall3.wastedvehicles.api.VehicleType; +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 5/05/2016 + */ +public final class Config extends ConfigLoader<Main> { + private final ItemStack jetpackItem; + private final boolean jetpackFuelEnabled; + private final ItemStack jetpackFuelItem; + private final int jetpackFuelInterval; + private final List<String> jetpackAllowedWeapons; + private final List<VehicleProperties> vehicleProperties; + + public Config(Main plugin) { + super("config.yml", plugin); + this.jetpackItem = this.customConfig.getItemNew(this.config, "Jetpack.Item"); + this.jetpackFuelEnabled = this.config.getBoolean("Jetpack.Fuel.Enabled"); +// this.jetpackFuelItem = this.customConfig.getItemNew(this.config, "Jetpack.Fuel.Item"); + this.jetpackFuelItem = this.customConfig.getItemNew(this.config, "Jetpack.Fuel.Item"); + this.jetpackFuelInterval = this.config.getInt("Jetpack.Fuel.Interval"); + this.jetpackAllowedWeapons = this.config.getStringList("Jetpack.AllowedWeapons"); + this.vehicleProperties = this.loadVehicleProperties(); + } + + private List<VehicleProperties> loadVehicleProperties() { + List<VehicleProperties> vehicleProperties = new ArrayList<>(); + this.customConfig.getKeys("Vehicles").forEach(s -> vehicleProperties.add(new VehicleProperties( + s, + VehicleType.valueOf(this.config.getString("Vehicles." + s + ".VehicleType").toUpperCase()), + this.config.getDouble("Vehicles." + s + ".Acceleration"), + this.config.getDouble("Vehicles." + s + ".Deceleration"), + this.config.getDouble("Vehicles." + s + ".TakeOffSpeed"), + this.config.getDouble("Vehicles." + s + ".RotationSpeed"), + this.config.getBoolean("Vehicles." + s + ".Invisible"), + this.customConfig.getItemNew(this.config, "Vehicles." + s + ".Item"), + (float) this.config.getDouble("Vehicles." + s + ".BoundingBoxWidth"), + (float) this.config.getDouble("Vehicles." + s + ".BoundingBoxHeight"), + this.config.getDouble("Vehicles." + s + ".LaunchLocationMultiplier"), + this.config.getDouble("Vehicles." + s + ".LaunchLocationYOffset"), + this.config.getDouble("Vehicles." + s + ".MaxHealth"), + this.config.getBoolean("Vehicles." + s + ".Explode"), + this.config.getBoolean("Vehicles." + s + ".DamageVehicleOnPlayerHit"), + this.config.getInt("Vehicles." + s + ".KnockOutChance"), + this.config.getInt("Vehicles." + s + ".Passengers"), + this.loadSpeedBoosts("Vehicles." + s + ".SpeedBoosts"), + this.config.getDouble("Vehicles." + s + ".MaxSpeed"), + this.config.getDouble("Vehicles." + s + ".DefaultSpeed"), + this.config.getDouble("Vehicles." + s + ".CollisionDamage"), + this.config.getString("Vehicles." + s + ".WastedGunsWeapon"), + this.config.getStringList("Vehicles." + s + ".AllowedWeapons"), + this.config.getStringList("Vehicles." + s + ".AllowedBlocks"), + this.config.getStringList("Vehicles." + s + ".DisplayBlocks") + ) + )); + return vehicleProperties; + } + + private Set<SpeedBoost> loadSpeedBoosts(String path) { + Set<SpeedBoost> speedBoosts = new HashSet<>(); + this.customConfig.getKeys(path).forEach(s -> speedBoosts.add(new SpeedBoost(this.customConfig.getItemNew(this.config, path + ".Item"), this.config.getDouble(path + ".SpeedBoost"), this.config.getInt(path + ".Duration")))); + return speedBoosts; + } + + public ItemStack getJetpackItem() { + return this.jetpackItem; + } + + public boolean isJetpackFuelEnabled() { + return this.jetpackFuelEnabled; + } + + public ItemStack getJetpackFuelItem() { + return this.jetpackFuelItem; + } + + public int getJetpackFuelInterval() { + return this.jetpackFuelInterval; + } + + public List<String> getJetpackAllowedWeapons() { + return this.jetpackAllowedWeapons; + } + + public List<VehicleProperties> getVehicleProperties() { + return this.vehicleProperties; + } +} diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/listeners/JetpackListener.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/listeners/JetpackListener.java new file mode 100644 index 0000000..f6e3602 --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/listeners/JetpackListener.java @@ -0,0 +1,247 @@ +package com.j0ach1mmall3.wastedvehicles.listeners; + +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.Effect; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.PlayerToggleFlightEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitRunnable; + +import com.j0ach1mmall3.jlib.player.JLibPlayer; +import com.j0ach1mmall3.wastedguns.api.events.WeaponRightClickEvent; +import com.j0ach1mmall3.wastedvehicles.Main; +import com.j0ach1mmall3.wastedvehicles.api.events.FuelUseEvent; +import com.j0ach1mmall3.wastedvehicles.api.events.JetpackFlyEvent; + +import net.grandtheftmc.core.anticheat.check.CheatType; +import net.grandtheftmc.core.anticheat.event.MovementCheatEvent; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 5/05/2016 + */ +public final class JetpackListener implements Listener { + private final Main plugin; + private final Set<UUID> active = new HashSet<>(); + + public JetpackListener(Main plugin) { + this.plugin = plugin; + plugin.getServer().getPluginManager().registerEvents(this, plugin); + Bukkit.getScheduler().scheduleAsyncRepeatingTask(this.plugin, () -> { + Bukkit.getOnlinePlayers().stream() + .filter(p -> { + return p.isFlying() && p.getGameMode() != GameMode.CREATIVE && p.getInventory().getChestplate() != null && isJetpack(p.getInventory().getChestplate()); + }).forEach(p -> new JLibPlayer(p).playSound(Sound.BLOCK_FIRE_EXTINGUISH)); + }, 5L, 5L); + } + + @EventHandler + public void onInventoryClick(InventoryClickEvent e) { + Player p = (Player) e.getWhoClicked(); + if (e.getSlot() == 38 && isJetpack(e.getCurrentItem()) && p.isFlying()) + p.setAllowFlight(false); + } + + private void updateFly(Player p, boolean state) { + if (p.getAllowFlight() != state) { + p.setAllowFlight(state); + } + } + + private void updateFlying(Player p, boolean state) { + if (p.isFlying() != state) { + p.setFlying(state); + } + } + + @EventHandler + public void onPlayerMove(PlayerMoveEvent e) { + Player p = e.getPlayer(); + Location from = e.getFrom(); + Location to = e.getTo(); + + if (from.getX() == to.getX() && from.getY() == to.getY() && from.getZ() == to.getZ()) { + return; + } + + if (!p.getAllowFlight()) { + this.updateFly(p, false); + p.setFlying(false); + } + + if (p.getGameMode() == GameMode.CREATIVE || p.getGameMode() == GameMode.SPECTATOR) { + this.updateFly(p, true); + return; + } + + if (p.getInventory().getChestplate() != null && isJetpack(p.getInventory().getChestplate())) { + if (p.isFlying() && p.getAllowFlight()) { + p.getWorld().spigot().playEffect(p.getLocation().add(0, 1, 0), Effect.CLOUD, 0, 0, 0, 0, 0, 0, 1, 50); + p.getWorld().spigot().playEffect(p.getLocation().add(0, 1, 0), Effect.FLAME, 0, 0, 0, 0, 0, 0, 1, 50); + } + if (this.plugin.getBabies().isJetpackFuelEnabled() && !containsAtLeast(p, 1)) { + this.updateFly(p, false); + p.setFlying(false); + } else { + boolean c = e.getTo().getY() < e.getFrom().getY() && e.getTo().getBlock().getRelative(BlockFace.DOWN).getType() != Material.AIR; + this.updateFly(p, !c); + } + } else { + this.updateFly(p, false); + } + } + + @EventHandler + public void onLeave(PlayerQuitEvent event){ + Player p = event.getPlayer(); + if(p.getInventory().getChestplate()!=null && isJetpack(p.getInventory().getChestplate())) { + updateFlying(p, false); + updateFly(p, false); + } + } + + @EventHandler(ignoreCancelled = true) + public void onPlayerToggleFlight(PlayerToggleFlightEvent e) { + Player p = e.getPlayer(); + + JetpackFlyEvent event = new JetpackFlyEvent(p); + Bukkit.getPluginManager().callEvent(event); + if(event.isCancelled()) { + e.setCancelled(true); + return; + } + + if (p.getGameMode() == GameMode.CREATIVE || p.getGameMode() == GameMode.SPECTATOR) { + p.setAllowFlight(true); + return; + } + + if (!this.active.contains(p.getUniqueId())){ + this.active.add(p.getUniqueId()); + new BukkitRunnable() { + @Override + public void run() { + if (!p.isOnline()) { + this.cancel(); + return; + } + if (p.isFlying()) { + FuelUseEvent fuelUseEvent = new FuelUseEvent(p); + Bukkit.getPluginManager().callEvent(fuelUseEvent); + if(fuelUseEvent.isCancelled()) {//this means that fuel shouldnt be used + return; + } + else if (JetpackListener.this.plugin.getBabies().isJetpackFuelEnabled() && !containsAtLeast(p, 1)) { + Bukkit.getScheduler().runTask(JetpackListener.this.plugin, () -> { + p.setAllowFlight(false); + p.setFlying(false); + }); + JetpackListener.this.active.remove(p.getUniqueId()); + this.cancel(); + } else { + ItemStack itemStack = JetpackListener.this.plugin.getBabies().getJetpackFuelItem().clone(); + for (ItemStack item : p.getInventory().getContents()) { + if (item != null && Objects.equals(item.getType(), itemStack.getType()) + && Objects.equals(item.getItemMeta().getDisplayName(), itemStack.getItemMeta().getDisplayName())) { + if (item.getAmount() == 1) { + p.getInventory().remove(item); + } else { + item.setAmount(item.getAmount() - 1); + } + + break; + } + } + } + } else { + JetpackListener.this.active.remove(p.getUniqueId()); + + if(p.isOnline()) { + Bukkit.getScheduler().runTask(JetpackListener.this.plugin, () -> { + p.setAllowFlight(false); + p.setFlying(false); + }); + this.cancel(); + } + } + } + }.runTaskTimerAsynchronously(this.plugin, 0, this.plugin.getBabies().getJetpackFuelInterval()); + } + } + + @EventHandler(priority = EventPriority.LOW) + public void onWeaponRightClick(WeaponRightClickEvent e) { + LivingEntity entity = e.getLivingEntity(); + if (entity.getEquipment().getChestplate() != null && isJetpack(entity.getEquipment().getChestplate()) && this.plugin.getBabies().getJetpackAllowedWeapons().contains(e.getWeapon().getCompactName()))//getIdentifier + e.setCancelled(true); + } + + private boolean isJetpack(ItemStack itemStack) { + if(itemStack != null && this.plugin.getBabies().getJetpackItem() != null) { + if (itemStack.getType() != this.plugin.getBabies().getJetpackItem().getType()) { + return false; + } + + if (itemStack.getItemMeta() == null || itemStack.getItemMeta().getDisplayName() == null || !itemStack.getItemMeta().getDisplayName().contains("Jetpack")) { + return false; + } + return true; + } + return false; + } + + private boolean containsAtLeast(Player player, int amount) { + + for (int i = 0; i < player.getInventory().getSize(); i++) { + + ItemStack item = player.getInventory().getContents()[i]; + ItemStack fuelItem = this.plugin.getBabies().getJetpackFuelItem(); + + if (item != null && item.getType().equals(fuelItem.getType()) && item.getItemMeta().getDisplayName().equals(fuelItem.getItemMeta().getDisplayName())) { + + if (item.getAmount() < 1 || item.getAmount() >= amount) { + return true; + } + } + } + + return false; + } + + @EventHandler + protected final void onMovementCheat(MovementCheatEvent<Double> event) { + Player player = event.getPlayerData().getPlayer(); + if(player == null) return; + if(event.getCheatType().getType() != CheatType.Type.SPEED) return; + + //System.out.println("Max speed: " + event.getObj()); + + if(player.isFlying() && player.getAllowFlight()) { + if (player.getEquipment().getChestplate() != null && isJetpack(player.getEquipment().getChestplate())) + event.setCancelled(true); + } + } + + @EventHandler + protected final void onPlayerLeave(PlayerQuitEvent event) { + if(this.active.contains(event.getPlayer().getUniqueId())) + this.active.remove(event.getPlayer().getUniqueId()); + } +} diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/listeners/VehicleListener.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/listeners/VehicleListener.java new file mode 100644 index 0000000..47926f3 --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/listeners/VehicleListener.java @@ -0,0 +1,475 @@ +package com.j0ach1mmall3.wastedvehicles.listeners; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Objects; +import java.util.Optional; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Creature; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.player.PlayerInteractAtEntityEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerKickEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.world.ChunkUnloadEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.util.Vector; +import org.spigotmc.event.entity.EntityDismountEvent; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketAdapter; +import com.comphenix.protocol.events.PacketEvent; +import com.j0ach1mmall3.jlib.integration.protocollib.ProtocolLibHook; +import com.j0ach1mmall3.jlib.inventory.JLibItem; +import com.j0ach1mmall3.wastedguns.api.events.WeaponRightClickEvent; +import com.j0ach1mmall3.wastedguns.api.events.explosives.ExplosionDamageEntityEvent; +import com.j0ach1mmall3.wastedvehicles.Main; +import com.j0ach1mmall3.wastedvehicles.api.SpeedBoost; +import com.j0ach1mmall3.wastedvehicles.api.VehicleType; +import com.j0ach1mmall3.wastedvehicles.api.events.VehicleDamageEvent; +import com.j0ach1mmall3.wastedvehicles.api.events.VehicleEnterEvent; +import com.j0ach1mmall3.wastedvehicles.api.events.VehicleImpactEntityEvent; +import com.j0ach1mmall3.wastedvehicles.api.events.VehicleImpactVehicleEvent; +import com.j0ach1mmall3.wastedvehicles.api.events.VehicleLeaveEvent; +import com.j0ach1mmall3.wastedvehicles.api.events.VehicleShootEvent; +import com.j0ach1mmall3.wastedvehicles.api.events.VehicleSpeedBoostEvent; +import com.j0ach1mmall3.wastedvehicles.api.vehicles.Submarine; +import com.j0ach1mmall3.wastedvehicles.api.vehicles.WastedVehicle; +import com.j0ach1mmall3.wastedvehicles.util.MiscUtil; +import com.j0ach1mmall3.wastedvehicles.util.SteerDirection; +import com.j0ach1mmall3.wastedvehicles.util.VehicleUtils; + +import net.grandtheftmc.core.Core; +import net.grandtheftmc.core.Lang; +import net.grandtheftmc.core.anticheat.event.MovementCheatEvent; +import net.grandtheftmc.core.users.User; +import net.grandtheftmc.core.util.ServerUtil; +import net.grandtheftmc.guns.GTMGuns; +import net.grandtheftmc.guns.weapon.Weapon; +import net.grandtheftmc.guns.weapon.ranged.RangedWeapon; + +public final class VehicleListener implements Listener { + private final MiscUtil miscUtil = MiscUtil.getMiscUtil(); + private final Main plugin; + + public VehicleListener(Main plugin) { + this.plugin = plugin; + plugin.getServer().getPluginManager().registerEvents(this, plugin); + new ProtocolLibHook().addPacketAdapter(new PacketAdapter(plugin, PacketType.Play.Client.STEER_VEHICLE) { + @Override + public void onPacketReceiving(PacketEvent event) { + Player p = event.getPlayer(); + if (p.isInsideVehicle()) { + Entity e = p.getVehicle(); + if (e.hasMetadata("WastedVehiclePassenger")) return; + if (e.hasMetadata("WastedVehicle")) { + ArmorStand armorStand = (ArmorStand) e; + SteerDirection steerDirection = new SteerDirection(event.getPacket()); + WastedVehicle wastedVehicle = (WastedVehicle) armorStand.getMetadata("WastedVehicle").get(0).value(); + if (Objects.equals(armorStand.getWorld().getName(), "spawn")) { + wastedVehicle.onDestroy(armorStand); + return; + } + Location l = armorStand.getLocation(); + l.setX(l.getX() + wastedVehicle.getVehicleProperties().getLaunchLocationMultiplier() * l.getDirection().getX()); + l.setY(l.getY() + wastedVehicle.getVehicleProperties().getLaunchLocationYOffset()); + l.setZ(l.getZ() + wastedVehicle.getVehicleProperties().getLaunchLocationMultiplier() * l.getDirection().getZ()); + Vector v = wastedVehicle.getWeaponDirection(armorStand, p); + if (wastedVehicle.getVehicleProperties().getVehicleType() == VehicleType.PLANE) { + if (Objects.equals(VehicleListener.this.miscUtil.getCardinalDirection(l), "East")) { + l.setX(l.getX() - 3); + } else if (Objects.equals(VehicleListener.this.miscUtil.getCardinalDirection(l), "North")) { + l.setZ(l.getZ() - 3); + } else if (Objects.equals(VehicleListener.this.miscUtil.getCardinalDirection(l), "West")) { + l.setX(l.getX() + 3); + } else if (Objects.equals(VehicleListener.this.miscUtil.getCardinalDirection(l), "South")) { + l.setZ(l.getZ() + 3); + } + if (l.getPitch() >= 30) { + l.setPitch(l.getPitch() + 15); + } else if (l.getPitch() >= -30) { + l.setPitch(l.getPitch() - 15); + } + l.setY(l.getY() - 3); + } + if (VehicleUtils.getBoundingBox(armorStand) != null) { + Location loc1 = VehicleUtils.getBoundingBox(armorStand)[0]; + Location loc2 = VehicleUtils.getBoundingBox(armorStand)[1]; + Collection<LivingEntity> nearbyEntities = new ArrayList<>(); + Collection<ArmorStand> nearbyVehicles = new ArrayList<>(); + for (Entity entity : loc1.getWorld().getNearbyEntities(loc1, loc2.getX(), loc2.getY(), loc2.getZ())) { + if (entity.getType() == EntityType.ARMOR_STAND && entity.hasMetadata("WastedVehicle")) { + if (entity == armorStand) continue; + if (entity.hasMetadata("WastedVehiclePassenger")) continue; + nearbyVehicles.add((ArmorStand) entity); + continue; + } + if (entity.getType() != EntityType.PLAYER && !(entity instanceof Creature)) continue; + if (entity == p) continue; + if (entity.getVehicle() != null && entity.getVehicle().hasMetadata("WastedVehiclePassenger")) + continue; + nearbyEntities.add((LivingEntity) entity); + } + for (ArmorStand as : nearbyVehicles) { + Vector vec1 = new Vector(loc1.getX(), loc1.getY(), loc1.getZ()); + Vector vec2 = new Vector(loc2.getX(), loc2.getY(), loc2.getZ()); + Vector asVector = new Vector(as.getLocation().getX(), as.getLocation().getY(), + as.getLocation().getZ()); + if (asVector.isInAABB(vec1, vec2)) { + Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(this.plugin, new Runnable() { + @Override + public void run() { + if (!(as.getMetadata("WastedVehicle").get(0).value() instanceof WastedVehicle)) + return; + WastedVehicle collidedWith = (WastedVehicle) as.getMetadata("WastedVehicle").get(0).value(); + if (as.getPassenger() == null || as.getPassenger().getType() != EntityType.PLAYER) + return; + Player collidedWithPlayer = (Player) as.getPassenger(); + VehicleImpactVehicleEvent impactEvent = + new VehicleImpactVehicleEvent(wastedVehicle, p, collidedWith, + collidedWithPlayer, armorStand, as, steerDirection); + plugin.getServer().getPluginManager().callEvent(impactEvent); + } + }, 0L); + } + } + for (LivingEntity livingEntity : nearbyEntities) { + Vector vec1 = new Vector(loc1.getX(), loc1.getY(), loc1.getZ()); + Vector vec2 = new Vector(loc2.getX(), loc2.getY(), loc2.getZ()); + Vector pVector = new Vector(livingEntity.getLocation().getX(), livingEntity.getLocation().getY(), + livingEntity.getLocation().getZ()); + if (pVector.isInAABB(vec1, vec2)) { + Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(this.plugin, new Runnable() { + @Override + public void run() { + VehicleImpactEntityEvent entityEvent = new VehicleImpactEntityEvent(wastedVehicle, p, livingEntity, armorStand, steerDirection); + plugin.getServer().getPluginManager().callEvent(entityEvent); + } + }, 0L); + } + } + } + if (steerDirection.isJump() && !wastedVehicle.isCooldown() && armorStand.getHealth() > 1 && l != null && v != null) { + if (wastedVehicle.getVehicleProperties().getVehicleType() == VehicleType.PLANE && armorStand.getTicksLived() <= 140) { + p.sendMessage(Lang.VEHICLES.f("&7Get in the air before firing your weapon!")); + event.setCancelled(true); + return; + } + Optional<Weapon<?>> weapon = GTMGuns.getInstance().getWeaponManager().getWeapon(wastedVehicle.getVehicleProperties().getWastedGunsWeapon()); + // TODO remove debug + ServerUtil.debug("[VehicleListener][DEBUG] - " + (weapon.isPresent() ? "exists as=" + weapon.get().getName() : "does not exist")); + if (weapon.isPresent() && weapon.get() instanceof RangedWeapon) { + Bukkit.getScheduler().callSyncMethod(this.plugin, () -> { + ((RangedWeapon) weapon.get()).vehicleShoot(p, l, v/*, GTMGuns.getInstance().getWeaponManager().getPlayerCache(p.getUniqueId())*/, ((RangedWeapon) weapon.get()).isAutomatic()); + return null; + }); + wastedVehicle.setCooldown(true); + Bukkit.getScheduler().scheduleSyncDelayedTask(this.plugin, () -> wastedVehicle.setCooldown(false), weapon.get().getDelay()); + } + } + if (wastedVehicle.getVehicleProperties().getDisplayBlocks().size() > 1 && wastedVehicle.isTick()){ + armorStand.setHelmet(wastedVehicle.getNextDisplayBlock()); + } + + wastedVehicle.setTick(!wastedVehicle.isTick()); + wastedVehicle.onSteer(armorStand, p, steerDirection); + } + } + } + }); + Bukkit.getScheduler().scheduleSyncRepeatingTask(this.plugin, () -> this.plugin.getEntityQueue().forEach(a -> ((WastedVehicle) a.getMetadata("WastedVehicle").get(0).value()).onTick(a)), 1, 1); + } + + + /** + * You may be thinking "Holy fuck Tim, this code is absolutely disgusting, why don't you just add a method to the rhino / hydra vehicle class??? Oh wait.." + * Yea, there are no vehicle-specific classes like how there are with weapons. So the cooldowns / shooting has to be hardcoded. This can be changed in the + * future, but this plugin would have to be rewritten. + */ + @EventHandler + public void onVehicleShoot(VehicleShootEvent event) { + Player player = event.getShooter(); + User user = Core.getUserManager().getLoadedUser(player.getUniqueId()); + WastedVehicle wastedVehicle = event.getVehicle(); + switch (wastedVehicle.getVehicleProperties().getIdentifier().toLowerCase()) { + case "hydra": + if(user.isOnCooldown("hydra_shoot", true)) + break; + user.addCooldown("hydra_shoot", 1, false, true); + wastedVehicle.shootWeapon(player); + break; + case "rhino": + if(user.isOnCooldown("rhino_shoot", true)) + break; + user.addCooldown("rhino_shoot", 2, false, true); + wastedVehicle.shootWeapon(player); + break; + } + } + + @EventHandler + public void onVehicleImpactEntity(VehicleImpactEntityEvent event) { + WastedVehicle vehicle = event.getVehicle(); + Player driver = event.getDriver(); + LivingEntity livingEntity = event.getImpactedEntity(); + vehicle.getPassengers().forEach(passenger -> { + if (passenger.getPassenger() != null) { + if (Objects.equals(livingEntity, passenger.getPassenger())) { + event.setCancelled(true); + } + } + }); + if (Objects.equals(vehicle.getVehicleProperties().getIdentifier(), "Rhino")) { + livingEntity.damage(3.0, driver); + } else if (vehicle.getVehicleProperties().getVehicleType() == VehicleType.CAR) { + Location loc = event.getArmorStand().getEyeLocation(); + loc.setPitch(-8); + if (event.getSteerDirection().isForward()) { + livingEntity.setVelocity(loc.getDirection().multiply(vehicle.getSpeed() * 2)); + } else if (event.getSteerDirection().isBackward()) { + livingEntity.setVelocity(loc.getDirection().multiply(vehicle.getSpeed() * 2 - 1)); + } + livingEntity.damage(5.0, driver); + event.getArmorStand().damage(2.0); + } + } + + @EventHandler + public void onVehicleImpactVehicle(VehicleImpactVehicleEvent event) { + WastedVehicle vehicle = event.getVehicle(); + WastedVehicle collided = event.getCollidedWith(); + Player player = event.getDriver(); + Player collidedDriver = event.getCollidedWithDriver(); + if (collided.getVehicleProperties().getVehicleType() != VehicleType.CAR) return; + if (event.getSteerDirection().isForward() || event.getSteerDirection().isBackward()) { + vehicle.explode(event.getArmorStand()); + } else { + player.damage(10.0, collidedDriver); + collidedDriver.damage(10.0, player); + } + } + + @EventHandler + public void onChunkUnload(ChunkUnloadEvent e) { + for (Entity entity : e.getChunk().getEntities()) { + if (entity.hasMetadata("WastedVehicle")) { + ArmorStand armorStand = (ArmorStand) entity; + armorStand.setHealth(0); + entity.remove(); + this.plugin.getEntityQueue().remove(entity); + } + } + } + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent e) { + Player player = e.getPlayer(); + player.removePotionEffect(PotionEffectType.INVISIBILITY); + Bukkit.getOnlinePlayers().stream().filter(p -> p.getVehicle() != null && p.getVehicle().hasMetadata("WastedVehicle")).forEach(player::hidePlayer); + if (player.isInsideVehicle()) { + player.getVehicle().remove(); + } + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent e) { + Player p = e.getPlayer(); + if (p.isInsideVehicle() && p.getVehicle().hasMetadata("WastedVehicle")) { + ArmorStand armorStand = (ArmorStand) p.getVehicle(); +// armorStand.eject(); + WastedVehicle wastedVehicle = (WastedVehicle) armorStand.getMetadata("WastedVehicle").get(0).value(); + VehicleLeaveEvent event = new VehicleLeaveEvent(wastedVehicle, p, armorStand); + Bukkit.getPluginManager().callEvent(event); + } + } + + @EventHandler + public void onPlayerKick(PlayerKickEvent e) { + Player p = e.getPlayer(); + if (p.isInsideVehicle() && p.getVehicle().hasMetadata("WastedVehicle")) { + ArmorStand armorStand = (ArmorStand) p.getVehicle(); +// armorStand.eject(); + WastedVehicle wastedVehicle = (WastedVehicle) armorStand.getMetadata("WastedVehicle").get(0).value(); + VehicleLeaveEvent event = new VehicleLeaveEvent(wastedVehicle, p, armorStand); + Bukkit.getPluginManager().callEvent(event); + } + } + + @EventHandler + public void onPlayerInteract(PlayerInteractEvent e) { + Player p = e.getPlayer(); + ItemStack heldItem = p.getInventory().getItemInMainHand(); + if (e.getAction() == Action.RIGHT_CLICK_AIR && p.getVehicle() != null && p.getVehicle().hasMetadata("WastedVehicle")) { + WastedVehicle wastedVehicle = (WastedVehicle) p.getVehicle().getMetadata("WastedVehicle").get(0).value(); + //speed boost + Optional<SpeedBoost> speedBoost = wastedVehicle.getVehicleProperties().getSpeedBoosts().stream().filter(s -> new JLibItem(s.getItemStack()).isSimilar(heldItem)).findFirst(); + speedBoost.ifPresent(s -> { + VehicleSpeedBoostEvent event = new VehicleSpeedBoostEvent(wastedVehicle, p, (ArmorStand) p.getVehicle(), s); + Bukkit.getPluginManager().callEvent(event); + if (!event.isCancelled()) { + wastedVehicle.onSpeedBoost(s); + heldItem.setAmount(heldItem.getAmount() - 1); + p.getInventory().setItemInMainHand(heldItem); + } + }); + + VehicleShootEvent event = new VehicleShootEvent(wastedVehicle, (ArmorStand)p.getVehicle(), p); + Bukkit.getPluginManager().callEvent(event); + if(event.isCancelled()) + e.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOW) + public void onVehicleEnterEvent(VehicleEnterEvent event){ + WastedVehicle vehicle = event.getVehicle(); + Player player = event.getPlayer(); + switch (vehicle.getVehicleProperties().getIdentifier().toLowerCase()) { + case "rhino": + case "hydra": + player.sendMessage(Lang.VEHICLES.f("&6In order to use the launcher in this vehicle, you must have an item in your hand and right click.")); + break; + } + } + + @EventHandler + public void onPlayerInteractAtEntity(PlayerInteractAtEntityEvent event) { + Entity rightClicked = event.getRightClicked(); + Player player = event.getPlayer(); + if (player.getVehicle() != null) return; + if (rightClicked.hasMetadata("WastedVehiclePassenger")) { + event.setCancelled(true); + WastedVehicle wastedVehicle = (WastedVehicle) rightClicked.getMetadata("WastedVehiclePassenger").get(0).value(); + if (rightClicked.getPassenger() == null) { + wastedVehicle.passengerMount((ArmorStand) rightClicked, player); + } + return; + } + if (rightClicked.hasMetadata("WastedVehicle")) { + event.setCancelled(true); + WastedVehicle wastedVehicle = (WastedVehicle) rightClicked.getMetadata("WastedVehicle").get(0).value(); + if (rightClicked.getPassenger() != null) { + wastedVehicle.passengerMount((ArmorStand) rightClicked, player); + } + + if (player.getFireTicks() > 0) { + player.sendMessage(Lang.VEHICLES.f("&cYou cannot enter a vehicle when you're on fire.")); + return; + } + + VehicleEnterEvent vehicleEnterEvent = new VehicleEnterEvent(wastedVehicle, player, (ArmorStand) rightClicked); + Bukkit.getPluginManager().callEvent(vehicleEnterEvent); + if (!vehicleEnterEvent.isCancelled()) wastedVehicle.onRightClick((ArmorStand) rightClicked, player); + } + } + + @EventHandler + public void onEntityDismount(EntityDismountEvent e) { + Entity dismounted = e.getDismounted(); + Entity entity = e.getEntity(); + if (dismounted.hasMetadata("WastedVehiclePassenger")) { + WastedVehicle wastedVehicle = (WastedVehicle) dismounted.getMetadata("WastedVehiclePassenger").get(0).value(); + wastedVehicle.onDismount((ArmorStand) dismounted); + + entity.setVelocity(dismounted.getLocation().getDirection().multiply(-0.7)); + return; + } + if (dismounted.hasMetadata("WastedVehicle") && entity instanceof Player) { + WastedVehicle wastedVehicle = (WastedVehicle) dismounted.getMetadata("WastedVehicle").get(0).value(); + VehicleLeaveEvent event = new VehicleLeaveEvent(wastedVehicle, (Player) entity, (ArmorStand) dismounted); + Bukkit.getPluginManager().callEvent(event); + if (!event.isCancelled() && !(wastedVehicle instanceof Submarine && !((Player) entity).isSneaking())) + ((WastedVehicle) dismounted.getMetadata("WastedVehicle").get(0).value()).onDismount((ArmorStand) dismounted); + + entity.setVelocity(dismounted.getLocation().getDirection().multiply(-0.7)); + } + } + + @EventHandler + public void onEntityDamageEntity(EntityDamageByEntityEvent event) { + Entity victim = event.getEntity(); + Entity damager = event.getDamager(); + if (victim.hasMetadata("WastedVehicle")) { + if (damager.getVehicle() != null && damager.getVehicle().hasMetadata("WastedVehiclePassenger")) { + event.setCancelled(true); + } + } + } + + @EventHandler + public void onEntityDamage(EntityDamageEvent e) { + Entity entity = e.getEntity(); + if (entity.hasMetadata("WastedVehiclePassenger")) { + e.setCancelled(true); + return; + } + if (entity.isInsideVehicle() && entity.getVehicle().hasMetadata("WastedVehicle")) { + if (e.getCause() == EntityDamageEvent.DamageCause.FALL) e.setCancelled(true); + WastedVehicle wastedVehicle = (WastedVehicle) entity.getVehicle().getMetadata("WastedVehicle").get(0).value(); + if (wastedVehicle.getVehicleProperties().isDamageVehicleOnPlayerHit()) { + e.setCancelled(true); + VehicleDamageEvent event = new VehicleDamageEvent(wastedVehicle, (ArmorStand) entity.getVehicle(), e.getCause(), e.getDamage()); + Bukkit.getPluginManager().callEvent(event); + if (!event.isCancelled()) + wastedVehicle.onDamage((ArmorStand) entity.getVehicle(), e.getCause(), e.getDamage()); + } + } + if (entity.hasMetadata("WastedVehicle")) { + e.setCancelled(true); + WastedVehicle wastedVehicle = (WastedVehicle) entity.getMetadata("WastedVehicle").get(0).value(); + VehicleDamageEvent event = new VehicleDamageEvent(wastedVehicle, (ArmorStand) entity, e.getCause(), e.getDamage()); + Bukkit.getPluginManager().callEvent(event); + if (!event.isCancelled()) wastedVehicle.onDamage((ArmorStand) entity, e.getCause(), e.getDamage()); + } + } + + @EventHandler + public void onExplosionDamageEntity(ExplosionDamageEntityEvent event) { + event.getVictims().forEach(entity -> { + if (entity.getType() != EntityType.ARMOR_STAND) return; + if (entity.hasMetadata("WastedVehicle")) { + WastedVehicle wastedVehicle = (WastedVehicle) entity.getMetadata("WastedVehicle").get(0).value(); + if (!Objects.equals(wastedVehicle.getVehicleProperties().getIdentifier(), "ArmoredKuruma")) { + wastedVehicle.explode((ArmorStand) entity); + } + } + }); + } + + @EventHandler(priority = EventPriority.LOW) + public void onWeaponRightClick(WeaponRightClickEvent event) { + LivingEntity entity = event.getLivingEntity(); + if (!entity.isInsideVehicle()) return; + if (entity.getVehicle().hasMetadata("WastedVehicle") || + entity.hasMetadata("WastedVehiclePassenger")) { + WastedVehicle wastedVehicle = entity.getVehicle().hasMetadata("WastedVehicle") + ? (WastedVehicle) entity.getVehicle().getMetadata("WastedVehicle").get(0).value() + : (WastedVehicle) entity.getVehicle().getMetadata("WastedVehiclePassenger").get(0).value(); + if (!wastedVehicle.getVehicleProperties().getAllowedWeapons().contains(event.getWeapon().getCompactName())) {//getIdentifier() + event.setCancelled(true); + } + } + } + + @EventHandler + protected final void onMovementCheat(MovementCheatEvent event) { + Player player = event.getPlayerData().getPlayer(); + if (!player.isInsideVehicle()) return; + if (player.getVehicle().hasMetadata("WastedVehicle") || player.hasMetadata("WastedVehiclePassenger")) + event.setCancelled(true); + } +} diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/util/MiscUtil.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/util/MiscUtil.java new file mode 100644 index 0000000..8ace6bc --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/util/MiscUtil.java @@ -0,0 +1,66 @@ +package com.j0ach1mmall3.wastedvehicles.util; + +import org.bukkit.Location; +import org.bukkit.block.Block; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class MiscUtil { + private static MiscUtil miscUtil; + + private MiscUtil() { + miscUtil = this; + } + + public static MiscUtil getMiscUtil() { + if(miscUtil == null) { + miscUtil = new MiscUtil(); + } + return miscUtil; + } + + public String getCardinalDirection(Location location) { + double rot = (location.getYaw() - 90) % 360; + if (rot < 0) { + rot += 360.0; + } + return this.getDirection(rot); + } + + public Set<Block> getBlocksInRadius(Location o, int radius) { + Set<Block> blocks = new HashSet<>(); + for(int x = o.getBlockX()-radius; x<=o.getBlockX()+radius; x++) + for(int y = o.getBlockY()-radius; y<=o.getBlockY()+radius; y++) + for(int z = o.getBlockZ()-radius; z<=o.getBlockZ()+radius; z++) + blocks.add(o.getWorld().getBlockAt(x,y,z)); + return blocks; + } + + private String getDirection(double rot) { + if (rot <= 0 && rot < 22.5) { + return "North"; + } else if (rot <= 22.5 && rot < 67.5) { + return "North"; + } else if (rot <= 67.5 && rot < 112.5) { + return "East"; + } else if (rot <= 112.5 && rot < 157.5) { + return "South"; + } else if (rot <= 157.5 && rot < 202.5) { + return "South"; + } else if (rot <= 202.5 && rot < 247.5) { + return "South"; + } else if (rot <= 247.5 && rot < 292.5) { + return "West"; + } else if (rot <= 292.5 && rot < 337.5) { + return "North"; + } else if (rot <= 337.5 && rot < 360.0) { + return "North"; + } else { + return null; + } + } +} + + diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/util/SteerDirection.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/util/SteerDirection.java new file mode 100644 index 0000000..134c337 --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/util/SteerDirection.java @@ -0,0 +1,47 @@ +package com.j0ach1mmall3.wastedvehicles.util; + +import com.comphenix.protocol.events.PacketContainer; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 5/05/2016 + */ +public final class SteerDirection { + private final float forMotion; + private final float sideMotion; + private final boolean jump; + + public SteerDirection(PacketContainer packet) { + this.forMotion = packet.getFloat().read(1); + this.sideMotion = packet.getFloat().read(0); + this.jump = packet.getBooleans().read(0); + } + + public boolean isForward() { + return this.forMotion > 0; + } + + public boolean isBackward() { + return this.forMotion < 0; + } + + public boolean isLeft() { + return this.sideMotion > 0; + } + + public boolean isRight() { + return this.sideMotion < 0; + } + + public float getForMotion() { + return this.forMotion; + } + + public float getSideMotion() { + return this.sideMotion; + } + + public boolean isJump() { + return this.jump; + } +} diff --git a/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/util/VehicleUtils.java b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/util/VehicleUtils.java new file mode 100644 index 0000000..5945dea --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/java/com/j0ach1mmall3/wastedvehicles/util/VehicleUtils.java @@ -0,0 +1,73 @@ +package com.j0ach1mmall3.wastedvehicles.util; + +import com.j0ach1mmall3.jlib.methods.ReflectionAPI; +import org.bukkit.Location; +import org.bukkit.craftbukkit.v1_12_R1.entity.CraftEntity; +import org.bukkit.entity.Entity; +import org.bukkit.util.EulerAngle; +import org.bukkit.util.Vector; + +/** + * @author j0ach1mmall3 (business.j0ach1mmall3@gmail.com) + * @since 5/05/2016 + */ +public final class VehicleUtils { + private VehicleUtils() {} + + public static Location[] getBoundingBox(Entity entity) { + try { + Object handle = ReflectionAPI.getHandle((Object) entity); + Object boundingBox = handle.getClass().getMethod("getBoundingBox").invoke(handle); + Location loc1 = new Location(entity.getWorld(), (double)ReflectionAPI.getNmsClass("AxisAlignedBB").getField("a").get(boundingBox), + (double)ReflectionAPI.getNmsClass("AxisAlignedBB").getField("b").get(boundingBox), + (double)ReflectionAPI.getNmsClass("AxisAlignedBB").getField("c").get(boundingBox)); + Location loc2 = new Location(entity.getWorld(), (double)ReflectionAPI.getNmsClass("AxisAlignedBB").getField("d").get(boundingBox), + (double)ReflectionAPI.getNmsClass("AxisAlignedBB").getField("e").get(boundingBox), + (double)ReflectionAPI.getNmsClass("AxisAlignedBB").getField("f").get(boundingBox)); + return new Location[]{loc1, loc2}; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public static void setYaw(Entity vehicle, float yaw) { + Object handle = ReflectionAPI.getHandle((Object) vehicle); + try { + handle.getClass().getField("yaw").set(handle, yaw); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void setPitch(Entity vehicle, float pitch) { + Object handle = ReflectionAPI.getHandle((Object) vehicle); + try { + handle.getClass().getField("pitch").set(handle, pitch); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void makeJumping(Entity entity) { + Object handle = ReflectionAPI.getHandle((Object) entity); + try { + handle.getClass().getField("P").set(handle, 1); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static EulerAngle toEulerAngle(Vector vector) { + return new EulerAngle(vector.getX(), vector.getY(), vector.getZ()); + } + + public static Vector multiply(EulerAngle eulerAngle, double factor) { + return new Vector(eulerAngle.getX() * factor, eulerAngle.getY() * factor, eulerAngle.getZ() * factor); + } + + public static void teleport(Entity entity, Location location) { + net.minecraft.server.v1_12_R1.Entity en = ((CraftEntity) entity).getHandle(); + en.setPosition(location.getX(), location.getY(), location.getZ()); + } +} \ No newline at end of file diff --git a/wastedvehicles-master@5cac11d6d43/src/main/resources/config.yml b/wastedvehicles-master@5cac11d6d43/src/main/resources/config.yml new file mode 100644 index 0000000..cb216f9 --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/resources/config.yml @@ -0,0 +1,530 @@ +Jetpack: + Item: '315 name:&4&lJetpack' + Fuel: + Enabled: true + Item: '263:1 name:&4&lJetpack_Fuel' + Interval: 20 +Vehicles: + Zentorno: + VehicleType: CAR + Acceleration: 0.03 + Deceleration: 0.01 + RotationSpeed: 8 + Invisible: true + TakeOffSpeed: 0.0 + Item: '215 name:&4&lZentorno lore:&7Manufacturer:_&a&lPegassi|&7Type:_&a&lSuper' + BoundingBoxWidth: 3.0 + BoundingBoxHeight: 1.8 + LaunchLocationMultiplier: 0.0 + LaunchLocationYOffset: 0.0 + MaxHealth: 200.0 + Explode: true + DamageVehicleOnPlayerHit: true + KnockOutChance: 0 + Passengers: 1 + SpeedBoosts: + Small: + Item: '336 name:&a&lSmall_Speed_Boost' + SpeedBoost: 1.5 + Duration: 200 + Medium: + Item: '265 name:&a&lMedium_Speed_Boost' + SpeedBoost: 2.0 + Duration: 400 + Large: + Item: '266 name:&a&lLarge_Speed_Boost' + SpeedBoost: 2.5 + Duration: 600 + MaxSpeed: 1.5 + DefaultSpeed: 0.0 + CollisionDamage: 2.0 + WastedGunsWeapon: '' + AllowedWeapons: + - Pistol + - StunGun + - CombatPistol + - HeavyPistol + - MarksmanPistol + - MicroSMG + - SMG + - AssaultSMG + - CombatPDW + - GusenbergSweeper + - Grenade + - MolotovCocktail + - TearGas + - StickyBomb + - ProximityMine + AllowedBlocks: + - STONE + - STAINED_CLAY + - WOOL + - SNOW_BLOCK + DisplayBlocks: + - 215 + Entity_XF: + VehicleType: CAR + Acceleration: 0.025 + Deceleration: 0.01 + RotationSpeed: 7 + Invisible: true + TakeOffSpeed: 0.0 + Item: '206 name:&4&lEntity_XF lore:&7Manufacturer:_&a&lÖverflöd|&7Type:_&a&lSuper' + BoundingBoxWidth: 3.0 + BoundingBoxHeight: 1.9 + LaunchLocationMultiplier: 0.0 + LaunchLocationYOffset: 0.0 + MaxHealth: 175.0 + Explode: true + DamageVehicleOnPlayerHit: true + KnockOutChance: 0 + Passengers: 1 + SpeedBoosts: + Small: + Item: '336 name:&a&lSmall_Speed_Boost' + SpeedBoost: 1.5 + Duration: 200 + Medium: + Item: '265 name:&a&lMedium_Speed_Boost' + SpeedBoost: 2.0 + Duration: 400 + Large: + Item: '266 name:&a&lLarge_Speed_Boost' + SpeedBoost: 2.5 + Duration: 600 + MaxSpeed: 1.4 + DefaultSpeed: 0.0 + CollisionDamage: 2.0 + WastedGunsWeapon: '' + AllowedWeapons: + - Pistol + - StunGun + - CombatPistol + - HeavyPistol + - MarksmanPistol + - MicroSMG + - SMG + - AssaultSMG + - CombatPDW + - GusenbergSweeper + - Grenade + - MolotovCocktail + - TearGas + - StickyBomb + - ProximityMine + AllowedBlocks: + - STONE + - STAINED_CLAY + - WOOL + - SNOW_BLOCK + DisplayBlocks: + - 206 + 9F: + VehicleType: CAR + Acceleration: 0.02 + Deceleration: 0.01 + RotationSpeed: 6 + Invisible: true + TakeOffSpeed: 0.0 + Item: '214 name:&4&l9F lore:&7Manufacturer:_&a&lObey|&7Type:_&a&lSports' + BoundingBoxWidth: 3.0 + BoundingBoxHeight: 1.9 + LaunchLocationMultiplier: 0.0 + LaunchLocationYOffset: 0.0 + MaxHealth: 150.0 + Explode: true + DamageVehicleOnPlayerHit: true + KnockOutChance: 0 + Passengers: 1 + SpeedBoosts: + Small: + Item: '336 name:&a&lSmall_Speed_Boost' + SpeedBoost: 1.5 + Duration: 200 + Medium: + Item: '265 name:&a&lMedium_Speed_Boost' + SpeedBoost: 2.0 + Duration: 400 + Large: + Item: '266 name:&a&lLarge_Speed_Boost' + SpeedBoost: 2.5 + Duration: 600 + MaxSpeed: 1.3 + DefaultSpeed: 0.0 + CollisionDamage: 2.0 + WastedGunsWeapon: '' + AllowedWeapons: + - Pistol + - StunGun + - CombatPistol + - HeavyPistol + - MarksmanPistol + - MicroSMG + - SMG + - AssaultSMG + - CombatPDW + - GusenbergSweeper + - Grenade + - MolotovCocktail + - TearGas + - StickyBomb + - ProximityMine + AllowedBlocks: + - STONE + - STAINED_CLAY + - WOOL + - SNOW_BLOCK + DisplayBlocks: + - 214 + ArmoredKuruma: + VehicleType: CAR + Acceleration: 0.03 + Deceleration: 0.01 + RotationSpeed: 5 + Invisible: true + TakeOffSpeed: 0.0 + Item: '213 name:&4&lArmored_Kuruma lore:&7Manufacturer:_&a&lKarin|&7Type:_&a&lSports' + BoundingBoxWidth: 3.0 + BoundingBoxHeight: 2.1 + LaunchLocationMultiplier: 0.0 + LaunchLocationYOffset: 0.0 + MaxHealth: 350.0 + Explode: true + DamageVehicleOnPlayerHit: true + KnockOutChance: 0 + Passengers: 1 + SpeedBoosts: + Small: + Item: '336 name:&a&lSmall_Speed_Boost' + SpeedBoost: 1.5 + Duration: 200 + Medium: + Item: '265 name:&a&lMedium_Speed_Boost' + SpeedBoost: 2.0 + Duration: 400 + Large: + Item: '266 name:&a&lLarge_Speed_Boost' + SpeedBoost: 2.5 + Duration: 600 + MaxSpeed: 1.2 + DefaultSpeed: 0.0 + CollisionDamage: 2.0 + WastedGunsWeapon: '' + AllowedWeapons: + - Pistol + - StunGun + - CombatPistol + - HeavyPistol + - MarksmanPistol + - MicroSMG + - SMG + - AssaultSMG + - CombatPDW + - GusenbergSweeper + - Grenade + - MolotovCocktail + - TearGas + - StickyBomb + - ProximityMine + AllowedBlocks: + - STONE + - STAINED_CLAY + - WOOL + - SNOW_BLOCK + DisplayBlocks: + - 213 + Primo: + VehicleType: CAR + Acceleration: 0.015 + Deceleration: 0.01 + RotationSpeed: 3 + Invisible: true + TakeOffSpeed: 0.0 + Item: '216 name:&4&lPrimo lore:&7Manufacturer:_&a&lAlbany|&7Type:_&a&lSedan' + BoundingBoxWidth: 3.0 + BoundingBoxHeight: 2.3 + LaunchLocationMultiplier: 0.0 + LaunchLocationYOffset: 0.0 + MaxHealth: 150.0 + Explode: true + DamageVehicleOnPlayerHit: true + KnockOutChance: 0 + Passengers: 1 + SpeedBoosts: + Small: + Item: '336 name:&a&lSmall_Speed_Boost' + SpeedBoost: 1.5 + Duration: 200 + Medium: + Item: '265 name:&a&lMedium_Speed_Boost' + SpeedBoost: 2.0 + Duration: 400 + Large: + Item: '266 name:&a&lLarge_Speed_Boost' + SpeedBoost: 2.5 + Duration: 600 + MaxSpeed: 1.0 + DefaultSpeed: 0.0 + CollisionDamage: 2.0 + WastedGunsWeapon: '' + AllowedWeapons: + - Pistol + - StunGun + - CombatPistol + - HeavyPistol + - MarksmanPistol + - MicroSMG + - SMG + - AssaultSMG + - CombatPDW + - GusenbergSweeper + - Grenade + - MolotovCocktail + - TearGas + - StickyBomb + - ProximityMine + AllowedBlocks: + - STONE + - STAINED_CLAY + - WOOL + - SNOW_BLOCK + DisplayBlocks: + - 216 + BMX: + VehicleType: CAR + Acceleration: 0.05 + Deceleration: 0.01 + TakeOffSpeed: 0.0 + RotationSpeed: 11 + Invisible: false + Item: '168 name:&4&lBMX lore:&7Type:_&a&lBicycle' + BoundingBoxWidth: 1.0 + BoundingBoxHeight: 1.0 + LaunchLocationMultiplier: 0.0 + LaunchLocationYOffset: 0.0 + MaxHealth: 50 + Explode: false + DamageVehicleOnPlayerHit: false + KnockOutChance: 50 + Passengers: 0 + SpeedBoosts: {} + MaxSpeed: 0.75 + DefaultSpeed: 0 + CollisionDamage: 2.0 + WastedGunsWeapon: '' + AllowedWeapons: + - Pistol + - StunGun + - CombatPistol + - HeavyPistol + - MarksmanPistol + - MicroSMG + - SMG + - AssaultSMG + - CombatPDW + - GusenbergSweeper + - Grenade + - MolotovCocktail + - TearGas + - StickyBomb + - ProximityMine + - SawedoffShotgun + AllowedBlocks: + - STONE + - STAINED_CLAY + - WOOL + - SNOW_BLOCK + DisplayBlocks: + - 168 + Rhino: + VehicleType: CAR + Acceleration: 0.05 + Deceleration: 0.01 + TakeOffSpeed: 0.0 + RotationSpeed: 2 + Invisible: true + Item: '168:1 name:&4&lRhino lore:&7Type:_&a&lTank' + BoundingBoxWidth: 4.0 + BoundingBoxHeight: 3.4 + LaunchLocationMultiplier: 4.0 + LaunchLocationYOffset: 2.8 + MaxHealth: 500.0 + Explode: true + DamageVehicleOnPlayerHit: true + KnockOutChance: 0 + Passengers: 0 + SpeedBoosts: {} + MaxSpeed: 0.7 + DefaultSpeed: 0 + CollisionDamage: 20.0 + WastedGunsWeapon: RPG + AllowedWeapons: [] + AllowedBlocks: + - STONE + - STAINED_CLAY + - WOOL + - SNOW_BLOCK + DisplayBlocks: + - '168:1' + Hydra: + VehicleType: PLANE + Acceleration: 0.05 + Deceleration: 0.01 + TakeOffSpeed: 0.5 + RotationSpeed: 4.0 + Invisible: true + Item: '153 name:&4&lHydra lore:&7Type:_&a&lPlane' + BoundingBoxWidth: 7.0 + BoundingBoxHeight: 1.6 + LaunchLocationMultiplier: 6.5 + LaunchLocationYOffset: -1 + MaxHealth: 400.0 + Explode: true + DamageVehicleOnPlayerHit: true + KnockOutChance: 0 + Passengers: 0 + SpeedBoosts: {} + MaxSpeed: 1.5 + DefaultSpeed: 0 + CollisionDamage: 50 + WastedGunsWeapon: RPG + AllowedWeapons: [] + AllowedBlocks: + - STONE + - STAINED_CLAY + - WOOL + - SNOW_BLOCK + DisplayBlocks: + - 153 + Maverick: + VehicleType: HELICOPTER + Acceleration: 0.0 + Deceleration: 0.0 + TakeOffSpeed: 0.0 + RotationSpeed: 5 + Invisible: true + Item: '200 name:&4&lMaverick lore:&7Type:_&a&lHelicopter' + BoundingBoxWidth: 3.2 + BoundingBoxHeight: 3.2 + LaunchLocationMultiplier: 0.0 + LaunchLocationYOffset: 0.0 + MaxHealth: 200.0 + Explode: true + DamageVehicleOnPlayerHit: true + KnockOutChance: 0 + Passengers: 0 + SpeedBoosts: {} + MaxSpeed: 1.3 + DefaultSpeed: 1.3 + CollisionDamage: 15.0 + WastedGunsWeapon: '' + AllowedWeapons: [] + AllowedBlocks: + - STONE + - STAINED_CLAY + - WOOL + - SNOW_BLOCK + DisplayBlocks: + - 200 + AttackMaverick: + VehicleType: HELICOPTER + Acceleration: 0.0 + Deceleration: 0.0 + TakeOffSpeed: 0.0 + RotationSpeed: 5 + Invisible: true + Item: '121 name:&4&lAttack_Maverick lore:&7Type:_&a&lHelicopter' + BoundingBoxWidth: 3.2 + BoundingBoxHeight: 3.2 + LaunchLocationMultiplier: 3.0 + LaunchLocationYOffset: 0.3 + MaxHealth: 220.0 + Explode: true + DamageVehicleOnPlayerHit: true + KnockOutChance: 0 + Passengers: 0 + SpeedBoosts: {} + MaxSpeed: 1.3 + DefaultSpeed: 1.3 + CollisionDamage: 15.0 + WastedGunsWeapon: Minigun + AllowedWeapons: [] + AllowedBlocks: + - STONE + - STAINED_CLAY + - WOOL + - SNOW_BLOCK + DisplayBlocks: + - 121 + Dinghy: + VehicleType: BOAT + Acceleration: 0.05 + Deceleration: 0.01 + TakeOffSpeed: 0.0 + RotationSpeed: 2.0 + Invisible: false + Item: '91 name:&4&lDinghy lore:&7Type:_&a&lBoat' + BoundingBoxWidth: 2.0 + BoundingBoxHeight: 1.4 + LaunchLocationMultiplier: 0.0 + LaunchLocationYOffset: 0.0 + MaxHealth: 90.0 + Explode: true + DamageVehicleOnPlayerHit: false + KnockOutChance: 0 + Passengers: 0 + SpeedBoosts: {} + MaxSpeed: 1.5 + DefaultSpeed: 0 + CollisionDamage: 5.0 + WastedGunsWeapon: '' + AllowedWeapons: + - Pistol + - StunGun + - CombatPistol + - HeavyPistol + - MarksmanPistol + - MicroSMG + - SMG + - AssaultSMG + - CombatPDW + - GusenbergSweeper + - Grenade + - MolotovCocktail + - TearGas + - StickyBomb + - ProximityMine + AllowedBlocks: + - WATER + - STATIONARY_WATER + DisplayBlocks: + - 91 + Submarine: + VehicleType: SUBMARINE + Acceleration: 0.0 + Deceleration: 0.0 + TakeOffSpeed: 0.0 + RotationSpeed: 0.0 + Invisible: true + Item: '56 name:&6Submarine' + BoundingBoxWidth: 0.0 + BoundingBoxHeight: 0.0 + LaunchLocationMultiplier: 0.0 + LaunchLocationYOffset: 0.0 + MaxHealth: 100.0 + Explode: true + DamageVehicleOnPlayerHit: false + KnockOutChance: 10 + Passengers: 0 + SpeedBoosts: {} + MaxSpeed: 0.5 + DefaultSpeed: 0.5 + CollisionDamage: 2.0 + WastedGunsWeapon: '' + AllowedWeapons: [] + AllowedBlocks: + - WATER + - STATIONARY_WATER + DisplayBlocks: + - 56 +DoNotChange: 1.0.0 diff --git a/wastedvehicles-master@5cac11d6d43/src/main/resources/plugin.yml b/wastedvehicles-master@5cac11d6d43/src/main/resources/plugin.yml new file mode 100644 index 0000000..54907a6 --- /dev/null +++ b/wastedvehicles-master@5cac11d6d43/src/main/resources/plugin.yml @@ -0,0 +1,27 @@ +name: WastedVehicles +main: com.j0ach1mmall3.wastedvehicles.Main +version: 1.0.0 +author: j0ach1mmall3 +description: A Vehicles plugin for GTM +depend: [JLib, WastedGuns] +commands: + GiveVehicle: + description: Gives a vehicle to a player + usage: /<command> <identifier> <player> + WVReload: + description: Reloads the config + usage: /<command> + FixVehicles: +permissions: + wv.*: + description: All the WastedVehicles permissions + default: op + children: + wv.givevehicle: true + wv.reload: true + wv.givevehicle: + description: Access to /givevehicle + default: op + wv.reload: + description: Access to /wvreload + default: op \ No newline at end of file

")); + ret.append(TextUtil.implode(args, " ")); + } + + if (addShortHelp) { + ret.append(p.txt.parseTags(" ")); + ret.append(this.getHelpShort()); + } + + return ret.toString(); + } + + public String getUseageTemplate(boolean addShortHelp) { + return getUseageTemplate(this.commandChain, addShortHelp); + } + + public String getUseageTemplate() { + return getUseageTemplate(false); + } + + // -------------------------------------------- // + // Message Sending Helpers + // -------------------------------------------- // + + public void msg(String str, Object... args) { + sender.sendMessage(p.txt.parse(str, args)); + } + + public void msg(TL translation, Object... args) { + sender.sendMessage(p.txt.parse(translation.toString(), args)); + } + + public void sendMessage(String msg) { + sender.sendMessage(msg); + } + + public void sendMessage(List msgs) { + for (String msg : msgs) { + this.sendMessage(msg); + } + } + + public void sendFancyMessage(FancyMessage message) { + message.send(sender); + } + + public void sendFancyMessage(List messages) { + for (FancyMessage m : messages) { + sendFancyMessage(m); + } + } + + public List getToolTips(FPlayer player) { + List lines = new ArrayList(); + for (String s : p.getConfig().getStringList("tooltips.show")) { + lines.add(ChatColor.translateAlternateColorCodes('&', replaceFPlayerTags(s, player))); + } + return lines; + } + + public List getToolTips(Faction faction) { + List lines = new ArrayList(); + for (String s : p.getConfig().getStringList("tooltips.list")) { + lines.add(ChatColor.translateAlternateColorCodes('&', replaceFactionTags(s, faction))); + } + return lines; + } + + public String replaceFPlayerTags(String s, FPlayer player) { + if (s.contains("{balance}")) { + String balance = player.hasFaction() ? "" + player.getFaction().getStash() : "no balance"; + s = s.replace("{balance}", balance); + } + if (s.contains("{stash}")) { + String balance = player.hasFaction() ? "" + player.getFaction().getStash() : "no balance"; + s = s.replace("{stash}", balance); + } + if (s.contains("{lastSeen}")) { + String humanized = DurationFormatUtils.formatDurationWords(System.currentTimeMillis() - player.getLastLoginTime(), true, true) + " ago"; + String lastSeen = player.isOnline() ? ChatColor.GREEN + "Online" : (System.currentTimeMillis() - player.getLastLoginTime() < 432000000 ? ChatColor.YELLOW + humanized : ChatColor.RED + humanized); + s = s.replace("{lastSeen}", lastSeen); + } + if (s.contains("{power}")) { + String power = player.getPowerRounded() + "/" + player.getPowerMaxRounded(); + s = s.replace("{power}", power); + } + if (s.contains("{group}")) { + String group = P.p.getPrimaryGroup(Bukkit.getOfflinePlayer(UUID.fromString(player.getId()))); + s = s.replace("{group}", group); + } + return s; + } + + public String replaceFactionTags(String s, Faction faction) { + if (s.contains("{power}")) { + s = s.replace("{power}", String.valueOf(faction.getPowerRounded())); + } + if (s.contains("{stash}")) { + s = s.replace("{stash}", String.valueOf(faction.getStash())); + } + if (s.contains("{maxPower}")) { + s = s.replace("{maxPower}", String.valueOf(faction.getPowerMaxRounded())); + } + if (s.contains("{leader}")) { + FPlayer fLeader = faction.getFPlayerAdmin(); + String leader = fLeader == null ? "Server" : fLeader.getName().substring(0, fLeader.getName().length() > 14 ? 13 : fLeader.getName().length()); + s = s.replace("{leader}", leader); + } + if (s.contains("{chunks}")) { + s = s.replace("{chunks}", String.valueOf(faction.getLandRounded())); + } + if (s.contains("{members}")) { + s = s.replace("{members}", String.valueOf(faction.getSize())); + + } + if (s.contains("{online}")) { + s = s.replace("{online}", String.valueOf(faction.getOnlinePlayers().size())); + } + return s; + } + + // -------------------------------------------- // + // Argument Readers + // -------------------------------------------- // + + // Is set? ====================== + public boolean argIsSet(int idx) { + return this.args.size() >= idx + 1; + } + + // STRING ====================== + public String argAsString(int idx, String def) { + if (this.args.size() < idx + 1) { + return def; + } + return this.args.get(idx); + } + + public String argAsString(int idx) { + return this.argAsString(idx, null); + } + + // INT ====================== + public Integer strAsInt(String str, Integer def) { + if (str == null) { + return def; + } + try { + return Integer.parseInt(str); + } catch (Exception e) { + return def; + } + } + + public Integer argAsInt(int idx, Integer def) { + return strAsInt(this.argAsString(idx), def); + } + + public Integer argAsInt(int idx) { + return this.argAsInt(idx, null); + } + + // Double ====================== + public Double strAsDouble(String str, Double def) { + if (str == null) { + return def; + } + try { + return Double.parseDouble(str); + } catch (Exception e) { + return def; + } + } + + public Double argAsDouble(int idx, Double def) { + return strAsDouble(this.argAsString(idx), def); + } + + public Double argAsDouble(int idx) { + return this.argAsDouble(idx, null); + } + + // TODO: Go through the str conversion for the other arg-readers as well. + // Boolean ====================== + public Boolean strAsBool(String str) { + str = str.toLowerCase(); + return str.startsWith("y") || str.startsWith("t") || str.startsWith("on") || str.startsWith("+") || str.startsWith("1"); + } + + public Boolean argAsBool(int idx, boolean def) { + String str = this.argAsString(idx); + if (str == null) { + return def; + } + + return strAsBool(str); + } + + public Boolean argAsBool(int idx) { + return this.argAsBool(idx, false); + } + + // PLAYER ====================== + public Player strAsPlayer(String name, Player def, boolean msg) { + Player ret = def; + + if (name != null) { + Player player = Bukkit.getServer().getPlayer(name); + if (player != null) { + ret = player; + } + } + + if (msg && ret == null) { + this.msg(TL.GENERIC_NOPLAYERFOUND, name); + } + + return ret; + } + + public Player argAsPlayer(int idx, Player def, boolean msg) { + return this.strAsPlayer(this.argAsString(idx), def, msg); + } + + public Player argAsPlayer(int idx, Player def) { + return this.argAsPlayer(idx, def, true); + } + + public Player argAsPlayer(int idx) { + return this.argAsPlayer(idx, null); + } + + // BEST PLAYER MATCH ====================== + public Player strAsBestPlayerMatch(String name, Player def, boolean msg) { + Player ret = def; + + if (name != null) { + List players = Bukkit.getServer().matchPlayer(name); + if (players.size() > 0) { + ret = players.get(0); + } + } + + if (msg && ret == null) { + this.msg(TL.GENERIC_NOPLAYERMATCH, name); + } + + return ret; + } + + public Player argAsBestPlayerMatch(int idx, Player def, boolean msg) { + return this.strAsBestPlayerMatch(this.argAsString(idx), def, msg); + } + + public Player argAsBestPlayerMatch(int idx, Player def) { + return this.argAsBestPlayerMatch(idx, def, true); + } + + public Player argAsBestPlayerMatch(int idx) { + return this.argAsPlayer(idx, null); + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/MPlugin.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/MPlugin.java new file mode 100644 index 0000000..f9496d7 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/MPlugin.java @@ -0,0 +1,350 @@ +package com.massivecraft.factions.zcore; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.reflect.TypeToken; +import com.massivecraft.factions.Board; +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.FPlayers; +import com.massivecraft.factions.Factions; +import com.massivecraft.factions.zcore.persist.SaveTask; +import com.massivecraft.factions.zcore.util.PermUtil; +import com.massivecraft.factions.zcore.util.Persist; +import com.massivecraft.factions.zcore.util.TL; +import com.massivecraft.factions.zcore.util.TextUtil; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.java.JavaPlugin; + +import java.io.*; +import java.lang.reflect.Modifier; +import java.lang.reflect.Type; +import java.util.*; +import java.util.Map.Entry; +import java.util.logging.Level; + + +public abstract class MPlugin extends JavaPlugin { + + // Some utils + public Persist persist; + public TextUtil txt; + public PermUtil perm; + + // Persist related + public Gson gson; + private Integer saveTask = null; + private boolean autoSave = true; + protected boolean loadSuccessful = false; + + public boolean getAutoSave() { + return this.autoSave; + } + + public void setAutoSave(boolean val) { + this.autoSave = val; + } + + public String refCommand = ""; + + // Listeners + private MPluginSecretPlayerListener mPluginSecretPlayerListener; + + // Our stored base commands + private List> baseCommands = new ArrayList>(); + + public List> getBaseCommands() { + return this.baseCommands; + } + + // holds f stuck start times + private Map timers = new HashMap(); + + //holds f stuck taskids + public Map stuckMap = new HashMap(); + + // -------------------------------------------- // + // ENABLE + // -------------------------------------------- // + private long timeEnableStart; + + public boolean preEnable() { + log("=== ENABLE START ==="); + timeEnableStart = System.currentTimeMillis(); + + // Ensure basefolder exists! + this.getDataFolder().mkdirs(); + + // Create Utility Instances + this.perm = new PermUtil(this); + this.persist = new Persist(this); + + // GSON 2.1 is now embedded in CraftBukkit, used by the auto-updater: https://github.com/Bukkit/CraftBukkit/commit/0ed1d1fdbb1e0bc09a70bc7bfdf40c1de8411665 +// if ( ! lib.require("gson.jar", "http://search.maven.org/remotecontent?filepath=com/google/code/gson/gson/2.1/gson-2.1.jar")) return false; + this.gson = this.getGsonBuilder().create(); + + this.txt = new TextUtil(); + initTXT(); + + // attempt to get first command defined in plugin.yml as reference command, if any commands are defined in there + // reference command will be used to prevent "unknown command" console messages + try { + Map> refCmd = this.getDescription().getCommands(); + if (refCmd != null && !refCmd.isEmpty()) { + this.refCommand = (String) (refCmd.keySet().toArray()[0]); + } + } catch (ClassCastException ex) { + } + + // Create and register player command listener + this.mPluginSecretPlayerListener = new MPluginSecretPlayerListener(this); + getServer().getPluginManager().registerEvents(this.mPluginSecretPlayerListener, this); + + // Register recurring tasks + if (saveTask == null && Conf.saveToFileEveryXMinutes > 0.0) { + long saveTicks = (long) (20 * 60 * Conf.saveToFileEveryXMinutes); // Approximately every 30 min by default + saveTask = Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(this, new SaveTask(this), saveTicks, saveTicks); + } + + loadLang(); + + loadSuccessful = true; + return true; + } + + public void postEnable() { + log("=== ENABLE DONE (Took " + (System.currentTimeMillis() - timeEnableStart) + "ms) ==="); + } + + public void loadLang() { + File lang = new File(getDataFolder(), "lang.yml"); + OutputStream out = null; + InputStream defLangStream = this.getResource("lang.yml"); + if (!lang.exists()) { + try { + getDataFolder().mkdir(); + lang.createNewFile(); + if (defLangStream != null) { + out = new FileOutputStream(lang); + int read; + byte[] bytes = new byte[1024]; + + while ((read = defLangStream.read(bytes)) != -1) { + out.write(bytes, 0, read); + } + YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(new BufferedReader(new InputStreamReader(defLangStream))); + TL.setFile(defConfig); + } + } catch (IOException e) { + e.printStackTrace(); // So they notice + getLogger().severe("[Cartels] Couldn't create language file."); + getLogger().severe("[Cartels] This is a fatal error. Now disabling"); + this.setEnabled(false); // Without it loaded, we can't send them messages + } finally { + if (defLangStream != null) { + try { + defLangStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (out != null) { + try { + out.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + } + } + } + + YamlConfiguration conf = YamlConfiguration.loadConfiguration(lang); + for (TL item : TL.values()) { + if (conf.getString(item.getPath()) == null) { + conf.set(item.getPath(), item.getDefault()); + } + } + + // Remove this here because I'm sick of dealing with bug reports due to bad decisions on my part. + if (conf.getString(TL.COMMAND_SHOW_POWER.getPath(), "").contains("%5$s")) { + conf.set(TL.COMMAND_SHOW_POWER.getPath(), TL.COMMAND_SHOW_POWER.getDefault()); + log(Level.INFO, "Removed errant format specifier from c show power."); + } + + TL.setFile(conf); + try { + conf.save(lang); + } catch (IOException e) { + getLogger().log(Level.WARNING, "Cartels: Failed to save lang.yml."); + getLogger().log(Level.WARNING, "Cartels: Report this stack trace to drtshock."); + e.printStackTrace(); + } + } + + public void onDisable() { + if (saveTask != null) { + this.getServer().getScheduler().cancelTask(saveTask); + saveTask = null; + } + // only save data if plugin actually loaded successfully + if (loadSuccessful) { + Factions.getInstance().forceSave(); + FPlayers.getInstance().forceSave(); + Board.getInstance().forceSave(); + } + log("Disabled"); + } + + public void suicide() { + log("Now I suicide!"); + this.getServer().getPluginManager().disablePlugin(this); + } + + // -------------------------------------------- // + // Some inits... + // You are supposed to override these in the plugin if you aren't satisfied with the defaults + // The goal is that you always will be satisfied though. + // -------------------------------------------- // + + public GsonBuilder getGsonBuilder() { + return new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().serializeNulls().excludeFieldsWithModifiers(Modifier.TRANSIENT, Modifier.VOLATILE); + } + + // -------------------------------------------- // + // LANG AND TAGS + // -------------------------------------------- // + + // These are not supposed to be used directly. + // They are loaded and used through the TextUtil instance for the plugin. + public Map rawTags = new LinkedHashMap(); + + public void addRawTags() { + this.rawTags.put("l", ""); // logo + this.rawTags.put("a", ""); // art + this.rawTags.put("n", ""); // notice + this.rawTags.put("i", ""); // info + this.rawTags.put("g", ""); // good + this.rawTags.put("b", ""); // bad + this.rawTags.put("h", ""); // highligh + this.rawTags.put("c", ""); // command + this.rawTags.put("p", ""); // parameter + } + + public void initTXT() { + this.addRawTags(); + + Type type = new TypeToken>() { + }.getType(); + + Map tagsFromFile = this.persist.load(type, "tags"); + if (tagsFromFile != null) { + this.rawTags.putAll(tagsFromFile); + } + this.persist.save(this.rawTags, "tags"); + + for (Entry rawTag : this.rawTags.entrySet()) { + this.txt.tags.put(rawTag.getKey(), TextUtil.parseColor(rawTag.getValue())); + } + } + + // -------------------------------------------- // + // COMMAND HANDLING + // -------------------------------------------- // + + // can be overridden by P method, to provide option + public boolean logPlayerCommands() { + return true; + } + + public boolean handleCommand(CommandSender sender, String commandString, boolean testOnly) { + return handleCommand(sender, commandString, testOnly, false); + } + + public boolean handleCommand(final CommandSender sender, String commandString, boolean testOnly, boolean async) { + boolean noSlash = true; + if (commandString.startsWith("/")) { + noSlash = false; + commandString = commandString.substring(1); + } + + for (final MCommand command : this.getBaseCommands()) { + if (noSlash && !command.allowNoSlashAccess) { + continue; + } + + for (String alias : command.aliases) { + // disallow double-space after alias, so specific commands can be prevented (preventing "f home" won't prevent "f home") + if (commandString.startsWith(alias + " ")) { + return false; + } + + if (commandString.startsWith(alias + " ") || commandString.equals(alias)) { + final List args = new ArrayList(Arrays.asList(commandString.split("\\s+"))); + args.remove(0); + + if (testOnly) { + return true; + } + + if (async) { + Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() { + @Override + public void run() { + command.execute(sender, args); + } + }); + } else { + command.execute(sender, args); + } + + return true; + } + } + } + return false; + } + + public boolean handleCommand(CommandSender sender, String commandString) { + return this.handleCommand(sender, commandString, false); + } + + // -------------------------------------------- // + // HOOKS + // -------------------------------------------- // + public void preAutoSave() { + + } + + public void postAutoSave() { + + } + + public Map getStuckMap() { + return this.stuckMap; + } + + public Map getTimers() { + return this.timers; + } + + // -------------------------------------------- // + // LOGGING + // -------------------------------------------- // + public void log(Object msg) { + log(Level.INFO, msg); + } + + public void log(String str, Object... args) { + log(Level.INFO, this.txt.parse(str, args)); + } + + public void log(Level level, String str, Object... args) { + log(level, this.txt.parse(str, args)); + } + + public void log(Level level, Object msg) { + Bukkit.getLogger().log(level, "[" + this.getDescription().getFullName() + "] " + msg); + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/MPluginSecretPlayerListener.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/MPluginSecretPlayerListener.java new file mode 100644 index 0000000..7df5d34 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/MPluginSecretPlayerListener.java @@ -0,0 +1,52 @@ +package com.massivecraft.factions.zcore; + +import com.massivecraft.factions.FPlayers; +import com.massivecraft.factions.listeners.FactionsPlayerListener; +import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerLoginEvent; + +public class MPluginSecretPlayerListener implements Listener { + + private MPlugin p; + + public MPluginSecretPlayerListener(MPlugin p) { + this.p = p; + } + + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) { + if (FactionsPlayerListener.preventCommand(event.getMessage(), event.getPlayer())) { + if (p.logPlayerCommands()) { + Bukkit.getLogger().info("[PLAYER_COMMAND] " + event.getPlayer().getName() + ": " + event.getMessage()); + } + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onPlayerChat(AsyncPlayerChatEvent event) { + if (p.handleCommand(event.getPlayer(), event.getMessage(), false, true)) { + if (p.logPlayerCommands()) { + Bukkit.getLogger().info("[PLAYER_COMMAND] " + event.getPlayer().getName() + ": " + event.getMessage()); + } + event.setCancelled(true); + } + + /* Should be handled by stuff in FactionsChatListener + Player speaker = event.getPlayer(); + String format = event.getFormat(); + format = format.replace(Conf.chatTagReplaceString, P.p.getPlayerFactionTag(speaker)).replace("[FACTION_TITLE]", P.p.getPlayerTitle(speaker)); + event.setFormat(format); + */ + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onPlayerPreLogin(PlayerLoginEvent event) { + FPlayers.getInstance().getByPlayer(event.getPlayer()); + } +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/MemoryBoard.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/MemoryBoard.java new file mode 100644 index 0000000..bb8d817 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/MemoryBoard.java @@ -0,0 +1,313 @@ +package com.massivecraft.factions.zcore.persist; + +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; +import com.massivecraft.factions.*; +import com.massivecraft.factions.struct.Relation; +import com.massivecraft.factions.util.AsciiCompass; +import com.massivecraft.factions.util.LazyLocation; +import org.bukkit.ChatColor; + +import java.util.*; +import java.util.Map.Entry; + + +public abstract class MemoryBoard extends Board { + + public class MemoryBoardMap extends HashMap { + private static final long serialVersionUID = -6689617828610585368L; + + Multimap factionToLandMap = HashMultimap.create(); + + @Override + public String put(FLocation floc, String factionId) { + String previousValue = super.put(floc, factionId); + if (previousValue != null) { + factionToLandMap.remove(previousValue, floc); + } + + factionToLandMap.put(factionId, floc); + return previousValue; + } + + @Override + public String remove(Object key) { + String result = super.remove(key); + if (result != null) { + FLocation floc = (FLocation) key; + factionToLandMap.remove(result, floc); + } + + return result; + } + + @Override + public void clear() { + super.clear(); + factionToLandMap.clear(); + } + + public int getOwnedLandCount(String factionId) { + return factionToLandMap.get(factionId).size(); + } + + public void removeFaction(String factionId) { + Collection flocations = factionToLandMap.removeAll(factionId); + for (FLocation floc : flocations) { + super.remove(floc); + } + } + } + + public MemoryBoardMap flocationIds = new MemoryBoardMap(); + + //----------------------------------------------// + // Get and Set + //----------------------------------------------// + public String getIdAt(FLocation flocation) { + if (!flocationIds.containsKey(flocation)) { + return "0"; + } + + return flocationIds.get(flocation); + } + + public Faction getFactionAt(FLocation flocation) { + return Factions.getInstance().getFactionById(getIdAt(flocation)); + } + + public void setIdAt(String id, FLocation flocation) { + clearOwnershipAt(flocation); + + if (id.equals("0")) { + removeAt(flocation); + } + + flocationIds.put(flocation, id); + } + + public void setFactionAt(Faction faction, FLocation flocation) { + setIdAt(faction.getId(), flocation); + } + + public void removeAt(FLocation flocation) { + Faction faction = getFactionAt(flocation); + Iterator it = faction.getWarps().values().iterator(); + while (it.hasNext()) { + if (flocation.isInChunk(it.next().getLocation())) { + it.remove(); + } + } + clearOwnershipAt(flocation); + flocationIds.remove(flocation); + } + + public Set getAllClaims(String factionId) { + Set locs = new HashSet(); + Iterator> iter = flocationIds.entrySet().iterator(); + while (iter.hasNext()) { + Entry entry = iter.next(); + if (entry.getValue().equals(factionId)) { + locs.add(entry.getKey()); + } + } + return locs; + } + + public Set getAllClaims(Faction faction) { + return getAllClaims(faction.getId()); + } + + // not to be confused with claims, ownership referring to further member-specific ownership of a claim + public void clearOwnershipAt(FLocation flocation) { + Faction faction = getFactionAt(flocation); + if (faction != null && faction.isNormal()) { + faction.clearClaimOwnership(flocation); + } + } + + public void unclaimAll(String factionId) { + Faction faction = Factions.getInstance().getFactionById(factionId); + if (faction != null && faction.isNormal()) { + faction.clearAllClaimOwnership(); + faction.clearWarps(); + } + clean(factionId); + } + + public void clean(String factionId) { + flocationIds.removeFaction(factionId); + } + + // Is this coord NOT completely surrounded by coords claimed by the same faction? + // Simpler: Is there any nearby coord with a faction other than the faction here? + public boolean isBorderLocation(FLocation flocation) { + Faction faction = getFactionAt(flocation); + FLocation a = flocation.getRelative(1, 0); + FLocation b = flocation.getRelative(-1, 0); + FLocation c = flocation.getRelative(0, 1); + FLocation d = flocation.getRelative(0, -1); + return faction != getFactionAt(a) || faction != getFactionAt(b) || faction != getFactionAt(c) || faction != getFactionAt(d); + } + + // Is this coord connected to any coord claimed by the specified faction? + public boolean isConnectedLocation(FLocation flocation, Faction faction) { + FLocation a = flocation.getRelative(1, 0); + FLocation b = flocation.getRelative(-1, 0); + FLocation c = flocation.getRelative(0, 1); + FLocation d = flocation.getRelative(0, -1); + return faction == getFactionAt(a) || faction == getFactionAt(b) || faction == getFactionAt(c) || faction == getFactionAt(d); + } + + /** + * Checks if there is another faction within a given radius other than Wilderness. Used for HCF feature that + * requires a 'buffer' between factions. + * + * @param flocation - center location. + * @param faction - faction checking for. + * @param radius - chunk radius to check. + * + * @return true if another Faction is within the radius, otherwise false. + */ + public boolean hasFactionWithin(FLocation flocation, Faction faction, int radius) { + for (int x = -radius; x <= radius; x++) { + for (int z = -radius; z <= radius; z++) { + if (x == 0 && z == 0) { + continue; + } + + FLocation relative = flocation.getRelative(x, z); + Faction other = getFactionAt(relative); + + if (other.isNormal() && other != faction) { + return true; + } + } + } + return false; + } + + + //----------------------------------------------// + // Cleaner. Remove orphaned foreign keys + //----------------------------------------------// + + public void clean() { + Iterator> iter = flocationIds.entrySet().iterator(); + while (iter.hasNext()) { + Entry entry = iter.next(); + if (!Factions.getInstance().isValidFactionId(entry.getValue())) { + P.p.log("Board cleaner removed " + entry.getValue() + " from " + entry.getKey()); + iter.remove(); + } + } + } + + //----------------------------------------------// + // Coord count + //----------------------------------------------// + + public int getFactionCoordCount(String factionId) { + return flocationIds.getOwnedLandCount(factionId); + } + + public int getFactionCoordCount(Faction faction) { + return getFactionCoordCount(faction.getId()); + } + + public int getFactionCoordCountInWorld(Faction faction, String worldName) { + String factionId = faction.getId(); + int ret = 0; + Iterator> iter = flocationIds.entrySet().iterator(); + while (iter.hasNext()) { + Entry entry = iter.next(); + if (entry.getValue().equals(factionId) && entry.getKey().getWorldName().equals(worldName)) { + ret += 1; + } + } + return ret; + } + + //----------------------------------------------// + // Map generation + //----------------------------------------------// + + /** + * The map is relative to a coord and a faction north is in the direction of decreasing x east is in the direction + * of decreasing z + */ + public ArrayList getMap(Faction faction, FLocation flocation, double inDegrees) { + ArrayList ret = new ArrayList(); + Faction factionLoc = getFactionAt(flocation); + ret.add(P.p.txt.titleize("(" + flocation.getCoordString() + ") " + factionLoc.getTag(faction))); + + int halfWidth = Conf.mapWidth / 2; + int halfHeight = Conf.mapHeight / 2; + FLocation topLeft = flocation.getRelative(-halfWidth, -halfHeight); + int width = halfWidth * 2 + 1; + int height = halfHeight * 2 + 1; + + if (Conf.showMapFactionKey) { + height--; + } + + Map fList = new HashMap(); + int chrIdx = 0; + + // For each row + for (int dz = 0; dz < height; dz++) { + // Draw and add that row + String row = ""; + for (int dx = 0; dx < width; dx++) { + if (dx == halfWidth && dz == halfHeight) { + row += ChatColor.AQUA + "+"; + } else { + FLocation flocationHere = topLeft.getRelative(dx, dz); + Faction factionHere = getFactionAt(flocationHere); + Relation relation = faction.getRelationTo(factionHere); + if (factionHere.isWilderness()) { + row += ChatColor.GRAY + "-"; + } else if (factionHere.isSafeZone()) { + row += Conf.colorPeaceful + "+"; + } else if (factionHere.isWarZone()) { + row += ChatColor.DARK_RED + "+"; + } else if (factionHere == faction || + factionHere == factionLoc || + relation.isAtLeast(Relation.ALLY) || + (Conf.showNeutralFactionsOnMap && relation.equals(Relation.NEUTRAL)) || + (Conf.showEnemyFactionsOnMap && relation.equals(Relation.ENEMY))) { + if (!fList.containsKey(factionHere.getTag())) { + fList.put(factionHere.getTag(), Conf.mapKeyChrs[Math.min(chrIdx++, Conf.mapKeyChrs.length - 1)]); + } + char tag = fList.get(factionHere.getTag()); + row += factionHere.getColorTo(faction) + "" + tag; + } else { + row += ChatColor.GRAY + "-"; + } + } + } + ret.add(row); + } + + // Get the compass + ArrayList asciiCompass = AsciiCompass.getAsciiCompass(inDegrees, ChatColor.RED, P.p.txt.parse("")); + + // Add the compass + ret.set(1, asciiCompass.get(0) + ret.get(1).substring(3 * 3)); + ret.set(2, asciiCompass.get(1) + ret.get(2).substring(3 * 3)); + ret.set(3, asciiCompass.get(2) + ret.get(3).substring(3 * 3)); + + // Add the faction key + if (Conf.showMapFactionKey) { + String fRow = ""; + for (String key : fList.keySet()) { + fRow += String.format("%s%s: %s ", ChatColor.GRAY, fList.get(key), key); + } + ret.add(fRow); + } + + return ret; + } + + public abstract void convertFrom(MemoryBoard old); +} diff --git a/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFPlayer.java b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFPlayer.java new file mode 100644 index 0000000..7441ed1 --- /dev/null +++ b/cartels-master@e4f5c2ecec5/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFPlayer.java @@ -0,0 +1,953 @@ +package com.massivecraft.factions.zcore.persist; + +import com.massivecraft.factions.*; +import com.massivecraft.factions.eco.EcoResult; +import com.massivecraft.factions.event.FPlayerLeaveEvent; +import com.massivecraft.factions.event.LandClaimEvent; +import com.massivecraft.factions.iface.EconomyParticipator; +import com.massivecraft.factions.iface.RelationParticipator; +import com.massivecraft.factions.integration.Econ; +import com.massivecraft.factions.integration.Essentials; +import com.massivecraft.factions.integration.Worldguard; +import com.massivecraft.factions.scoreboards.FScoreboard; +import com.massivecraft.factions.scoreboards.sidebar.FInfoSidebar; +import com.massivecraft.factions.struct.ChatMode; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.struct.Relation; +import com.massivecraft.factions.struct.Role; +import com.massivecraft.factions.util.RelationUtil; +import com.massivecraft.factions.util.WarmUpUtil; +import com.massivecraft.factions.zcore.util.TL; +import net.grandtheftmc.core.util.NumeralUtil; +import org.bukkit.*; +import org.bukkit.entity.Player; + +import java.util.*; + + +/** + * Logged in players always have exactly one FPlayer instance. Logged out players may or may not have an FPlayer + * instance. They will always have one if they are part of a faction. This is because only players with a faction are + * saved to disk (in order to not waste disk space). + *